summaryrefslogtreecommitdiffstats
path: root/usr.bin/tn3270
diff options
context:
space:
mode:
authorrgrimes <rgrimes@FreeBSD.org>1994-05-27 12:33:43 +0000
committerrgrimes <rgrimes@FreeBSD.org>1994-05-27 12:33:43 +0000
commitf9ab90d9d6d02989a075d0f0074496d5b1045e4b (patch)
treeadd7e996bac5289cdc55e6935750c352505560a9 /usr.bin/tn3270
parentbe22b15ae2ff8d7fe06b6e14fddf0c5b444a95da (diff)
downloadFreeBSD-src-f9ab90d9d6d02989a075d0f0074496d5b1045e4b.zip
FreeBSD-src-f9ab90d9d6d02989a075d0f0074496d5b1045e4b.tar.gz
BSD 4.4 Lite Usr.bin Sources
Diffstat (limited to 'usr.bin/tn3270')
-rw-r--r--usr.bin/tn3270/Makefile9
-rw-r--r--usr.bin/tn3270/Makefile.inc4
-rw-r--r--usr.bin/tn3270/api/api_bsd.c281
-rw-r--r--usr.bin/tn3270/api/api_exch.c429
-rw-r--r--usr.bin/tn3270/api/api_exch.h161
-rw-r--r--usr.bin/tn3270/api/apilib.c411
-rw-r--r--usr.bin/tn3270/api/apilib.h44
-rw-r--r--usr.bin/tn3270/api/asc_ebc.c110
-rw-r--r--usr.bin/tn3270/api/asc_ebc.h51
-rw-r--r--usr.bin/tn3270/api/astosc.c98
-rw-r--r--usr.bin/tn3270/api/astosc.h58
-rw-r--r--usr.bin/tn3270/api/dctype.c245
-rw-r--r--usr.bin/tn3270/api/dctype.h54
-rw-r--r--usr.bin/tn3270/api/disp_asc.c45
-rw-r--r--usr.bin/tn3270/api/disp_asc.h43
-rw-r--r--usr.bin/tn3270/api/ebc_disp.c106
-rw-r--r--usr.bin/tn3270/api/ebc_disp.h38
-rw-r--r--usr.bin/tn3270/ascii/default.map79
-rw-r--r--usr.bin/tn3270/ascii/map3270.c934
-rw-r--r--usr.bin/tn3270/ascii/map3270.h41
-rw-r--r--usr.bin/tn3270/ascii/mset.c410
-rw-r--r--usr.bin/tn3270/ascii/state.h50
-rw-r--r--usr.bin/tn3270/ascii/termin.c281
-rw-r--r--usr.bin/tn3270/ctlr/3180.kbd182
-rw-r--r--usr.bin/tn3270/ctlr/3270pc.kbd182
-rw-r--r--usr.bin/tn3270/ctlr/api.c755
-rw-r--r--usr.bin/tn3270/ctlr/api.h403
-rw-r--r--usr.bin/tn3270/ctlr/declare.h53
-rw-r--r--usr.bin/tn3270/ctlr/externs.h66
-rw-r--r--usr.bin/tn3270/ctlr/function.c47
-rw-r--r--usr.bin/tn3270/ctlr/function.h166
-rw-r--r--usr.bin/tn3270/ctlr/hostctlr.h222
-rw-r--r--usr.bin/tn3270/ctlr/inbound.c1194
-rw-r--r--usr.bin/tn3270/ctlr/oia.c51
-rw-r--r--usr.bin/tn3270/ctlr/oia.h190
-rw-r--r--usr.bin/tn3270/ctlr/options.c181
-rw-r--r--usr.bin/tn3270/ctlr/options.h41
-rw-r--r--usr.bin/tn3270/ctlr/outbound.c605
-rw-r--r--usr.bin/tn3270/ctlr/screen.h145
-rw-r--r--usr.bin/tn3270/ctlr/scrnctlr.h48
-rw-r--r--usr.bin/tn3270/ctlr/unix.kbd184
-rw-r--r--usr.bin/tn3270/distribution/README99
-rw-r--r--usr.bin/tn3270/distribution/arpa/makefile67
-rw-r--r--usr.bin/tn3270/distribution/arpa/telnet.h191
-rw-r--r--usr.bin/tn3270/distribution/makefile_4.2268
-rw-r--r--usr.bin/tn3270/distribution/sys_dos/makefile127
-rw-r--r--usr.bin/tn3270/distribution/sys_dos/spint.h49
-rw-r--r--usr.bin/tn3270/distribution/sys_dos/spintasm.asm252
-rw-r--r--usr.bin/tn3270/distribution/sys_dos/spintc.c186
-rw-r--r--usr.bin/tn3270/distribution/sys_dos/support.asm60
-rw-r--r--usr.bin/tn3270/distribution/sys_dos/system.c140
-rw-r--r--usr.bin/tn3270/distribution/sys_dos/termout.c514
-rw-r--r--usr.bin/tn3270/distribution/sys_dos/termout.ext47
-rw-r--r--usr.bin/tn3270/distribution/sys_dos/video.h75
-rw-r--r--usr.bin/tn3270/distribution/telnet/Makefile_ultrix179
-rw-r--r--usr.bin/tn3270/distribution/ultrix.curses46
-rw-r--r--usr.bin/tn3270/distribution/utilities/adm3a.keys78
-rw-r--r--usr.bin/tn3270/distribution/utilities/cross.c55
-rw-r--r--usr.bin/tn3270/distribution/utilities/makefile121
-rw-r--r--usr.bin/tn3270/distribution/utilities/srccmd/tar/makefile8
-rw-r--r--usr.bin/tn3270/distribution/utilities/srccmd/tar/tar.h19
-rw-r--r--usr.bin/tn3270/distribution/utilities/srccmd/tar/tarread.c208
-rw-r--r--usr.bin/tn3270/distribution/utilities/tncomp.h51
-rw-r--r--usr.bin/tn3270/distribution/utilities/tnrecv.c674
-rw-r--r--usr.bin/tn3270/general/genbsubs.c125
-rw-r--r--usr.bin/tn3270/general/general.h65
-rw-r--r--usr.bin/tn3270/general/globals.c74
-rw-r--r--usr.bin/tn3270/general/globals.h130
-rw-r--r--usr.bin/tn3270/general/vaxbsubs.s101
-rw-r--r--usr.bin/tn3270/mset/Makefile34
-rw-r--r--usr.bin/tn3270/mset/map3270.5341
-rw-r--r--usr.bin/tn3270/mset/mset.1188
-rw-r--r--usr.bin/tn3270/sys_curses/system.c753
-rw-r--r--usr.bin/tn3270/sys_curses/telextrn.h71
-rw-r--r--usr.bin/tn3270/sys_curses/terminal.h81
-rw-r--r--usr.bin/tn3270/sys_curses/termout.c957
-rw-r--r--usr.bin/tn3270/telnet/Makefile87
-rw-r--r--usr.bin/tn3270/tn3270/Makefile80
-rw-r--r--usr.bin/tn3270/tn3270/tn3270.1339
-rw-r--r--usr.bin/tn3270/tools/Makefile5
-rw-r--r--usr.bin/tn3270/tools/mkastods/Makefile9
-rw-r--r--usr.bin/tn3270/tools/mkastods/mkastods.c77
-rw-r--r--usr.bin/tn3270/tools/mkastosc/Makefile9
-rw-r--r--usr.bin/tn3270/tools/mkastosc/mkastosc.c166
-rw-r--r--usr.bin/tn3270/tools/mkdctype/Makefile9
-rw-r--r--usr.bin/tn3270/tools/mkdctype/ectype.c313
-rw-r--r--usr.bin/tn3270/tools/mkdctype/ectype.h52
-rw-r--r--usr.bin/tn3270/tools/mkdctype/mkdctype.c99
-rw-r--r--usr.bin/tn3270/tools/mkdstoas/Makefile9
-rw-r--r--usr.bin/tn3270/tools/mkdstoas/mkdstoas.c78
-rw-r--r--usr.bin/tn3270/tools/mkhits/Makefile9
-rw-r--r--usr.bin/tn3270/tools/mkhits/dohits.c295
-rw-r--r--usr.bin/tn3270/tools/mkhits/dohits.h56
-rw-r--r--usr.bin/tn3270/tools/mkhits/mkhits.c147
-rw-r--r--usr.bin/tn3270/tools/mkmake.y1097
-rw-r--r--usr.bin/tn3270/tools/prt3270.c620
96 files changed, 18687 insertions, 0 deletions
diff --git a/usr.bin/tn3270/Makefile b/usr.bin/tn3270/Makefile
new file mode 100644
index 0000000..009e31f
--- /dev/null
+++ b/usr.bin/tn3270/Makefile
@@ -0,0 +1,9 @@
+# @(#)Makefile 8.1 (Berkeley) 6/6/93
+
+SUBDIR= tn3270 mset
+
+.if !make(install)
+SUBDIR+=tools
+.endif
+
+.include <bsd.subdir.mk>
diff --git a/usr.bin/tn3270/Makefile.inc b/usr.bin/tn3270/Makefile.inc
new file mode 100644
index 0000000..bd2446e
--- /dev/null
+++ b/usr.bin/tn3270/Makefile.inc
@@ -0,0 +1,4 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/6/93
+
+KBD= unix.kbd
+CFLAGS+=-DTERMCAP -DSRCRT -DKLUDGELINEMODE -DUSE_TERMIO -DTN3270
diff --git a/usr.bin/tn3270/api/api_bsd.c b/usr.bin/tn3270/api/api_bsd.c
new file mode 100644
index 0000000..46db372
--- /dev/null
+++ b/usr.bin/tn3270/api/api_bsd.c
@@ -0,0 +1,281 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)api_bsd.c 8.2 (Berkeley) 1/7/94";
+#endif /* not lint */
+
+#if defined(unix)
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <stdio.h>
+
+#include "../ctlr/api.h"
+#include "api_exch.h"
+
+
+int
+api_close_api()
+{
+ if (api_exch_outcommand(EXCH_CMD_DISASSOCIATE) == -1) {
+ return -1;
+ } else if (api_exch_flush() == -1) {
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+
+int
+api_open_api(string)
+char *string; /* if non-zero, where to connect to */
+{
+ struct sockaddr_in server;
+ struct hostent *hp;
+ struct storage_descriptor sd;
+ extern char *getenv();
+ char thehostname[100];
+ char keyname[100];
+ char inkey[100];
+ FILE *keyfile;
+ int sock;
+ unsigned int port;
+ int i;
+
+ if (string == 0) {
+ string = getenv("API3270"); /* Get API */
+ if (string == 0) {
+ fprintf(stderr,
+ "API3270 environmental variable not set - no API.\n");
+ return -1; /* Nothing */
+ }
+ }
+
+ if (sscanf(string, "%[^:]:%d:%s", thehostname,
+ (int *)&port, keyname) != 3) {
+ fprintf(stderr, "API3270 environmental variable has bad format.\n");
+ return -1;
+ }
+ /* Now, try to connect */
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (sock < 0) {
+ perror("opening API socket");
+ return -1;
+ }
+ server.sin_family = AF_INET;
+ hp = gethostbyname(thehostname);
+ if (hp == 0) {
+ fprintf(stderr, "%s specifies bad host name.\n", string);
+ return -1;
+ }
+ bcopy(hp->h_addr, (char *)&server.sin_addr, hp->h_length);
+ server.sin_port = htons(port);
+
+ if (connect(sock, (struct sockaddr *)&server, sizeof server) < 0) {
+ perror("connecting to API server");
+ return -1;
+ }
+ /* Now, try application level connection */
+ if (api_exch_init(sock, "client") == -1) {
+ return -1;
+ }
+ if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) {
+ return -1;
+ }
+ keyfile = fopen(keyname, "r");
+ if (keyfile == 0) {
+ perror("fopen");
+ return -1;
+ }
+ if (fscanf(keyfile, "%s\n", inkey) != 1) {
+ perror("fscanf");
+ return -1;
+ }
+ sd.length = strlen(inkey)+1;
+ if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
+ return -1;
+ }
+ if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length, inkey) == -1) {
+ return -1;
+ }
+ while ((i = api_exch_nextcommand()) != EXCH_CMD_ASSOCIATED) {
+ int passwd_length;
+ char *passwd, *getpass();
+ char buffer[200];
+
+ switch (i) {
+ case EXCH_CMD_REJECTED:
+ if (api_exch_intype(EXCH_TYPE_STORE_DESC,
+ sizeof sd, (char *)&sd) == -1) {
+ return -1;
+ }
+ if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
+ return -1;
+ }
+ buffer[sd.length] = 0;
+ fprintf(stderr, "%s\n", buffer);
+ if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) {
+ return -1;
+ }
+ break;
+ case EXCH_CMD_SEND_AUTH:
+ if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
+ return -1;
+ }
+ if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
+ return -1;
+ }
+ buffer[sd.length] = 0;
+ passwd = getpass(buffer); /* Go to terminal */
+ passwd_length = strlen(passwd);
+ if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
+ return -1;
+ }
+ if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
+ return -1;
+ }
+ buffer[sd.length] = 0;
+ if (sd.length) {
+ char *ptr;
+
+ ptr = passwd;
+ i = 0;
+ while (*ptr) {
+ *ptr++ ^= buffer[i++];
+ if (i >= sd.length) {
+ i = 0;
+ }
+ }
+ }
+ sd.length = passwd_length;
+ if (api_exch_outcommand(EXCH_CMD_AUTH) == -1) {
+ return -1;
+ }
+ if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
+ return -1;
+ }
+ if (api_exch_outtype(EXCH_TYPE_BYTES, passwd_length, passwd) == -1) {
+ return -1;
+ }
+ break;
+ case -1:
+ return -1;
+ default:
+ fprintf(stderr,
+ "Waiting for connection indicator, received 0x%x.\n", i);
+ break;
+ }
+ }
+ /* YEAH */
+ return 0; /* Happiness! */
+}
+
+
+api_exch_api(regs, sregs, parms, length)
+union REGS *regs;
+struct SREGS *sregs;
+char *parms;
+int length;
+{
+ struct storage_descriptor sd;
+ int i;
+
+ if (api_exch_outcommand(EXCH_CMD_REQUEST) == -1) {
+ return -1;
+ }
+ if (api_exch_outtype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) {
+ return -1;
+ }
+ if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) {
+ return -1;
+ }
+ sd.length = length;
+ sd.location = (long) parms;
+ if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
+ return -1;
+ }
+ if (api_exch_outtype(EXCH_TYPE_BYTES, length, parms) == -1) {
+ return -1;
+ }
+ while ((i = api_exch_nextcommand()) != EXCH_CMD_REPLY) {
+ switch (i) {
+ case EXCH_CMD_GIMME:
+ if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
+ == -1) {
+ return -1;
+ }
+ /*XXX validity check GIMME? */
+ if (api_exch_outcommand(EXCH_CMD_HEREIS) == -1) {
+ return -1;
+ }
+ if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
+ == -1) {
+ return -1;
+ }
+ if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length,
+ (char *)sd.location) == -1) {
+ return -1;
+ }
+ break;
+ case EXCH_CMD_HEREIS:
+ if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
+ == -1) {
+ return -1;
+ }
+ /* XXX Validty check HEREIS? */
+ if (api_exch_intype(EXCH_TYPE_BYTES, sd.length,
+ (char *)sd.location) == -1) {
+ return -1;
+ }
+ break;
+ default:
+ fprintf(stderr, "Waiting for reply command, we got command %d.\n",
+ i);
+ return -1;
+ }
+ }
+ if (api_exch_intype(EXCH_TYPE_REGS, sizeof *regs, (char *)regs) == -1) {
+ return -1;
+ }
+ if (api_exch_intype(EXCH_TYPE_SREGS, sizeof *sregs, (char *)sregs) == -1) {
+ return -1;
+ }
+ /* YEAH */
+ return 0; /* Happiness! */
+}
+
+#endif /* unix */
diff --git a/usr.bin/tn3270/api/api_exch.c b/usr.bin/tn3270/api/api_exch.c
new file mode 100644
index 0000000..a4626b9
--- /dev/null
+++ b/usr.bin/tn3270/api/api_exch.c
@@ -0,0 +1,429 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)api_exch.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include <stdio.h>
+
+#include "../general/general.h"
+
+#include "api_exch.h"
+
+static int sock; /* Socket number */
+
+static char whoarewe[40] = "";
+#define WHO_ARE_WE() fprintf(stderr, "(API %s) ", whoarewe);
+
+static enum {CONTENTION, SEND, RECEIVE } conversation;
+
+static struct exch_exch exch_state;
+
+static unsigned int
+ my_sequence,
+ your_sequence;
+
+static char ibuffer[4000], *ibuf_next, *ibuf_last;
+#define IBUFADDED(i) ibuf_last += (i)
+#define IBUFAVAILABLE() (ibuf_last-ibuf_next)
+#define IBUFFER() ibuffer
+#define IBUFFREE() (ibuffer+sizeof ibuffer-ibuf_last-1)
+#define IBUFGETBYTES(w,l) { memcpy(w, ibuf_next, l); ibuf_next += l; }
+#define IBUFRESET() (ibuf_next = ibuf_last = ibuffer)
+
+char obuffer[4000], *obuf_next;
+#define OBUFADDBYTES(w,l) { memcpy(obuf_next, w, l); obuf_next += l; }
+#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) {
+ WHO_ARE_WE();
+ perror("write");
+ return -1;
+ }
+ OBUFRESET();
+ }
+ return 0; /* All OK */
+}
+
+
+static int
+iget(location, length)
+char *location;
+int length;
+{
+ int count;
+
+ if (OBUFAVAILABLE()) {
+ if (outflush() == -1) {
+ return -1;
+ }
+ }
+ if ((count = IBUFAVAILABLE()) != 0) {
+ if (count > length) {
+ count = length;
+ }
+ IBUFGETBYTES(location, count);
+ length -= count;
+ location += count;
+ }
+ while (length) {
+ if (ibuf_next == ibuf_last) {
+ IBUFRESET();
+ }
+ if ((count = read(sock, IBUFFER(), IBUFFREE())) < 0) {
+ WHO_ARE_WE();
+ perror("read");
+ return -1;
+ }
+ if (count == 0) {
+ /* Reading past end-of-file */
+ WHO_ARE_WE();
+ fprintf(stderr, "End of file read\r\n");
+ return -1;
+ }
+ IBUFADDED(count);
+ if (count > length) {
+ count = length;
+ }
+ IBUFGETBYTES(location, count);
+ length -= count;
+ location += count;
+ }
+ return 0;
+}
+
+static char *
+exch_to_ascii(exch)
+int exch; /* opcode to decode */
+{
+ switch (exch) {
+ case EXCH_EXCH_COMMAND:
+ return "Command";
+ case EXCH_EXCH_TYPE:
+ return "Type";
+ case EXCH_EXCH_TURNAROUND:
+ return "Turnaround";
+ case EXCH_EXCH_RTS:
+ return "Request to Send";
+ default:
+ {
+ static char unknown[40];
+
+ sprintf(unknown, "(Unknown exchange 0x%02x)", exch&0xff);
+ return unknown;
+ }
+ }
+}
+
+/*
+ * Send the exch structure, updating the sequnce number field.
+ */
+
+static int
+send_state()
+{
+ if (OBUFROOM() < sizeof exch_state) {
+ if (outflush() == -1) {
+ return -1;
+ }
+ }
+ my_sequence = (my_sequence+1)&0xff;
+ exch_state.my_sequence = my_sequence;
+ exch_state.your_sequence = your_sequence;
+ OBUFADDBYTES((char *)&exch_state, sizeof exch_state);
+ return 0;
+}
+
+/*
+ * Receive the exch structure from the other side, checking
+ * sequence numbering.
+ */
+
+static int
+receive_state()
+{
+ if (iget((char *)&exch_state, sizeof exch_state) == -1) {
+ return -1;
+ }
+ if (conversation != CONTENTION) {
+ if (exch_state.your_sequence != my_sequence) {
+ WHO_ARE_WE();
+ fprintf(stderr, "Send sequence number mismatch.\n");
+ return -1;
+ }
+ if (exch_state.my_sequence != ((++your_sequence)&0xff)) {
+ WHO_ARE_WE();
+ fprintf(stderr, "Receive sequence number mismatch.\n");
+ return -1;
+ }
+ }
+ your_sequence = exch_state.my_sequence;
+ return 0;
+}
+
+static int
+enter_receive()
+{
+ switch (conversation) {
+ case CONTENTION:
+ exch_state.opcode = EXCH_EXCH_TURNAROUND;
+ if (send_state() == -1) {
+ return -1;
+ }
+ if (receive_state() == -1) {
+ return -1;
+ }
+ if (exch_state.opcode != EXCH_EXCH_RTS) {
+ WHO_ARE_WE();
+ fprintf(stderr, "In CONTENTION state: ");
+ if (exch_state.opcode == EXCH_EXCH_TURNAROUND) {
+ fprintf(stderr,
+ "Both sides tried to enter RECEIVE state.\n");
+ } else {
+ fprintf(stderr,
+ "Protocol error trying to enter RECEIVE state.\n");
+ }
+ return -1;
+ }
+ break;
+ case SEND:
+ exch_state.opcode = EXCH_EXCH_TURNAROUND;
+ if (send_state() == -1) {
+ return -1;
+ }
+ break;
+ }
+ conversation = RECEIVE;
+ return 0;
+}
+
+static int
+enter_send()
+{
+ switch (conversation) {
+ case CONTENTION:
+ exch_state.opcode = EXCH_EXCH_RTS;
+ if (send_state() == -1) {
+ return -1;
+ }
+ /* fall through */
+ case RECEIVE:
+ if (receive_state() == -1) {
+ return -1;
+ }
+ if (exch_state.opcode != EXCH_EXCH_TURNAROUND) {
+ WHO_ARE_WE();
+ fprintf(stderr, "Conversation error - both sides in SEND state.\n");
+ return -1;
+ }
+ }
+ conversation = SEND;
+ return 0;
+}
+
+int
+api_exch_nextcommand()
+{
+ if (conversation != RECEIVE) {
+ if (enter_receive() == -1) {
+ return -1;
+ }
+ }
+ if (receive_state() == -1) {
+ return -1;
+ }
+ if (exch_state.opcode != EXCH_EXCH_COMMAND) {
+ WHO_ARE_WE();
+ fprintf(stderr, "Expected a %s exchange, received a %s exchange.\n",
+ exch_to_ascii(EXCH_EXCH_COMMAND), exch_to_ascii(exch_state.opcode));
+ return -1;
+ }
+ return exch_state.command_or_type;
+}
+
+
+int
+api_exch_incommand(command)
+int command;
+{
+ int i;
+
+ if ((i = api_exch_nextcommand()) == -1) {
+ return -1;
+ }
+ if (i != command) {
+ WHO_ARE_WE();
+ fprintf(stderr, "Expected API command 0x%x, got API command 0x%x.\n",
+ command, i);
+ return -1;
+ }
+ return 0;
+}
+
+
+int
+api_exch_outcommand(command)
+int command;
+{
+ if (conversation != SEND) {
+ if (enter_send() == -1) {
+ return -1;
+ }
+ }
+ exch_state.command_or_type = command;
+ exch_state.opcode = EXCH_EXCH_COMMAND;
+ if (send_state() == -1) {
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+
+int
+api_exch_outtype(type, length, location)
+int
+ type,
+ length;
+char
+ *location;
+{
+ int netleng = length;
+
+ if (conversation != SEND) {
+ if (enter_send() == -1) {
+ return -1;
+ }
+ }
+ exch_state.opcode = EXCH_EXCH_TYPE;
+ exch_state.command_or_type = type;
+ exch_state.length = netleng;
+ if (send_state() == -1) {
+ return -1;
+ }
+ if (length) {
+ if (OBUFROOM() > length) {
+ OBUFADDBYTES(location, length);
+ } else {
+ if (outflush() == -1) {
+ return -1;
+ }
+ if (write(sock, location, length) != length) {
+ WHO_ARE_WE();
+ perror("write");
+ return -1;
+ }
+ }
+ }
+ return 0;
+}
+
+
+int
+api_exch_intype(type, length, location)
+int
+ type,
+ length;
+char
+ *location;
+{
+ int netleng = length;
+
+ if (conversation != RECEIVE) {
+ if (enter_receive() == -1) {
+ return -1;
+ }
+ }
+ if (receive_state() == -1) {
+ return -1;
+ }
+ if (exch_state.opcode != EXCH_EXCH_TYPE) {
+ WHO_ARE_WE();
+ fprintf(stderr,
+ "Expected to receive a %s exchange, received a %s exchange.\n",
+ exch_to_ascii(EXCH_EXCH_TYPE), exch_to_ascii(exch_state.opcode));
+ return -1;
+ }
+ if (exch_state.command_or_type != type) {
+ WHO_ARE_WE();
+ fprintf(stderr, "Expected type 0x%x, got type 0x%x.\n",
+ type, exch_state.command_or_type);
+ return -1;
+ }
+ if (exch_state.length != netleng) {
+ fprintf(stderr, "Type 0x%x - expected length %d, received length %u.\n",
+ type, length, exch_state.length);
+ return -1;
+ }
+ if (iget(location, length) == -1) {
+ return -1;
+ }
+ return 0;
+}
+
+int
+api_exch_flush()
+{
+ return outflush();
+}
+
+int
+api_exch_init(sock_number, ourname)
+int sock_number;
+char *ourname;
+{
+ extern char *strcpy();
+
+ sock = sock_number;
+ (void) strcpy(whoarewe, ourname); /* For error messages */
+
+ my_sequence = your_sequence = 0;
+
+ conversation = CONTENTION; /* We don't know which direction */
+
+ IBUFRESET();
+ OBUFRESET();
+
+ return 0;
+}
diff --git a/usr.bin/tn3270/api/api_exch.h b/usr.bin/tn3270/api/api_exch.h
new file mode 100644
index 0000000..24e6691
--- /dev/null
+++ b/usr.bin/tn3270/api/api_exch.h
@@ -0,0 +1,161 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)api_exch.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * This file describes the structures passed back and forth
+ * between the API client and API server on a Unix-based
+ * tn3270 implementation.
+ */
+
+/*
+ * The following are the low-level opcodes exchanged between the
+ * two sides. These are designed to allow for type, sequence number,
+ * and direction checking.
+ *
+ * We enforce conversation flow. There are three states: CONTENTION,
+ * SEND, and RECEIVE. Both sides start in CONTENTION.
+ * We never leave RECEIVE state without first reading a TURNAROUND
+ * opcode. We never leave SEND state without first writing a TURNAROUND
+ * opcode. This scheme ensures that we always have conversation flowing
+ * in a synchronized direction (or detect an application error), and that
+ * we never hang with both sides trying to read from the "wire".
+ *
+ * State event action
+ *
+ * CONTENTION read request send TURNAROUND
+ * read RTS
+ * enter RECEIVE
+ * CONTENTION write request send RTS
+ * read TURNAROUND
+ * enter SEND
+ *
+ * RECEIVE read request read whatever
+ * RECEIVE write request read TURNAROUND
+ *
+ * SEND read request send TURNAROUND
+ * SEND write write whatever
+ */
+
+#define EXCH_EXCH_COMMAND 0 /* The following is a command */
+#define EXCH_EXCH_TURNAROUND 1 /* Your turn to send */
+#define EXCH_EXCH_RTS 2 /* Request to send */
+#define EXCH_EXCH_TYPE 3 /* The following is a type */
+
+struct exch_exch {
+ char
+ opcode; /* COMMAND, TURNAROUND, or TYPE */
+ unsigned char
+ my_sequence, /* 0-ff, initially zero */
+ your_sequence, /* 0-ff, initially zero */
+ command_or_type; /* Application level command or type */
+ unsigned short
+ length; /* The length of any following data */
+};
+
+/*
+ * The following are the command codes which the higher level protocols
+ * send and receive.
+ */
+
+#define EXCH_CMD_ASSOCIATE 0 /* Connect [client->server] */
+ /*
+ * struct storage_desc
+ * char key[]
+ */
+#define EXCH_CMD_DISASSOCIATE 1 /* Disconnect [client->server] */
+#define EXCH_CMD_SEND_AUTH 2 /* Send password [server->client] */
+ /*
+ * struct storage_desc
+ * char prompt[]
+ * struct storage_desc
+ * char seed[]
+ */
+#define EXCH_CMD_AUTH 3 /* Authorization [client->server] */
+ /*
+ * struct storage_desc
+ * char authenticator[]
+ */
+#define EXCH_CMD_ASSOCIATED 4 /* Connected [server->client] */
+#define EXCH_CMD_REJECTED 5 /* Too bad [server->client] */
+ /*
+ * struct storage_desc
+ * char message[]
+ */
+
+#define EXCH_CMD_REQUEST 6 /* A request [client->server] */
+ /* struct regs,
+ * struct sregs,
+ * struct storage_desc
+ * char bytes[]
+ */
+#define EXCH_CMD_GIMME 7 /* Send storage [server->client] */
+ /*
+ * struct storage_desc
+ */
+#define EXCH_CMD_HEREIS 8 /* Here is storage [BOTH WAYS] */
+ /*
+ * struct storage_desc
+ * char bytes[]
+ */
+#define EXCH_CMD_REPLY 9 /* End of discussion */
+ /*
+ * struct regs,
+ * struct sregs,
+ */
+
+/*
+ * The following are typed parameters sent across the wire.
+ *
+ * This should be done much more generally, with some form of
+ * XDR or mapped conversation ability.
+ */
+
+#define EXCH_TYPE_REGS 0
+#define EXCH_TYPE_SREGS 1
+#define EXCH_TYPE_STORE_DESC 2
+#define EXCH_TYPE_BYTES 3
+
+/*
+ * each parameter that comes over looks like:
+ *
+ * char type of following
+ * short (2 bytes) length of following (network byte order)
+ * following
+ */
+
+struct storage_descriptor {
+ long location; /* In network byte order */
+ short length; /* In network byte order */
+};
diff --git a/usr.bin/tn3270/api/apilib.c b/usr.bin/tn3270/api/apilib.c
new file mode 100644
index 0000000..3146170
--- /dev/null
+++ b/usr.bin/tn3270/api/apilib.c
@@ -0,0 +1,411 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)apilib.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include "../ctlr/api.h"
+
+#include "apilib.h"
+
+int
+ api_sup_errno = 0, /* Supervisor error number */
+ api_sup_fcn_id = 0, /* Supervisor function id (0x12) */
+ api_fcn_errno = 0, /* Function error number */
+ api_fcn_fcn_id = 0; /* Function ID (0x6b, etc.) */
+
+static int
+ gate_sessmgr = 0,
+ gate_keyboard = 0,
+ gate_copy = 0,
+ gate_oiam = 0;
+
+/*
+ * Issue an API request, with reg structures supplied by the caller.
+ *
+ * Only certain routines need this (supervisor services come to mind).
+ */
+
+static int
+api_issue_regs(ah, al, bh, bl, cx, dx, parms, length, regs, sregs)
+int ah, al, bh, bl, cx, dx;
+char *parms;
+int length;
+union REGS *regs;
+struct SREGS *sregs;
+{
+ char far *ourseg = parms;
+
+ regs->h.ah = ah;
+ regs->h.al = al;
+ regs->h.bh = bh;
+ regs->h.bl = bl;
+ regs->x.cx = cx;
+ regs->x.dx = dx;
+ sregs->es = FP_SEG(ourseg);
+ regs->x.di = FP_OFF(ourseg);
+
+#if defined(MSDOS)
+ int86x(API_INTERRUPT_NUMBER, regs, regs, sregs);
+#endif /* defined(MSDOS) */
+#if defined(unix)
+ api_exch_api(regs, sregs, parms, length);
+#endif /* defined(unix) */
+
+ if (regs->h.cl != 0) {
+ api_sup_errno = regs->h.cl;
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+
+/*
+ * Issue an API request without requiring caller to supply
+ * registers. Most routines use this.
+ */
+
+static int
+api_issue(ah, al, bh, bl, cx, dx, parms, length)
+int
+ ah,
+ al,
+ bh,
+ bl,
+ cx,
+ dx;
+char *parms;
+int length; /* Length of parms */
+{
+ union REGS regs;
+ struct SREGS sregs;
+
+ return api_issue_regs(ah, al, bh, bl, cx, dx, parms, length, &regs, &sregs);
+}
+
+/*
+ * Supervisor Services
+ */
+
+int
+api_name_resolve(name)
+char *name;
+{
+ NameResolveParms parms;
+ int i;
+ union REGS regs;
+ struct SREGS sregs;
+
+ for (i = 0; i < sizeof parms.gate_name; i++) {
+ if (*name) {
+ parms.gate_name[i] = *name++;
+ } else {
+ parms.gate_name[i] = ' ';
+ }
+ }
+
+ if (api_issue_regs(NAME_RESOLUTION, 0, 0, 0, 0, 0, (char *) &parms,
+ sizeof parms, &regs, &sregs) == -1) {
+ return -1;
+ } else {
+ return regs.x.dx;
+ }
+}
+
+#if defined(unix)
+/*
+ * Block until the oia or ps is modified.
+ */
+
+int
+api_ps_or_oia_modified()
+{
+ union REGS regs;
+ struct SREGS sregs;
+
+ if (api_issue_regs(PS_OR_OIA_MODIFIED, 0, 0, 0, 0, 0, (char *) 0,
+ 0, &regs, &sregs) == -1) {
+ return -1;
+ } else {
+ return 0;
+ }
+}
+#endif /* defined(unix) */
+
+/*
+ * Session Information Services
+ */
+
+api_query_session_id(parms)
+QuerySessionIdParms *parms;
+{
+ if (api_issue(0x09, QUERY_SESSION_ID, 0x80, 0x20, 0,
+ gate_sessmgr, (char *)parms, sizeof *parms) == -1) {
+ api_fcn_errno = 0;
+ api_fcn_fcn_id = 0;
+ return -1;
+ } else if (parms->rc == 0) {
+ return 0;
+ } else {
+ api_fcn_errno = parms->rc;
+ api_fcn_fcn_id = parms->function_id;
+ return -1;
+ }
+}
+
+
+api_query_session_parameters(parms)
+QuerySessionParametersParms *parms;
+{
+ if (api_issue(0x09, QUERY_SESSION_PARAMETERS, 0x80, 0x20, 0,
+ gate_sessmgr, (char *)parms, sizeof *parms) == -1) {
+ api_fcn_errno = 0;
+ api_fcn_fcn_id = 0;
+ return -1;
+ } else if (parms->rc == 0) {
+ return 0;
+ } else {
+ api_fcn_errno = parms->rc;
+ api_fcn_fcn_id = parms->function_id;
+ return -1;
+ }
+}
+
+api_query_session_cursor(parms)
+QuerySessionCursorParms *parms;
+{
+ if (api_issue(0x09, QUERY_SESSION_CURSOR, 0x80, 0x20, 0xff,
+ gate_sessmgr, (char *)parms, sizeof *parms) == -1) {
+ api_fcn_errno = 0;
+ api_fcn_fcn_id = 0;
+ return -1;
+ } else if (parms->rc == 0) {
+ return 0;
+ } else {
+ api_fcn_errno = parms->rc;
+ api_fcn_fcn_id = parms->function_id;
+ return -1;
+ }
+}
+
+/*
+ * Keyboard Services
+ */
+
+api_connect_to_keyboard(parms)
+ConnectToKeyboardParms *parms;
+{
+ if (api_issue(0x09, CONNECT_TO_KEYBOARD, 0x80, 0x20, 0,
+ gate_keyboard, (char *)parms, sizeof *parms) == -1) {
+ api_fcn_errno = 0;
+ api_fcn_fcn_id = 0;
+ return -1;
+ } else if (parms->rc == 0) {
+ return 0;
+ } else {
+ api_fcn_errno = parms->rc;
+ api_fcn_fcn_id = parms->function_id;
+ return -1;
+ }
+}
+
+
+api_disconnect_from_keyboard(parms)
+DisconnectFromKeyboardParms *parms;
+{
+ if (api_issue(0x09, DISCONNECT_FROM_KEYBOARD, 0x80, 0x20, 0,
+ gate_keyboard, (char *)parms, sizeof *parms) == -1) {
+ api_fcn_errno = 0;
+ api_fcn_fcn_id = 0;
+ return -1;
+ } else if (parms->rc == 0) {
+ return 0;
+ } else {
+ api_fcn_errno = parms->rc;
+ api_fcn_fcn_id = parms->function_id;
+ return -1;
+ }
+}
+
+
+api_write_keystroke(parms)
+WriteKeystrokeParms *parms;
+{
+ if (api_issue(0x09, WRITE_KEYSTROKE, 0x80, 0x20, 0,
+ gate_keyboard, (char *)parms, sizeof *parms) == -1) {
+ api_fcn_errno = 0;
+ api_fcn_fcn_id = 0;
+ return -1;
+ } else if (parms->rc == 0) {
+ return 0;
+ } else {
+ api_fcn_errno = parms->rc;
+ api_fcn_fcn_id = parms->function_id;
+ return -1;
+ }
+}
+
+
+api_disable_input(parms)
+DisableInputParms *parms;
+{
+ if (api_issue(0x09, DISABLE_INPUT, 0x80, 0x20, 0,
+ gate_keyboard, (char *)parms, sizeof *parms) == -1) {
+ api_fcn_errno = 0;
+ api_fcn_fcn_id = 0;
+ return -1;
+ } else if (parms->rc == 0) {
+ return 0;
+ } else {
+ api_fcn_errno = parms->rc;
+ api_fcn_fcn_id = parms->function_id;
+ return -1;
+ }
+}
+
+api_enable_input(parms)
+EnableInputParms *parms;
+{
+ if (api_issue(0x09, ENABLE_INPUT, 0x80, 0x20, 0,
+ gate_keyboard, (char *)parms, sizeof *parms) == -1) {
+ api_fcn_errno = 0;
+ api_fcn_fcn_id = 0;
+ return -1;
+ } else if (parms->rc == 0) {
+ return 0;
+ } else {
+ api_fcn_errno = parms->rc;
+ api_fcn_fcn_id = parms->function_id;
+ return -1;
+ }
+}
+
+/*
+ * Copy Services
+ */
+
+api_copy_string(parms)
+CopyStringParms *parms;
+{
+ if (api_issue(0x09, COPY_STRING, 0x80, 0x20, 0xff,
+ gate_copy, (char *)parms, sizeof *parms) == -1) {
+ api_fcn_errno = 0;
+ api_fcn_fcn_id = 0;
+ return -1;
+ } else if (parms->rc == 0) {
+ return 0;
+ } else {
+ api_fcn_errno = parms->rc;
+ api_fcn_fcn_id = parms->function_id;
+ return -1;
+ }
+}
+
+/*
+ * Operator Information Area Services
+ */
+
+api_read_oia_group(parms)
+ReadOiaGroupParms *parms;
+{
+ if (api_issue(0x09, READ_OIA_GROUP, 0x80, 0x20, 0xff,
+ gate_oiam, (char *)parms, sizeof *parms) == -1) {
+ api_fcn_errno = 0;
+ api_fcn_fcn_id = 0;
+ return -1;
+ } else if (parms->rc == 0) {
+ return 0;
+ } else {
+ api_fcn_errno = parms->rc;
+ api_fcn_fcn_id = parms->function_id;
+ return -1;
+ }
+}
+
+/*
+ * The "we are done" routine. This gets called last.
+ */
+
+api_finish()
+{
+#if defined(unix)
+ if (api_close_api() == -1) {
+ return -1;
+ } else {
+ return 0;
+ }
+#endif /* defined(unix) */
+}
+
+
+/*
+ * The initialization routine. Be sure to call this first.
+ */
+
+api_init()
+{
+#if defined(MSDOS)
+ union REGS regs;
+ struct SREGS sregs;
+
+ regs.h.ah = 0x35;
+ regs.h.al = API_INTERRUPT_NUMBER;
+ intdosx(&regs, &regs, &sregs);
+
+ if ((regs.x.bx == 0) && (sregs.es == 0)) {
+ return 0; /* Interrupt not being handled */
+ }
+#endif /* defined(MSDOS) */
+#if defined(unix)
+ if (api_open_api((char *)0) == -1) {
+ return 0;
+ }
+#endif /* defined(unix) */
+
+ gate_sessmgr = api_name_resolve("SESSMGR");
+ gate_keyboard = api_name_resolve("KEYBOARD");
+ gate_copy = api_name_resolve("COPY");
+ gate_oiam = api_name_resolve("OIAM");
+
+ if ((gate_sessmgr == gate_keyboard) ||
+ (gate_sessmgr == gate_copy) ||
+ (gate_sessmgr == gate_oiam) ||
+ (gate_keyboard == gate_copy) ||
+ (gate_keyboard == gate_oiam) ||
+ (gate_copy == gate_oiam)) {
+ return 0; /* Interrupt doesn't seem correct */
+ }
+ return 1;
+}
diff --git a/usr.bin/tn3270/api/apilib.h b/usr.bin/tn3270/api/apilib.h
new file mode 100644
index 0000000..3253e39
--- /dev/null
+++ b/usr.bin/tn3270/api/apilib.h
@@ -0,0 +1,44 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)apilib.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * What one needs to specify
+ */
+
+extern int
+ api_sup_errno, /* Supervisor error number */
+ api_sup_fcn_id, /* Supervisor function id (0x12) */
+ api_fcn_errno, /* Function error number */
+ api_fcn_fcn_id; /* Function ID (0x6b, etc.) */
diff --git a/usr.bin/tn3270/api/asc_ebc.c b/usr.bin/tn3270/api/asc_ebc.c
new file mode 100644
index 0000000..14061f0
--- /dev/null
+++ b/usr.bin/tn3270/api/asc_ebc.c
@@ -0,0 +1,110 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)asc_ebc.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+/*
+ * Ascii<->Ebcdic translation tables.
+ */
+
+#include "asc_ebc.h"
+
+unsigned char asc_ebc[NASCII] = {
+
+/* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 20 */ 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
+/* 28 */ 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
+/* 30 */ 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+/* 38 */ 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
+/* 40 */ 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+/* 48 */ 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
+/* 50 */ 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
+/* 58 */ 0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
+/* 60 */ 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+/* 68 */ 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
+/* 70 */ 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
+/* 78 */ 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x00,
+
+};
+
+/*
+ * ebcdic to ascii translation tables
+ */
+
+unsigned char ebc_asc[NEBC] = {
+/* 00 */ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+/* 08 */ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+/* 10 */ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+/* 18 */ ' ', ' ', ' ', ' ', '*', ' ', ';', ' ',
+/* 20 */ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+/* 28 */ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+/* 30 */ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+/* 38 */ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+/* 40 */ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+
+/* 48 */ ' ', ' ',
+#if !defined(MSDOS)
+ /* 4A */ '\\',
+#else /* !defined(MSDOS) */
+ /* 4A */ '\233', /* PC cent sign */
+#endif /* !defined(MSDOS) */
+ /* 4B */ '.', '<', '(', '+', '|',
+
+/* 50 */ '&', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+/* 58 */ ' ', ' ', '!', '$', '*', ')', ';', '^',
+/* 60 */ '-', '/', ' ', ' ', ' ', ' ', ' ', ' ',
+/* 68 */ ' ', ' ', '|', ',', '%', '_', '>', '?',
+/* 70 */ ' ', '^', ' ', ' ', ' ', ' ', ' ', ' ',
+/* 78 */ ' ', '`', ':', '#', '@', '\'', '=', '"',
+/* 80 */ ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+/* 88 */ 'h', 'i', ' ', ' ', ' ', ' ', ' ', ' ',
+/* 90 */ ' ', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
+/* 98 */ 'q', 'r', ' ', ' ', ' ', ' ', ' ', ' ',
+/* A0 */ ' ', '~', 's', 't', 'u', 'v', 'w', 'x',
+/* A8 */ 'y', 'z', ' ', ' ', ' ', '[', ' ', ' ',
+/* B0 */ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+/* B8 */ ' ', ' ', ' ', ' ', ' ', ']', ' ', ' ',
+/* C0 */ '{', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+/* C8 */ 'H', 'I', ' ', ' ', ' ', ' ', ' ', ' ',
+/* D0 */ '}', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+/* D8 */ 'Q', 'R', ' ', ' ', ' ', ' ', ' ', ' ',
+/* E0 */ '\\', ' ', 'S', 'T', 'U', 'V', 'W', 'X',
+/* E8 */ 'Y', 'Z', ' ', ' ', ' ', ' ', ' ', ' ',
+/* F0 */ '0', '1', '2', '3', '4', '5', '6', '7',
+/* F8 */ '8', '9', ' ', ' ', ' ', ' ', ' ', ' ',
+};
diff --git a/usr.bin/tn3270/api/asc_ebc.h b/usr.bin/tn3270/api/asc_ebc.h
new file mode 100644
index 0000000..17c0488
--- /dev/null
+++ b/usr.bin/tn3270/api/asc_ebc.h
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)asc_ebc.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * Definitions of translate tables used for ascii<->ebcdic translation.
+ */
+
+#define INCLUDED_ASCEBC
+
+/*
+ * ascii/ebcdic translation information
+ */
+
+#define NASCII 128 /* number of ascii characters */
+
+#define NEBC 256 /* number of ebcdic characters */
+
+extern unsigned char
+ asc_ebc[NASCII], ebc_asc[NEBC];
diff --git a/usr.bin/tn3270/api/astosc.c b/usr.bin/tn3270/api/astosc.c
new file mode 100644
index 0000000..ff641d6
--- /dev/null
+++ b/usr.bin/tn3270/api/astosc.c
@@ -0,0 +1,98 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)astosc.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include <ctype.h>
+
+#include "../general/general.h"
+
+#include "../ctlr/function.h"
+
+#include "astosc.h"
+
+struct astosc astosc[256] = {
+#include "astosc.out"
+};
+
+/* compare two strings, ignoring case */
+
+static
+ustrcmp(string1, string2)
+register char *string1;
+register char *string2;
+{
+ register int c1, c2;
+
+ while ((c1 = (unsigned char) *string1++) != 0) {
+ if (isupper(c1)) {
+ c1 = tolower(c1);
+ }
+ if (isupper(c2 = (unsigned char) *string2++)) {
+ c2 = tolower(c2);
+ }
+ if (c1 < c2) {
+ return(-1);
+ } else if (c1 > c2) {
+ return(1);
+ }
+ }
+ if (*string2) {
+ return(-1);
+ } else {
+ return(0);
+ }
+}
+
+
+/*
+ * This routine takes a string and returns an integer. It may return
+ * -1 if there is no other integer which corresponds to the
+ * string. -1 implies an error.
+ */
+
+int
+ascii_to_index(string)
+register char *string;
+{
+ register struct astosc *this;
+
+ for (this = astosc; this <= &astosc[highestof(astosc)]; this++) {
+ if ((this->name != 0) && (ustrcmp(this->name, string) == 0)) {
+ return this-astosc;
+ }
+ }
+ return -1;
+}
diff --git a/usr.bin/tn3270/api/astosc.h b/usr.bin/tn3270/api/astosc.h
new file mode 100644
index 0000000..bbafd5f
--- /dev/null
+++ b/usr.bin/tn3270/api/astosc.h
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)astosc.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * This defines the structure used to translate:
+ *
+ * ascii name ==> (scancode, shiftstate)
+ *
+ * (Actually, map3270 does "ascii name ==> index", and
+ * termin does "index ==> (scancode, shiftstate)". Both
+ * mappings use this structure.)
+ */
+
+#define INCLUDED_ASTOSC
+
+struct astosc {
+ unsigned char
+ scancode, /* Scan code for this function */
+ shiftstate; /* Shift state for this function */
+ enum ctlrfcn function; /* Internal function identifier */
+ char *name; /* Name of this function */
+};
+
+int ascii_to_index(); /* Function to feed InitControl() */
+
+extern struct astosc astosc[256];
diff --git a/usr.bin/tn3270/api/dctype.c b/usr.bin/tn3270/api/dctype.c
new file mode 100644
index 0000000..1fd8a90
--- /dev/null
+++ b/usr.bin/tn3270/api/dctype.c
@@ -0,0 +1,245 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)dctype.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include "dctype.h"
+
+unsigned char dctype[192] = {
+/*00*/
+ D_SPACE,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+/*10*/
+ D_SPACE,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+ 0,
+ 0,
+ 0,
+ 0,
+/*20*/
+ D_DIGIT|D_PRINT,
+ D_DIGIT|D_PRINT,
+ D_DIGIT|D_PRINT,
+ D_DIGIT|D_PRINT,
+ D_DIGIT|D_PRINT,
+ D_DIGIT|D_PRINT,
+ D_DIGIT|D_PRINT,
+ D_DIGIT|D_PRINT,
+ D_DIGIT|D_PRINT,
+ D_DIGIT|D_PRINT,
+ 0,
+ 0,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+/*30*/
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+ 0,
+ 0,
+ 0,
+ 0,
+ D_PUNCT|D_PRINT,
+ 0,
+ D_PUNCT|D_PRINT,
+ 0,
+ 0,
+/*40*/
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+/*50*/
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+/*60*/
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+/*70*/
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+/*80*/
+ D_LOWER|D_PRINT,
+ D_LOWER|D_PRINT,
+ D_LOWER|D_PRINT,
+ D_LOWER|D_PRINT,
+ D_LOWER|D_PRINT,
+ D_LOWER|D_PRINT,
+ D_LOWER|D_PRINT,
+ D_LOWER|D_PRINT,
+ D_LOWER|D_PRINT,
+ D_LOWER|D_PRINT,
+ D_LOWER|D_PRINT,
+ D_LOWER|D_PRINT,
+ D_LOWER|D_PRINT,
+ D_LOWER|D_PRINT,
+ D_LOWER|D_PRINT,
+ D_LOWER|D_PRINT,
+/*90*/
+ D_LOWER|D_PRINT,
+ D_LOWER|D_PRINT,
+ D_LOWER|D_PRINT,
+ D_LOWER|D_PRINT,
+ D_LOWER|D_PRINT,
+ D_LOWER|D_PRINT,
+ D_LOWER|D_PRINT,
+ D_LOWER|D_PRINT,
+ D_LOWER|D_PRINT,
+ D_LOWER|D_PRINT,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+/*A0*/
+ D_UPPER|D_PRINT,
+ D_UPPER|D_PRINT,
+ D_UPPER|D_PRINT,
+ D_UPPER|D_PRINT,
+ D_UPPER|D_PRINT,
+ D_UPPER|D_PRINT,
+ D_UPPER|D_PRINT,
+ D_UPPER|D_PRINT,
+ D_UPPER|D_PRINT,
+ D_UPPER|D_PRINT,
+ D_UPPER|D_PRINT,
+ D_UPPER|D_PRINT,
+ D_UPPER|D_PRINT,
+ D_UPPER|D_PRINT,
+ D_UPPER|D_PRINT,
+ D_UPPER|D_PRINT,
+/*B0*/
+ D_UPPER|D_PRINT,
+ D_UPPER|D_PRINT,
+ D_UPPER|D_PRINT,
+ D_UPPER|D_PRINT,
+ D_UPPER|D_PRINT,
+ D_UPPER|D_PRINT,
+ D_UPPER|D_PRINT,
+ D_UPPER|D_PRINT,
+ D_UPPER|D_PRINT,
+ D_UPPER|D_PRINT,
+ 0,
+ 0,
+ 0,
+ 0,
+ D_PUNCT|D_PRINT,
+ D_PUNCT|D_PRINT,
+};
diff --git a/usr.bin/tn3270/api/dctype.h b/usr.bin/tn3270/api/dctype.h
new file mode 100644
index 0000000..2b0c068
--- /dev/null
+++ b/usr.bin/tn3270/api/dctype.h
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)dctype.h 8.1 (Berkeley) 6/6/93
+ */
+
+#define INCLUDED_ECTYPE
+
+#define D_UPPER 0x01
+#define D_LOWER 0x02
+#define D_DIGIT 0x04
+#define D_SPACE 0x08
+#define D_PUNCT 0x10
+#define D_PRINT 0x20
+
+#define Disalpha(c) (dctype[(c)]&(D_UPPER|D_LOWER))
+#define Disupper(c) (dctype[(c)]&D_UPPER)
+#define Dislower(c) (dctype[(c)]&D_LOWER)
+#define Disdigit(c) (dctype[(c)]&D_DIGIT)
+#define Disalnum(c) (dctype[(c)]&(D_UPPER|D_LOWER|D_DIGIT))
+#define Disspace(c) (dctype[(c)]&D_SPACE) /* blank or null */
+#define Dispunct(c) (dctype[(c)]&D_PUNCT)
+#define Disprint(c) (dctype[(c)]&D_PRINT)
+
+extern unsigned char dctype[192];
diff --git a/usr.bin/tn3270/api/disp_asc.c b/usr.bin/tn3270/api/disp_asc.c
new file mode 100644
index 0000000..85ba106
--- /dev/null
+++ b/usr.bin/tn3270/api/disp_asc.c
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)disp_asc.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+/*
+ * There isn't much excuse for this file, but here it is.
+ */
+
+#include "disp_asc.h"
+
+#include "asc_disp.out"
+#include "disp_asc.out"
diff --git a/usr.bin/tn3270/api/disp_asc.h b/usr.bin/tn3270/api/disp_asc.h
new file mode 100644
index 0000000..5abe92b
--- /dev/null
+++ b/usr.bin/tn3270/api/disp_asc.h
@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)disp_asc.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * Define the translate tables used to go between 3270 display code
+ * and ascii
+ */
+
+extern unsigned char
+ disp_asc[256], /* Goes between display code and ascii */
+ asc_disp[256]; /* Goes between ascii and display code */
diff --git a/usr.bin/tn3270/api/ebc_disp.c b/usr.bin/tn3270/api/ebc_disp.c
new file mode 100644
index 0000000..a601099
--- /dev/null
+++ b/usr.bin/tn3270/api/ebc_disp.c
@@ -0,0 +1,106 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)ebc_disp.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+/*
+ * Translate table to map EBCDIC into 3270 display codes.
+ */
+
+unsigned char ebc_disp[256] = {
+/*00*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*08*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*10*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*18*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*20*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*28*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*30*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*38*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*40*/ 0x10, 0x0a, 0x0b, 0x1c, 0x1d, 0x1e, 0x1f, 0x2a,
+/*48*/ 0x2b, 0x37, 0x1b, 0x32, 0x09, 0x0d, 0x35, 0x16,
+/*50*/ 0x30, 0x38, 0x39, 0x3a, 0x3c, 0x3e, 0x3f, 0x40,
+/*58*/ 0x41, 0x42, 0x19, 0x1a, 0xbf, 0x0c, 0xbe, 0x36,
+/*60*/ 0x31, 0x14, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
+/*68*/ 0x49, 0x4a, 0x17, 0x33, 0x2e, 0x2f, 0x08, 0x18,
+/*70*/ 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52,
+/*78*/ 0x53, 0x3d, 0x34, 0x2c, 0x2d, 0x12, 0x11, 0x13,
+/*80*/ 0x54, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86,
+/*88*/ 0x87, 0x88, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,
+/*90*/ 0x5b, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+/*98*/ 0x90, 0x91, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61,
+/*A0*/ 0x62, 0x3b, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+/*A8*/ 0x98, 0x99, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+/*B0*/ 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
+/*B8*/ 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+/*C0*/ 0x0f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
+/*C8*/ 0xa7, 0xa8, 0x79, 0x7a, 0x7b, 0x7c, 0x01, 0x02,
+/*D0*/ 0x0e, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+/*D8*/ 0xb0, 0xb1, 0x7d, 0x7e, 0x7f, 0x03, 0x04, 0x05,
+/*E0*/ 0x15, 0x9a, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+/*E8*/ 0xb8, 0xb9, 0x9b, 0x9c, 0x9d, 0x06, 0x07, 0x9e,
+/*F0*/ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+/*F8*/ 0x28, 0x29, 0xba, 0xbb, 0xbc, 0xbd, 0x9f, 0x00,
+};
+
+/*
+ * Translate table to map 3270 display codes to EBCDIC.
+ */
+
+unsigned char disp_ebc[192] = {
+/*00*/ 0x00, 0xce, 0xcf, 0xdd, 0xde, 0xdf, 0xed, 0xee,
+/*08*/ 0x6e, 0x4c, 0x41, 0x42, 0x5d, 0x4d, 0xd0, 0xc0,
+/*10*/ 0x40, 0x7e, 0x7d, 0x7f, 0x61, 0xe0, 0x4f, 0x6a,
+/*18*/ 0x6f, 0x5a, 0x5b, 0x4a, 0x43, 0x44, 0x45, 0x46,
+/*20*/ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+/*28*/ 0xf8, 0xf9, 0x47, 0x48, 0x7b, 0x7c, 0x6c, 0x6d,
+/*30*/ 0x50, 0x60, 0x4b, 0x6b, 0x7a, 0x4e, 0x5f, 0x49,
+/*38*/ 0x51, 0x52, 0x53, 0xa1, 0x54, 0x79, 0x55, 0x56,
+/*40*/ 0x57, 0x58, 0x59, 0x62, 0x63, 0x64, 0x65, 0x66,
+/*48*/ 0x67, 0x68, 0x69, 0x70, 0x71, 0x72, 0x73, 0x74,
+/*50*/ 0x75, 0x76, 0x77, 0x78, 0x80, 0x8a, 0x8b, 0x8c,
+/*58*/ 0x8d, 0x8e, 0x8f, 0x90, 0x9a, 0x9b, 0x9c, 0x9d,
+/*60*/ 0x9e, 0x9f, 0xa0, 0xaa, 0xab, 0xac, 0xad, 0xae,
+/*68*/ 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+/*70*/ 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe,
+/*78*/ 0xbf, 0xca, 0xcb, 0xcc, 0xcd, 0xda, 0xdb, 0xdc,
+/*80*/ 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
+/*88*/ 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+/*90*/ 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+/*98*/ 0xa8, 0xa9, 0xe1, 0xea, 0xeb, 0xec, 0xef, 0xfe,
+/*A0*/ 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
+/*A8*/ 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+/*B0*/ 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+/*B8*/ 0xe8, 0xe9, 0xfa, 0xfb, 0xfc, 0xfd, 0x5e, 0x5c,
+};
diff --git a/usr.bin/tn3270/api/ebc_disp.h b/usr.bin/tn3270/api/ebc_disp.h
new file mode 100644
index 0000000..201c39d
--- /dev/null
+++ b/usr.bin/tn3270/api/ebc_disp.h
@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)ebc_disp.h 8.1 (Berkeley) 6/6/93
+ */
+
+extern unsigned char
+ ebc_disp[256],
+ disp_ebc[192];
diff --git a/usr.bin/tn3270/ascii/default.map b/usr.bin/tn3270/ascii/default.map
new file mode 100644
index 0000000..a4cf6e1
--- /dev/null
+++ b/usr.bin/tn3270/ascii/default.map
@@ -0,0 +1,79 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)default.map 8.1 (Berkeley) 6/6/93
+ */
+
+/* default.map3270: This file is the system default for the key sequence
+ * if neither the user's TERM nor "unknown" are found in either of
+ * MAP3270 or /etc/map3270.
+ *
+ *
+ */
+#if defined(MSDOS)
+"tn3270pc{",
+" ENTER='^M';CLEAR='^Z'|'^Aw';NL='^N'|'^AO';TAB='^I';DP='^U';FM='^Y';",
+" BTAB='^B'|'^[^I'|'^A^O';LEFT='^H'|'^AK';RIGHT='^L'|'^AM';UP='^K'|'^AH';",
+" DOWN='^J'|'^AP';HOME='^^'|'^AG';DELETE='^AS'|'^D';EINP='^W';FLINP='^X';",
+" EEOF='^E'|'^Au';WERASE='^As';FERASE='^At';INSRT='^[ '|'^AR';CURSEL='^[.';",
+" PFK1='^A;'|'^F01'|'^[1'|'^Ax';PFK2='^A<'|'^F02'|'^[2'|'^Ay';SETTAB='^[;';",
+" PFK3='^A='|'^F03'|'^[3'|'^Az';CLRTAB='^[+'|'^[:';SETMRG='^[(';",
+" PFK4='^A>'|'^F04'|'^[4'|'^A{';PFK5='^A?'|'^F05'|'^[5'|'^A|';",
+" PFK6='^A@'|'^F06'|'^[6'|'^A}';PFK7='^AA'|'^AI'|'^F07'|'^[7'|'^A~';",
+" PFK8='^AB'|'^AQ'|'^F08'|'^[8'|'^A^?';PFK9='^AC'|'^F09'|'^[9'|'^A^A^@';",
+" PFK10='^AD'|'^F10'|'^[0'|'^A^A^A';SETHOM='^[!';COLTAB='^[i'|'^[I';",
+" COLBAK='^[b'|'^[B';INDENT='^[l'|'^[L';UNDENT='^[h'|'^[H';",
+" PFK11='^AT'|'^F11'|'^[-'|'^A^A^B';PFK12='^AU'|'^F12'|'^A^A^C'|'^[=';",
+" PFK13='^AV'|'^F13';PFK14='^AW'|'^F14';PFK15='^AX'|'^F15';",
+" PFK16='^AY'|'^F16';",
+" PFK17='^AZ'|'^F17';PFK18='^A['|'^F18';PFK19='^A\\\\'|'^F19';",
+" PFK20='^A]'|'^F20';PFK21='^A\\^'|'^F21';PFK22='^A_'|'^F22';PA3='^Aj'|'^P3';",
+" PFK23='^A`'|'^F23';PFK24='^Aa'|'^F24';PA1='^Ah'|'^P1';PA2='^Ai'|'^P2';",
+" RESET='^T'|'^R'; ",
+" MASTER_RESET='^G';RESHOW='^V';DELTAB='^[\\\'';ESCAPE='^C';",
+"}",
+#else /* defined(MSDOS) */
+"generic { clear = '^z'; flinp = '^x'; enter = '^m'; delete = '^d' | '^?';",
+" synch = '^r'; reshow = '^v'; eeof = '^e'; tab = '^i';",
+" btab = '^b'; nl = '^n'; left = '^h'; right = '^l';",
+" up = '^k'; down = '^j'; einp = '^w'; reset = '^t';",
+" xoff = '^s'; xon = '^q'; escape = '^c'; ferase = '^u';",
+" insrt = '\\E ';",
+" pa1 = '^p1'; pa2 = '^p2'; pa3 = '^p3';",
+" pfk1 = '\\E1'; pfk2 = '\\E2'; pfk3 = '\\E3'; pfk4 = '\\E4';",
+" pfk5 = '\\E5'; pfk6 = '\\E6'; pfk7 = '\\E7'; pfk8 = '\\E8';",
+" pfk9 = '\\E9'; pfk10 = '\\E0'; pfk11 = '\\E-'; pfk12 = '\\E=';",
+" pfk13 = '\\E!'; pfk14 = '\\E@'; pfk15 = '\\E#'; pfk16 = '\\E$';",
+" pfk17 = '\\E%'; pfk18 = '\\E\\^'; pfk19 = '\\E&'; pfk20 = '\\E*';",
+" pfk21 = '\\E('; pfk22 = '\\E)'; pfk23 = '\\E_'; pfk24 = '\\E+';",
+"}",
+#endif /* defined(MSDOS) */
diff --git a/usr.bin/tn3270/ascii/map3270.c b/usr.bin/tn3270/ascii/map3270.c
new file mode 100644
index 0000000..0295509
--- /dev/null
+++ b/usr.bin/tn3270/ascii/map3270.c
@@ -0,0 +1,934 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)map3270.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+/* This program reads a description file, somewhat like /etc/termcap,
+ that describes the mapping between the current terminal's keyboard and
+ a 3270 keyboard.
+ */
+#ifdef DOCUMENTATION_ONLY
+/* here is a sample (very small) entry...
+
+ # this table is sensitive to position on a line. In particular,
+ # a terminal definition for a terminal is terminated whenever a
+ # (non-comment) line beginning in column one is found.
+ #
+ # this is an entry to map tvi924 to 3270 keys...
+ v8|tvi924|924|televideo model 924 {
+ pfk1 = '\E1';
+ pfk2 = '\E2';
+ clear = '^z'; # clear the screen
+ }
+ */
+#endif /* DOCUMENTATION_ONLY */
+
+#include <stdio.h>
+#include <ctype.h>
+#if defined(unix)
+#include <strings.h>
+#else /* defined(unix) */
+#include <string.h>
+#endif /* defined(unix) */
+
+#define IsPrint(c) ((isprint(c) && !isspace(c)) || ((c) == ' '))
+
+#include "state.h"
+#include "map3270.h"
+
+#include "../general/globals.h"
+
+/* this is the list of types returned by the lex processor */
+#define LEX_CHAR 400 /* plain unadorned character */
+#define LEX_ESCAPED LEX_CHAR+1 /* escaped with \ */
+#define LEX_CARETED LEX_ESCAPED+1 /* escaped with ^ */
+#define LEX_END_OF_FILE LEX_CARETED+1 /* end of file encountered */
+#define LEX_ILLEGAL LEX_END_OF_FILE+1 /* trailing escape character */
+
+/* the following is part of our character set dependancy... */
+#define ESCAPE 0x1b
+#define TAB 0x09
+#define NEWLINE 0x0a
+#define CARRIAGE_RETURN 0x0d
+
+typedef struct {
+ int type; /* LEX_* - type of character */
+ int value; /* character this was */
+} lexicon;
+
+typedef struct {
+ int length; /* length of character string */
+ char array[500]; /* character string */
+} stringWithLength;
+
+#define panic(s) { fprintf(stderr, s); exit(1); }
+
+static state firstentry = { 0, STATE_NULL, 0, 0 };
+static state *headOfQueue = &firstentry;
+
+/* the following is a primitive adm3a table, to be used when nothing
+ * else seems to be avaliable.
+ */
+
+#ifdef DEBUG
+static int debug = 0; /* debug flag (for debuggin tables) */
+#endif /* DEBUG */
+
+static int (*GetTc)();
+static int doPaste = 1; /* should we have side effects */
+static int picky = 0; /* do we complain of unknown functions? */
+static char usePointer = 0; /* use pointer, or file */
+static FILE *ourFile= 0;
+static char *environPointer = 0;/* if non-zero, point to input
+ * string in core.
+ */
+static char **whichkey = 0;
+static char *keysgeneric[] = {
+#include "default.map" /* Define the default default */
+
+ 0, /* Terminate list of entries */
+};
+ ;
+
+static int Empty = 1, /* is the unget lifo empty? */
+ Full = 0; /* is the unget lifo full? */
+static lexicon lifo[200] = { 0 }; /* character stack for parser */
+static int rp = 0, /* read pointer into lifo */
+ wp = 0; /* write pointer into lifo */
+
+static int
+GetC()
+{
+ int character;
+
+ if (usePointer) {
+ if ((*environPointer) == 0) {
+ /*
+ * If we have reached the end of this string, go on to
+ * the next (if there is a next).
+ */
+ if (whichkey == 0) {
+ static char suffix = 'A'; /* From environment */
+ char envname[9];
+ extern char *getenv();
+
+ (void) sprintf(envname, "MAP3270%c", suffix++);
+ environPointer = getenv(envname);
+ } else {
+ whichkey++; /* default map */
+ environPointer = *whichkey;
+ }
+ }
+ if (*environPointer) {
+ character = 0xff&*environPointer++;
+ } else {
+ character = EOF;
+ }
+ } else {
+ character = getc(ourFile);
+ }
+ return(character);
+}
+
+static lexicon
+Get()
+{
+ static lexicon c;
+ register lexicon *pC = &c;
+ register int character;
+
+ if (!Empty) {
+ *pC = lifo[rp];
+ rp++;
+ if (rp == sizeof lifo/sizeof (lexicon)) {
+ rp = 0;
+ }
+ if (rp == wp) {
+ Empty = 1;
+ }
+ Full = 0;
+ } else {
+ character = GetC();
+ switch (character) {
+ case EOF:
+ pC->type = LEX_END_OF_FILE;
+ break;
+ case '^':
+ character = GetC();
+ if (!IsPrint(character)) {
+ pC->type = LEX_ILLEGAL;
+ } else {
+ pC->type = LEX_CARETED;
+ if (character == '?') {
+ character |= 0x40; /* rubout */
+ } else {
+ character &= 0x1f;
+ }
+ }
+ break;
+ case '\\':
+ character = GetC();
+ if (!IsPrint(character)) {
+ pC->type = LEX_ILLEGAL;
+ } else {
+ pC->type = LEX_ESCAPED;
+ switch (character) {
+ case 'E': case 'e':
+ character = ESCAPE;
+ break;
+ case 't':
+ character = TAB;
+ break;
+ case 'n':
+ character = NEWLINE;
+ break;
+ case 'r':
+ character = CARRIAGE_RETURN;
+ break;
+ default:
+ pC->type = LEX_ILLEGAL;
+ break;
+ }
+ }
+ break;
+ default:
+ if ((IsPrint(character)) || isspace(character)) {
+ pC->type = LEX_CHAR;
+ } else {
+ pC->type = LEX_ILLEGAL;
+ }
+ break;
+ }
+ pC->value = character;
+ }
+ return(*pC);
+}
+
+static void
+UnGet(c)
+lexicon c; /* character to unget */
+{
+ if (Full) {
+ fprintf(stderr, "attempt to put too many characters in lifo\n");
+ panic("map3270");
+ /* NOTREACHED */
+ } else {
+ lifo[wp] = c;
+ wp++;
+ if (wp == sizeof lifo/sizeof (lexicon)) {
+ wp = 0;
+ }
+ if (wp == rp) {
+ Full = 1;
+ }
+ Empty = 0;
+ }
+}
+
+/*
+ * Construct a control character sequence
+ * for a special character.
+ */
+char *
+uncontrol(c)
+ register int c;
+{
+ static char buf[3];
+
+ if (c == 0x7f)
+ return ("^?");
+ if (c == '\377') {
+ return "-1";
+ }
+ if (c >= 0x20) {
+ buf[0] = c;
+ buf[1] = 0;
+ } else {
+ buf[0] = '^';
+ buf[1] = '@'+c;
+ buf[2] = 0;
+ }
+ return (buf);
+}
+
+/* compare two strings, ignoring case */
+
+ustrcmp(string1, string2)
+register char *string1;
+register char *string2;
+{
+ register int c1, c2;
+
+ while ((c1 = (unsigned char) *string1++) != 0) {
+ if (isupper(c1)) {
+ c1 = tolower(c1);
+ }
+ if (isupper(c2 = (unsigned char) *string2++)) {
+ c2 = tolower(c2);
+ }
+ if (c1 < c2) {
+ return(-1);
+ } else if (c1 > c2) {
+ return(1);
+ }
+ }
+ if (*string2) {
+ return(-1);
+ } else {
+ return(0);
+ }
+}
+
+
+static stringWithLength *
+GetQuotedString()
+{
+ lexicon lex, *lp;
+ static stringWithLength output = { 0 }; /* where return value is held */
+ char *pointer = output.array;
+
+ lex = Get();
+ if ((lex.type != LEX_CHAR) || (lex.value != '\'')) {
+ UnGet(lex);
+ return(0);
+ }
+ while (1) {
+ lex = Get();
+ if ((lex.type == LEX_CHAR) && (lex.value == '\'')) {
+ break;
+ }
+ lp = &lex;
+ if ((lp->type == LEX_CHAR) && !IsPrint(lp->value)) {
+ UnGet(lex);
+ return(0); /* illegal character in quoted string */
+ }
+ if (pointer >= output.array+sizeof output.array) {
+ return(0); /* too long */
+ }
+ *pointer++ = lex.value;
+ }
+ output.length = pointer-output.array;
+ return(&output);
+}
+
+#ifdef NOTUSED
+static stringWithLength *
+GetCharString()
+{
+ lexicon lex;
+ static stringWithLength output;
+ char *pointer = output.array;
+
+ lex = Get();
+
+ while ((lex.type == LEX_CHAR) &&
+ !isspace(lex.value) && (lex.value != '=')) {
+ *pointer++ = lex.value;
+ lex = Get();
+ if (pointer >= output.array + sizeof output.array) {
+ return(0); /* too long */
+ }
+ }
+ UnGet(lex);
+ output.length = pointer-output.array;
+ return(&output);
+}
+#endif /* NOTUSED */
+
+static
+GetCharacter(character)
+int character; /* desired character */
+{
+ lexicon lex;
+
+ lex = Get();
+
+ if ((lex.type != LEX_CHAR) || (lex.value != character)) {
+ UnGet(lex);
+ return(0);
+ }
+ return(1);
+}
+
+#ifdef NOTUSED
+static
+GetString(string)
+char *string; /* string to get */
+{
+ lexicon lex;
+
+ while (*string) {
+ lex = Get();
+ if ((lex.type != LEX_CHAR) || (lex.value != *string&0xff)) {
+ UnGet(lex);
+ return(0); /* XXX restore to state on entry */
+ }
+ string++;
+ }
+ return(1);
+}
+#endif /* NOTUSED */
+
+
+static stringWithLength *
+GetAlphaMericString()
+{
+ lexicon lex, *lp;
+ static stringWithLength output = { 0 };
+ char *pointer = output.array;
+# define IsAlnum(c) (isalnum(c) || (c == '_') \
+ || (c == '-') || (c == '.'))
+
+ lex = Get();
+ lp = &lex;
+
+ if ((lp->type != LEX_CHAR) || !IsAlnum(lp->value)) {
+ UnGet(lex);
+ return(0);
+ }
+
+ while ((lp->type == LEX_CHAR) && IsAlnum(lp->value)) {
+ *pointer++ = lex.value;
+ lex = Get();
+ }
+ UnGet(lex);
+ *pointer = 0;
+ output.length = pointer-output.array;
+ return(&output);
+}
+
+
+/* eat up characters until a new line, or end of file. returns terminating
+ character.
+ */
+
+static lexicon
+EatToNL()
+{
+ lexicon lex;
+
+ lex = Get();
+
+ while (!((lex.type != LEX_ESCAPED) && (lex.type != LEX_CARETED) &&
+ (lex.value == '\n')) && (!(lex.type == LEX_END_OF_FILE))) {
+ lex = Get();
+ }
+ if (lex.type != LEX_END_OF_FILE) {
+ return(Get());
+ } else {
+ return(lex);
+ }
+}
+
+
+static void
+GetWS()
+{
+ lexicon lex, *lp;
+
+ lex = Get();
+ lp = &lex;
+
+ while ((lp->type == LEX_CHAR) &&
+ (isspace(lp->value) || (lp->value == '#'))) {
+ if (lex.value == '#') {
+ lex = EatToNL();
+ } else {
+ lex = Get();
+ }
+ }
+ UnGet(lex);
+}
+
+static void
+FreeState(pState)
+state *pState;
+{
+ extern int free();
+
+ free((char *)pState);
+}
+
+
+static state *
+GetState()
+{
+ state *pState;
+ extern char *malloc();
+
+ pState = (state *) malloc(sizeof (state));
+
+ pState->result = STATE_NULL;
+ pState->next = 0;
+
+ return(pState);
+}
+
+
+static state *
+FindMatchAtThisLevel(pState, character)
+state *pState;
+int character;
+{
+ while (pState) {
+ if (pState->match == character) {
+ return(pState);
+ }
+ pState = pState->next;
+ }
+ return(0);
+}
+
+
+static state *
+PasteEntry(head, string, count, identifier)
+state *head; /* points to who should point here... */
+char *string; /* which characters to paste */
+int count; /* number of character to do */
+char *identifier; /* for error messages */
+{
+ state *pState, *other;
+
+ if (!doPaste) { /* flag to not have any side effects */
+ return((state *)1);
+ }
+ if (!count) {
+ return(head); /* return pointer to the parent */
+ }
+ if ((head->result != STATE_NULL) && (head->result != STATE_GOTO)) {
+ /* this means that a previously defined sequence is an initial
+ * part of this one.
+ */
+ fprintf(stderr, "Conflicting entries found when scanning %s\n",
+ identifier);
+ return(0);
+ }
+# ifdef DEBUG
+ if (debug) {
+ fprintf(stderr, "%s", uncontrol(*string));
+ }
+# endif /* DEBUG */
+ pState = GetState();
+ pState->match = *string;
+ if (head->result == STATE_NULL) {
+ head->result = STATE_GOTO;
+ head->address = pState;
+ other = pState;
+ } else { /* search for same character */
+ if ((other = FindMatchAtThisLevel(head->address, *string)) != 0) {
+ FreeState(pState);
+ } else {
+ pState->next = head->address;
+ head->address = pState;
+ other = pState;
+ }
+ }
+ return(PasteEntry(other, string+1, count-1, identifier));
+}
+
+static
+GetInput(tc, identifier)
+int tc;
+char *identifier; /* entry being parsed (for error messages) */
+{
+ stringWithLength *outputString;
+ state *head;
+ state fakeQueue;
+
+ if (doPaste) {
+ head = headOfQueue; /* always points to level above this one */
+ } else {
+ head = &fakeQueue; /* don't have any side effects... */
+ }
+
+ if ((outputString = GetQuotedString()) == 0) {
+ return(0);
+ } else if (IsPrint(outputString->array[0])) {
+ fprintf(stderr,
+ "first character of sequence for %s is not a control type character\n",
+ identifier);
+ return(0);
+ } else {
+ if ((head = PasteEntry(head, outputString->array,
+ outputString->length, identifier)) == 0) {
+ return(0);
+ }
+ GetWS();
+ while ((outputString = GetQuotedString()) != 0) {
+ if ((head = PasteEntry(head, outputString->array,
+ outputString->length, identifier)) == 0) {
+ return(0);
+ }
+ GetWS();
+ }
+ }
+ if (!doPaste) {
+ return(1);
+ }
+ if ((head->result != STATE_NULL) && (head->result != tc)) {
+ /* this means that this sequence is an initial part
+ * of a previously defined one.
+ */
+ fprintf(stderr, "Conflicting entries found when scanning %s\n",
+ identifier);
+ return(0);
+ } else {
+ head->result = tc;
+ return(1); /* done */
+ }
+}
+
+static
+GetDefinition()
+{
+ stringWithLength *string;
+ int Tc;
+
+ GetWS();
+ if ((string = GetAlphaMericString()) == 0) {
+ return(0);
+ }
+ string->array[string->length] = 0;
+ if (doPaste) {
+ if ((Tc = (*GetTc)(string->array)) == -1) {
+ if (picky) {
+ fprintf(stderr, "%s: unknown 3270 key identifier\n",
+ string->array);
+ }
+ Tc = STATE_NULL;
+ }
+ } else {
+ Tc = STATE_NULL; /* XXX ? */
+ }
+ GetWS();
+ if (!GetCharacter('=')) {
+ fprintf(stderr,
+ "Required equal sign after 3270 key identifier %s missing\n",
+ string->array);
+ return(0);
+ }
+ GetWS();
+ if (!GetInput(Tc, string->array)) {
+ fprintf(stderr, "Missing definition part for 3270 key %s\n",
+ string->array);
+ return(0);
+ } else {
+ GetWS();
+ while (GetCharacter('|')) {
+# ifdef DEBUG
+ if (debug) {
+ fprintf(stderr, " or ");
+ }
+# endif /* DEBUG */
+ GetWS();
+ if (!GetInput(Tc, string->array)) {
+ fprintf(stderr, "Missing definition part for 3270 key %s\n",
+ string->array);
+ return(0);
+ }
+ GetWS();
+ }
+ }
+ GetWS();
+ if (!GetCharacter(';')) {
+ fprintf(stderr, "Missing semi-colon for 3270 key %s\n", string->array);
+ return(0);
+ }
+# ifdef DEBUG
+ if (debug) {
+ fprintf(stderr, ";\n");
+ }
+# endif /* DEBUG */
+ return(1);
+}
+
+
+static
+GetDefinitions()
+{
+ if (!GetDefinition()) {
+ return(0);
+ } else {
+ while (GetDefinition()) {
+ ;
+ }
+ }
+ return(1);
+}
+
+static
+GetBegin()
+{
+ GetWS();
+ if (!GetCharacter('{')) {
+ return(0);
+ }
+ return(1);
+}
+
+static
+GetEnd()
+{
+ GetWS();
+ if (!GetCharacter('}')) {
+ return(0);
+ }
+ return(1);
+}
+
+static
+GetName()
+{
+ if (!GetAlphaMericString()) {
+ return(0);
+ }
+ GetWS();
+ while (GetAlphaMericString()) {
+ GetWS();
+ }
+ return(1);
+}
+
+static
+GetNames()
+{
+ GetWS();
+ if (!GetName()) {
+ return(0);
+ } else {
+ GetWS();
+ while (GetCharacter('|')) {
+ GetWS();
+ if (!GetName()) {
+ return(0);
+ }
+ }
+ }
+ return(1);
+}
+
+static
+GetEntry0()
+{
+ if (!GetBegin()) {
+ fprintf(stderr, "no '{'\n");
+ return(0);
+ } else if (!GetDefinitions()) {
+ fprintf(stderr, "unable to parse the definitions\n");
+ return(0);
+ } else if (!GetEnd()) {
+ fprintf(stderr, "No '}' or scanning stopped early due to error.\n");
+ return(0);
+ } else {
+ /* done */
+ return(1);
+ }
+}
+
+
+static
+GetEntry()
+{
+ if (!GetNames()) {
+ fprintf(stderr, "Invalid name field in entry.\n");
+ return(0);
+ } else {
+ return(GetEntry0());
+ }
+}
+
+/* position ourselves within a given filename to the entry for the current
+ * KEYBD (or TERM) variable
+ */
+
+Position(filename, keybdPointer)
+char *filename;
+char *keybdPointer;
+{
+ lexicon lex;
+ stringWithLength *name = 0;
+ stringWithLength *oldName;
+# define Return(x) {doPaste = 1; return(x);}
+
+ doPaste = 0;
+
+ if ((ourFile = fopen(filename, "r")) == NULL) {
+# if !defined(MSDOS)
+ fprintf(stderr, "Unable to open file %s\n", filename);
+# endif /* !defined(MSDOS) */
+ Return(0);
+ }
+ lex = Get();
+ while (lex.type != LEX_END_OF_FILE) {
+ UnGet(lex);
+ /* now, find an entry that is our type. */
+ GetWS();
+ oldName = name;
+ if ((name = GetAlphaMericString()) != 0) {
+ if (!ustrcmp(name->array, keybdPointer)) {
+ /* need to make sure there is a name here... */
+ lex.type = LEX_CHAR;
+ lex.value = 'a';
+ UnGet(lex);
+ Return(1);
+ }
+ } else if (GetCharacter('|')) {
+ ; /* more names coming */
+ } else {
+ lex = Get();
+ UnGet(lex);
+ if (lex.type != LEX_END_OF_FILE) {
+ if (!GetEntry0()) { /* start of an entry */
+ fprintf(stderr,
+ "error was in entry for %s in file %s\n",
+ (oldName)? oldName->array:"(unknown)", filename);
+ Return(0);
+ }
+ }
+ }
+ lex = Get();
+ }
+#if !defined(MSDOS)
+ fprintf(stderr, "Unable to find entry for %s in file %s\n", keybdPointer,
+ filename);
+#endif /* !defined(MSDOS) */
+ Return(0);
+}
+
+char *
+strsave(string)
+char *string;
+{
+ char *p;
+ extern char *malloc();
+
+ p = malloc((unsigned int)strlen(string)+1);
+ if (p != 0) {
+ strcpy(p, string);
+ }
+ return(p);
+}
+
+
+/*
+ * InitControl - our interface to the outside. What we should
+ * do is figure out keyboard (or terminal) type, set up file pointer
+ * (or string pointer), etc.
+ */
+
+state *
+InitControl(keybdPointer, pickyarg, translator)
+char *keybdPointer;
+int pickyarg; /* Should we be picky? */
+int (*translator)(); /* Translates ascii string to integer */
+{
+ extern char *getenv();
+ int GotIt;
+
+ picky = pickyarg;
+ GetTc = translator;
+
+ if (keybdPointer == 0) {
+ keybdPointer = getenv("KEYBD");
+ }
+ if (keybdPointer == 0) {
+ keybdPointer = getenv("TERM");
+ }
+
+ /*
+ * Some environments have getenv() return
+ * out of a static area. So, save the keyboard name.
+ */
+ if (keybdPointer) {
+ keybdPointer = strsave(keybdPointer);
+ }
+ environPointer = getenv("MAP3270");
+ if (environPointer
+ && (environPointer[0] != '/')
+#if defined(MSDOS)
+ && (environPointer[0] != '\\')
+#endif /* defined(MSDOS) */
+ && (strncmp(keybdPointer, environPointer,
+ strlen(keybdPointer) != 0)
+ || (environPointer[strlen(keybdPointer)] != '{'))) /* } */
+ {
+ environPointer = 0;
+ }
+
+ if ((!environPointer)
+#if defined(MSDOS)
+ || (*environPointer == '\\')
+#endif /* defined(MSDOS) */
+ || (*environPointer == '/')) {
+ usePointer = 0;
+ GotIt = 0;
+ if (!keybdPointer) {
+#if !defined(MSDOS)
+ fprintf(stderr, "%s%s%s%s",
+ "Neither the KEYBD environment variable nor the TERM ",
+ "environment variable\n(one of which is needed to determine ",
+ "the type of keyboard you are using)\n",
+ "is set. To set it, say 'setenv KEYBD <type>'\n");
+#endif /* !defined(MSDOS) */
+ } else {
+ if (environPointer) {
+ GotIt = Position(environPointer, keybdPointer);
+ }
+ if (!GotIt) {
+ GotIt = Position("/etc/map3270", keybdPointer);
+ }
+ }
+ if (!GotIt) {
+ if (environPointer) {
+ GotIt = Position(environPointer, "unknown");
+ }
+ if (!GotIt) {
+ GotIt = Position("/etc/map3270", keybdPointer);
+ }
+ }
+ if (!GotIt) {
+#if !defined(MSDOS)
+ fprintf(stderr, "Using default key mappings.\n");
+#endif /* !defined(MSDOS) */
+ usePointer = 1; /* flag use of non-file */
+ whichkey = keysgeneric;
+ environPointer = *whichkey; /* use default table */
+ }
+ } else {
+ usePointer = 1;
+ }
+ (void) GetEntry();
+ return(firstentry.address);
+}
diff --git a/usr.bin/tn3270/ascii/map3270.h b/usr.bin/tn3270/ascii/map3270.h
new file mode 100644
index 0000000..f8d6e5c
--- /dev/null
+++ b/usr.bin/tn3270/ascii/map3270.h
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)map3270.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * Declaration for map3270.c.
+ */
+
+extern state
+ *InitControl();
diff --git a/usr.bin/tn3270/ascii/mset.c b/usr.bin/tn3270/ascii/mset.c
new file mode 100644
index 0000000..508fe66
--- /dev/null
+++ b/usr.bin/tn3270/ascii/mset.c
@@ -0,0 +1,410 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1988, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)mset.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+/*
+ * this program outputs the user's 3270 mapping table in a form suitable
+ * for inclusion in the environment. Typically, this might be used
+ * by:
+ * setenv MAP3270 "`mset`"
+ */
+
+#include <stdio.h>
+#if defined(unix)
+#include <strings.h>
+#else /* defined(unix) */
+#include <string.h>
+#endif /* defined(unix) */
+#include "../ctlr/function.h"
+
+#include "state.h"
+#include "map3270.h"
+
+#include "../api/astosc.h"
+
+#include "../general/globals.h"
+
+struct regstate {
+ char *result;
+ char *match_start;
+ char *match_end; /* start of NEXT state's match string */
+ struct regstate *forward;
+ struct regstate *backward;
+};
+
+static struct regstate regstates[500], *rptr= 0; /* for sorting states */
+static char array[5000]; /* lot's of room */
+static int toshell = 0; /* export to shell */
+static int numbchars = 0; /* number of chars in envir. var */
+
+static int
+MyStrcmp(str1, str2)
+char *str1, *str2;
+{
+ if (strncmp(str1, "PFK", 3) == 0 && strncmp(str2, "PFK", 3) == 0
+ && strlen(str1) != strlen(str2)) {
+ return(strlen(str1) - strlen(str2));
+ }
+ return(strcmp(str1, str2));
+}
+
+static void
+forwRegister(regptr, sptr)
+struct regstate *regptr, *sptr;
+{
+
+ regptr->forward = sptr->forward;
+ regptr->backward = sptr;
+ (sptr->forward)->backward = regptr;
+ sptr->forward = regptr;
+}
+
+static void
+backRegister(regptr, sptr)
+struct regstate *regptr, *sptr;
+{
+
+ regptr->forward = sptr;
+ regptr->backward = sptr->backward;
+ (sptr->backward)->forward = regptr;
+ sptr->backward = regptr;
+}
+
+static struct regstate *
+doRegister(regptr)
+register struct regstate *regptr;
+{
+ static struct regstate *pivot = regstates;
+ register struct regstate *sptr = pivot;
+ int check;
+
+ if (pivot == regstates) { /* first time called */
+ pivot->forward = regptr;
+ regptr->backward = pivot++;
+ pivot->backward = regptr;
+ regptr->forward = pivot++;
+ return(++regptr);
+ }
+ if ((check = MyStrcmp(regptr->result, pivot->result)) < 0) {
+ while (check < 0) {
+ if (sptr->backward == regstates) {
+ backRegister(regptr, sptr);
+ pivot = pivot->backward;
+ return(++regptr);
+ }
+ sptr = sptr->backward;
+ check = MyStrcmp(regptr->result, sptr->result);
+ }
+ forwRegister(regptr, sptr);
+ pivot = pivot->backward;
+ return(++regptr);
+ }
+ while (check > 0) {
+ if ((sptr->forward)->result == 0) {
+ forwRegister(regptr, sptr);
+ pivot = pivot->forward;
+ return(++regptr);
+ }
+ sptr = sptr->forward;
+ check = MyStrcmp(regptr->result, sptr->result);
+ }
+ backRegister(regptr, sptr);
+ if (pivot->forward->result) {
+ pivot = pivot->forward;
+ }
+ return(++regptr);
+}
+
+static char *
+addString(strcount, character)
+int strcount;
+char character;
+{
+ static char *string = array;
+ int i;
+
+ if (rptr->match_start == 0) {
+ rptr->match_start = string;
+ for (i=0; i < strcount; i++) {
+ *string++ = *((rptr-1)->match_start+i);
+ }
+ }
+ *string++ = character;
+ return(string);
+}
+
+static char savename[20] = " "; /* for deciding if name is new */
+
+static void
+printString(string, begin, tc_name)
+register char *string;
+char *begin, *tc_name;
+{
+ register char *st1, *st2;
+ register int pchar;
+ static char suffix = 'A';
+ int new = strcmp(savename, tc_name);
+ char delim = new ? ';' : '|';
+ char *uncontrol();
+
+ st1 = begin;
+
+ numbchars += 5 + (new ? strlen(tc_name) : -1);
+ if (toshell && numbchars > 1011) {
+ new = 1;
+ delim = ';';
+ numbchars = 5 + strlen(tc_name);
+ printf(";\nsetenv MAP3270%c ", suffix++);
+ }
+ if (strcmp(" ", savename)) {
+ if (toshell) {
+ printf("%c%c", '\\', delim);
+ }
+ else {
+ printf("%c", delim);
+ }
+ }
+ else {
+ numbchars -= 2;
+ }
+ if (toshell && new) {
+ printf("%s=%c'", tc_name,'\\');
+ }
+ else if (new) {
+ printf("%s='", tc_name);
+ }
+ else if (toshell) {
+ printf("%c'", '\\');
+ }
+ else {
+ printf("'");
+ }
+ (void) strcpy(savename, tc_name);
+ while (st1 != string) {
+ if (toshell && numbchars >= 1016) { /* leave room for ctrl and delim */
+ numbchars = 0;
+ printf(";\nsetenv MAP3270%c ", suffix++);
+ }
+ pchar = 0xff&(*st1++);
+ switch (pchar) {
+ case '"':
+ case '!':
+ case '$':
+ case '(':
+ case ')':
+ case ' ':
+ case ';':
+ case '&':
+ case '|':
+ case '>':
+ case '<':
+ case '`':
+ case '#':
+ numbchars += 2;
+ if (toshell) {
+ printf("%c%c", '\\', pchar);
+ }
+ else {
+ printf("%c", pchar);
+ }
+ break;
+ case '\\':
+ case '\'':
+ numbchars += 4;
+ if (toshell) {
+ printf("%c%c%c%c", '\\', '\\', '\\', pchar);
+ }
+ else {
+ printf("%c%c", '\\', pchar);
+ }
+ break;
+ case '^':
+ numbchars += 3;
+ if (toshell) {
+ printf("%c%c%c", '\\', '\\', pchar);
+ }
+ else {
+ printf("%c%c", '\\', pchar);
+ }
+ break;
+ default:
+ st2 = uncontrol(pchar);
+ while ((pchar = *st2++) != 0) {
+ switch (pchar) {
+ case '"':
+ case '!':
+ case '$':
+ case '(':
+ case ')':
+ case ' ':
+ case ';':
+ case '&':
+ case '|':
+ case '>':
+ case '<':
+ case '`':
+ case '#':
+ case '\\':
+ case '\'':
+ if (toshell) {
+ numbchars += 2;
+ printf("%c%c", '\\', pchar);
+ }
+ else {
+ printf("%c", pchar);
+ }
+ break;
+ default:
+ numbchars++;
+ printf("%c", pchar);
+ break;
+ }
+ }
+ break;
+ }
+ }
+ numbchars += 2;
+ if (toshell) {
+ printf("%c'", '\\');
+ }
+ else {
+ printf("'");
+ }
+}
+
+static void
+recurse(strcount, head)
+state *head;
+int strcount;
+{
+ /* if there is a left,
+ * recurse on left,
+ * if there is no down,
+ * print the string to here
+ * else,
+ * add the current match to the string,
+ * recurse.
+ * exit.
+ */
+
+ if (head->next) {
+ recurse(strcount, head->next);
+ }
+ if (head->result != STATE_GOTO) {
+ rptr->match_end = addString(strcount, head->match);
+ rptr->result = astosc[head->result].name;
+ rptr = doRegister(rptr);
+ } else {
+ (void) addString(strcount, head->match);
+ recurse(strcount+1, head->address);
+ strcount--;
+ }
+ return;
+}
+
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ state *head;
+ char *keybdPointer = (char *) 0;
+ char *commandName = argv[0];
+ extern char *getenv();
+ int picky = 0;
+
+ while ((argc > 1) && (argv[1][0] == '-')) {
+ if (!strcmp(argv[1], "-picky")) {
+ picky++;
+ } else if (!strcmp(argv[1], "-shell")) {
+ toshell++;
+ } else {
+ fprintf(stderr, "usage: %s [-picky] [-shell] [keyboardname]\n",
+ commandName);
+ exit(1);
+ /*NOTREACHED*/
+ }
+ argv++;
+ argc--;
+ }
+ if (argc == 2) {
+ keybdPointer = argv[1];
+ } else if (argc > 2) {
+ fprintf(stderr, "usage: %s [-picky] [-shell] [keyboardname]\n",
+ commandName);
+ exit(1);
+ /*NOTREACHED*/
+ }
+ head = InitControl(keybdPointer, picky, ascii_to_index);
+ if (!head) {
+ return(1);
+ }
+ if (keybdPointer == 0) {
+ keybdPointer = getenv("KEYBD");
+ }
+ if (keybdPointer == 0) {
+ keybdPointer = getenv("TERM");
+ }
+ if (keybdPointer == 0) {
+ keybdPointer = "3a"; /* use 3a as the terminal */
+ }
+ if (toshell) {
+ printf("set noglob;\nsetenv MAP3270 ");
+ }
+ printf("%s{", keybdPointer);
+ numbchars = 2 + strlen(keybdPointer);
+ /* now, run through the table registering entries */
+ rptr = regstates + 2;
+ recurse(0, head);
+ /* now print them out */
+ for (rptr = regstates[0].forward; rptr->result != 0;
+ rptr = rptr->forward) {
+ printString(rptr->match_end, rptr->match_start, rptr->result);
+ }
+ if (toshell) {
+ printf("%c;};\nunset noglob;\n", '\\');
+ }
+ else {
+ printf(";}\n");
+ }
+ return(0);
+}
diff --git a/usr.bin/tn3270/ascii/state.h b/usr.bin/tn3270/ascii/state.h
new file mode 100644
index 0000000..562522a
--- /dev/null
+++ b/usr.bin/tn3270/ascii/state.h
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)state.h 8.1 (Berkeley) 6/6/93
+ */
+
+#define INCLUDED_STATE
+
+/* this defines the state structure used by the key mapping routines */
+
+
+#define STATE_NULL -1 /* Falls off edge */
+#define STATE_GOTO -2 /* GOTO internal state */
+
+#define state struct State
+struct State {
+ int match; /* character to match */
+ int result; /* 3270 control code */
+ state *next; /* next entry in this same state */
+ state *address; /* if goto, where is next state */
+};
diff --git a/usr.bin/tn3270/ascii/termin.c b/usr.bin/tn3270/ascii/termin.c
new file mode 100644
index 0000000..a783189
--- /dev/null
+++ b/usr.bin/tn3270/ascii/termin.c
@@ -0,0 +1,281 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)termin.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+/* this takes characters from the keyboard, and produces 3270 keystroke
+ codes
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+
+#include "../general/general.h"
+#include "../ctlr/function.h"
+#include "../ctlr/externs.h"
+#include "../ctlr/declare.h"
+
+#include "../api/astosc.h"
+#include "state.h"
+
+#include "../general/globals.h"
+
+#define IsControl(c) (!isprint(c) || (isspace(c) && ((c) != ' ')))
+
+#define NextState(x) (x->next)
+
+/* XXX temporary - hard code in the state table */
+
+#define MATCH_ANY 0xff /* actually, match any character */
+
+
+static unsigned char
+ ourBuffer[100], /* where we store stuff */
+ *ourPHead = ourBuffer, /* first character in buffer */
+ *ourPTail = ourBuffer, /* where next character goes */
+ *TransPointer = 0; /* For transparent mode data */
+
+static int InControl;
+static int WaitingForSynch;
+
+static struct astosc
+ *spacePTR = 0; /* Space is hard to enter */
+
+static state
+ *headOfControl = 0; /* where we enter code state table */
+
+#define FullChar ((ourPTail+5) >= ourBuffer+sizeof ourBuffer)
+#define EmptyChar (ourPTail == ourPHead)
+
+
+/*
+ * init_keyboard()
+ *
+ * Initialize the keyboard variables.
+ */
+
+void
+init_keyboard()
+{
+ ourPHead = ourPTail = ourBuffer;
+ InControl = 0;
+ WaitingForSynch = 0;
+}
+
+
+/*
+ * Initialize the keyboard mapping file.
+ */
+
+void
+InitMapping()
+{
+ extern state *InitControl();
+ register struct astosc *ptr;
+
+ if (!headOfControl) {
+ /* need to initialize */
+ headOfControl = InitControl((char *)0, 0, ascii_to_index);
+ if (!headOfControl) { /* should not occur */
+ quit();
+ }
+ for (ptr = &astosc[0]; ptr <= &astosc[highestof(astosc)]; ptr++) {
+ if (ptr->function == FCN_SPACE) {
+ spacePTR = ptr;
+ }
+ }
+ }
+}
+
+
+/* AddChar - put a function index in our buffer */
+
+static void
+AddChar(c)
+int c;
+{
+ if (!FullChar) {
+ *ourPTail++ = c;
+ } else {
+ RingBell("Typeahead buffer full");
+ }
+}
+
+/* FlushChar - put everything where it belongs */
+
+static void
+FlushChar()
+{
+ ourPTail = ourBuffer;
+ ourPHead = ourBuffer;
+}
+
+/*ARGSUSED*/
+void
+TransInput(onoff, mode)
+int mode; /* Which KIND of transparent input */
+int onoff; /* Going in, or coming out */
+{
+ if (onoff) {
+ /* Flush pending input */
+ FlushChar();
+ TransPointer = ourBuffer;
+ } else {
+ }
+}
+
+int
+TerminalIn()
+{
+ /* send data from us to next link in stream */
+ int work = 0;
+ register struct astosc *ptr;
+
+ while (!EmptyChar) { /* send up the link */
+ if (*ourPHead == ' ') {
+ ptr = spacePTR;
+ } else {
+ ptr = &astosc[*ourPHead];
+ }
+ if (AcceptKeystroke(ptr->scancode, ptr->shiftstate) == 1) {
+ ourPHead++;
+ work = 1;
+ } else {
+ break;
+ }
+ }
+
+ if (EmptyChar) {
+ FlushChar();
+ }
+ /* return value answers question: "did we do anything useful?" */
+ return work;
+}
+
+int
+DataFromTerminal(buffer, count)
+register char *buffer; /* the data read in */
+register int count; /* how many bytes in this buffer */
+{
+ register state *regControlPointer;
+ register char c;
+ register int result;
+ int origCount;
+ extern int bellwinup;
+ static state *controlPointer;
+
+ if (TransPointer) {
+ int i;
+
+ if ((count+TransPointer) >= (ourBuffer+sizeof ourBuffer)) {
+ i = ourBuffer+sizeof ourBuffer-TransPointer;
+ } else {
+ i = count;
+ }
+ while (i--) {
+ c = (*buffer++)&0x7f;
+ *TransPointer++ = c|0x80;
+ if (c == '\r') {
+ SendTransparent((char *)ourBuffer, TransPointer-ourBuffer);
+ TransPointer = 0; /* Done */
+ break;
+ }
+ }
+ return count;
+ }
+
+ if (bellwinup) {
+ void BellOff();
+
+ BellOff();
+ }
+
+ origCount = count;
+
+ while (count) {
+ c = *buffer++&0x7f;
+ count--;
+
+ if (!InControl && !IsControl(c)) {
+ AddChar(c); /* add ascii character */
+ } else {
+ if (!InControl) { /* first character of sequence */
+ InControl = 1;
+ controlPointer = headOfControl;
+ }
+ /* control pointer points to current position in state table */
+ for (regControlPointer = controlPointer; ;
+ regControlPointer = NextState(regControlPointer)) {
+ if (!regControlPointer) { /* ran off end */
+ RingBell("Invalid control sequence");
+ regControlPointer = headOfControl;
+ InControl = 0;
+ count = 0; /* Flush current input */
+ break;
+ }
+ if ((regControlPointer->match == c) /* hit this character */
+ || (regControlPointer->match == MATCH_ANY)) {
+ result = regControlPointer->result;
+ if (result == STATE_GOTO) {
+ regControlPointer = regControlPointer->address;
+ break; /* go to next character */
+ }
+ if (WaitingForSynch) {
+ if (astosc[result].function == FCN_SYNCH) {
+ WaitingForSynch = 0;
+ } else {
+ void RingBell();
+
+ RingBell("Need to type synch character");
+ }
+ }
+ else if (astosc[result].function == FCN_FLINP) {
+ FlushChar(); /* Don't add FLINP */
+ } else {
+ if (astosc[result].function == FCN_MASTER_RESET) {
+ FlushChar();
+ }
+ AddChar(result); /* add this code */
+ }
+ InControl = 0; /* out of control now */
+ break;
+ }
+ }
+ controlPointer = regControlPointer; /* save state */
+ }
+ }
+ (void) TerminalIn(); /* try to send data */
+ return(origCount-count);
+}
diff --git a/usr.bin/tn3270/ctlr/3180.kbd b/usr.bin/tn3270/ctlr/3180.kbd
new file mode 100644
index 0000000..1fc7204
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/3180.kbd
@@ -0,0 +1,182 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)3180.kbd 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * keynumber [ scancode [ unshifted [ shifted [ alted [ shiftalted ] ] ] ] ]
+ *
+ * keynumber is in decimal, and starts in column 1.
+ * scancode is hexadecimal.
+ * unshifted, etc. - these are either a single ascii character,
+ * or the name of a function or an AID-generating key.
+ *
+ * all fields are separated by a single space.
+ */
+1 0e ` ~
+2 16 1 VERTICAL_BAR
+3 1e 2 @
+4 26 3 #
+5 25 4 $
+6 2e 5 %
+7 36 6 ^
+8 3d 7 &
+9 3e 8 *
+10 46 9 (
+11 45 0 )
+12 4e - _
+13 55 = +
+14 5d
+15 66 LEFT
+16 0d TAB
+17 15 q Q
+18 1d w W
+19 24 e E
+20 2d r R
+21 2c t T
+22 35 y Y
+23 3c u U
+24 43 i I
+25 44 o O
+26 4d p P
+27 54 CENTSIGN !
+28 5b \ |
+29 5c
+30 14 CAPS_LOCK
+31 1c a A
+32 1b s S
+33 23 d D
+34 2b f F
+35 34 g G
+36 33 h H
+37 3b j J
+38 42 k K
+39 4b l L
+40 4c ; :
+41 52 ' "
+42 53 { }
+43 5a NL
+44 12 MAKE_SHIFT MAKE_SHIFT MAKE_SHIFT
+45 13 < >
+46 1a z Z
+47 22 x X
+48 21 c C
+49 2a v V
+50 32 b B
+51 31 n N
+52 3a m M
+53 41 , ,
+54 49 . .
+55 4a / ?
+56 51
+57 59 MAKE_SHIFT MAKE_SHIFT MAKE_SHIFT
+58 11 RESET NULL DVCNL
+59
+60 19 MAKE_ALT MAKE_ALT MAKE_ALT
+61 29 SPACE SPACE
+62 39 MAKE_ALT MAKE_ALT MAKE_ALT
+63
+64 58 ENTER
+65 06 CLEAR
+66 0c NULL NULL EINP
+67 0b EEOF
+68 0a
+69 09
+70 05 ATTN NULL TREQ
+71 04
+72 03
+73 83
+74 01
+75 67 PA1 DP
+76 64 BTAB
+77
+78 61 LEFT NULL LEFT2
+79
+80 6e PA2 FM
+81 65 INSRT
+82 63 UP
+83 62 NULL NULL HOME
+84 60 DOWN
+85 6f
+86 6d DELETE
+87
+88 6a RIGHT NULL RIGHT2
+89
+90 76
+91 6c 7
+92 6b 4
+93 69 1
+94 68
+95 77
+96 75 8
+97 73 5
+98 72 2
+99 70 0
+100 7e ,
+101 7d 9
+102 74 6
+103 7a 3
+104 71 .
+105 84 SPACE
+106 7c TAB
+107 7b -
+108 79 ENTER
+109 78
+110 07 PF1
+111 0f PF2
+112 17 PF3
+113 1f PF4
+114 27 PF5
+115 2f PF6
+116 37 PF7
+117 3f PF8 NULL MONOCASE
+118 47 PF9
+119 4f PF10
+120 56 PF11
+121 5e PF12
+122 08 PF13
+123 10 PF14
+124 18 PF15
+125 20 PF16
+126 28 PF17
+127 30 PF18
+128 38 PF19
+129 40 PF20
+130 48 PF21
+131 50 PF22
+132 57 PF23
+133 5f PF24
+134 92 BREAK_SHIFT BREAK_SHIFT BREAK_SHIFT
+135 D9 BREAK_SHIFT BREAK_SHIFT BREAK_SHIFT
+136 99 BREAK_ALT BREAK_ALT BREAK_ALT
+137 B9 BREAK_ALT BREAK_ALT BREAK_ALT
diff --git a/usr.bin/tn3270/ctlr/3270pc.kbd b/usr.bin/tn3270/ctlr/3270pc.kbd
new file mode 100644
index 0000000..df75046
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/3270pc.kbd
@@ -0,0 +1,182 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)3270pc.kbd 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * keynumber [ scancode [ unshifted [ shifted [ alted [ shiftalted ] ] ] ] ]
+ *
+ * keynumber is in decimal, and starts in column 1.
+ * scancode is hexadecimal.
+ * unshifted, etc. - these are either a single ascii character,
+ * or the name of a function or an AID-generating key.
+ *
+ * all fields are separated by a single space.
+ */
+1 0e ` ~
+2 16 1 !
+3 1e 2 @
+4 26 3 #
+5 25 4 $
+6 2e 5 %
+7 36 6 ^
+8 3d 7 &
+9 3e 8 *
+10 46 9 (
+11 45 0 )
+12 4e - _
+13 55 = +
+14 5d
+15 66 LEFT
+16 0d TAB BTAB
+17 15 q Q
+18 1d w W
+19 24 e E
+20 2d r R
+21 2c t T
+22 35 y Y
+23 3c u U
+24 43 i I
+25 44 o O
+26 4d p P
+27 54 [ {
+28 5b \ |
+29 5c
+30 14 CAPS_LOCK
+31 1c a A
+32 1b s S
+33 23 d D
+34 2b f F
+35 34 g G
+36 33 h H
+37 3b j J
+38 42 k K
+39 4b l L
+40 4c ; :
+41 52 ' "
+42 53 ] }
+43 5a NL
+44 12 MAKE_SHIFT MAKE_SHIFT MAKE_SHIFT
+45 13 < >
+46 1a z Z
+47 22 x X
+48 21 c C
+49 2a v V
+50 32 b B
+51 31 n N
+52 3a m M
+53 41 , <
+54 49 . >
+55 4a / ?
+56 51
+57 59 MAKE_SHIFT MAKE_SHIFT MAKE_SHIFT
+58 11 RESET NULL DVCNL
+59
+60 19 MAKE_ALT MAKE_ALT MAKE_ALT
+61 29 SPACE SPACE
+62 39 MAKE_ALT MAKE_ALT MAKE_ALT
+63
+64 58 ENTER
+65 06 CLEAR NULL TEST
+66 0c NULL NULL ATTN
+67 0b EEOF NULL EINP
+68 0a
+69 09 MAKE_CTRL
+70 05 ATTN NULL TREQ
+71 04
+72 03
+73 83
+74 01
+75 67 PA1 DP
+76 64 BTAB
+77
+78 61 LEFT NULL LEFT2
+79
+80 6e PA2 FM
+81 65 INSRT
+82 63 UP
+83 62 NULL NULL HOME
+84 60 DOWN
+85 6f PA3
+86 6d DELETE
+87
+88 6a RIGHT NULL RIGHT2
+89
+90 76
+91 6c 7
+92 6b 4
+93 69 1
+94 68
+95 77
+96 75 8
+97 73 5
+98 72 2
+99 70 0
+100 7e ,
+101 7d 9
+102 74 6
+103 7a 3
+104 71 .
+105 84 SPACE
+106 7c TAB
+107 7b -
+108 79 ENTER
+109 78
+110 07 PF1
+111 0f PF2
+112 17 PF3
+113 1f PF4
+114 27 PF5
+115 2f PF6
+116 37 PF7
+117 3f PF8 NULL MONOCASE
+118 47 PF9
+119 4f PF10
+120 56 PF11
+121 5e PF12
+122 08 PF13
+123 10 PF14
+124 18 PF15
+125 20 PF16
+126 28 PF17
+127 30 PF18
+128 38 PF19
+129 40 PF20
+130 48 PF21
+131 50 PF22
+132 57 PF23
+133 5f PF24
+134 92 BREAK_SHIFT BREAK_SHIFT BREAK_SHIFT
+135 D9 BREAK_SHIFT BREAK_SHIFT BREAK_SHIFT
+136 99 BREAK_ALT BREAK_ALT BREAK_ALT
+137 B9 BREAK_ALT BREAK_ALT BREAK_ALT
diff --git a/usr.bin/tn3270/ctlr/api.c b/usr.bin/tn3270/ctlr/api.c
new file mode 100644
index 0000000..1113295
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/api.c
@@ -0,0 +1,755 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)api.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+/*
+ * This file implements the API used in the PC version.
+ */
+
+#include <stdio.h>
+
+#include "api.h"
+#include "../general/general.h"
+
+#include "../api/disp_asc.h"
+
+#include "screen.h"
+#include "hostctlr.h"
+#include "oia.h"
+
+#include "../general/globals.h"
+
+int apitrace = 0;
+
+/*
+ * Some defines for things we use internally.
+ */
+
+#define PS_SESSION_ID 23
+#define BUF_SESSION_ID 0
+
+/*
+ * General utility routines.
+ */
+
+#if defined(MSDOS)
+
+#if defined(LINT_ARGS)
+static void movetous(char *, int, int, int);
+static void movetothem(int, int, char *, int);
+#endif /* defined(LINT_ARGS) */
+
+#define access_api(foo,length,copyin) (foo)
+#define unaccess_api(foo,goo,length,copyout)
+
+static void
+movetous(parms, es, di, length)
+char *parms;
+int es, di;
+int length;
+{
+ char far *farparms = parms;
+
+ movedata(es, di, FP_SEG(farparms), FP_OFF(farparms), length);
+ if (apitrace) {
+ Dump('(', parms, length);
+ }
+}
+
+static void
+movetothem(es, di, parms, length)
+int es, di;
+char *parms;
+int length;
+{
+ char far *farparms = parms;
+
+ movedata(FP_SEG(farparms), FP_OFF(farparms), es, di, length);
+ if (apitrace) {
+ Dump(')', parms, length);
+ }
+}
+#endif /* defined(MSDOS) */
+
+#if defined(unix)
+extern char *access_api();
+extern void movetous(), movetothem(), unaccess_api();
+#endif /* defined(unix) */
+
+
+/*
+ * Supervisor Services.
+ */
+
+static void
+name_resolution(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+ NameResolveParms parms;
+
+ movetous((char *) &parms, sregs->es, regs->x.di, sizeof parms);
+
+ regs->h.cl = 0;
+ if (memcmp((char *)&parms, NAME_SESSMGR, sizeof parms.gate_name) == 0) {
+ regs->x.dx = GATE_SESSMGR;
+ } else if (memcmp((char *)&parms, NAME_KEYBOARD,
+ sizeof parms.gate_name) == 0) {
+ regs->x.dx = GATE_KEYBOARD;
+ } else if (memcmp((char *)&parms, NAME_COPY, sizeof parms.gate_name) == 0) {
+ regs->x.dx = GATE_COPY;
+ } else if (memcmp((char *)&parms, NAME_OIAM, sizeof parms.gate_name) == 0) {
+ regs->x.dx = GATE_OIAM;
+ } else {
+ regs->h.cl = 0x2e; /* Name not found */
+ }
+ regs->h.ch = 0x12;
+ regs->h.bh = 7;
+}
+
+/*
+ * Session Information Services.
+ */
+
+static void
+query_session_id(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+ QuerySessionIdParms parms;
+
+ movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
+
+ if ((parms.rc != 0) || (parms.function_id != 0)) {
+ parms.rc = 0x0c;
+ } else if (parms.option_code != 0x01) {
+ parms.rc = 0x0d; /* Invalid option code */
+#ifdef NOTOBS
+ } else if ((parms.data_code != 0x45) && (parms.data_code != 0x00/*OBS*/)) {
+ parms.rc = 0x0b;
+#endif /* NOTOBS */
+ } else {
+ NameArray list;
+
+ movetous((char *)&list, FP_SEG(parms.name_array),
+ FP_OFF(parms.name_array), sizeof list);
+ if ((list.length < 14) || (list.length > 170)) {
+ parms.rc = 0x12;
+ } else {
+ list.number_matching_session = 1;
+ list.name_array_element.short_name = parms.data_code;
+ list.name_array_element.type = TYPE_DFT;
+ list.name_array_element.session_id = PS_SESSION_ID;
+ memcpy(list.name_array_element.long_name, "ONLYSESS",
+ sizeof list.name_array_element.long_name);
+ movetothem(FP_SEG(parms.name_array),
+ FP_OFF(parms.name_array), (char *)&list, sizeof list);
+ parms.rc = 0;
+ }
+ }
+ parms.function_id = 0x6b;
+ movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
+}
+
+static void
+query_session_parameters(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+ QuerySessionParametersParms parms;
+
+ movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
+
+ if ((parms.rc !=0) || (parms.function_id != 0)) {
+ parms.rc = 0x0c;
+ } else if (parms.session_id != PS_SESSION_ID) {
+ parms.rc = 0x02;
+ } else {
+ parms.rc = 0;
+ parms.session_type = TYPE_DFT;
+ parms.session_characteristics = 0; /* Neither EAB nor PSS */
+ parms.rows = MaxNumberLines;
+ parms.columns = MaxNumberColumns;
+ parms.presentation_space = 0;
+ }
+ parms.function_id = 0x6b;
+ movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
+}
+
+static void
+query_session_cursor(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+ QuerySessionCursorParms parms;
+
+ movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
+
+ if ((parms.rc != 0) || (parms.function_id != 0)) {
+ parms.rc = 0x0c;
+ } else if (parms.session_id != PS_SESSION_ID) {
+ parms.rc = 0x02;
+ } else {
+ parms.rc = 0;
+ parms.cursor_type = CURSOR_BLINKING; /* XXX what is inhibited? */
+ parms.row_address = ScreenLine(CursorAddress);
+ parms.column_address = ScreenLineOffset(CursorAddress);
+ }
+
+ parms.function_id = 0x6b;
+ movetothem(sregs->es, regs->x.di, (char *) &parms, sizeof parms);
+}
+
+/*
+ * Keyboard Services.
+ */
+
+
+static void
+connect_to_keyboard(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+ ConnectToKeyboardParms parms;
+
+ movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
+
+ if ((parms.rc != 0) || (parms.function_id != 0)) {
+ parms.rc = 0x0c;
+ } else if (parms.session_id != PS_SESSION_ID) {
+ parms.rc = 0x02;
+ } else if (parms.intercept_options != 0) {
+ parms.rc = 0x01;
+ } else {
+ parms.rc = 0;
+ parms.first_connection_identifier = 0;
+ }
+ parms.function_id = 0x62;
+
+ movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
+}
+
+static void
+disconnect_from_keyboard(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+ DisconnectFromKeyboardParms parms;
+
+ movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
+
+ if ((parms.rc != 0) || (parms.function_id != 0)) {
+ parms.rc = 0x0c;
+ } else if (parms.session_id != PS_SESSION_ID) {
+ parms.rc = 0x02;
+ } else if (parms.connectors_task_id != 0) {
+ parms.rc = 04; /* XXX */
+ } else {
+ parms.rc = 0;
+ }
+ parms.function_id = 0x62;
+
+ movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
+}
+
+static void
+write_keystroke(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+ WriteKeystrokeParms parms;
+
+ movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
+
+ if ((parms.rc != 0) || (parms.function_id != 0)) {
+ parms.rc = 0x0c;
+ } else if (parms.session_id != PS_SESSION_ID) {
+ parms.rc = 0x02;
+ } else if (parms.connectors_task_id != 0) {
+ parms.rc = 0x04;
+ } else {
+ parms.number_of_keys_sent = 0;
+ parms.rc = 0;
+ if (parms.options == OPTION_SINGLE_KEYSTROKE) {
+ KeystrokeEntry *entry = &parms.keystroke_specifier.keystroke_entry;
+
+ if (AcceptKeystroke(entry->scancode, entry->shift_state) == 0) {
+ parms.rc = 0x10; /* XXX needs 0x12 too! */
+ }
+ parms.number_of_keys_sent++;
+ } else if (parms.options == OPTION_MULTIPLE_KEYSTROKES) {
+ KeystrokeList
+ list,
+ far *atlist = parms.keystroke_specifier.keystroke_list;
+ KeystrokeEntry
+ entry[10], /* 10 at a time */
+ *ourentry,
+ far *theirentry;
+ int
+ todo;
+
+ movetous((char *)&list, FP_SEG(atlist),
+ FP_OFF(atlist), sizeof *atlist);
+ todo = list.length/2;
+ ourentry = entry+(highestof(entry)+1);
+ theirentry = &atlist->keystrokes;
+
+ while (todo) {
+ if (ourentry > &entry[highestof(entry)]) {
+ int thistime;
+
+ thistime = todo;
+ if (thistime > numberof(entry)) {
+ thistime = numberof(entry);
+ }
+ movetous((char *)entry, FP_SEG(theirentry),
+ FP_OFF(theirentry), thistime*sizeof *theirentry);
+ theirentry += thistime;
+ ourentry = entry;
+ }
+ if (AcceptKeystroke(ourentry->scancode,
+ ourentry->shift_state) == 0) {
+ parms.rc = 0x10; /* XXX needs 0x12 too! */
+ break;
+ }
+ parms.number_of_keys_sent++;
+ ourentry++;
+ todo--;
+ }
+ } else {
+ parms.rc = 0x01;
+ }
+ }
+ parms.function_id = 0x62;
+
+ movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
+/* XXX */
+}
+
+
+static void
+disable_input(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+ DisableInputParms parms;
+
+ movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
+
+ if ((parms.rc != 0) || (parms.function_id != 0)) {
+ parms.rc = 0x0c;
+ } else if (parms.session_id != PS_SESSION_ID) {
+ parms.rc = 0x02;
+ } else if (parms.connectors_task_id != 0) {
+ parms.rc = 0x04;
+ } else {
+ SetOiaApiInhibit(&OperatorInformationArea);
+ parms.rc = 0;
+ }
+ parms.function_id = 0x62;
+
+ movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
+}
+
+static void
+enable_input(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+ EnableInputParms parms;
+
+ movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
+
+ if ((parms.rc != 0) || (parms.function_id != 0)) {
+ parms.rc = 0x0c;
+ } else if (parms.session_id != PS_SESSION_ID) {
+ parms.rc = 0x02;
+ } else if (parms.connectors_task_id != 0) {
+ parms.rc = 0x04;
+ } else {
+ ResetOiaApiInhibit(&OperatorInformationArea);
+ parms.rc = 0;
+ }
+ parms.function_id = 0x62;
+
+ movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
+}
+
+/*
+ * Copy Services.
+ */
+
+static
+copy_subroutine(target, source, parms, what_is_user, length)
+BufferDescriptor *target, *source;
+CopyStringParms *parms;
+int what_is_user;
+#define USER_IS_TARGET 0
+#define USER_IS_SOURCE 1
+{
+#define TARGET_NO_EAB 1
+#define SOURCE_NO_EAB 2
+#define TARGET_PC 4
+#define SOURCE_PC 8
+#define NO_FIELD_ATTRIBUTES 16
+ int needtodo = 0;
+ int access_length;
+ char far *input;
+ char far *output;
+ char far *access_pointer;
+
+ if ((target->characteristics^source->characteristics)
+ &CHARACTERISTIC_EAB) {
+ if (target->characteristics&CHARACTERISTIC_EAB) {
+ needtodo |= TARGET_NO_EAB; /* Need to bump for EAB in target */
+ } else {
+ needtodo |= SOURCE_NO_EAB; /* Need to bump for EAB in source */
+ }
+ }
+ if (target->session_type != source->session_type) {
+ if (target->session_type == TYPE_PC) {
+ needtodo |= TARGET_PC; /* scan codes to PC */
+ } else {
+ needtodo |= SOURCE_PC; /* PC to scan codes */
+ }
+ }
+ if ((parms->copy_mode&COPY_MODE_FIELD_ATTRIBUTES) == 0) {
+ needtodo |= NO_FIELD_ATTRIBUTES;
+ }
+ access_length = length;
+ if (what_is_user == USER_IS_TARGET) {
+ if (target->characteristics&CHARACTERISTIC_EAB) {
+ access_length *= 2;
+ }
+ input = (char far *) &Host[source->begin];
+ access_pointer = target->buffer;
+ output = access_api(target->buffer, access_length, 0);
+ } else {
+ if (source->characteristics&CHARACTERISTIC_EAB) {
+ access_length *= 2;
+ }
+ access_pointer = source->buffer;
+ input = access_api(source->buffer, access_length, 1);
+ output = (char far *) &Host[target->begin];
+ }
+ while (length--) {
+ if (needtodo&TARGET_PC) {
+ *output++ = disp_asc[*input++];
+ } else if (needtodo&SOURCE_PC) {
+ *output++ = asc_disp[*input++];
+ } else {
+ *output++ = *input++;
+ }
+ if (needtodo&TARGET_NO_EAB) {
+ input++;
+ } else if (needtodo&SOURCE_NO_EAB) {
+ *output++ = 0; /* Should figure out good EAB? */
+ }
+ }
+ if (what_is_user == USER_IS_TARGET) {
+ unaccess_api(target->buffer, access_pointer, access_length, 1);
+ } else {
+ unaccess_api(source->buffer, access_pointer, access_length, 0);
+ }
+}
+
+
+static void
+copy_string(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+ CopyStringParms parms;
+ BufferDescriptor *target = &parms.target, *source = &parms.source;
+ int length;
+
+ movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
+
+ length = 1+parms.source_end-source->begin;
+ if ((parms.rc != 0) || (parms.function_id !=0)) {
+ parms.rc = 0x0c;
+ } else if (target->session_id == BUF_SESSION_ID) { /* Target is buffer */
+ if (source->session_id != PS_SESSION_ID) { /* A no-no */
+ parms.rc = 0x2;
+ } else {
+ if ((source->begin < 0) || (source->begin > highestof(Host))) {
+ parms.rc = 0x06; /* invalid source definition */
+ } else {
+ if ((source->begin+length) > highestof(Host)) {
+ length = highestof(Host)-source->begin;
+ parms.rc = 0x0f; /* Truncate */
+ }
+ if ((source->characteristics == target->characteristics) &&
+ (source->session_type == target->session_type)) {
+ if (source->characteristics&CHARACTERISTIC_EAB) {
+ length *= 2;
+ }
+ movetothem(FP_SEG(target->buffer),
+ FP_OFF(target->buffer),
+ (char *)&Host[source->begin], length);
+ } else {
+ copy_subroutine(target, source, &parms,
+ USER_IS_TARGET, length);
+ }
+ }
+ }
+ } else if (source->session_id != BUF_SESSION_ID) {
+ parms.rc = 0xd;
+ } else {
+ /* Send to presentation space (3270 buffer) */
+ if ((target->begin < 0) || (target->begin > highestof(Host))) {
+ parms.rc = 0x07; /* invalid target definition */
+ } if (!UnLocked) {
+ parms.rc = 0x03; /* Keyboard locked */
+ } else if (parms.copy_mode != 0) {
+ parms.rc = 0x0f; /* Copy of field attr's not allowed */
+ } else if (IsProtected(target->begin) || /* Make sure no protected */
+ (WhereAttrByte(target->begin) != /* in range */
+ WhereAttrByte(target->begin+length-1))) {
+ parms.rc = 0x0e; /* Attempt to write in protected */
+ } else {
+ if ((target->begin+length) > highestof(Host)) {
+ length = highestof(Host)-target->begin;
+ parms.rc = 0x0f; /* Truncate */
+ }
+ TurnOnMdt(target->begin); /* Things have changed */
+ if ((source->characteristics == target->characteristics) &&
+ (source->session_type == target->session_type)) {
+ if (source->characteristics&CHARACTERISTIC_EAB) {
+ length *= 2;
+ }
+ movetous((char *)&Host[target->begin],
+ FP_SEG(source->buffer),
+ FP_OFF(source->buffer), length);
+ } else {
+ copy_subroutine(target, source, &parms, USER_IS_SOURCE, length);
+ }
+ }
+ }
+ parms.function_id = 0x64;
+ movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
+}
+
+
+/*
+ * Operator Information Area Services.
+ */
+
+static void
+read_oia_group(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+ ReadOiaGroupParms parms;
+
+ movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
+
+ if ((parms.rc != 0) || (parms.function_id != 0)) {
+ parms.rc = 0x0c;
+ } else if (parms.session_id != PS_SESSION_ID) {
+ parms.rc = 0x02;
+ } else {
+ int group = parms.oia_group_number;
+ char *from;
+ int size;
+
+ if ((group != API_OIA_ALL_GROUPS) &&
+ ((group > API_OIA_LAST_LEGAL_GROUP) || (group < 0))) {
+ } else {
+ if (group == API_OIA_ALL_GROUPS) {
+ size = API_OIA_BYTES_ALL_GROUPS;
+ from = (char *)&OperatorInformationArea;
+ } else if (group == API_OIA_INPUT_INHIBITED) {
+ size = sizeof OperatorInformationArea.input_inhibited;
+ from = (char *)&OperatorInformationArea.input_inhibited[0];
+ } else {
+ size = 1;
+ from = ((char *)&OperatorInformationArea)+group;
+ }
+ movetothem(FP_SEG(parms.oia_buffer), FP_OFF(parms.oia_buffer),
+ from, size);
+ }
+ }
+ parms.function_id = 0x6d;
+ movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
+}
+
+/*ARGSUSED*/
+static void
+unknown_op(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+ regs->h.ch = 0x12;
+ regs->h.cl = 0x05;
+}
+
+
+handle_api(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+/*
+ * Do we need to log this transaction?
+ */
+ if (apitrace) {
+ Dump('<', (char *)regs, sizeof *regs);
+ Dump('<', (char *)sregs, sizeof *sregs);
+ }
+ if (regs->h.ah == NAME_RESOLUTION) {
+ name_resolution(regs, sregs);
+#if defined(unix)
+ } else if (regs->h.ah == PS_OR_OIA_MODIFIED) {
+ while ((oia_modified == 0) && (ps_modified == 0)) {
+ (void) Scheduler(1);
+ }
+ oia_modified = ps_modified = 0;
+#endif /* defined(unix) */
+ } else if (regs->h.ah != 0x09) {
+ regs->h.ch = 0x12;
+ regs->h.cl = 0x0f; /* XXX Invalid environmental access */
+ } else if (regs->x.bx != 0x8020) {
+ regs->h.ch = 0x12;
+ regs->h.cl = 0x08; /* XXX Invalid wait specified */
+ } else if (regs->h.ch != 0) {
+ regs->x.cx = 0x1206; /* XXX Invalid priority */
+ } else {
+ switch (regs->x.dx) {
+ case GATE_SESSMGR:
+ switch (regs->h.al) {
+ case QUERY_SESSION_ID:
+ if (regs->h.cl != 0) {
+ regs->x.cx = 0x1206;
+ } else {
+ regs->x.cx = 0x1200;
+ query_session_id(regs, sregs);
+ }
+ break;
+ case QUERY_SESSION_PARAMETERS:
+ if (regs->h.cl != 0) {
+ regs->x.cx = 0x1206;
+ } else {
+ regs->x.cx = 0x1200;
+ query_session_parameters(regs, sregs);
+ }
+ break;
+ case QUERY_SESSION_CURSOR:
+ if ((regs->h.cl != 0xff) && (regs->h.cl != 0x00/*OBS*/)) {
+ regs->x.cx = 0x1206;
+ } else {
+ regs->x.cx = 0x1200;
+ query_session_cursor(regs, sregs);
+ }
+ break;
+ default:
+ unknown_op(regs, sregs);
+ break;
+ }
+ break;
+ case GATE_KEYBOARD:
+ if (regs->h.cl != 00) {
+ regs->x.cx = 0x1206;
+ } else {
+ regs->x.cx = 0x1200;
+ switch (regs->h.al) {
+ case CONNECT_TO_KEYBOARD:
+ connect_to_keyboard(regs, sregs);
+ break;
+ case DISABLE_INPUT:
+ disable_input(regs, sregs);
+ break;
+ case WRITE_KEYSTROKE:
+ write_keystroke(regs, sregs);
+ break;
+ case ENABLE_INPUT:
+ enable_input(regs, sregs);
+ break;
+ case DISCONNECT_FROM_KEYBOARD:
+ disconnect_from_keyboard(regs, sregs);
+ break;
+ default:
+ unknown_op(regs, sregs);
+ break;
+ }
+ }
+ break;
+ case GATE_COPY:
+ if (regs->h.cl != 0xff) {
+ regs->x.cx = 0x1206;
+ } else {
+ regs->x.cx = 0x1200;
+ switch (regs->h.al) {
+ case COPY_STRING:
+ copy_string(regs, sregs);
+ break;
+ default:
+ unknown_op(regs, sregs);
+ break;
+ }
+ }
+ break;
+ case GATE_OIAM:
+ if (regs->h.cl != 0xff) {
+ regs->x.cx = 0x1206;
+ } else {
+ regs->x.cx = 0x1200;
+ switch (regs->h.al) {
+ case READ_OIA_GROUP:
+ read_oia_group(regs, sregs);
+ break;
+ default:
+ unknown_op(regs, sregs);
+ break;
+ }
+ }
+ break;
+ default:
+ regs->h.ch = 0x12;
+ regs->h.cl = 0x34; /* Invalid GATE entry */
+ break;
+ }
+ }
+/*
+ * Do we need to log this transaction?
+ */
+ if (apitrace) {
+ Dump('>', (char *)regs, sizeof *regs);
+ Dump('>', (char *)sregs, sizeof *sregs);
+#ifdef MSDOS
+ { char buf[10]; gets(buf); }
+#endif /* MSDOS */
+ }
+}
diff --git a/usr.bin/tn3270/ctlr/api.h b/usr.bin/tn3270/ctlr/api.h
new file mode 100644
index 0000000..8004f34
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/api.h
@@ -0,0 +1,403 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)api.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * This file contains header information used by the PC API routines.
+ */
+
+#if !defined(MSDOS)
+#define far /* For 'far *' checks */
+#endif /* !defined(MSDOS) */
+
+#define API_INTERRUPT_NUMBER 0x7A /* API Interrupt Number */
+
+/*
+ * Define the gate numbers. These are returned via the Name Resolution
+ * service.
+ */
+
+#define GATE_SESSMGR 1234
+#define GATE_KEYBOARD 5678
+#define GATE_COPY 9101
+#define GATE_OIAM 1121
+
+/*
+ * The names which correspond to the above gate numbers.
+ */
+
+#define NAME_SESSMGR "SESSMGR "
+#define NAME_KEYBOARD "KEYBOARD"
+#define NAME_COPY "COPY "
+#define NAME_OIAM "OIAM "
+
+
+/*
+ * Name Resolution is specified in AH.
+ */
+
+#define NAME_RESOLUTION 0x81
+
+#if defined(unix)
+/*
+ * In unix, we offer a service to allow the application to keep from
+ * having to poll us constantly.
+ */
+#define PS_OR_OIA_MODIFIED 0x99
+
+#endif /* defined(unix) */
+
+/*
+ * Codes specified in AL for various services.
+ */
+
+#define QUERY_SESSION_ID 0x01
+#define QUERY_SESSION_PARAMETERS 0x02
+#define QUERY_SESSION_CURSOR 0x0b
+
+#define CONNECT_TO_KEYBOARD 0x01
+#define DISCONNECT_FROM_KEYBOARD 0x02
+#define WRITE_KEYSTROKE 0x04
+#define DISABLE_INPUT 0x05
+#define ENABLE_INPUT 0x06
+
+#define COPY_STRING 0x01
+
+#define READ_OIA_GROUP 0x02
+
+/*
+ * For each service, we define the assoicated parameter blocks.
+ */
+
+/*
+ * Supervisor Services
+ */
+
+typedef struct {
+ char gate_name[8];
+} NameResolveParms;
+
+
+/*
+ * Session Information Services
+ */
+
+typedef struct {
+ char
+ short_name,
+ type,
+ session_id,
+ reserved,
+ long_name[8];
+} NameArrayElement;
+
+typedef struct {
+ unsigned char
+ length,
+ number_matching_session;
+ NameArrayElement
+ name_array_element; /* Variable number */
+} NameArray;
+
+typedef struct {
+ char
+ rc,
+ function_id,
+ option_code,
+ data_code;
+ NameArray far
+ *name_array;
+ char
+ long_name[8];
+} QuerySessionIdParms;
+
+#define ID_OPTION_BY_NAME 0x01 /* By short (or long) name */
+#define ID_OPTION_ALL 0x00 /* All (of specified type */
+
+typedef struct {
+ char
+ rc,
+ function_id,
+ session_id,
+ reserved,
+ session_type,
+ session_characteristics,
+ rows,
+ columns;
+ char far
+ *presentation_space;
+} QuerySessionParametersParms;
+
+#define TYPE_WSCTL 0x01 /* Work Station Control */
+#define TYPE_DFT 0x02 /* DFT Host Session */
+#define TYPE_CUT 0x03 /* CUT Host Session */
+#define TYPE_NOTEPAD 0x04 /* Notepad Session */
+#define TYPE_PC 0x05 /* Personal Computer Session */
+
+#define CHARACTERISTIC_EAB 0x80 /* Extended Attribute Buffer */
+#define CHARACTERISTIC_PSS 0x40 /* Program Symbols Supported */
+
+typedef struct {
+ char
+ rc,
+ function_id,
+ session_id,
+ cursor_type,
+ row_address, /* from 0 */
+ column_address; /* from 0 */
+} QuerySessionCursorParms;
+
+#define CURSOR_INHIBITED_AUTOSCROLL 0x10
+#define CURSOR_INHIBITED 0x04
+#define CURSOR_BLINKING 0x02
+#define CURSOR_BOX 0x01
+typedef struct {
+ char
+ rc,
+ function_id,
+ session_id,
+ reserved;
+ short
+ event_queue_id,
+ input_queue_id;
+ char
+ intercept_options,
+ first_connection_identifier;
+} ConnectToKeyboardParms;
+
+typedef struct {
+ char
+ rc,
+ function_id,
+ session_id,
+ reserved;
+ short
+ connectors_task_id;
+} DisconnectFromKeyboardParms;
+
+typedef struct {
+ unsigned char
+ scancode,
+ shift_state;
+} KeystrokeEntry;
+
+typedef struct {
+ short
+ length; /* Length (in bytes) of list */
+ KeystrokeEntry keystrokes; /* Variable size */
+} KeystrokeList;
+
+typedef struct {
+ char
+ rc,
+ function_id,
+ session_id,
+ reserved;
+ short
+ connectors_task_id;
+ char
+ options,
+ number_of_keys_sent;
+ union {
+ KeystrokeEntry
+ keystroke_entry;
+ KeystrokeList far
+ *keystroke_list;
+ } keystroke_specifier;
+} WriteKeystrokeParms;
+
+#define OPTION_SINGLE_KEYSTROKE 0x20
+#define OPTION_MULTIPLE_KEYSTROKES 0x30
+
+typedef struct {
+ char
+ rc,
+ function_id,
+ session_id,
+ reserved;
+ short
+ connectors_task_id;
+} DisableInputParms;
+
+typedef DisableInputParms EnableInputParms;
+
+typedef struct {
+ char
+ session_id,
+ reserved;
+ char far
+ *buffer;
+ char
+ characteristics,
+ session_type;
+ short
+ begin; /* Offset within buffer */
+} BufferDescriptor;
+
+typedef struct {
+ char
+ rc,
+ function_id;
+ BufferDescriptor
+ source;
+ short
+ source_end; /* Offset within source buffer */
+ BufferDescriptor
+ target;
+ char
+ copy_mode,
+ reserved;
+} CopyStringParms;
+
+#define COPY_MODE_7_COLOR 0x80 /* Else 4 color mode */
+#define COPY_MODE_FIELD_ATTRIBUTES 0x40 /* Else don't copy attributes */
+
+typedef struct {
+ char
+ rc,
+ function_id,
+ session_id,
+ reserved;
+ char far
+ *oia_buffer;
+ char
+ oia_group_number;
+} ReadOiaGroupParms;
+
+/* If the user wants all groups, we return API_OIA_BYTES_ALL_GROUPS bytes */
+#define API_OIA_ALL_GROUPS '\377'
+#define API_OIA_BYTES_ALL_GROUPS 22 /* 22 bytes of data */
+
+/* API_OIA_INPUT_INHIBITED is special. It returns more than on byte of data */
+#define API_OIA_INPUT_INHIBITED 8
+
+#define API_OIA_LAST_LEGAL_GROUP 18 /* Highest legal number */
+
+
+
+#if defined(MSDOS)
+
+#if !defined(FP_SEG)
+#include <dos.h>
+#endif /* !defined(FP_SEG) */
+
+#else /* defined(MSDOS) */
+
+/*
+ * These definitions are here to provide the descriptions of
+ * some registers which are, normally, defined in <dos.h> on
+ * a dos system.
+ */
+
+#define FP_SEG(x) ((unsigned int)(((unsigned long)(x))>>16))
+#define FP_OFF(y) ((unsigned int)(((unsigned long)(y))&0xFFFF))
+
+/*
+ * Undo the preceeding.
+ */
+
+#define SEG_OFF_BACK(x,y) (((x)<<16)|(y))
+
+/*
+ * Now, it is somewhat of a pain, but we need to keep
+ * 8086 conventions about which of the "highlow"'s map
+ * into which of the "words".
+ */
+
+#include <sys/param.h> /* Get ENDIAN from machine/endian.h */
+
+/* Determine endian'ess (if necessary) */
+
+#if !(defined(BYTE_ORDER) && defined(BIG_ENDIAN))
+#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax) */
+#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */
+
+#if defined(vax) || defined(ns32000) || defined(i386) || (defined(mips)&&defined(MIPSEL))
+#define BYTE_ORDER LITTLE_ENDIAN
+#endif /* defined(vax) || defined(ns32000) */
+
+#if defined(sun) || defined(tahoe) || defined(ibm032) || defined(pyr) || defined(gould) || (defined(mips)&&defined(MIPSEB))
+#define BYTE_ORDER BIG_ENDIAN
+#endif /* defined(sun) || defined(tahoe) || defined(ibm032) || defined(pyr) || defined(gould) */
+
+#endif /* !(defined(BYTE_ORDER) && defined(BIG_ENDIAN)) */
+
+struct highlow {
+ unsigned char
+#if BYTE_ORDER == LITTLE_ENDIAN
+ al,
+ ah,
+ bl,
+ bh,
+ cl,
+ ch,
+ dl,
+ dh;
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+#if BYTE_ORDER == BIG_ENDIAN
+ ah,
+ al,
+ bh,
+ bl,
+ ch,
+ cl,
+ dh,
+ dl;
+#endif /* BYTE_ORDER == BIG_ENDIAN */
+};
+
+struct words {
+ unsigned short
+ ax,
+ bx,
+ cx,
+ dx;
+ unsigned short
+ si,
+ di;
+};
+
+union REGS {
+ struct highlow h;
+ struct words x;
+};
+
+struct SREGS {
+ unsigned short
+ cs,
+ ds,
+ es,
+ ss;
+};
+#endif /* defined(MSDOS) (else section) */
diff --git a/usr.bin/tn3270/ctlr/declare.h b/usr.bin/tn3270/ctlr/declare.h
new file mode 100644
index 0000000..0400b33
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/declare.h
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)declare.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * Declarations of routines from the controller.
+ */
+
+extern void
+ AddHost(),
+ DoReadModified(),
+ DoReadBuffer(),
+ OptInit(),
+ SendToIBM(),
+ SendTransparent();
+
+extern int
+ DataFrom3270(),
+ DataFromNetwork(),
+ OptOrder(),
+ OutputClock,
+ TransparentClock;
diff --git a/usr.bin/tn3270/ctlr/externs.h b/usr.bin/tn3270/ctlr/externs.h
new file mode 100644
index 0000000..11c983c
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/externs.h
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)externs.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * External references from the controller.
+ */
+
+#if !defined(MSDOS)
+extern char *access_api();
+extern void movetous(), movetothem(), unaccess_api();
+#endif /* !defined(MSDOS) */
+
+extern unsigned char
+ *memNSchr(); /* Search for a character ANDED, increment by stride */
+
+extern int
+ DataToNetwork(),
+ OutputClock,
+ suspend(),
+ TransparentClock,
+ UnLocked; /* keyboard is UnLocked? */
+
+extern void
+ command(),
+ ConnectScreen(),
+ ExitString(),
+ init_inbound(),
+ LocalClearScreen(),
+ RefreshScreen(),
+ RingBell(),
+ setconnmode(),
+ StopScreen(),
+ TransOut(),
+ TransStop();
diff --git a/usr.bin/tn3270/ctlr/function.c b/usr.bin/tn3270/ctlr/function.c
new file mode 100644
index 0000000..1844860
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/function.c
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)function.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+/*
+ * This file, which never produces a function.o, is used solely to
+ * be run through the preprocessor.
+ *
+ * On a 4.3 system (or even msdos), "cc -E function.h" would produce
+ * the correct output. Unfortunately, 4.2 compilers aren't quite that
+ * useful.
+ */
+
+#include "function.h"
diff --git a/usr.bin/tn3270/ctlr/function.h b/usr.bin/tn3270/ctlr/function.h
new file mode 100644
index 0000000..a62018d
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/function.h
@@ -0,0 +1,166 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)function.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * The following are the various functions which the keyboard can ask
+ * the controller to perform.
+ *
+ * Note that this file (the following entries) are scanned by mkhit.c,
+ * and that the format must remain more-or-less consistent
+ * [ \t]*TOKEN
+ */
+
+enum ctlrfcn {
+
+ undefined = 0, /* Not yet touched */
+
+ FCN_NULL, /* Illegal sequence */
+
+ FCN_RESET, /* unlock keyboard */
+ FCN_MAKE_SHIFT_LOCK,
+ FCN_BREAK_SHIFT_LOCK,
+
+ FCN_MAKE_SHIFT, /* shift key pressed DOWN */
+ FCN_BREAK_SHIFT, /* shift key released */
+
+ FCN_MAKE_ALT, /* alt key pressed DOWN */
+ FCN_BREAK_ALT, /* alt key released */
+
+ FCN_MAKE_CTRL,
+
+ FCN_CAPS_LOCK,
+
+ FCN_MONOCASE, /* DISPLAY in upper case */
+ FCN_DVCNL,
+
+ FCN_CHARACTER, /* Not one of the following, but ... */
+ FCN_VERTICAL_BAR, /* EBCDIC solid vertical bar */
+ FCN_CENTSIGN, /* EBCDIC cent sign */
+ FCN_SPACE, /* EBCDIC space */
+ FCN_DP, /* EBCDIC dup character */
+ FCN_FM, /* EBCDIC field mark */
+
+ FCN_AID, /* Some AID key */
+ FCN_ATTN,
+ FCN_CURSEL, /* Cursor select function (and aid) */
+ FCN_TEST, /* Test function */
+
+ FCN_EINP, /* erase input (dangerous) */
+ FCN_EEOF,
+ FCN_DELETE,
+ FCN_INSRT,
+ FCN_TAB,
+ FCN_BTAB,
+ FCN_NL,
+ FCN_HOME,
+ FCN_UP,
+ FCN_DOWN,
+ FCN_RIGHT,
+ FCN_LEFT,
+ FCN_LEFT2,
+ FCN_RIGHT2,
+
+#if !defined(PURE3274)
+ /*
+ * Local editing functions
+ */
+ FCN_SETTAB, /* set a column tab */
+ FCN_DELTAB,
+ FCN_COLTAB,
+ FCN_COLBAK,
+ FCN_INDENT, /* more margin over one col tab */
+ FCN_UNDENT,
+ FCN_SETMRG,
+ FCN_SETHOM,
+ FCN_CLRTAB,
+ FCN_ERASE, /* erase last character */
+ FCN_WERASE,
+ FCN_FERASE,
+ FCN_WORDTAB, /* tab to start of next word */
+ FCN_WORDBACKTAB,
+ FCN_WORDEND, /* find next end of word */
+ FCN_FIELDEND, /* find next end of field */
+
+ /*
+ * APL functions
+ */
+ FCN_APLON, /* start using apl character set */
+ FCN_APLOFF,
+ FCN_APLEND,
+
+ FCN_PCON,
+ FCN_PCOFF,
+ FCN_INIT, /* re-init screen */
+ FCN_SYNCH, /* synch up after line/control error */
+ FCN_FLINP, /* flush input buffer */
+ FCN_RESHOW, /* redraw screen */
+ FCN_MASTER_RESET, /* FLINP, RESET, RESHOW, + more */
+
+ FCN_DISC, /* suspend application */
+ FCN_ESCAPE, /* enter command mode */
+
+ FCN_ALTK, /* Dvorak keyboard */
+
+ FCN_XOFF, /* suspend output to screen */
+ FCN_XON, /* resume output to screen */
+
+ FCN_LPRT /* print screen on printer */
+#endif /* !defined(PURE3274) */
+};
+/*
+ * The following is the structure which defines what a 3270 keystroke
+ * can do.
+ */
+
+struct hits {
+ unsigned char keynumber;
+ struct hit {
+ enum ctlrfcn ctlrfcn;
+ unsigned char code; /* AID value or 3270 display code */
+ } hit[4]; /* plain, shifted, alted, shiftalted */
+};
+
+extern struct hits hits[];
+
+/*
+ * Definitions of the shift state (and the left/right shift key position).
+ */
+
+#define SHIFT_RIGHT 0x20 /* Right shift key is down */
+#define SHIFT_LEFT 0x10 /* Left shift key is down */
+#define SHIFT_CONTROL 0x08 /* Control shift state (unused) */
+#define SHIFT_ALT 0x04 /* ALT shift state */
+#define SHIFT_CAPS 0x02 /* Caps lock state */
+#define SHIFT_UPSHIFT 0x01 /* Upshift state */
diff --git a/usr.bin/tn3270/ctlr/hostctlr.h b/usr.bin/tn3270/ctlr/hostctlr.h
new file mode 100644
index 0000000..086d7ee
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/hostctlr.h
@@ -0,0 +1,222 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)hostctlr.h 8.1 (Berkeley) 6/6/93
+ */
+
+#define INCLUDED_HOST3270
+
+/* define orders given to 3270's */
+
+#define ORDER_SF 0x1d /* Start Field */
+#define ORDER_SFE 0x29 /* Start Field Extended */
+#define ORDER_SBA 0x11 /* Set Buffer Address (for output) */
+#define ORDER_SA 0x28 /* Set Attribute */
+#define ORDER_MF 0x2c /* Modify field */
+#define ORDER_IC 0x13 /* Insert Cursor (at buffer address) */
+#define ORDER_PT 0x05 /* Program Tab (absurdly complicated) */
+#define ORDER_RA 0x3c /* Repeat next character to some addr */
+#define ORDER_EUA 0x12 /* Null out every unprotected field
+ * to some address.
+ */
+#define ORDER_GE 0x08 /* Graphics Escape */
+#define ORDER_YALE 0x2b /* This is a special YALE order, which
+ * introduces YALE extended orders
+ * (like setting tabs, etc.).
+ */
+
+/* The following is defined for initialization and error messages. */
+
+struct orders_def {
+ int
+ code; /* As in 3270 data stream */
+ char
+ *short_name, /* Short name */
+ *long_name; /* Long name */
+};
+
+#define ORDERS_DEF { \
+ ORDER_SF, "SF", "Start Field", \
+ ORDER_SFE, "SFE", "Start Field Extended", \
+ ORDER_SBA, "SBA", "Set Buffer Address", \
+ ORDER_SA, "SA", "Set Attribute", \
+ ORDER_MF, "MF", "Modify Field", \
+ ORDER_IC, "IC", "Insert Cursor", \
+ ORDER_PT, "PT", "Program Tab", \
+ ORDER_RA, "RA", "Repeat to Address", \
+ ORDER_EUA, "EUA", "Erase Unprotected to Address", \
+ ORDER_GE, "GE", "Graphics Escape", \
+ ORDER_YALE, "YALE", "Yale Order" \
+ }
+
+
+#define ATTR_RESET 0x00 /* SA only - reset to default */
+# define ATTR_DEFAULT 0x00 /* reset to default */
+ /* Also for 0x41-43 below */
+#define ATTR_FIELD 0xC0 /* Field attributes */
+# define ATTR_MASK 0xc0 /* control bits */
+# define ATTR_PROT 0x20 /* protected bit */
+# define ATTR_NUMERIC 0x10 /* numeric field */
+# define ATTR_AUTO_SKIP_MASK 0x30 /* mask to check auto skip */
+# define ATTR_AUTO_SKIP_VALUE 0x30 /* value to have auto skip */
+# define ATTR_DSPD_MASK 0x0c /* highlighting, etc. */
+# define ATTR_DSPD_DNSPD 0x00 /* display, no select */
+# define ATTR_DSPD_DSPD 0x04 /* display, select */
+# define ATTR_DSPD_HIGH 0x08 /* highlighted, select */
+# define ATTR_DSPD_NONDISPLAY 0x0c /* non-display, no select */
+# define ATTR_MDT 0x01 /* modified data tag */
+
+#define ATTR_EXTENDED_HIGHLIGHT 0x41 /* Extended highlighting */
+# define ATTR_BLINK 0xf1 /* Blinking */
+# define ATTR_REVERSE_VIDEO 0xf2 /* Reverse video */
+# define ATTR_UNDERSCORE 0xf3 /* Underline */
+#define ATTR_COLOR 0x42 /* Color */
+# define ATTR_BLUE 0xf1
+# define ATTR_RED 0xf2
+# define ATTR_PINK 0xf3
+# define ATTR_GREEN 0xf4
+# define ATTR_TURQUOISE 0xf5
+# define ATTR_YELLOW 0xf6
+# define ATTR_WHITE 0xf7 /* for 3279; black for 3287; */
+ /* multicolor for triple */
+ /* plane symbol */
+#define ATTR_PROGRAMMED_SYMBOLS 0x43 /* Programmed Symbols */
+# define ATTR_SYMBOL_SET_LOW 0x40 /* Lowest loadable set ID */
+# define ATTR_SYMBOL_SET_HIGH 0xef /* Highest loadable set ID */
+# define ATTR_SYMBOL_SET_APLTEXT 0xf1
+
+/* Non-SNA control unit commands */
+
+#define CMD_ERASE_ALL_UNPROTECTED 0x0f
+#define CMD_ERASE_WRITE 0x05
+#define CMD_ERASE_WRITE_ALTERNATE 0x0d
+#define CMD_READ_BUFFER 0x02
+#define CMD_READ_MODIFIED 0x06
+#define CMD_WRITE 0x01
+#define CMD_WRITE_STRUCTURED_FIELD 0x11
+
+/* SNA control unit commands */
+
+#define CMD_SNA_COPY 0xf7
+#define CMD_SNA_ERASE_ALL_UNPROTECTED 0x6f
+#define CMD_SNA_ERASE_WRITE 0xf5
+#define CMD_SNA_ERASE_WRITE_ALTERNATE 0x7e
+#define CMD_SNA_READ_BUFFER 0xf2
+#define CMD_SNA_READ_MODIFIED 0xf6
+#define CMD_SNA_READ_MODIFIED_ALL 0x6e
+#define CMD_SNA_WRITE 0xf1
+#define CMD_SNA_WRITE_STRUCTURED_FIELD 0xf3
+
+
+#define WCC_RESET 0x40
+#define WCC_ALARM 0x04
+#define WCC_RESTORE 0x02
+#define WCC_RESET_MDT 0x01
+
+
+/* Special EBCDIC characters unique to a 3270 */
+
+#define EBCDIC_BLANK 0x40 /* Space */
+#define EBCDIC_CENTSIGN 0x4a /* Cent sign */
+#define EBCDIC_DUP 0x1c /* DUP character */
+#define EBCDIC_FM 0x1e /* Field mark character */
+#define EBCDIC_PERCENT 0x6c /* Percent sign */
+#define EBCDIC_SLASH 0x61 /* Slash */
+#define EBCDIC_SOH 0x01 /* Start of Heading */
+#define EBCDIC_STX 0x02 /* Start of Text */
+
+/* Structured field types */
+#define SF_3270DS 0x40 /* For write operations */
+#define SF_LPS 0x06 /* Load Programmed Symbols */
+#define SF_SRM 0x09 /* Set Reply Mode */
+#define SF_SWO 0x0b /* Set Window Origin */
+#define SF_READ_PARTITION 0x01 /* Read Partition (Query) */
+#define SF_ERASE_RESET 0x03 /* Erase (and/or Reset) */
+#define SF_SCS_DATA 0x41 /* SCS Data */
+#define SF_CREATE_PARTITION 0x0c /* Create a partition */
+
+/* AID characters sent to host.
+ *
+ * Note that this file (the following entries) are scanned by mkhit.c,
+ * and that the format must remain more-or-less consistent
+ * (#define\tAID_name\t[\t]*TOKEN)
+ */
+
+#define AID_NONE 0x60 /* No AID (display) */
+#define AID_NONE_PRINTER 0xe8 /* No AID (printer) */
+
+#define AID_PA1 0x6c
+#define AID_PA2 0x6e
+#define AID_PA3 0x6b
+#define AID_CLEAR 0x6d
+#define AID_TREQ 0xf0
+#define AID_ENTER 0x7d
+#define AID_SELPEN 0x7e /*
+ * Really, only SELPEN with DESIGNATOR
+ * = space or null
+ */
+#define AID_PF1 0xf1
+#define AID_PF2 0xf2
+#define AID_PF3 0xf3
+#define AID_PF4 0xf4
+#define AID_PF5 0xf5
+#define AID_PF6 0xf6
+#define AID_PF7 0xf7
+#define AID_PF8 0xf8
+#define AID_PF9 0xf9
+#define AID_PF10 0x7a
+#define AID_PF11 0x7b
+#define AID_PF12 0x7c
+#define AID_PF13 0xc1
+#define AID_PF14 0xc2
+#define AID_PF15 0xc3
+#define AID_PF16 0xc4
+#define AID_PF17 0xc5
+#define AID_PF18 0xc6
+#define AID_PF19 0xc7
+#define AID_PF20 0xc8
+#define AID_PF21 0xc9
+#define AID_PF22 0x4a
+#define AID_PF23 0x4b
+#define AID_PF24 0x4c
+#define AID_PF25 0xd1
+#define AID_PF26 0xd2
+#define AID_PF27 0xd3
+#define AID_PF28 0xd4
+#define AID_PF29 0xd5
+#define AID_PF30 0xd6
+#define AID_PF31 0xd7
+#define AID_PF32 0xd8
+#define AID_PF33 0xd9
+#define AID_PF34 0x5a
+#define AID_PF35 0x5b
+#define AID_PF36 0x5c
diff --git a/usr.bin/tn3270/ctlr/inbound.c b/usr.bin/tn3270/ctlr/inbound.c
new file mode 100644
index 0000000..fe8d142
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/inbound.c
@@ -0,0 +1,1194 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)inbound.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include <stdio.h>
+
+#include "../general/general.h"
+#include "function.h"
+#include "hostctlr.h"
+#include "oia.h"
+#include "scrnctlr.h"
+#include "screen.h"
+#include "options.h"
+#include "../api/dctype.h"
+#include "../api/ebc_disp.h"
+
+#include "../general/globals.h"
+#include "externs.h"
+#include "declare.h"
+
+#define EmptyChar() (ourPTail == ourPHead)
+#define FullChar() (ourPHead == ourBuffer+sizeof ourBuffer)
+
+
+/*
+ * We define something to allow us to to IsProtected() quickly
+ * on unformatted screens (with the current algorithm for fields,
+ * unprotected takes exponential time...).
+ *
+ * The idea is to call SetXIsProtected() BEFORE the
+ * loop, then use XIsProtected().
+ */
+
+#define SetXIsProtected() (XWasSF = 1)
+#define XIsProtected(p) (IsStartField(p)? \
+ XWasSF = 1 : \
+ (XWasSF? \
+ (XWasSF = 0, XProtected = IsProtected(p)) : \
+ XProtected))
+
+static char ourBuffer[400];
+
+static char *ourPHead = ourBuffer,
+ *ourPTail = ourBuffer;
+
+static int HadAid; /* Had an AID haven't sent */
+
+static int InsertMode; /* is the terminal in insert mode? */
+
+static unsigned int
+ rememberedshiftstate; /* Shift (alt) state of terminal */
+
+# define HITNUM(s) ((((s)&(SHIFT_CAPS|SHIFT_UPSHIFT))? 1:0) \
+ + ((((s)&SHIFT_ALT)? 1:0)<<1))
+
+static int XWasSF, XProtected; /* For optimizations */
+#if !defined(PURE3274)
+extern int TransparentClock, OutputClock;
+#endif /* !defined(PURE3274) */
+
+#include "kbd.out" /* Get keyboard mapping function */
+
+/* the following are global variables */
+
+extern int UnLocked; /* keyboard is UnLocked? */
+
+
+/*
+ * init_inbound :
+ *
+ * Reset variables to initial state.
+ */
+
+void
+init_inbound()
+{
+ ourPHead = ourPTail = ourBuffer;
+ HadAid = 0;
+ rememberedshiftstate = 0;
+ InsertMode = 0;
+}
+
+
+/* Tab() - sets cursor to the start of the next unprotected field */
+static void
+Tab()
+{
+ register int i, j;
+
+ i = CursorAddress;
+ j = WhereAttrByte(CursorAddress);
+ do {
+ if (IsStartField(i) && IsUnProtected(ScreenInc(i))) {
+ break;
+ }
+ i = FieldInc(i);
+ } while (i != j);
+ if (IsStartField(i) && IsUnProtected(ScreenInc(i))) {
+ CursorAddress = ScreenInc(i);
+ } else {
+ CursorAddress = SetBufferAddress(0,0);
+ }
+}
+
+
+/* BackTab() - sets cursor to the start of the most recent field */
+
+static void
+BackTab()
+{
+ register int i;
+
+ i = ScreenDec(CursorAddress);
+ for (;;) {
+ if (IsStartField(ScreenDec(i)) && IsUnProtected(i)) {
+ CursorAddress = i;
+ break;
+ }
+ if (i == CursorAddress) {
+ CursorAddress = SetBufferAddress(0,0);
+ break;
+ }
+ i = ScreenDec(i);
+ }
+}
+
+/*
+ * ModifyMdt() - Turn a modified data tag bit on or off (watch
+ * out for unformatted screens).
+ */
+
+ModifyMdt(x,on)
+int x;
+int on;
+{
+ int i = x;
+
+ if (IsStartField(i)) { /* If we are at a start field position... */
+ if (on) {
+ ModifyHost(i, |= ATTR_MDT); /* Turn it on */
+ } else {
+ ModifyHost(i, &= ~ATTR_MDT); /* Turn it off */
+ }
+ } else {
+ i = WhereAttrByte(i); /* Find beginning of field */
+ if (IsStartField(i)) { /* Is there one? */
+ if (on) {
+ ModifyHost(i, |= ATTR_MDT); /* Turn it on */
+ } else {
+ ModifyHost(i, &= ~ATTR_MDT); /* Turn it off */
+ }
+ } /* else, don't modify - this is an unformatted screen */
+ }
+}
+
+
+/* EraseEndOfField - erase all characters to the end of a field */
+
+static void
+EraseEndOfField()
+{
+ register int i;
+
+ if (IsProtected(CursorAddress)) {
+ RingBell("Protected Field");
+ } else {
+ TurnOnMdt(CursorAddress);
+ if (FormattedScreen()) {
+ i = CursorAddress;
+ do {
+ AddHost(i, 0);
+ i = ScreenInc(i);
+ } while ((i != CursorAddress) && !IsStartField(i));
+ } else { /* Screen is Unformatted */
+ i = CursorAddress;
+ do {
+ AddHost(i, 0);
+ i = ScreenInc(i);
+ } while (i != HighestScreen());
+ }
+ }
+}
+
+/* Delete() - deletes a character from the screen
+ *
+ * What we want to do is delete the section
+ * [where, from-1] from the screen,
+ * filling in with what comes at from.
+ *
+ * The deleting continues to the end of the field (or
+ * until the cursor wraps).
+ *
+ * From can be a start of a field. We
+ * check for that. However, there can't be any
+ * fields that start between where and from.
+ * We don't check for that.
+ *
+ * Also, we assume that the protection status of
+ * everything has been checked by the caller.
+ *
+ */
+
+static void
+Delete(where, from)
+register int where, /* Where to start deleting from */
+ from; /* Where to pull back from */
+{
+ register int i;
+
+ TurnOnMdt(where); /* Only do this once in this field */
+ i = where;
+ do {
+ if (IsStartField(from)) {
+ AddHost(i, 0); /* Stick the edge at the start field */
+ } else {
+ AddHost(i, (char)GetHost(from));
+ from = ScreenInc(from); /* Move the edge */
+ }
+ i = ScreenInc(i);
+ } while ((!IsStartField(i)) && (i != where));
+}
+
+static void
+ColBak()
+{
+ register int i;
+
+ i = ScreenLineOffset(CursorAddress);
+ for (i = i-1; i >= 0; i--) {
+ if (OptColTabs[i]) {
+ break;
+ }
+ }
+ if (i < 0) {
+ i = 0;
+ }
+ CursorAddress = SetBufferAddress(ScreenLine(CursorAddress), i);
+}
+
+static void
+ColTab()
+{
+ register int i;
+
+ i = ScreenLineOffset(CursorAddress);
+ for (i = i+1; i < NumberColumns; i++) {
+ if (OptColTabs[i]) {
+ break;
+ }
+ }
+ if (i >= NumberColumns) {
+ i = NumberColumns-1;
+ }
+ CursorAddress = SetBufferAddress(ScreenLine(CursorAddress), i);
+}
+
+static void
+Home()
+{
+ register int i;
+ register int j;
+
+ i = SetBufferAddress(OptHome, 0);
+ j = WhereLowByte(i);
+ /*
+ * If the initial value of i points to the field attribute of
+ * an unprotected field, we need to return the address of the
+ * first data byte in the field (assuming there are any!).
+ */
+ if (IsStartField(i) && IsUnProtected(j)) {
+ CursorAddress = j;
+ return;
+ }
+ do {
+ if (IsUnProtected(i)) {
+ CursorAddress = i;
+ return;
+ }
+ /* the following could be a problem if we got here with an
+ * unformatted screen. However, this is "impossible", since
+ * with an unformatted screen, the IsUnProtected(i) above
+ * should be true.
+ */
+ i = ScreenInc(FieldInc(i));
+ } while (i != j);
+ CursorAddress = LowestScreen();
+}
+
+static
+LastOfField(i)
+register int i; /* position to start from */
+{
+ register int j;
+ register int k;
+
+ k = j = i;
+ SetXIsProtected();
+ while (XIsProtected(i) || Disspace(GetHost(i))) {
+ i = ScreenInc(i);
+ if (i == j) {
+ break;
+ }
+ }
+ /* We are now IN a word IN an unprotected field (or wrapped) */
+ while (!XIsProtected(i)) {
+ if (!Disspace(GetHost(i))) {
+ k = i;
+ }
+ i = ScreenInc(i);
+ if (i == j) {
+ break;
+ }
+ }
+ return(k);
+}
+
+
+static void
+FlushChar()
+{
+ ourPTail = ourPHead = ourBuffer;
+}
+
+
+/*
+ * Add one EBCDIC (NOT display code) character to the buffer.
+ */
+
+static void
+AddChar(character)
+char character;
+{
+ if (FullChar()) {
+ ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 0);
+ if (EmptyChar()) {
+ FlushChar();
+ } else {
+ char buffer[100];
+
+ sprintf(buffer, "File %s, line %d: No room in network buffer!\n",
+ __FILE__, __LINE__);
+ ExitString(buffer, 1);
+ /*NOTREACHED*/
+ }
+ }
+ *ourPHead++ = character;
+}
+
+
+static void
+SendUnformatted()
+{
+ register int i, j;
+ register int Nulls;
+ register int c;
+
+ /* look for start of field */
+ Nulls = 0;
+ i = j = LowestScreen();
+ do {
+ c = GetHost(i);
+ if (c == 0) {
+ Nulls++;
+ } else {
+ while (Nulls) {
+ Nulls--;
+ AddChar(EBCDIC_BLANK); /* put in blanks */
+ }
+ AddChar((char)disp_ebc[c]);
+ }
+ i = ScreenInc(i);
+ } while (i != j);
+}
+
+static
+SendField(i, cmd)
+register int i; /* where we saw MDT bit */
+int cmd; /* The command code (type of read) */
+{
+ register int j;
+ register int k;
+ register int Nulls;
+ register int c;
+
+ /* look for start of field */
+ i = j = WhereLowByte(i);
+
+ /* On a test_request_read, don't send sba and address */
+ if ((AidByte != AID_TREQ)
+ || (cmd == CMD_SNA_READ_MODIFIED_ALL)) {
+ AddChar(ORDER_SBA); /* set start field */
+ AddChar(BufferTo3270_0(j)); /* set address of this field */
+ AddChar(BufferTo3270_1(j));
+ }
+ /*
+ * Only on read_modified_all do we return the contents
+ * of the field when the attention was caused by a
+ * selector pen.
+ */
+ if ((AidByte != AID_SELPEN)
+ || (cmd == CMD_SNA_READ_MODIFIED_ALL)) {
+ if (!IsStartField(j)) {
+ Nulls = 0;
+ k = ScreenInc(WhereHighByte(j));
+ do {
+ c = GetHost(j);
+ if (c == 0) {
+ Nulls++;
+ } else {
+ while (Nulls) {
+ Nulls--;
+ AddChar(EBCDIC_BLANK); /* put in blanks */
+ }
+ AddChar((char)disp_ebc[c]);
+ }
+ j = ScreenInc(j);
+ } while ((j != k) && (j != i));
+ }
+ } else {
+ j = FieldInc(j);
+ }
+ return(j);
+}
+
+/* Various types of reads... */
+void
+DoReadModified(cmd)
+int cmd; /* The command sent */
+{
+ register int i, j;
+
+ if (AidByte) {
+ if (AidByte != AID_TREQ) {
+ AddChar(AidByte);
+ } else {
+ /* Test Request Read header */
+ AddChar(EBCDIC_SOH);
+ AddChar(EBCDIC_PERCENT);
+ AddChar(EBCDIC_SLASH);
+ AddChar(EBCDIC_STX);
+ }
+ } else {
+ AddChar(AID_NONE);
+ }
+ if (((AidByte != AID_PA1) && (AidByte != AID_PA2)
+ && (AidByte != AID_PA3) && (AidByte != AID_CLEAR))
+ || (cmd == CMD_SNA_READ_MODIFIED_ALL)) {
+ if ((AidByte != AID_TREQ)
+ || (cmd == CMD_SNA_READ_MODIFIED_ALL)) {
+ /* Test request read_modified doesn't give cursor address */
+ AddChar(BufferTo3270_0(CursorAddress));
+ AddChar(BufferTo3270_1(CursorAddress));
+ }
+ i = j = WhereAttrByte(LowestScreen());
+ /* Is this an unformatted screen? */
+ if (!IsStartField(i)) { /* yes, handle separate */
+ SendUnformatted();
+ } else {
+ do {
+ if (HasMdt(i)) {
+ i = SendField(i, cmd);
+ } else {
+ i = FieldInc(i);
+ }
+ } while (i != j);
+ }
+ }
+ ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1);
+ if (EmptyChar()) {
+ FlushChar();
+ HadAid = 0; /* killed that buffer */
+ }
+}
+
+/* A read buffer operation... */
+
+void
+DoReadBuffer()
+{
+ register int i, j;
+
+ if (AidByte) {
+ AddChar(AidByte);
+ } else {
+ AddChar(AID_NONE);
+ }
+ AddChar(BufferTo3270_0(CursorAddress));
+ AddChar(BufferTo3270_1(CursorAddress));
+ i = j = LowestScreen();
+ do {
+ if (IsStartField(i)) {
+ AddChar(ORDER_SF);
+ AddChar(BufferTo3270_1(FieldAttributes(i)));
+ } else {
+ AddChar((char)disp_ebc[GetHost(i)]);
+ }
+ i = ScreenInc(i);
+ } while (i != j);
+ ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1);
+ if (EmptyChar()) {
+ FlushChar();
+ HadAid = 0; /* killed that buffer */
+ }
+}
+
+/* Send some transparent data to the host */
+
+void
+SendTransparent(buffer, count)
+char *buffer;
+int count;
+{
+ char stuff[3];
+
+ stuff[0] = AID_NONE_PRINTER;
+ stuff[1] = BufferTo3270_0(count);
+ stuff[2] = BufferTo3270_1(count);
+ DataToNetwork(stuff, sizeof stuff, 0);
+ DataToNetwork(buffer, count, 1);
+}
+
+
+/* Try to send some data to host */
+
+void
+SendToIBM()
+{
+#if !defined(PURE3274)
+ if (TransparentClock >= OutputClock) {
+ if (HadAid) {
+ AddChar(AidByte);
+ HadAid = 0;
+ } else {
+ AddChar(AID_NONE_PRINTER);
+ }
+ do {
+ ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1);
+ } while (!EmptyChar());
+ FlushChar();
+ } else if (HadAid) {
+ DoReadModified(CMD_READ_MODIFIED);
+ }
+#else /* !defined(PURE3274) */
+ if (HadAid) {
+ DoReadModified(CMD_READ_MODIFIED);
+ }
+#endif /* !defined(PURE3274) */
+}
+
+/* This takes in one character from the keyboard and places it on the
+ * screen.
+ */
+
+static void
+OneCharacter(c, insert)
+int c; /* character (Ebcdic) to be shoved in */
+int insert; /* are we in insert mode? */
+{
+ register int i, j;
+
+ if (IsProtected(CursorAddress)) {
+ RingBell("Protected Field");
+ return;
+ }
+ if (insert) {
+ /* is the last character in the field a blank or null? */
+ i = ScreenDec(FieldInc(CursorAddress));
+ j = GetHost(i);
+ if (!Disspace(j)) {
+ RingBell("No more room for insert");
+ return;
+ } else {
+ for (j = ScreenDec(i); i != CursorAddress;
+ j = ScreenDec(j), i = ScreenDec(i)) {
+ AddHost(i, (char)GetHost(j));
+ }
+ }
+ }
+ AddHost(CursorAddress, c);
+ TurnOnMdt(CursorAddress);
+ CursorAddress = ScreenInc(CursorAddress);
+ if (IsStartField(CursorAddress) &&
+ ((FieldAttributes(CursorAddress)&ATTR_AUTO_SKIP_MASK) ==
+ ATTR_AUTO_SKIP_VALUE)) {
+ Tab();
+ }
+}
+
+/*
+ * AcceptKeystroke()
+ *
+ * Processes one keystroke.
+ *
+ * Returns:
+ *
+ * 0 if this keystroke was NOT processed.
+ * 1 if everything went OK.
+ */
+
+int
+AcceptKeystroke(scancode, shiftstate)
+unsigned int
+ scancode, /* 3270 scancode */
+ shiftstate; /* The shift state */
+{
+ register int c;
+ register int i;
+ register int j;
+ enum ctlrfcn ctlrfcn;
+
+ if (scancode >= numberof(hits)) {
+ ExitString(
+ "Unknown scancode encountered in AcceptKeystroke.\n", 1);
+ /*NOTREACHED*/
+ }
+ ctlrfcn = hits[scancode].hit[HITNUM(shiftstate)].ctlrfcn;
+ c = hits[scancode].hit[HITNUM(shiftstate)].code;
+
+ if (!UnLocked || HadAid) {
+ if (HadAid) {
+ SendToIBM();
+ if (!EmptyChar()) {
+ return 0; /* nothing to do */
+ }
+ }
+#if !defined(PURE3274)
+ if (!HadAid && EmptyChar()) {
+ if ((ctlrfcn == FCN_RESET) || (ctlrfcn == FCN_MASTER_RESET)) {
+ UnLocked = 1;
+ }
+ }
+#endif /* !defined(PURE3274) */
+ if (!UnLocked) {
+ return 0;
+ }
+ }
+
+ /* now, either empty, or haven't seen aid yet */
+
+#if !defined(PURE3274)
+ /*
+ * If we are in transparent (output) mode, do something special
+ * with keystrokes.
+ */
+ if (TransparentClock == OutputClock) {
+ if (ctlrfcn == FCN_AID) {
+ UnLocked = 0;
+ InsertMode = 0;
+ AidByte = (c);
+ HadAid = 1;
+ } else {
+ switch (ctlrfcn) {
+ case FCN_ESCAPE:
+ StopScreen(1);
+ command(0);
+ if (shell_active == 0) {
+ ConnectScreen();
+ }
+ break;
+
+ case FCN_RESET:
+ case FCN_MASTER_RESET:
+ UnLocked = 1;
+ break;
+
+ default:
+ return 0;
+ }
+ }
+ }
+#endif /* !defined(PURE3274) */
+
+ if (ctlrfcn == FCN_CHARACTER) {
+ /* Add the character to the buffer */
+ OneCharacter(c, InsertMode);
+ } else if (ctlrfcn == FCN_AID) { /* got Aid */
+ if (c == AID_CLEAR) {
+ LocalClearScreen(); /* Side effect is to clear 3270 */
+ }
+ ResetOiaOnlineA(&OperatorInformationArea);
+ SetOiaTWait(&OperatorInformationArea);
+ ResetOiaInsert(&OperatorInformationArea);
+ InsertMode = 0; /* just like a 3278 */
+ SetOiaSystemLocked(&OperatorInformationArea);
+ SetOiaModified();
+ UnLocked = 0;
+ AidByte = c;
+ HadAid = 1;
+ SendToIBM();
+ } else {
+ switch (ctlrfcn) {
+
+ case FCN_CURSEL:
+ c = FieldAttributes(CursorAddress)&ATTR_DSPD_MASK;
+ if (!FormattedScreen()
+ || ((c != ATTR_DSPD_DSPD) && (c != ATTR_DSPD_HIGH))) {
+ RingBell("Cursor not in selectable field");
+ } else {
+ i = ScreenInc(WhereAttrByte(CursorAddress));
+ c = GetHost(i);
+ if (c == DISP_QUESTION) {
+ AddHost(i, DISP_GREATER_THAN);
+ TurnOnMdt(i);
+ } else if (c == DISP_GREATER_THAN) {
+ AddHost(i, DISP_QUESTION);
+ TurnOffMdt(i);
+ } else if (c == DISP_BLANK || c == DISP_NULL
+ || c == DISP_AMPERSAND) {
+ UnLocked = 0;
+ InsertMode = 0;
+ ResetOiaOnlineA(&OperatorInformationArea);
+ SetOiaTWait(&OperatorInformationArea);
+ SetOiaSystemLocked(&OperatorInformationArea);
+ ResetOiaInsert(&OperatorInformationArea);
+ SetOiaModified();
+ if (c == DISP_AMPERSAND) {
+ TurnOnMdt(i); /* Only for & type */
+ AidByte = AID_ENTER;
+ } else {
+ AidByte = AID_SELPEN;
+ }
+ HadAid = 1;
+ SendToIBM();
+ } else {
+ RingBell(
+ "Cursor not in a selectable field (designator)");
+ }
+ }
+ break;
+
+#if !defined(PURE3274)
+ case FCN_ERASE:
+ if (IsProtected(ScreenDec(CursorAddress))) {
+ RingBell("Protected Field");
+ } else {
+ CursorAddress = ScreenDec(CursorAddress);
+ Delete(CursorAddress, ScreenInc(CursorAddress));
+ }
+ break;
+ case FCN_WERASE:
+ j = CursorAddress;
+ i = ScreenDec(j);
+ if (IsProtected(i)) {
+ RingBell("Protected Field");
+ } else {
+ SetXIsProtected();
+ while ((!XIsProtected(i) && Disspace(GetHost(i)))
+ && (i != j)) {
+ i = ScreenDec(i);
+ }
+ /* we are pointing at a character in a word, or
+ * at a protected position
+ */
+ while ((!XIsProtected(i) && !Disspace(GetHost(i)))
+ && (i != j)) {
+ i = ScreenDec(i);
+ }
+ /* we are pointing at a space, or at a protected
+ * position
+ */
+ CursorAddress = ScreenInc(i);
+ Delete(CursorAddress, j);
+ }
+ break;
+
+ case FCN_FERASE:
+ if (IsProtected(CursorAddress)) {
+ RingBell("Protected Field");
+ } else {
+ CursorAddress = ScreenInc(CursorAddress); /* for btab */
+ BackTab();
+ EraseEndOfField();
+ }
+ break;
+
+ case FCN_RESET:
+ if (InsertMode) {
+ InsertMode = 0;
+ ResetOiaInsert(&OperatorInformationArea);
+ SetOiaModified();
+ }
+ break;
+ case FCN_MASTER_RESET:
+ if (InsertMode) {
+ InsertMode = 0;
+ ResetOiaInsert(&OperatorInformationArea);
+ SetOiaModified();
+ }
+ RefreshScreen();
+ break;
+#endif /* !defined(PURE3274) */
+
+ case FCN_UP:
+ CursorAddress = ScreenUp(CursorAddress);
+ break;
+
+ case FCN_LEFT:
+ CursorAddress = ScreenDec(CursorAddress);
+ break;
+
+ case FCN_RIGHT:
+ CursorAddress = ScreenInc(CursorAddress);
+ break;
+
+ case FCN_DOWN:
+ CursorAddress = ScreenDown(CursorAddress);
+ break;
+
+ case FCN_DELETE:
+ if (IsProtected(CursorAddress)) {
+ RingBell("Protected Field");
+ } else {
+ Delete(CursorAddress, ScreenInc(CursorAddress));
+ }
+ break;
+
+ case FCN_INSRT:
+ InsertMode = !InsertMode;
+ if (InsertMode) {
+ SetOiaInsert(&OperatorInformationArea);
+ } else {
+ ResetOiaInsert(&OperatorInformationArea);
+ }
+ SetOiaModified();
+ break;
+
+ case FCN_HOME:
+ Home();
+ break;
+
+ case FCN_NL:
+ /* The algorithm is to look for the first unprotected
+ * column after column 0 of the following line. Having
+ * found that unprotected column, we check whether the
+ * cursor-address-at-entry is at or to the right of the
+ * LeftMargin AND the LeftMargin column of the found line
+ * is unprotected. If this conjunction is true, then
+ * we set the found pointer to the address of the LeftMargin
+ * column in the found line.
+ * Then, we set the cursor address to the found address.
+ */
+ i = SetBufferAddress(ScreenLine(ScreenDown(CursorAddress)), 0);
+ j = ScreenInc(WhereAttrByte(CursorAddress));
+ do {
+ if (IsUnProtected(i)) {
+ break;
+ }
+ /* Again (see comment in Home()), this COULD be a problem
+ * with an unformatted screen.
+ */
+ /* If there was a field with only an attribute byte,
+ * we may be pointing to the attribute byte of the NEXT
+ * field, so just look at the next byte.
+ */
+ if (IsStartField(i)) {
+ i = ScreenInc(i);
+ } else {
+ i = ScreenInc(FieldInc(i));
+ }
+ } while (i != j);
+ if (!IsUnProtected(i)) { /* couldn't find unprotected */
+ i = SetBufferAddress(0,0);
+ }
+ if (OptLeftMargin <= ScreenLineOffset(CursorAddress)) {
+ if (IsUnProtected(SetBufferAddress(ScreenLine(i),
+ OptLeftMargin))) {
+ i = SetBufferAddress(ScreenLine(i), OptLeftMargin);
+ }
+ }
+ CursorAddress = i;
+ break;
+
+ case FCN_EINP:
+ if (!FormattedScreen()) {
+ i = CursorAddress;
+ TurnOffMdt(i);
+ do {
+ AddHost(i, 0);
+ i = ScreenInc(i);
+ } while (i != CursorAddress);
+ } else {
+ /*
+ * The algorithm is: go through each unprotected
+ * field on the screen, clearing it out. When
+ * we are at the start of a field, skip that field
+ * if its contents are protected.
+ */
+ i = j = FieldInc(CursorAddress);
+ do {
+ if (IsUnProtected(ScreenInc(i))) {
+ i = ScreenInc(i);
+ TurnOffMdt(i);
+ do {
+ AddHost(i, 0);
+ i = ScreenInc(i);
+ } while (!IsStartField(i));
+ } else {
+ i = FieldInc(i);
+ }
+ } while (i != j);
+ }
+ Home();
+ break;
+
+ case FCN_EEOF:
+ EraseEndOfField();
+ break;
+
+ case FCN_SPACE:
+ OneCharacter(DISP_BLANK, InsertMode); /* Add cent */
+ break;
+
+ case FCN_CENTSIGN:
+ OneCharacter(DISP_CENTSIGN, InsertMode); /* Add cent */
+ break;
+
+ case FCN_FM:
+ OneCharacter(DISP_FM, InsertMode); /* Add field mark */
+ break;
+
+ case FCN_DP:
+ if (IsProtected(CursorAddress)) {
+ RingBell("Protected Field");
+ } else {
+ OneCharacter(DISP_DUP, InsertMode);/* Add dup character */
+ Tab();
+ }
+ break;
+
+ case FCN_TAB:
+ Tab();
+ break;
+
+ case FCN_BTAB:
+ BackTab();
+ break;
+
+#ifdef NOTUSED /* Actually, this is superseded by unix flow
+ * control.
+ */
+ case FCN_XOFF:
+ Flow = 0; /* stop output */
+ break;
+
+ case FCN_XON:
+ if (!Flow) {
+ Flow = 1; /* turn it back on */
+ DoTerminalOutput();
+ }
+ break;
+#endif /* NOTUSED */
+
+#if !defined(PURE3274)
+ case FCN_ESCAPE:
+ /* FlushChar(); do we want to flush characters from before? */
+ StopScreen(1);
+ command(0);
+ if (shell_active == 0) {
+ ConnectScreen();
+ }
+ break;
+
+ case FCN_DISC:
+ StopScreen(1);
+ suspend();
+ setconnmode();
+ ConnectScreen();
+ break;
+
+ case FCN_RESHOW:
+ RefreshScreen();
+ break;
+
+ case FCN_SETTAB:
+ OptColTabs[ScreenLineOffset(CursorAddress)] = 1;
+ break;
+
+ case FCN_DELTAB:
+ OptColTabs[ScreenLineOffset(CursorAddress)] = 0;
+ break;
+
+ /*
+ * Clear all tabs, home line, and left margin.
+ */
+ case FCN_CLRTAB:
+ for (i = 0; i < sizeof OptColTabs; i++) {
+ OptColTabs[i] = 0;
+ }
+ OptHome = 0;
+ OptLeftMargin = 0;
+ break;
+
+ case FCN_COLTAB:
+ ColTab();
+ break;
+
+ case FCN_COLBAK:
+ ColBak();
+ break;
+
+ case FCN_INDENT:
+ ColTab();
+ OptLeftMargin = ScreenLineOffset(CursorAddress);
+ break;
+
+ case FCN_UNDENT:
+ ColBak();
+ OptLeftMargin = ScreenLineOffset(CursorAddress);
+ break;
+
+ case FCN_SETMRG:
+ OptLeftMargin = ScreenLineOffset(CursorAddress);
+ break;
+
+ case FCN_SETHOM:
+ OptHome = ScreenLine(CursorAddress);
+ break;
+
+ /*
+ * Point to first character of next unprotected word on
+ * screen.
+ */
+ case FCN_WORDTAB:
+ i = CursorAddress;
+ SetXIsProtected();
+ while (!XIsProtected(i) && !Disspace(GetHost(i))) {
+ i = ScreenInc(i);
+ if (i == CursorAddress) {
+ break;
+ }
+ }
+ /* i is either protected, a space (blank or null),
+ * or wrapped
+ */
+ while (XIsProtected(i) || Disspace(GetHost(i))) {
+ i = ScreenInc(i);
+ if (i == CursorAddress) {
+ break;
+ }
+ }
+ CursorAddress = i;
+ break;
+
+ case FCN_WORDBACKTAB:
+ i = ScreenDec(CursorAddress);
+ SetXIsProtected();
+ while (XIsProtected(i) || Disspace(GetHost(i))) {
+ i = ScreenDec(i);
+ if (i == CursorAddress) {
+ break;
+ }
+ }
+ /* i is pointing to a character IN an unprotected word
+ * (or i wrapped)
+ */
+ while (!Disspace(GetHost(i))) {
+ i = ScreenDec(i);
+ if (i == CursorAddress) {
+ break;
+ }
+ }
+ CursorAddress = ScreenInc(i);
+ break;
+
+ /* Point to last non-blank character of this/next
+ * unprotected word.
+ */
+ case FCN_WORDEND:
+ i = ScreenInc(CursorAddress);
+ SetXIsProtected();
+ while (XIsProtected(i) || Disspace(GetHost(i))) {
+ i = ScreenInc(i);
+ if (i == CursorAddress) {
+ break;
+ }
+ }
+ /* we are pointing at a character IN an
+ * unprotected word (or we wrapped)
+ */
+ while (!Disspace(GetHost(i))) {
+ i = ScreenInc(i);
+ if (i == CursorAddress) {
+ break;
+ }
+ }
+ CursorAddress = ScreenDec(i);
+ break;
+
+ /* Get to last non-blank of this/next unprotected
+ * field.
+ */
+ case FCN_FIELDEND:
+ i = LastOfField(CursorAddress);
+ if (i != CursorAddress) {
+ CursorAddress = i; /* We moved; take this */
+ } else {
+ j = FieldInc(CursorAddress); /* Move to next field */
+ i = LastOfField(j);
+ if (i != j) {
+ CursorAddress = i; /* We moved; take this */
+ }
+ /* else - nowhere else on screen to be; stay here */
+ }
+ break;
+#endif /* !defined(PURE3274) */
+
+ default:
+ /* We don't handle this yet */
+ RingBell("Function not implemented");
+ }
+ }
+ return 1; /* We did something! */
+}
+
+
+/*
+ * We get data from the terminal. We keep track of the shift state
+ * (including ALT, CONTROL), and then call AcceptKeystroke to actually
+ * process any non-shift keys.
+ */
+
+int
+DataFrom3270(buffer, count)
+unsigned char *buffer; /* where the data is */
+int count; /* how much data there is */
+{
+ int origCount;
+
+ origCount = count;
+
+ while (count) {
+ if (*buffer >= numberof(hits)) {
+ ExitString("Unknown scancode encountered in DataFrom3270.\n", 1);
+ /*NOTREACHED*/
+ }
+
+ switch (hits[*buffer].hit[HITNUM(rememberedshiftstate)].ctlrfcn) {
+
+ case FCN_MAKE_SHIFT:
+ rememberedshiftstate |= (SHIFT_RIGHT|SHIFT_UPSHIFT);
+ break;
+ case FCN_BREAK_SHIFT:
+ rememberedshiftstate &= ~(SHIFT_RIGHT|SHIFT_UPSHIFT);
+ break;
+ case FCN_MAKE_ALT:
+ rememberedshiftstate |= SHIFT_ALT;
+ break;
+ case FCN_BREAK_ALT:
+ rememberedshiftstate &= ~SHIFT_ALT;
+ break;
+ default:
+ if (AcceptKeystroke(*buffer, rememberedshiftstate) == 0) {
+ return(origCount-count);
+ }
+ break;
+ }
+ buffer++;
+ count--;
+ }
+ return(origCount-count);
+}
diff --git a/usr.bin/tn3270/ctlr/oia.c b/usr.bin/tn3270/ctlr/oia.c
new file mode 100644
index 0000000..1f80359
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/oia.c
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)oia.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+/*
+ * Routines to maintain the Operator Information Area.
+ */
+
+#include "../general/general.h"
+
+#include "oia.h"
+#include "../general/globals.h"
+
+
+init_oia()
+{
+ ClearElement(OperatorInformationArea);
+}
diff --git a/usr.bin/tn3270/ctlr/oia.h b/usr.bin/tn3270/ctlr/oia.h
new file mode 100644
index 0000000..a1414ca
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/oia.h
@@ -0,0 +1,190 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)oia.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * This file describes the Operator Information Area in the 3270.
+ *
+ * Our OIA looks like that used by the 3270 PC and PC 3270 products.
+ */
+
+#define INCLUDED_OIA
+
+typedef struct {
+ char
+ online_ownership,
+ character_selection,
+ shift_state,
+ pss_group_1,
+ highlight_group_1,
+ color_group_1,
+ insert,
+ input_inhibited[5],
+ pss_group_2,
+ highlight_group_2,
+ color_group_2,
+ comm_error_reminder,
+ printer_status,
+ reserved_group_14,
+ reserved_group_15,
+ autokey_play_record_status,
+ autokey_abort_pause_status,
+ enlarge_state;
+} OIA;
+
+/* Bits in online_ownership */
+#define OIA_SETUP 0x80
+#define OIA_TEST 0x40
+#define OIA_SSCP_LU 0x20
+#define OIA_LU_LU 0x10
+#define OIA_UNOWNED 0x08
+#define OIA_SUBSYSTEM_READY 0x04
+
+/* Bit in character_selection */
+#define OIA_EXTENDED_SELECT 0x80
+#define OIA_APL 0x40
+#define OIA_KANA 0x20
+#define OIA_ALPHA 0x10
+#define OIA_TEXT 0x08
+
+/* Bits in shift_state */
+#define OIA_NUMERIC 0x80
+#define OIA_UPPER_SHIFT 0x40
+
+/* Bits in pss_group_1, highlight_group_1, and color_group_1 */
+#define OIA_SELECTABLE 0x80
+#define OIA_FIELD_INHERIT 0x40
+
+/* Bits in insert */
+#define OIA_INSERT_MODE 0x80
+
+/* We define this to be a 'long' followed by a 'char' (5 bytes) */
+
+#define OIA_NON_RESETTABLE 0x80
+#define OIA_SECURITY_KEY 0x40
+#define OIA_MACHINE_CHECK 0x20
+#define OIA_COMM_CHECK 0x10
+#define OIA_PROGRAM_CHECK 0x08
+#define OIA_RETRY 0x04
+#define OIA_DEVICE_NOT_WORKING 0x02
+#define OIA_DEVICE_VERY_BUSY 0x01
+
+#define OIA_DEVICE_BUSY 0x80
+#define OIA_TERMINAL_WAIT 0x40
+#define OIA_MINUS_SYMBOL 0x20
+#define OIA_MINUS_FUNCTION 0x10
+#define OIA_TOO_MUCH_ENTERED 0x08
+#define OIA_NOT_ENOUGH_ENTERED 0x04
+#define OIA_WRONG_NUMBER 0x02
+#define OIA_NUMERIC_FIELD 0x01
+
+#define OIA_OP_UNAUTHORIZED 0x80
+#define OIA_OP_UNAUTHORIZED_MIN 0x40
+#define OIA_INVALID_DEAD_KEY_COMBO 0x20
+#define OIA_WRONG_PLACE 0x10
+
+#define OIA_MESSAGE_PENDING 0x80
+#define OIA_PARTITION_WAIT 0x40
+#define OIA_SYSTEM_WAIT 0x20
+#define OIA_HARDWARE_MISMATCH 0x10
+#define OIA_LOGICAL_TERM_NOT_CONF 0x08
+
+
+#define OIA_AUTOKEY_INHIBIT 0x80
+#define OIA_API_INHIBIT 0x40
+
+/* Bits in pss_group_2 */
+#define OIA_PS_SELECTED 0x80
+#define OIA_PC_DISPLAY_DISABLE 0x40
+
+/* Bits in highlight_group_2 and color_group_2 */
+#define OIA_SELECTED 0x80
+
+/* Bits in comm_error_reminder */
+#define OIA_COMM_ERROR 0x80
+#define OIA_RTM 0x40
+
+/* Bits in printer_status */
+#define OIA_PRINT_NOT_CUSTOM 0x80
+#define OIA_PRINTER_MALFUNCTION 0x40
+#define OIA_PRINTER_PRINTING 0x20
+#define OIA_ASSIGN_PRINTER 0x10
+#define OIA_WHAT_PRINTER 0x08
+#define OIA_PRINTER_ASSIGNMENT 0x04
+
+/* Bits in autokey_play_record_status */
+#define OIA_PLAY 0x80
+#define OIA_RECORD 0x40
+
+/* Bits in autokey_abort_pause_status */
+#define OIA_RECORDING_OVERFLOW 0x80
+#define OIA_PAUSE 0x40
+
+/* Bits in enlarge_state */
+#define OIA_WINDOW_IS_ENLARGED 0x80
+
+/* Define functions to set and read the oia */
+
+#define SetOiaOnlineA(oia) SetOiaMyJob((oia)) /* Side-effect */
+#define ResetOiaOnlineA(oia) \
+ /* Nothing defined for this */
+
+#define IsOiaReady3274(oia) ((oia)->online_ownership&OIA_SUBSYSTEM_READY)
+#define ResetOiaReady3274(oia) (oia)->online_ownership &= ~OIA_SUBSYSTEM_READY
+#define SetOiaReady3274(oia) (oia)->online_ownership |= OIA_SUBSYSTEM_READY
+
+#define IsOiaMyJob(oia) ((oia)->online_ownership&OIA_LU_LU)
+#define ResetOiaMyJob(oia) (oia)->online_ownership &= ~OIA_LU_LU
+#define SetOiaMyJob(oia) (oia)->online_ownership |= OIA_LU_LU
+
+#define IsOiaInsert(oia) ((oia)->online_ownership&OIA_INSERT_MODE)
+#define ResetOiaInsert(oia) (oia)->online_ownership &= ~OIA_INSERT_MODE
+#define SetOiaInsert(oia) (oia)->online_ownership |= OIA_INSERT_MODE
+
+#define IsOiaSystemLocked(oia) ((oia)->input_inhibited[3]&OIA_SYSTEM_WAIT)
+#define ResetOiaSystemLocked(oia) \
+ (oia)->input_inhibited[3] &= ~OIA_SYSTEM_WAIT
+#define SetOiaSystemLocked(oia) (oia)->input_inhibited[3] |= OIA_SYSTEM_WAIT
+
+#define IsOiaTWait(oia) ((oia)->input_inhibited[1]&OIA_TERMINAL_WAIT)
+#define ResetOiaTWait(oia) (oia)->input_inhibited[1] &= ~OIA_TERMINAL_WAIT
+#define SetOiaTWait(oia) (oia)->input_inhibited[1] |= OIA_TERMINAL_WAIT
+
+#define IsOiaApiInhibit(oia) ((oia)->input_inhibited[4] & OIA_API_INHIBIT)
+#define ResetOiaApiInhibit(oia) ((oia)->input_inhibited[4] &= ~OIA_API_INHIBIT)
+#define SetOiaApiInhibit(oia) ((oia)->input_inhibited[4] |= OIA_API_INHIBIT)
+
+/* A macro to let the world know that someone has modified the OIA. */
+#define SetOiaModified() oia_modified = 1
+#define SetPsModified() ps_modified = 1
diff --git a/usr.bin/tn3270/ctlr/options.c b/usr.bin/tn3270/ctlr/options.c
new file mode 100644
index 0000000..38a2d43
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/options.c
@@ -0,0 +1,181 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)options.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+/*
+ * this file contains the definitions, initialization, and processing of
+ * commands to handle the various local options (APL ON, etc.)
+ */
+
+#include "options.h"
+
+#include "../general/globals.h"
+#include "declare.h"
+
+void
+OptInit()
+{
+ register int i;
+
+ OptAPLmode = 0;
+ OptNullProcessing = 1; /* improved null processing */
+ OptZonesMode = 0; /* zones mode off */
+ OptEnterNL = 0; /* regular enter/new line keys */
+ OptColFieldTab = 0; /* regular column/field tab keys */
+ OptPacing = 1; /* do pacing */
+ OptAlphaInNumeric = 0; /* allow alpha in numeric fields */
+ for (i = 0; i < sizeof OptColTabs; i++) {
+ OptColTabs[i] = ((i%8) == 0); /* every 8 columns */
+ }
+ OptHome = 0;
+ OptLeftMargin = 0;
+ OptWordWrap = 0;
+}
+
+OptOrder(pointer, count, control)
+unsigned char *pointer;
+int count;
+int control;
+{
+ int i, j, character, origCount;
+
+ origCount = count;
+
+ if (count == 0) {
+ return(0);
+ }
+ character = *pointer&0xff;
+ pointer++;
+ count--;
+ switch (character) {
+ case 0xa0:
+ OptAPLmode = 1;
+ break;
+ case 0x61:
+ OptAPLmode = 0;
+ break;
+ case 0x95:
+ OptNullProcessing = 0;
+ break;
+ case 0xd5:
+ OptNullProcessing = 1;
+ break;
+ case 0xa9:
+ OptZonesMode = 1;
+ break;
+ case 0xe9:
+ OptZonesMode = 0;
+ break;
+ case 0x85:
+ OptEnterNL = 1;
+ break;
+ case 0xc5:
+ OptEnterNL = 0;
+ break;
+ case 0x83:
+ OptColFieldTab = 1;
+ break;
+ case 0xc3:
+ OptColFieldTab = 0;
+ break;
+ case 0x97:
+ OptPacing = 0;
+ break;
+ case 0xd7:
+ OptPacing = 1;
+ break;
+ case 0xa5:
+ OptAlphaInNumeric = 1;
+ break;
+ case 0xe5:
+ OptAlphaInNumeric = 0;
+ break;
+ case 0xe3:
+ if (!control && count < 30) {
+ return(0); /* want more! */
+ }
+ for (i = 0; i < sizeof OptColTabs; i++) {
+ OptColTabs[i] = 0;
+ }
+ if (!count) {
+ break;
+ }
+ j = (*pointer&0xff)-0x40;
+ count--;
+ pointer++;
+ if (j < 0 || j >= 24) {
+ break;
+ }
+ OptHome = j;
+ if (!count) {
+ break;
+ }
+ j = (*pointer&0xff)-0x40;
+ count--;
+ pointer++;
+ if (j < 0 || j >= 80) {
+ break;
+ }
+ OptLeftMargin = j;
+ if (!count) {
+ break;
+ }
+ i = count;
+ if (i > 28) {
+ i = 28;
+ }
+ while (i) {
+ j = (*pointer&0xff)-0x40;
+ if (j < 0 || j >= sizeof OptColTabs) {
+ break;
+ }
+ OptColTabs[j] = 1;
+ i --;
+ pointer++;
+ count--;
+ }
+ break;
+ case 0xa6:
+ OptWordWrap = 1;
+ break;
+ case 0xe6:
+ OptWordWrap = 0;
+ break;
+ default:
+ break;
+ }
+ return(origCount - count);
+}
diff --git a/usr.bin/tn3270/ctlr/options.h b/usr.bin/tn3270/ctlr/options.h
new file mode 100644
index 0000000..fbf5b10
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/options.h
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)options.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * the various options that run our life. Very few of these are implemented
+ * as yet.
+ */
+
+#define INCLUDED_OPTIONS
diff --git a/usr.bin/tn3270/ctlr/outbound.c b/usr.bin/tn3270/ctlr/outbound.c
new file mode 100644
index 0000000..72432f2
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/outbound.c
@@ -0,0 +1,605 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)outbound.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include <stdio.h>
+
+#include "../general/general.h"
+
+#include "hostctlr.h"
+#include "oia.h"
+#include "screen.h"
+#include "../api/ebc_disp.h"
+
+#include "../general/globals.h"
+#include "externs.h"
+#include "declare.h"
+
+#define SetHighestLowest(position) { \
+ if (position < Lowest) { \
+ Lowest = position; \
+ } \
+ if (position > Highest) { \
+ Highest = position; \
+ } \
+ }
+
+
+static int LastWasTerminated = 1; /* was "control" = 1 last time? */
+
+/* some globals */
+
+#if !defined(PURE3274)
+int OutputClock; /* what time it is */
+int TransparentClock; /* time we were last in transparent */
+#endif /* !defined(PURE3274) */
+
+char CIABuffer[64] = {
+ 0x40, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x61, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f
+};
+
+static struct orders_def orders_def[] = ORDERS_DEF;
+
+/*
+ * init_ctlr()
+ *
+ * Initialize all data from the 'data' portion to their startup values.
+ */
+
+void
+init_ctlr()
+{
+ LastWasTerminated = 1;
+ init_inbound();
+ init_oia();
+}
+
+
+FieldInc(position)
+register int position; /* Position in previous field */
+{
+ register ScreenImage *ptr;
+
+ ptr = (ScreenImage *)memNSchr((char *)Host+position+1, ATTR_MASK,
+ HighestScreen()-position, ATTR_MASK, sizeof Host[0]);
+ if (ptr == 0) {
+ ptr = (ScreenImage *)memNSchr((char *)Host+LowestScreen(), ATTR_MASK,
+ position-LowestScreen(), ATTR_MASK, sizeof Host[0]);
+ if (ptr == 0) {
+ return LowestScreen();
+ }
+ }
+ return ptr-Host;
+}
+
+FieldDec(position)
+int position;
+{
+ register ScreenImage *ptr;
+
+ ptr = (ScreenImage *)memNSchr((char *)(Host+position)-1, ATTR_MASK,
+ position-LowestScreen(), ATTR_MASK, -sizeof Host[0]);
+ if (ptr == 0) {
+ ptr = (ScreenImage *)memNSchr((char *)Host+HighestScreen(), ATTR_MASK,
+ HighestScreen()-position, ATTR_MASK, -sizeof Host[0]);
+ if (ptr == 0) {
+ return LowestScreen();
+ }
+ }
+ return ptr-Host;
+}
+
+/* Clear3270 - called to clear the screen */
+
+void
+Clear3270()
+{
+ ClearArray(Host);
+ DeleteAllFields(); /* get rid of all fields */
+ BufferAddress = SetBufferAddress(0,0);
+ CursorAddress = SetBufferAddress(0,0);
+ Lowest = LowestScreen();
+ Highest = HighestScreen();
+}
+
+/* AddHost - called to add a character to the buffer.
+ * We use a macro in this module, since we call it so
+ * often from loops.
+ *
+ * NOTE: It is a macro, so don't go around using AddHost(p, *c++), or
+ * anything similar. (I don't define any temporary variables, again
+ * just for the speed.)
+ */
+void
+AddHost(position, character)
+int position;
+char character;
+{
+# define AddHostA(p,c) \
+ { \
+ if (IsStartField(p)) { \
+ DeleteField(p); \
+ Highest = HighestScreen(); \
+ Lowest = LowestScreen(); \
+ SetHighestLowest(p); \
+ } \
+ SetHost(p, c); \
+ }
+# define AddHost(p,c) \
+ { \
+ if (c != GetHost(p)) { \
+ SetHighestLowest(p); \
+ } \
+ AddHostA(p,c); \
+ } /* end of macro of AddHost */
+
+ AddHost(position, character);
+}
+
+/* returns the number of characters consumed */
+int
+DataFromNetwork(Buffer, count, control)
+char *Buffer; /* what the data is */
+register int count; /* and how much there is */
+int control; /* this buffer ended block? */
+{
+ int origCount;
+ register unsigned char *buffer = (unsigned char *)Buffer;
+ register int c;
+ register int i;
+ static int Command;
+ static int Wcc;
+
+ origCount = count;
+
+ /*
+ * If this is the start of a new data stream, then look
+ * for an op-code and (possibly) a WCC.
+ */
+ if (LastWasTerminated) {
+
+ if (count < 2) {
+ if (count == 0) {
+ ExitString("Short count received from host!\n", 1);
+ return(count);
+ }
+ Command = buffer[0];
+ switch (Command) { /* This had better be a read command */
+ case CMD_READ_MODIFIED:
+ case CMD_SNA_READ_MODIFIED:
+ case CMD_SNA_READ_MODIFIED_ALL:
+ SetOiaOnlineA(&OperatorInformationArea);
+ SetOiaModified();
+ DoReadModified(Command);
+ break;
+ case CMD_READ_BUFFER:
+ case CMD_SNA_READ_BUFFER:
+ SetOiaOnlineA(&OperatorInformationArea);
+ SetOiaModified();
+ DoReadBuffer();
+ break;
+ default:
+ {
+ char s_buffer[100];
+
+ sprintf(s_buffer,
+ "Unexpected read command code 0x%x received.\n",
+ Command);
+ ExitString(s_buffer, 1);
+ break;
+ }
+ }
+ return(1); /* We consumed everything */
+ }
+ Command = buffer[0];
+ Wcc = buffer[1];
+ if (Wcc & WCC_RESET_MDT) {
+ i = c = WhereAttrByte(LowestScreen());
+ do {
+ if (HasMdt(i)) {
+ TurnOffMdt(i);
+ }
+ i = FieldInc(i);
+ } while (i != c);
+ }
+
+ switch (Command) {
+ case CMD_ERASE_WRITE:
+ case CMD_ERASE_WRITE_ALTERNATE:
+ case CMD_SNA_ERASE_WRITE:
+ case CMD_SNA_ERASE_WRITE_ALTERNATE:
+ {
+ int newlines, newcolumns;
+
+ SetOiaOnlineA(&OperatorInformationArea);
+ ResetOiaTWait(&OperatorInformationArea);
+ SetOiaModified();
+ if ((Command == CMD_ERASE_WRITE)
+ || (Command == CMD_SNA_ERASE_WRITE)) {
+ newlines = 24;
+ newcolumns = 80;
+ } else {
+ newlines = MaxNumberLines;
+ newcolumns = MaxNumberColumns;
+ }
+ if ((newlines != NumberLines)
+ || (newcolumns != NumberColumns)) {
+ /*
+ * The LocalClearScreen() is really for when we
+ * are going from a larger screen to a smaller
+ * screen, and we need to clear off the stuff
+ * at the end of the lines, or the lines at
+ * the end of the screen.
+ */
+ LocalClearScreen();
+ NumberLines = newlines;
+ NumberColumns = newcolumns;
+ ScreenSize = NumberLines * NumberColumns;
+ }
+ Clear3270();
+#if !defined(PURE3274)
+ if (TransparentClock == OutputClock) {
+ TransStop();
+ }
+#endif /* !defined(PURE3274) */
+ break;
+ }
+
+ case CMD_ERASE_ALL_UNPROTECTED:
+ case CMD_SNA_ERASE_ALL_UNPROTECTED:
+ SetOiaOnlineA(&OperatorInformationArea);
+ ResetOiaTWait(&OperatorInformationArea);
+ SetOiaModified();
+ CursorAddress = HighestScreen()+1;
+ for (i = LowestScreen(); i <= HighestScreen(); i = ScreenInc(i)) {
+ if (IsUnProtected(i)) {
+ if (CursorAddress > i) {
+ CursorAddress = i;
+ }
+ AddHost(i, '\0');
+ }
+ if (HasMdt(i)) {
+ TurnOffMdt(i);
+ }
+ }
+ if (CursorAddress == HighestScreen()+1) {
+ CursorAddress = SetBufferAddress(0,0);
+ }
+ UnLocked = 1;
+ AidByte = 0;
+ ResetOiaSystemLocked(&OperatorInformationArea);
+ SetOiaModified();
+ TerminalIn();
+ break;
+ case CMD_WRITE:
+ case CMD_SNA_WRITE:
+ SetOiaOnlineA(&OperatorInformationArea);
+ ResetOiaTWait(&OperatorInformationArea);
+ SetOiaModified();
+ break;
+ default:
+ {
+ char s_buffer[100];
+
+ sprintf(s_buffer,
+ "Unexpected write command code 0x%x received.\n",
+ Command);
+ ExitString(s_buffer, 1);
+ break;
+ }
+ }
+
+ count -= 2; /* strip off command and wcc */
+ buffer += 2;
+
+ } else {
+#if !defined(PURE3274)
+ if (TransparentClock == OutputClock) {
+ TransOut(buffer, count, -1, control);
+ count = 0;
+ }
+#endif /* !defined(PURE3274) */
+ }
+ LastWasTerminated = 0; /* then, reset at end... */
+
+ while (count) {
+ count--;
+ c = *buffer++;
+ if (IsOrder(c)) {
+ /* handle an order */
+ switch (c) {
+# define Ensure(x) if (count < x) { \
+ if (!control) { \
+ return(origCount-(count+1)); \
+ } else { \
+ /* XXX - should not occur */ \
+ count = 0; \
+ break; \
+ } \
+ }
+ case ORDER_SF:
+ Ensure(1);
+ c = *buffer++;
+ count--;
+ if ( ! (IsStartField(BufferAddress) &&
+ FieldAttributes(BufferAddress) == c)) {
+ SetHighestLowest(BufferAddress);
+ NewField(BufferAddress,c);
+ }
+ BufferAddress = ScreenInc(BufferAddress);
+ break;
+ case ORDER_SBA:
+ Ensure(2);
+ i = buffer[0];
+ c = buffer[1];
+#if !defined(PURE3274)
+ /* Check for transparent write */
+ if ((i == 0) && ((c == 0) || (c == 1) || (c == 5))) {
+ TransparentClock = OutputClock+1;
+ TransOut(buffer+2, count-2, c, control);
+ buffer += count;
+ count -= count;
+ break;
+ }
+#endif /* !defined(PURE3274) */
+ BufferAddress = Addr3270(i, c);
+ buffer += 2;
+ count -= 2;
+ break;
+ case ORDER_IC:
+ CursorAddress = BufferAddress;
+ break;
+ /*
+ * XXX - PT is supposed to null fill the screen buffer
+ * under certain draconian conditions.
+ */
+ case ORDER_PT:
+ i = BufferAddress;
+ do {
+ if (IsStartField(i)) {
+ if (!IsProtected(ScreenInc(i))) {
+ break;
+ }
+ }
+ i = ScreenInc(i);
+ } while (i != HighestScreen());
+ BufferAddress = ScreenInc(i);
+ break;
+ case ORDER_RA:
+ Ensure(3);
+ i = Addr3270(buffer[0], buffer[1]);
+ if ((i < 0) || (i > HighestScreen())) {
+ char s_buffer[200];
+
+ sprintf(s_buffer, "tn3270: %s%d.\n\t%s%d%s%d%s\n",
+ "Invalid 3270 order 'Repeat to Address' to address ",
+ i,
+ "(Screen currently set to ",
+ NumberLines,
+ " by ",
+ NumberColumns,
+ ".)");
+ ExitString(s_buffer, 1);
+ /*NOTREACHED*/
+ }
+ c = buffer[2];
+ if (c == ORDER_GE) {
+ Ensure(4);
+ c = buffer[3];
+ buffer += 4;
+ count -= 4;
+ } else {
+ buffer += 3;
+ count -= 3;
+ }
+ do {
+ AddHost(BufferAddress, ebc_disp[c]);
+ BufferAddress = ScreenInc(BufferAddress);
+ } while (BufferAddress != i);
+ break;
+ case ORDER_EUA: /* (from [here,there), ie: half open interval] */
+ Ensure(2);
+ /*
+ * Compiler error - msc version 4.0:
+ * "expression too complicated".
+ */
+ i = WhereAttrByte(BufferAddress);
+ c = FieldAttributes(i);
+ i = Addr3270(buffer[0], buffer[1]);
+ if ((i < 0) || (i > HighestScreen())) {
+ char s_buffer[200];
+
+ sprintf(s_buffer, "tn3270: %s%d.\n\t%s%d%s%d%s\n",
+ "Invalid 3270 order 'Erase Unprotected to Address' to address ",
+ i,
+ "(Screen currently set to ",
+ NumberLines,
+ " by ",
+ NumberColumns,
+ ".)");
+ ExitString(s_buffer, 1);
+ /*NOTREACHED*/
+ }
+ do {
+ if (IsStartField(BufferAddress)) {
+ c = FieldAttributes(BufferAddress);
+ } else if (!IsProtectedAttr(BufferAddress, c)) {
+ AddHost(BufferAddress, 0);
+ }
+ BufferAddress = ScreenInc(BufferAddress);
+ } while (i != BufferAddress);
+ buffer += 2;
+ count -= 2;
+ break;
+ case ORDER_GE:
+ Ensure(2);
+ /* XXX Should do SOMETHING! */
+ /* XXX buffer += 0; */
+ /* XXX count -= 0; *//* For now, just use this character */
+ break;
+ case ORDER_YALE: /* special YALE defined order */
+ Ensure(2); /* need at least two characters */
+ if (*buffer == 0x5b) {
+ i = OptOrder(buffer+1, count-1, control);
+ if (i == 0) {
+ return(origCount-(count+1)); /* come here again */
+ } else {
+ buffer += 1 + i;
+ count -= (1 + i);
+ }
+ }
+ break;
+ default:
+ {
+ char s_buffer[100];
+ static struct orders_def unk_order
+ = { 0, "??", "(unknown)" };
+ struct orders_def *porder = &unk_order;
+ int s_i;
+
+ for (s_i = 0; s_i <= highestof(orders_def); s_i++) {
+ if (orders_def[s_i].code == c) {
+ porder = &orders_def[s_i];
+ break;
+ }
+ }
+ sprintf(s_buffer,
+ "Unsupported order '%s' (%s, 0x%x) received.\n",
+ porder->long_name, porder->short_name, c);
+ ExitString(s_buffer, 1);
+ /*NOTREACHED*/
+ }
+ }
+ if (count < 0) {
+ count = 0;
+ }
+ } else {
+ /* Data comes in large clumps - take it all */
+ i = BufferAddress;
+ AddHostA(i, ebc_disp[c]);
+ SetHighestLowest(i);
+ i = ScreenInc(i);
+ c = *buffer;
+ while (count && !IsOrder(c)) {
+ AddHostA(i, ebc_disp[c]);
+ i = ScreenInc(i);
+ if (i == LowestScreen()) {
+ SetHighestLowest(HighestScreen());
+ }
+ count--;
+ buffer++;
+ c = *buffer;
+ }
+ SetHighestLowest(i);
+ BufferAddress = i;
+ }
+ }
+ if (count == 0) {
+ if (control) {
+#if !defined(PURE3274)
+ OutputClock++; /* time rolls on */
+#endif /* !defined(PURE3274) */
+ if (Wcc & WCC_RESTORE) {
+#if !defined(PURE3274)
+ if (TransparentClock != OutputClock) {
+ AidByte = 0;
+ }
+#else /* !defined(PURE3274) */
+ AidByte = 0;
+#endif /* !defined(PURE3274) */
+ UnLocked = 1;
+ ResetOiaSystemLocked(&OperatorInformationArea);
+ SetOiaModified();
+ SetPsModified();
+ TerminalIn();
+ }
+ if (Wcc & WCC_ALARM) {
+ RingBell((char *)0);
+ }
+ }
+ LastWasTerminated = control; /* state for next time */
+ return(origCount);
+ } else {
+ return(origCount-count);
+ }
+}
+
+/*
+ * Init3270()
+ *
+ * Initialize any 3270 (controller) variables to an initial state
+ * in preparation for accepting a connection.
+ */
+
+void
+Init3270()
+{
+ int i;
+
+ OptInit(); /* initialize mappings */
+
+ ClearArray(Host);
+
+ ClearArray(Orders);
+ for (i = 0; i <= highestof(orders_def); i++) {
+ Orders[orders_def[i].code] = 1;
+ }
+
+ DeleteAllFields(); /* Clear screen */
+ Lowest = HighestScreen()+1;
+ Highest = LowestScreen()-1;
+ CursorAddress = BufferAddress = SetBufferAddress(0,0);
+ UnLocked = 1;
+#if !defined(PURE3274)
+ OutputClock = 1;
+ TransparentClock = -1;
+#endif /* !defined(PURE3274) */
+ SetOiaReady3274(&OperatorInformationArea);
+}
+
+
+void
+Stop3270()
+{
+ ResetOiaReady3274(&OperatorInformationArea);
+}
diff --git a/usr.bin/tn3270/ctlr/screen.h b/usr.bin/tn3270/ctlr/screen.h
new file mode 100644
index 0000000..9dd8595
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/screen.h
@@ -0,0 +1,145 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)screen.h 8.1 (Berkeley) 6/6/93
+ */
+
+#define INCLUDED_SCREEN
+
+/* defines and defines to describe how to deal with the screen */
+
+#if !defined(MSDOS)
+#define MAXNUMBERLINES 43 /* 3278-4 */
+#define MAXNUMBERCOLUMNS 132 /* 3278-5 */
+#define MAXSCREENSIZE 3564 /* (27*132) 3278-5 */
+#else /* !defined(MSDOS) */ /* MSDOS has memory constraints */
+#define MAXNUMBERLINES 25 /* XXX */
+#define MAXNUMBERCOLUMNS 80
+#define MAXSCREENSIZE (MAXNUMBERLINES*MAXNUMBERCOLUMNS)
+#endif /* !defined(MSDOS) */ /* MSDOS has memory constraints */
+#define LowestScreen() 0
+#define HighestScreen() (ScreenSize-1)
+
+#define ScreenLineOffset(x) ((x)%NumberColumns)
+#define ScreenLine(x) ((int)((x)/NumberColumns))
+#define ScreenInc(x) (((x)==HighestScreen())? LowestScreen():x+1)
+#define ScreenDec(x) (((x)==LowestScreen())? HighestScreen():x-1)
+#define ScreenUp(x) (((x)+(ScreenSize-NumberColumns))%ScreenSize)
+#define ScreenDown(x) (((x)+NumberColumns)%ScreenSize)
+#define IsOrder(x) (Orders[x])
+#define BAIC(x) ((x)&0x3f)
+#define CIAB(x) (CIABuffer[(x)&0x3f])
+#define BufferTo3270_0(x) (CIABuffer[(int)((x)/0x40)])
+#define BufferTo3270_1(x) (CIABuffer[(x)&0x3f])
+#define Addr3270(x,y) (BAIC(x)*64+BAIC(y))
+#define SetBufferAddress(x,y) ((x)*NumberColumns+(y))
+
+/* These know how fields are implemented... */
+
+#define WhereAttrByte(p) (IsStartField(p)? p: FieldDec(p))
+#define WhereHighByte(p) ScreenDec(FieldInc(p))
+#define WhereLowByte(p) ScreenInc(WhereAttrByte(p))
+#define FieldAttributes(x) (IsStartField(x)? GetHost(x) : \
+ GetHost(WhereAttrByte(x)))
+#define FieldAttributesPointer(p) (IsStartFieldPointer(p)? \
+ GetHostPointer(p): \
+ GetHost(WhereAttrByte((p)-&Host[0])))
+
+/*
+ * The MDT functions need to protect against the case where the screen
+ * is unformatted (sigh).
+ */
+
+/* Turn off the Modified Data Tag */
+#define TurnOffMdt(x) \
+ if (HasMdt(WhereAttrByte(x))) { \
+ ModifyMdt(x, 0); \
+ }
+
+/* Turn on the Modified Data Tag */
+#define TurnOnMdt(x) \
+ if (!HasMdt(WhereAttrByte(x))) { \
+ ModifyMdt(x, 1); \
+ }
+
+/* If this location has the MDT bit turned on (implies start of field) ... */
+#define HasMdt(x) \
+ ((GetHost(x)&(ATTR_MDT|ATTR_MASK)) == (ATTR_MDT|ATTR_MASK))
+
+ /*
+ * Is the screen formatted? Some algorithms change depending
+ * on whether there are any attribute bytes lying around.
+ */
+#define FormattedScreen() \
+ ((WhereAttrByte(0) != 0) || ((GetHost(0)&ATTR_MASK) == ATTR_MASK))
+
+ /* field starts here */
+#define IsStartField(x) ((GetHost(x)&ATTR_MASK) == ATTR_MASK)
+#define IsStartFieldPointer(p) ((GetHostPointer(p)&ATTR_MASK) == ATTR_MASK)
+
+#define NewField(p,a) SetHost(p, (a)|ATTR_MASK)
+#define DeleteField(p) SetHost(p, 0)
+#define DeleteAllFields()
+
+/* The following are independent of the implementation of fields */
+#define IsProtectedAttr(p,a) (IsStartField(p) || ((a)&ATTR_PROT))
+#define IsProtected(p) IsProtectedAttr(p,FieldAttributes(p))
+
+#define IsUnProtected(x) (!IsProtected(x))
+
+#define IsAutoSkip(x) (FieldAttributes(x)&ATTR_AUTO_SKIP)
+
+#define IsNonDisplayAttr(c) (((c)&ATTR_DSPD_MASK) == ATTR_DSPD_NONDISPLAY)
+#define IsNonDisplay(p) IsNonDisplayAttr(FieldAttributes(p))
+
+#define IsHighlightedAttr(c) \
+ (((c)&ATTR_DSPD_MASK) == ATTR_DSPD_HIGH)
+#define IsHighlighted(p) \
+ (IsHighlightedAttr(FieldAttributes(p)) && !IsStartField(p))
+
+typedef unsigned char ScreenImage;
+
+extern int
+ FieldFind();
+
+extern char
+ CIABuffer[];
+
+#define GetGeneric(i,h) (h)[i]
+#define GetGenericPointer(p) (*(p))
+#define SetGeneric(i,c,h) ((h)[i] = (c))
+#define ModifyGeneric(i,what,h) {(h)[i] what;}
+
+#define GetHost(i) GetGeneric(i,Host)
+#define GetHostPointer(p) GetGenericPointer(p)
+#define SetHost(i,c) SetGeneric(i,c,Host)
+#define ModifyHost(i,what) ModifyGeneric(i,what,Host)
diff --git a/usr.bin/tn3270/ctlr/scrnctlr.h b/usr.bin/tn3270/ctlr/scrnctlr.h
new file mode 100644
index 0000000..8c140c6
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/scrnctlr.h
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)scrnctlr.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * definitions that have to do with the interface between the
+ * controller and the screen.
+ */
+
+#define DISP_AMPERSAND 0x30
+#define DISP_BLANK 0x10
+#define DISP_CENTSIGN 0x1b
+#define DISP_DUP 0x9f
+#define DISP_FM 0x9e
+#define DISP_GREATER_THAN 0x08
+#define DISP_NULL 0x00
+#define DISP_QUESTION 0x18
diff --git a/usr.bin/tn3270/ctlr/unix.kbd b/usr.bin/tn3270/ctlr/unix.kbd
new file mode 100644
index 0000000..ad41eec
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/unix.kbd
@@ -0,0 +1,184 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)unix.kbd 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * keynumber [ scancode [ unshifted [ shifted [ alted [ shiftalted ] ] ] ] ]
+ *
+ * keynumber is in decimal, and starts in column 1.
+ * scancode is hexadecimal.
+ * unshifted, etc. - these are either a single ascii character,
+ * or the name of a function or an AID-generating key.
+ *
+ * all fields are separated by a single space.
+ */
+
+extern struct hits hits[];
+1 0e ` ~ LPRT
+2 16 1 ! XON
+3 1e 2 @ XOFF
+4 26 3 # ALTK
+5 25 4 $ ESCAPE
+6 2e 5 % DISC
+7 36 6 ^ MASTER_RESET
+8 3d 7 & RESHOW
+9 3e 8 * FLINP
+10 46 9 ( SYNCH
+11 45 0 ) INIT
+12 4e - _ PCOFF
+13 55 = + PCON
+14 5d APLON APLOFF APLEND
+15 66 LEFT
+16 0d TAB BTAB
+17 15 q Q FIELDEND
+18 1d w W WORDEND
+19 24 e E WORDBACKTAB
+20 2d r R FERASE
+21 2c t T WERASE
+22 35 y Y ERASE
+23 3c u U CLRTAB
+24 43 i I SETHOM
+25 44 o O SETMRG
+26 4d p P UNDENT
+27 54 [ { INDENT
+28 5b \ | SETTAB
+29 5c DELTAB COLTAB COLBAK
+30 14 CAPS_LOCK
+31 1c a A WORDTAB
+32 1b s S CURSEL
+33 23 d D VERTICAL_BAR
+34 2b f F CENTSIGN
+35 34 g G PF25
+36 33 h H PF26
+37 3b j J PF27
+38 42 k K PF28
+39 4b l L PF29
+40 4c ; : PF30
+41 52 ' " PF31
+42 53 ] } PF32
+43 5a NL
+44 12 MAKE_SHIFT MAKE_SHIFT MAKE_SHIFT
+45 13 < > PF33
+46 1a z Z PF34
+47 22 x X PF35
+48 21 c C PF36
+49 2a v V
+50 32 b B
+51 31 n N
+52 3a m M
+53 41 , <
+54 49 . >
+55 4a / ?
+56 51
+57 59 MAKE_SHIFT MAKE_SHIFT MAKE_SHIFT
+58 11 RESET NULL DVCNL
+59
+60 19 MAKE_ALT MAKE_ALT MAKE_ALT
+61 29 SPACE SPACE
+62 39 MAKE_ALT MAKE_ALT MAKE_ALT
+63
+64 58 ENTER
+65 06 CLEAR NULL TEST
+66 0c NULL NULL ATTN
+67 0b EEOF NULL EINP
+68 0a
+69 09 MAKE_CTRL
+70 05 ATTN NULL TREQ
+71 04
+72 03
+73 83
+74 01
+75 67 PA1 DP
+76 64 BTAB
+77
+78 61 LEFT NULL LEFT2
+79
+80 6e PA2 FM
+81 65 INSRT
+82 63 UP
+83 62 NULL NULL HOME
+84 60 DOWN
+85 6f PA3
+86 6d DELETE
+87
+88 6a RIGHT NULL RIGHT2
+89
+90 76
+91 6c 7
+92 6b 4
+93 69 1
+94 68
+95 77
+96 75 8
+97 73 5
+98 72 2
+99 70 0
+100 7e ,
+101 7d 9
+102 74 6
+103 7a 3
+104 71 .
+105 84 SPACE
+106 7c TAB
+107 7b -
+108 79 ENTER
+109 78
+110 07 PF1
+111 0f PF2
+112 17 PF3
+113 1f PF4
+114 27 PF5
+115 2f PF6
+116 37 PF7
+117 3f PF8 NULL MONOCASE
+118 47 PF9
+119 4f PF10
+120 56 PF11
+121 5e PF12
+122 08 PF13
+123 10 PF14
+124 18 PF15
+125 20 PF16
+126 28 PF17
+127 30 PF18
+128 38 PF19
+129 40 PF20
+130 48 PF21
+131 50 PF22
+132 57 PF23
+133 5f PF24
+134 92 BREAK_SHIFT BREAK_SHIFT BREAK_SHIFT
+135 D9 BREAK_SHIFT BREAK_SHIFT BREAK_SHIFT
+136 99 BREAK_ALT BREAK_ALT BREAK_ALT
+137 B9 BREAK_ALT BREAK_ALT BREAK_ALT
diff --git a/usr.bin/tn3270/distribution/README b/usr.bin/tn3270/distribution/README
new file mode 100644
index 0000000..29afc73
--- /dev/null
+++ b/usr.bin/tn3270/distribution/README
@@ -0,0 +1,99 @@
+Welcome to the new tn3270 - version 4.1.1.
+
+This version consists entirely of bug fixes to the August 1987 beta release
+of tn3270. This version will now deal with CICS and VM/XA on the IBM
+side, and with SunOS 4.0 on Sun 3's and Sun 4's.
+
+This version has been tested on various versions of BSD Unix, including
+4.2 and 4.3 (but there are never vanilla versions) and the post-4.3 systems
+running at Berkeley. It has been tested on CCI's, Vaxen, Sun 3's and Sun 4's.
+However, it doesn't necessarily work on all systems (nor has the testing
+been as intensive as one might like).
+
+This version should build on any Berkeley-derived system.
+
+There are two alternate make files: ./makefile_4.2 and telnet/Makefile_ultrix.
+
+**** Try ./makefile_4.2 if you get compile-time errors, or get
+ "multiply defined" messages for "_putchar" from the loader.
+
+**** Try telnet/Makefile_ultrix if your make(1) utility doesn't
+ support VPATH. Also try this makefile if your ld(1) doesn't
+ support the -r flag correctly.
+
+The bad news is that I've had to drop MS-DOS support. The good news here is
+that there are various versions available for MS-DOS (from FTP Software in
+Cambridge, Mass.; from IBM; from Excelan; and probably from others). The
+hooks are still there, as well as some code to update the screen. However,
+I just haven't had the time to produce a fully integrated version that would
+"just make". I suspect that a future release may have MS-DOS support back
+in it.
+
+There is no Mac support. Contact Peter DiCamillo at Brown University if
+you need a Mac tn3270.
+
+The main code change in this version is to what used to be called "telnet.c".
+This is now replaced with a version of telnet (substantially what appeared
+in the "4.3tahoe" release from CSRG) which is broken into separate files.
+
+Here is an overview of the directory structure:
+
+ api/ General library of function needed by API
+ (and, to some extent, by the rest of tn3270).
+
+ arpa/ Location of "telnet.h" (for non-4.3 systems).
+
+ ascii/ Routines necessary to handle the case of running
+ from an ASCII-oriented system (ie: unix).
+
+ ctlr/ The main part of the emulator. Handles 3270 scan
+ codes, 3270 data stream, 3270 display codes,
+ and EBCDIC. Also, the internal API function
+ lives here.
+
+ general/ Some general subroutines and data structures of
+ interest to the emulator only.
+
+ sys_curses/ System-dependent code for a curses-based environment.
+
+ sys_dos/ System-dependent code for an MS-DOS-base environment.
+ Remember that this is included for your developmental
+ needs (ie: it doesn't work).
+
+ telnet/ Where the telnet portion of tn3720 is built.
+
+ tools/ Various tools. Most of these are used during the
+ build process. One (prt3270) is a debugging tool.
+ One (mkmake.y) is quite horrible, and attempts to
+ transform Unix makefiles into PC makefiles.
+
+ utilities/ The source for tnrecv, which receives files
+ (fairly slowly) from an IBM host. We don't
+ include the IBM side, because we really aren't
+ happy with very much of it (except that it does,
+ sometimes, work). Hopefully, when we get past
+ the beta stage we will have more robust (and
+ complete) code to share.
+
+The fact that system dependancies are isolated should make it easy
+to port to other systems. I would like to hear about problems porting
+to new areas.
+
+In the August, 1987 README file, the following appeared:
+
+> WHAT IS NOT IN THIS VERSION (sigh):
+
+> 1) We don't have a native X version yet. I am waiting for X version 11
+> (though this is mostly an excuse; I could have done version 10,
+> but I haven't had the time).
+
+> 2) We don't process structured fields.
+
+> 3) We don't do 3270-style graphics (ala 3193, say).
+
+> The above three items WILL be in the next version, which should come
+> along "any day now" (say 6 months) (but, they WON'T be in the production
+> release of this version).
+
+The next piece of bad news is that none of the above have happened yet,
+and I don't know when they might occur.
diff --git a/usr.bin/tn3270/distribution/arpa/makefile b/usr.bin/tn3270/distribution/arpa/makefile
new file mode 100644
index 0000000..2cf3bc0
--- /dev/null
+++ b/usr.bin/tn3270/distribution/arpa/makefile
@@ -0,0 +1,67 @@
+# @(#)makefile 8.1 (Berkeley) 6/6/93
+
+# msdos versus unix defines
+O = .o
+#PC_O = .obj
+
+X =
+#PC_X = .exe
+
+L =
+#PC_L = -link
+
+CC = cc
+#PC_CC = cl
+
+MV = mv
+#PC_MV = rename
+
+RM = rm -f
+#PC_RM= erase
+
+LINT_ARGS =
+#PC_LINT_ARGS = -DLINT_ARGS
+
+DEBUG_FLAGS = -g
+#PC_DEBUG_FLAGS = -Zi -Od
+
+AR = ar
+AR1 = cr
+AR2 =
+AR3 =
+#PC_AR = lib
+#PC_AR1 =
+#PC_AR2 = +
+#PC_AR3 = ";"
+
+RANLIB = ranlib
+#PC_RANLIB = echo "Done with "
+
+PRINT = lpr -p
+
+ALLC =
+ALLH = telnet.h
+
+ALLPRINT = ${ALLH} ${ALLC}
+
+ALLSOURCE = ${ALLPRINT} makefile makefile.mak
+
+clean:
+
+sccsclean:
+ -sccs clean
+ -sccs get makefile
+
+action:
+ ${ACTION}
+
+print:
+ ${PRINT} ${ALLPRINT}
+
+
+sourcelist: ${ALLSOURCE}
+ @for i in ${ALLSOURCE}; \
+ do (echo ${DIRPATH}$$i); done
+
+.DEFAULT:
+ sccs get $<
diff --git a/usr.bin/tn3270/distribution/arpa/telnet.h b/usr.bin/tn3270/distribution/arpa/telnet.h
new file mode 100644
index 0000000..eeb72c2
--- /dev/null
+++ b/usr.bin/tn3270/distribution/arpa/telnet.h
@@ -0,0 +1,191 @@
+/*-
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)telnet.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * Definitions for the TELNET protocol.
+ */
+#define IAC 255 /* interpret as command: */
+#define DONT 254 /* you are not to use option */
+#define DO 253 /* please, you use option */
+#define WONT 252 /* I won't use option */
+#define WILL 251 /* I will use option */
+#define SB 250 /* interpret as subnegotiation */
+#define GA 249 /* you may reverse the line */
+#define EL 248 /* erase the current line */
+#define EC 247 /* erase the current character */
+#define AYT 246 /* are you there */
+#define AO 245 /* abort output--but let prog finish */
+#define IP 244 /* interrupt process--permanently */
+#define BREAK 243 /* break */
+#define DM 242 /* data mark--for connect. cleaning */
+#define NOP 241 /* nop */
+#define SE 240 /* end sub negotiation */
+#define EOR 239 /* end of record (transparent mode) */
+#define ABORT 238 /* Abort process */
+#define SUSP 237 /* Suspend process */
+#define xEOF 236 /* End of file: EOF is already used... */
+
+#define SYNCH 242 /* for telfunc calls */
+
+#ifdef TELCMDS
+char *telcmds[] = {
+ "EOF", "SUSP", "ABORT", "EOR",
+ "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC",
+ "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC",
+};
+#define TELCMD_FIRST xEOF
+#define TELCMD_LAST IAC
+#define TELCMD_OK(x) ((x) <= TELCMD_LAST && (x) >= TELCMD_FIRST)
+#define TELCMD(x) telcmds[(x)-TELCMD_FIRST]
+#endif
+
+/* telnet options */
+#define TELOPT_BINARY 0 /* 8-bit data path */
+#define TELOPT_ECHO 1 /* echo */
+#define TELOPT_RCP 2 /* prepare to reconnect */
+#define TELOPT_SGA 3 /* suppress go ahead */
+#define TELOPT_NAMS 4 /* approximate message size */
+#define TELOPT_STATUS 5 /* give status */
+#define TELOPT_TM 6 /* timing mark */
+#define TELOPT_RCTE 7 /* remote controlled transmission and echo */
+#define TELOPT_NAOL 8 /* negotiate about output line width */
+#define TELOPT_NAOP 9 /* negotiate about output page size */
+#define TELOPT_NAOCRD 10 /* negotiate about CR disposition */
+#define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */
+#define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */
+#define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */
+#define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */
+#define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */
+#define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */
+#define TELOPT_XASCII 17 /* extended ascic character set */
+#define TELOPT_LOGOUT 18 /* force logout */
+#define TELOPT_BM 19 /* byte macro */
+#define TELOPT_DET 20 /* data entry terminal */
+#define TELOPT_SUPDUP 21 /* supdup protocol */
+#define TELOPT_SUPDUPOUTPUT 22 /* supdup output */
+#define TELOPT_SNDLOC 23 /* send location */
+#define TELOPT_TTYPE 24 /* terminal type */
+#define TELOPT_EOR 25 /* end or record */
+#define TELOPT_TUID 26 /* TACACS user identification */
+#define TELOPT_OUTMRK 27 /* output marking */
+#define TELOPT_TTYLOC 28 /* terminal location number */
+#define TELOPT_3270REGIME 29 /* 3270 regime */
+#define TELOPT_X3PAD 30 /* X.3 PAD */
+#define TELOPT_NAWS 31 /* window size */
+#define TELOPT_TSPEED 32 /* terminal speed */
+#define TELOPT_LFLOW 33 /* remote flow control */
+#define TELOPT_LINEMODE 34 /* Linemode option */
+#define TELOPT_EXOPL 255 /* extended-options-list */
+
+#define NTELOPTS (1+TELOPT_LINEMODE)
+#ifdef TELOPTS
+char *telopts[NTELOPTS] = {
+ "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME",
+ "STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP",
+ "NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS",
+ "NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
+ "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT",
+ "SEND LOCATION", "TERMINAL TYPE", "END OF RECORD",
+ "TACACS UID", "OUTPUT MARKING", "TTYLOC",
+ "3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW",
+ "LINEMODE",
+};
+#define TELOPT_FIRST TELOPT_BINARY
+#define TELOPT_LAST TELOPT_LINEMODE
+#define TELOPT_OK(x) ((x) <= TELOPT_LAST && (x) >= TELOPT_FIRST)
+#define TELOPT(x) telopts[(x)-TELOPT_FIRST]
+#endif
+
+/* sub-option qualifiers */
+#define TELQUAL_IS 0 /* option is... */
+#define TELQUAL_SEND 1 /* send option */
+
+/*
+ * LINEMODE suboptions
+ */
+
+#define LM_MODE 1
+#define LM_FORWARDMASK 2
+#define LM_SLC 3
+
+#define MODE_EDIT 0x01
+#define MODE_TRAPSIG 0x02
+#define MODE_ACK 0x04
+
+#define MODE_MASK (MODE_EDIT|MODE_TRAPSIG|MODE_ACK)
+
+/* Not part of protocol, but needed to simplify things... */
+#define MODE_FLOW 0x40
+#define MODE_ECHO 0x80
+#define MODE_FORCE 0x20
+
+#define SLC_SYNCH 1
+#define SLC_BRK 2
+#define SLC_IP 3
+#define SLC_AO 4
+#define SLC_AYT 5
+#define SLC_EOR 6
+#define SLC_ABORT 7
+#define SLC_EOF 8
+#define SLC_SUSP 9
+#define SLC_EC 10
+#define SLC_EL 11
+#define SLC_EW 12
+#define SLC_RP 13
+#define SLC_LNEXT 14
+#define SLC_XON 15
+#define SLC_XOFF 16
+#define SLC_FORW1 17
+#define SLC_FORW2 18
+
+#define NSLC 18
+
+#define SLC_NAMES "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \
+ "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \
+ "LNEXT", "XON", "XOFF", "FORW1", "FORW2"
+
+#define SLC_NOSUPPORT 0
+#define SLC_CANTCHANGE 1
+#define SLC_VARIABLE 2
+#define SLC_DEFAULT 3
+#define SLC_LEVELBITS 0x03
+
+#define SLC_FUNC 0
+#define SLC_FLAGS 1
+#define SLC_VALUE 2
+
+#define SLC_ACK 0x80
+#define SLC_FLUSHIN 0x40
+#define SLC_FLUSHOUT 0x20
diff --git a/usr.bin/tn3270/distribution/makefile_4.2 b/usr.bin/tn3270/distribution/makefile_4.2
new file mode 100644
index 0000000..b8e5eb8e
--- /dev/null
+++ b/usr.bin/tn3270/distribution/makefile_4.2
@@ -0,0 +1,268 @@
+# @(#)makefile 3.5 (Berkeley) 5/15/88
+
+# This makefile will make tn3270 on Vax 4.2 systems. Notice, however,
+# that on an ultrix system you will need to use the Makefile_ultrix in
+# telnet/ rather than the Makefile already in that directory.
+
+# Makefile for tn3270 and friends...
+#
+# This is the makefile for tn3270. Note that we use the 4.3+ telnet
+# (compiled with special options; see below) to provide the telnet
+# support we need.
+#
+# The following are the defines that may be passed (via the cc
+# -D option) to the compiler.
+#
+# TN3270 - This is to be linked with tn3270. Necessary
+# for creating tn3270. Only for compiling
+# telnet.
+#
+# NOT43 - Allows the program to compile and run on
+# a 4.2BSD system.
+#
+# PUTCHAR - Within tn3270, on a NOT43 system,
+# allows the use of the 4.3 curses
+# (greater speed updating the screen).
+# You need the 4.3 curses for this to work.
+#
+# FD_SETSIZE - On whichever system, if this isn't defined,
+# we patch over the FD_SET, etc., macros with
+# some homebrewed ones.
+#
+# SO_OOBINLINE - This is a socket option which we would like
+# to set to allow TCP urgent data to come
+# to us "inline". This is NECESSARY for
+# CORRECT operation, and desireable for
+# simpler operation.
+#
+# LNOFLSH - Detects the presence of the LNOFLSH bit
+# in the tty structure.
+#
+#
+# Here are some which are used throughout the system:
+#
+# unix - Compiles in unix specific stuff.
+#
+# msdos - Compiles in msdos specific stuff.
+#
+
+# msdos versus unix defines
+O = .o
+#PC_O = .obj
+
+X =
+#PC_X = .exe
+
+L =
+#PC_L = -link
+
+CC = cc
+#PC_CC = cl
+
+MV = mv
+#PC_MV = rename
+
+RM = rm -f
+#PC_RM= erase
+
+LINT_ARGS =
+#PC_LINT_ARGS = -DLINT_ARGS
+
+DEBUG_FLAGS = -g
+#PC_DEBUG_FLAGS = -Zi -Od
+
+AR = ar
+AR1 = cr
+AR2 =
+AR3 =
+#PC_AR = lib
+#PC_AR1 =
+#PC_AR2 = +
+#PC_AR3 = ";"
+
+RANLIB = ranlib
+#PC_RANLIB = echo "Done with "
+
+
+PRINT = print
+ACTION = @sccs tell
+
+DEFINES = -DNOT43 ${LINT_ARGS}
+
+INCLUDES = -I. -I..
+
+OPTIMIZE = -O
+OPTIMIZE = ${DEBUG_FLAGS}
+
+CFLAGS = $(OPTIMIZE) $(INCLUDES) $(DEFINES)
+
+# Lint flags
+LINTFLAGS = -hbxaz
+# How to install the bloody thing...
+
+DESTDIR=
+
+BINDIR = $(DESTDIR)/usr/ucb
+
+# Names for the terminal libraries...
+LIBCURSES = -lcurses
+LIBTERM = -ltermlib
+
+#PC_LIBCURSES =
+#PC_LIBTERM =
+
+# The source files...
+ALLH = telnet.ext
+
+MSMAIN = ascii/mset.c
+
+ALLC =
+
+ALLO = mset$O
+
+ALLHC= ${ALLH} ${ALLC}
+ALLPRINT = ${ALLHC}
+
+ALLSOURCE = ${ALLPRINT} makefile makefile.mak makefile_4.2 README
+
+SYS = sys_curses
+#PC_SYS = sys_dos
+
+# The places where the various components live...
+
+SUBDIR = api ascii ctlr general ${SYS} telnet
+
+# The following are directories we don't do regular make's in, but
+# we do make everywhere, print, and sourcelist in.
+
+EXTRADIR = arpa sys_dos tools utilities
+
+# The libraries we use. The order here is important.
+# syslib.a and ctlrlib.a should come first, then the rest.
+SUBLIB = ${SYS}/syslib.a ctlr/ctlrlib.a \
+ ascii/asciilib.a general/generallib.a
+
+.s.o:
+ /lib/cpp -E $< | as -o $@
+
+.c.obj:
+ ${CC} ${CFLAGS} -c $<
+
+all: FRC tn3270$X mset$X
+
+FRC:
+ for i in ${SUBDIR}; \
+ do (cd $$i; make ${MFLAGS} "CFLAGS=${CFLAGS}"); done
+
+tn3270$X: telnet/telprog.o ${SUBLIB} api/apilib.a
+ ${CC} ${CFLAGS} -o tn3270 telnet/telprog.o \
+ $L ${SUBLIB} api/apilib.a $(LIBCURSES) $(LIBTERM)
+
+#PC_tn3270$X:
+#PC_ link <@<
+#PC_ telnet
+#PC_ tn3270
+#PC_ nul
+#PC_ ${SUBLIB} api/apilib.a+
+#PC_ \lib\ublib\ubtcp
+#PC_ _PC_<
+
+mset$X: mset$O ascii/map3270$O
+ ${CC} ${CFLAGS} -o mset mset$O ascii/map3270$O $L api/apilib.a
+
+mset$O: $(MSMAIN)
+ $(CC) $(CFLAGS) -c $(MSMAIN)
+
+install: tn3270$X mset$X
+ install -m 755 -o bin -g bin -s tn3270 $(BINDIR)
+ install -m 755 -o bin -g bin -s mset $(BINDIR)
+
+action:
+ ${ACTION}
+
+clist: ${ALLHC}
+ @for i in ${SUBDIR}; \
+ do (cd $$i; make ${MFLAGS} "DIRPATH=${DIRPATH}$$i/" \
+ clist); done
+
+hclist: ${ALLHC}
+ @for i in ${SUBDIR}; \
+ do (cd $$i; make ${MFLAGS} "DIRPATH=${DIRPATH}$$i/" \
+ hclist); done
+
+everywhere: action
+ for i in ${SUBDIR} ${EXTRADIR}; \
+ do (echo "[$$i]"; cd $$i; make ${MFLAGS} action \
+ "ACTION=${ACTION}"); done
+
+clean:
+ for i in $(ALLO) mset tn3270 errs makefile.bak; \
+ do (${RM} $$i); done
+ for i in ${SUBDIR} ${EXTRADIR}; \
+ do (cd $$i; make ${MFLAGS} clean); done
+
+sccsclean:
+ -sccs clean
+ -sccs get makefile
+ for i in ${SUBDIR} ${EXTRADIR}; \
+ do (cd $$i; make ${MFLAGS} sccsclean); done
+
+print:
+ ${PRINT} ${ALLPRINT}
+ for i in ${SUBDIR} ${EXTRADIR}; \
+ do (cd $$i; make ${MFLAGS} "PRINT=${PRINT}" print); done
+
+tags: ${ALLC} ${ALLH}
+ ctags -t `make ${MFLAGS} hclist`
+
+sourcelist: ${ALLSOURCE}
+ @for i in ${ALLSOURCE}; \
+ do (echo ${DIRPATH}$$i); done
+ @for i in ${SUBDIR} ${EXTRADIR}; \
+ do (cd $$i; make ${MFLAGS} "DIRPATH=${DIRPATH}$$i/" \
+ sourcelist); done
+
+lint:
+ lint ${LINTFLAGS} ${INCLUDES} ${DEFINES} -DTN3270 \
+ `make clist` -lcurses
+
+lintmset:
+ lint ${LINTFLAGS} ${INCLUDES} ${DEFINES} ${MSMAIN} \
+ ascii/map3270.c -lcurses
+
+makefiles.pc: tools/mkmake
+ for i in . ${SUBDIR} ${EXTRADIR}; \
+ do (sed -e "s/lib\.a/.lib/g" -e "s/^#PC_//" < $$i/makefile | \
+ ./tools/mkmake | \
+ sed -e "sx/x\\\\xg" -e "s/[ ]*_PC_//" > $$i/makefile.mak); \
+ done
+
+tools/mkmake:
+ (cd tools; make mkmake)
+
+.DEFAULT:
+ sccs get $<
+
+depend: thisdepend
+ for i in ${SUBDIR}; do (cd $$i; make ${MFLAGS} depend); done
+
+thisdepend:
+ echo > eddep.c
+ grep '^#include' ${ALLC} eddep.c | grep -v '<' | \
+ sed -e 's/:[^"]*"\([^"]*\)".*/: \1/' \
+ -e 's/\.c/$$O/' | \
+ awk ' { if ($$1 != prev) { print rec; rec = $$0; prev = $$1; } \
+ else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \
+ else rec = rec " " $$2 } } \
+ END { print rec } ' > makedep
+ echo '$$r makedep' >>eddep
+ echo '/^# DO NOT DELETE THIS LINE/+1,$$d' >eddep
+ echo '$$r makedep' >>eddep
+ echo 'w' >>eddep
+ -rm -f makefile.bak
+ cp makefile makefile.bak
+ ed - makefile < eddep
+ rm eddep makedep eddep.c
+
+# DO NOT DELETE THIS LINE
+
diff --git a/usr.bin/tn3270/distribution/sys_dos/makefile b/usr.bin/tn3270/distribution/sys_dos/makefile
new file mode 100644
index 0000000..4188f9f
--- /dev/null
+++ b/usr.bin/tn3270/distribution/sys_dos/makefile
@@ -0,0 +1,127 @@
+# @(#)makefile 8.1 (Berkeley) 6/6/93
+
+# msdos versus unix defines
+O = .o
+#PC_O = .obj
+
+X =
+#PC_X = .exe
+
+L =
+#PC_L = -link
+
+CC = cc
+#PC_CC = cl
+
+MV = mv
+#PC_MV = rename
+
+RM = rm -f
+#PC_RM= erase
+
+LINT_ARGS =
+#PC_LINT_ARGS = -DLINT_ARGS
+
+DEBUG_FLAGS = -g
+#PC_DEBUG_FLAGS = -Zi -Od
+
+AR = ar
+AR1 = cr
+AR2 =
+AR3 =
+#PC_AR = lib
+#PC_AR1 =
+#PC_AR2 = +
+#PC_AR3 = ";"
+
+RANLIB = ranlib
+#PC_RANLIB = echo "Done with "
+
+PRINT = print
+
+DEFINES = ${LINT_ARGS}
+
+INCLUDES = -I.
+
+OPTIMIZE = -O
+OPTIMIZE = ${DEBUG_FLAGS}
+
+CFLAGS = $(OPTIMIZE) $(INCLUDES) $(DEFINES)
+
+# Lint flags
+LINTFLAGS = -hbxaz
+
+ALLH = spint.h video.h
+
+ALLC = spintc.c system.c termout.c
+
+ALLASM = spintasm.asm support.asm
+
+ALLO = spintasm$O spintc$O support$O system$O termout$O
+
+ALLPRINT = ${ALLH} ${ALLASM} ${ALLC}
+
+ALLSOURCE = ${ALLPRINT} makefile makefile.mak
+
+.c.obj:
+ ${CC} ${CFLAGS} -c $<
+
+syslib.a: $(ALLO)
+ ${RM} $@
+ for i in ${ALLO}; do (${AR} ${AR1} $@ ${AR2} $$i${AR3}); done
+ ${RANLIB} $@
+
+clean:
+ for i in $(ALLO) errs makefile.bak syslib.a; \
+ do (${RM} $$i); done
+
+sccsclean:
+ -sccs clean
+ -sccs get makefile
+
+sourcelist: ${ALLSOURCE}
+ @for i in ${ALLSOURCE}; \
+ do (echo ${DIRPATH}$$i); done
+
+print:
+ ${PRINT} ${ALLPRINT}
+
+tags: ${ALLC} ${ALLH}
+ ctags -t ${ALLC} ${ALLH}
+
+action:
+ ${ACTION}
+
+lint:
+ lint ${LINTFLAGS} ${INCLUDES} ${DEFINES} -DTN3270 \
+ ${TNMAIN} ${MOSTC} -lcurses
+ lint ${LINTFLAGS} ${INCLUDES} ${DEFINES} ${MSMAIN} map3270.c -lcurses
+
+.DEFAULT:
+ sccs get $<
+
+depend:
+ grep '^#include' ${ALLC} ${ALLH} | grep -v '<' | \
+ sed -e 's/:[^"]*"\([^"]*\)".*/: \1/' \
+ -e 's/\.c/$$O/' | \
+ awk ' { if ($$1 != prev) { print rec; rec = $$0; prev = $$1; } \
+ else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \
+ else rec = rec " " $$2 } } \
+ END { print rec } ' > makedep
+ echo '$$r makedep' >>eddep
+ echo '/^# DO NOT DELETE THIS LINE/+1,$$d' >eddep
+ echo '$$r makedep' >>eddep
+ echo 'w' >>eddep
+ -rm -f makefile.bak
+ cp makefile makefile.bak
+ ed - makefile < eddep
+ rm eddep makedep
+
+# DO NOT DELETE THIS LINE
+
+spintc$O: ../general/general.h spint.h
+system$O: ../general/general.h ../ctlr/api.h spint.h ../general/globals.h
+termout$O: ../general/general.h ../api/disp_asc.h
+termout$O: ../ctlr/hostctlr.h
+termout$O: ../ctlr/oia.h
+termout$O: ../ctlr/screen.h ../general/globals.h video.h
diff --git a/usr.bin/tn3270/distribution/sys_dos/spint.h b/usr.bin/tn3270/distribution/sys_dos/spint.h
new file mode 100644
index 0000000..023ee52
--- /dev/null
+++ b/usr.bin/tn3270/distribution/sys_dos/spint.h
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)spint.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * The 'spint' (spawn and interrupt) routines use this structure.
+ *
+ * Note that spint_asm.asm contains an Assembly language version of
+ * the following, so keep changes in synch!
+ */
+
+typedef struct {
+ union REGS regs;
+ struct SREGS sregs;
+ int int_no; /* Which interrupt to wait on */
+ int done; /* Are we done, or just took an interrupt? */
+ int rc; /* return code */
+} Spint;
diff --git a/usr.bin/tn3270/distribution/sys_dos/spintasm.asm b/usr.bin/tn3270/distribution/sys_dos/spintasm.asm
new file mode 100644
index 0000000..72efdec
--- /dev/null
+++ b/usr.bin/tn3270/distribution/sys_dos/spintasm.asm
@@ -0,0 +1,252 @@
+; Copyright (c) 1988, 1993
+; The Regents of the University of California. All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions
+; are met:
+; 1. Redistributions of source code must retain the above copyright
+; notice, this list of conditions and the following disclaimer.
+; 2. Redistributions in binary form must reproduce the above copyright
+; notice, this list of conditions and the following disclaimer in the
+; documentation and/or other materials provided with the distribution.
+; 3. All advertising materials mentioning features or use of this software
+; must display the following acknowledgement:
+; This product includes software developed by the University of
+; California, Berkeley and its contributors.
+; 4. Neither the name of the University nor the names of its contributors
+; may be used to endorse or promote products derived from this software
+; without specific prior written permission.
+;
+; THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+; ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+; SUCH DAMAGE.
+;
+; @(#)spintasm.asm 8.1 (Berkeley) 6/6/93
+;
+
+; The code in this file complete the spint calls
+
+spint struc
+; union REGS
+spint_ax dw 1
+spint_bx dw 1
+spint_cx dw 1
+spint_dx dw 1
+spint_si dw 1
+spint_di dw 1
+spint_cflag dw 1
+; struct SREGS
+spint_es dw 1
+spint_cs dw 1
+spint_ss dw 1
+spint_ds dw 1
+; int intno
+spint_intno dw 1
+; int done
+spint_done dw 1
+; int rc
+spint_rc dw 1
+;
+spint ends
+
+
+ENTER MACRO
+ ; Begin enter
+ push bp
+ mov bp,sp
+
+ push ax
+ push bx
+ push cx
+ push dx
+ push bp
+ push di
+ push si
+ push ds
+ push es
+ pushf
+
+ mov cs:start_sp, sp
+ mov cs:start_ss, ss
+ ; End enter
+ ENDM
+
+LEAVE MACRO
+ ; Begin leave
+ cli
+ mov sp, cs:start_sp
+ mov ss, cs:start_ss
+ sti
+
+ popf
+ pop es
+ pop ds
+ pop si
+ pop di
+ pop bp
+ pop dx
+ pop cx
+ pop bx
+ pop ax
+
+ mov sp,bp
+ pop bp
+ ret
+ ; End leave
+ ENDM
+
+GETREGS MACRO wherefrom
+ mov si, wherefrom
+ mov spint_segment, ds
+ mov spint_offset, si
+
+ mov ax, spint_ax[si]
+ mov bx, spint_bx[si]
+ mov cx, spint_cx[si]
+ mov dx, spint_dx[si]
+ ; XXX mov si, spint_si[si]
+ mov di, spint_di[si]
+ mov es, spint_es[si]
+ ; Now, need to do DS, SI
+ push spint_ds[si]
+ mov si, spint_si[si]
+ pop ds
+ ENDM
+
+
+SETREGS MACRO
+ mov cs:old_si, si
+ mov cs:old_ds, ds
+
+ mov ds, cs:spint_segment
+ mov si, cs:spint_offset
+
+ mov spint_ax[si], ax
+ mov spint_bx[si], bx
+ mov spint_cx[si], cx
+ mov spint_dx[si], dx
+
+ mov spint_si[si], si
+ mov spint_di[si], di
+
+ mov spint_cs[si], cs
+ mov spint_ds[si], ds
+ mov spint_es[si], es
+ mov spint_ss[si], ss
+ ; now, need to do SI, DS
+ mov ax, old_si
+ mov spint_si[si], ax
+ mov ax, old_ds
+ mov spint_ds[si], ax
+ ENDM
+
+
+_TEXT segment byte public 'CODE'
+_TEXT ends
+
+_DATA segment word public 'DATA'
+_DATA ends
+
+CONST segment word public 'CONST'
+CONST ends
+
+_BSS segment word public 'BSS'
+_BSS ends
+
+DGROUP group CONST, _BSS, _DATA
+
+ assume cs:_TEXT, ds:DGROUP, ss:DGROUP, es:DGROUP
+
+_TEXT segment
+
+start_sp dw 1 dup (?) ; For use in our 'longjmp'
+start_ss dw 1 dup (?) ; For use in our 'longjmp'
+
+spint_segment dw 1 dup (?) ; Segment of spawn control block
+spint_offset dw 1 dup (?) ; Offset of spawn control block
+
+old_si dw 1 dup (?) ; SI of interrupt issuer (temporary)
+old_ds dw 1 dup (?) ; DS of interrupt issuer (temporary)
+
+issuer_ss dw 1 dup (?) ; ss of person who called us (permanent)
+issuer_sp dw 1 dup (?) ; sp of person who called us (permanent)
+
+int21_stack db 100 dup (?) ; Stack for int21.
+
+;
+; _spint_int gets control on an interrupt. It switches the stack
+; and does a 'return' from _spint_start.
+;
+ public __spint_int
+
+__spint_int proc near
+ mov cs:issuer_sp, sp
+ mov cs:issuer_ss, ss
+ sti
+
+ SETREGS
+
+ LEAVE
+__spint_int endp
+
+;
+; _spint_start issues the dos interrupt after setting up the passed
+; registers. When control returns to it, it sets spint->done to non-zero.
+;
+ public __spint_start
+
+__spint_start proc near
+ ENTER
+
+ GETREGS 4[bp]
+
+ ; Now, switch to a different (short) stack. This is so
+ ; that our games won't mess up the stack int 21 (hardware and,
+ ; possibly, software) stores things on.
+
+ cli
+ mov cs:int21_stack, cs
+ mov ss, cs:int21_stack
+ mov sp, offset int21_stack
+ add sp, (length int21_stack) - 4
+ sti
+
+ int 21H ; Issue DOS interrupt
+
+ SETREGS
+
+ mov ds, cs:spint_segment
+ mov si, cs:spint_offset
+ mov spint_done[si], 1 ; We are done
+
+ LEAVE
+__spint_start endp
+
+;
+; After _spint_int has faked a return from start_spawn, we come here to
+; return to the interrupt issuer.
+;
+ public __spint_continue
+
+__spint_continue proc near
+ ENTER
+
+ GETREGS 4[bp]
+
+ mov sp, cs:issuer_sp ; Restore SP
+ mov ss, cs:issuer_ss ; Restore SS
+
+ iret
+__spint_continue endp
+
+_TEXT ends
+
+ end
diff --git a/usr.bin/tn3270/distribution/sys_dos/spintc.c b/usr.bin/tn3270/distribution/sys_dos/spintc.c
new file mode 100644
index 0000000..aa16405
--- /dev/null
+++ b/usr.bin/tn3270/distribution/sys_dos/spintc.c
@@ -0,0 +1,186 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)spintc.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include <stdio.h>
+#include <dos.h>
+#include <stdlib.h>
+
+#include "../general/general.h"
+#include "spint.h"
+
+#define PSP_ENVIRONMENT 0x2c
+#define PSP_FCB1 0x5c
+#define PSP_FCB2 0x6c
+
+typedef struct {
+ int
+ environment, /* Segment address of environment */
+ cmd_ptr_offset, /* Offset of command to execute */
+ cmd_ptr_segment, /* Segment where command lives */
+ fcb1_ptr_offset, /* Offset of FCB 1 */
+ fcb1_ptr_segment, /* Segment of FCB 1 */
+ fcb2_ptr_offset, /* Offset of FCB 2 */
+ fcb2_ptr_segment; /* Segment of FCB 2 */
+} ExecList;
+
+
+static int int_offset, int_segment;
+
+
+void
+spint_finish(spint)
+Spint *spint;
+{
+ union REGS regs;
+ struct SREGS sregs;
+
+ if (spint->done == 0) {
+ return; /* Not done yet */
+ }
+
+ /*
+ * Restore old interrupt handler.
+ */
+
+ regs.h.ah = 0x25;
+ regs.h.al = spint->int_no;
+ regs.x.dx = int_offset;
+ sregs.ds = int_segment;
+ intdosx(&regs, &regs, &sregs);
+
+ if (spint->regs.x.cflag) {
+ fprintf(stderr, "0x%x return code from EXEC.\n", spint->regs.x.ax);
+ spint->done = 1;
+ spint->rc = 99;
+ return;
+ }
+
+ regs.h.ah = 0x4d; /* Get return code */
+
+ intdos(&regs, &regs);
+
+ spint->rc = regs.x.ax;
+}
+
+void
+spint_continue(spint)
+Spint *spint;
+{
+ _spint_continue(spint); /* Return to caller */
+ spint_finish(spint);
+}
+
+
+void
+spint_start(command, spint)
+char *command;
+Spint *spint;
+{
+ ExecList mylist;
+ char *comspec;
+ void _spint_int();
+ union REGS regs;
+ struct SREGS sregs;
+
+ /*
+ * Get comspec.
+ */
+ comspec = getenv("COMSPEC");
+ if (comspec == 0) { /* Can't find where command.com is */
+ fprintf(stderr, "Unable to find COMSPEC in the environment.");
+ spint->done = 1;
+ spint->rc = 99; /* XXX */
+ return;
+ }
+
+ /*
+ * Now, hook up our interrupt routine.
+ */
+
+ regs.h.ah = 0x35;
+ regs.h.al = spint->int_no;
+ intdosx(&regs, &regs, &sregs);
+
+ /* Save old routine */
+ int_offset = regs.x.bx;
+ int_segment = sregs.es;
+
+ regs.h.ah = 0x25;
+ regs.h.al = spint->int_no;
+ regs.x.dx = (int) _spint_int;
+ segread(&sregs);
+ sregs.ds = sregs.cs;
+ intdosx(&regs, &regs, &sregs);
+
+ /*
+ * Read in segment registers.
+ */
+
+ segread(&spint->sregs);
+
+ /*
+ * Set up registers for the EXEC call.
+ */
+
+ spint->regs.h.ah = 0x4b;
+ spint->regs.h.al = 0;
+ spint->regs.x.dx = (int) comspec;
+ spint->sregs.es = spint->sregs.ds; /* Superfluous, probably */
+ spint->regs.x.bx = (int) &mylist;
+
+ /*
+ * Set up EXEC parameter list.
+ */
+
+ ClearElement(mylist);
+ mylist.cmd_ptr_offset = (int) command;
+ mylist.cmd_ptr_segment = spint->sregs.ds;
+ mylist.fcb1_ptr_offset = PSP_FCB1;
+ mylist.fcb1_ptr_segment = _psp;
+ mylist.fcb2_ptr_offset = PSP_FCB2;
+ mylist.fcb2_ptr_segment = _psp;
+ mylist.environment = *((int far *)(((long)_psp<<16)|PSP_ENVIRONMENT));
+
+ /*
+ * Call to assembly language routine to actually set up for
+ * the spint.
+ */
+
+ _spint_start(spint);
+
+ spint_finish(spint);
+}
diff --git a/usr.bin/tn3270/distribution/sys_dos/support.asm b/usr.bin/tn3270/distribution/sys_dos/support.asm
new file mode 100644
index 0000000..a51c41d
--- /dev/null
+++ b/usr.bin/tn3270/distribution/sys_dos/support.asm
@@ -0,0 +1,60 @@
+; Copyright (c) 1988, 1993
+; The Regents of the University of California. All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions
+; are met:
+; 1. Redistributions of source code must retain the above copyright
+; notice, this list of conditions and the following disclaimer.
+; 2. Redistributions in binary form must reproduce the above copyright
+; notice, this list of conditions and the following disclaimer in the
+; documentation and/or other materials provided with the distribution.
+; 3. All advertising materials mentioning features or use of this software
+; must display the following acknowledgement:
+; This product includes software developed by the University of
+; California, Berkeley and its contributors.
+; 4. Neither the name of the University nor the names of its contributors
+; may be used to endorse or promote products derived from this software
+; without specific prior written permission.
+;
+; THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+; ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+; SUCH DAMAGE.
+;
+; @(#)support.asm 8.1 (Berkeley) 6/6/93
+;
+
+_TEXT segment byte public 'CODE'
+_TEXT ends
+
+_DATA segment word public 'DATA'
+_DATA ends
+
+CONST segment word public 'CONST'
+CONST ends
+
+_BSS segment word public 'BSS'
+_BSS ends
+
+DGROUP group CONST, _BSS, _DATA
+
+ assume cs:_TEXT, ds:DGROUP, ss:DGROUP, es:DGROUP
+
+_TEXT segment
+ public _iret_subr
+
+_iret_subr proc far
+ iret
+_iret_subr endp
+
+_TEXT ends
+
+ end
diff --git a/usr.bin/tn3270/distribution/sys_dos/system.c b/usr.bin/tn3270/distribution/sys_dos/system.c
new file mode 100644
index 0000000..864926b
--- /dev/null
+++ b/usr.bin/tn3270/distribution/sys_dos/system.c
@@ -0,0 +1,140 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)system.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include <stdio.h>
+
+#include "../general/general.h"
+#include "../ctlr/api.h"
+#include "spint.h"
+
+#include "../general/globals.h"
+
+
+static Spint spinted;
+static char command[256];
+static int need_to_start = 0;
+
+/*
+ * shell_continue() actually runs the command, and looks for API
+ * requests coming back in.
+ *
+ * We are called from the main loop in telnet.c.
+ */
+
+int
+shell_continue()
+{
+ /*
+ * spint_start() returns when either the command has finished, or when
+ * the required interrupt comes in. In the latter case, the appropriate
+ * thing to do is to process the interrupt, and then return to
+ * the interrupt issuer by calling spint_continue().
+ */
+ if (need_to_start) {
+ need_to_start = 0;
+ spint_start(command, &spinted);
+ }
+
+ if (spinted.done == 0) {
+ /* Process request */
+ handle_api(&spinted.regs, &spinted.sregs);
+ spint_continue(&spinted);
+ } else {
+ char inputbuffer[100];
+
+ if (spinted.rc != 0) {
+ fprintf(stderr, "Process generated a return code of 0x%x.\n",
+ spinted.rc);
+ }
+ printf("[Hit return to continue]");
+ fflush(stdout);
+ (void) gets(inputbuffer);
+ shell_active = 0;
+ setconnmode();
+ ConnectScreen();
+ }
+ return shell_active;
+}
+
+
+/*
+ * Called from telnet.c to fork a lower command.com. We
+ * use the spint... routines so that we can pick up
+ * interrupts generated by application programs.
+ */
+
+
+int
+shell(argc,argv)
+int argc;
+char *argv[];
+{
+
+ ClearElement(spinted);
+ spinted.int_no = API_INTERRUPT_NUMBER;
+ if (argc == 1) {
+ command[0] = 0;
+ } else {
+ char *cmdptr;
+ int length;
+
+ argc--;
+ argv++;
+ strcpy(command, " /c");
+ cmdptr = command+strlen(command);
+ while (argc) {
+ if ((cmdptr+strlen(*argv)) >= (command+sizeof command)) {
+ fprintf(stderr, "Argument list too long at argument *%s*.\n",
+ *argv);
+ return 0;
+ }
+ *cmdptr++ = ' '; /* Blank separators */
+ strcpy(cmdptr, *argv);
+ cmdptr += strlen(cmdptr);
+ argc--;
+ argv++;
+ }
+ length = strlen(command)-1;
+ if (length < 0) {
+ length = 0;
+ }
+ command[0] = length;
+ }
+ need_to_start = 1;
+ shell_active = 1;
+ return 1; /* Go back to main loop */
+}
diff --git a/usr.bin/tn3270/distribution/sys_dos/termout.c b/usr.bin/tn3270/distribution/sys_dos/termout.c
new file mode 100644
index 0000000..0339072
--- /dev/null
+++ b/usr.bin/tn3270/distribution/sys_dos/termout.c
@@ -0,0 +1,514 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)termout.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include <stdio.h>
+#include <dos.h>
+#include "../general/general.h"
+
+#include "../telnet.ext"
+
+#include "../api/disp_asc.h"
+#include "../ascii/map3270.ext"
+
+#include "../ctlr/hostctlr.h"
+#include "../ctlr/externs.h"
+#include "../ctlr/declare.h"
+#include "../ctlr/oia.h"
+#include "../ctlr/screen.h"
+
+#include "../general/globals.h"
+
+#include "video.h"
+
+extern void EmptyTerminal();
+
+#define CorrectTerminalCursor() ((TransparentClock == OutputClock)? \
+ terminalCursorAddress:UnLocked? CursorAddress: HighestScreen())
+
+
+static int terminalCursorAddress; /* where the cursor is on term */
+static int screenInitd; /* the screen has been initialized */
+static int screenStopped; /* the screen has been stopped */
+
+static int needToRing; /* need to ring terinal bell */
+
+typedef struct {
+ char
+ data, /* The data for this position */
+ attr; /* The attributes for this position */
+} ScreenBuffer;
+
+ScreenBuffer Screen[MAXNUMBERLINES*MAXNUMBERCOLUMNS];
+ScreenBuffer saveScreen[sizeof Screen/sizeof Screen[0]];
+
+/* OurExitString - designed to keep us from going through infinite recursion */
+
+static void
+OurExitString(file, string, value)
+FILE *file;
+char *string;
+int value;
+{
+ static int recursion = 0;
+
+ if (!recursion) {
+ recursion = 1;
+ ExitString(file, string, value);
+ }
+}
+
+
+static void
+GoAway(from, where)
+char *from; /* routine that gave error */
+int where; /* cursor address */
+{
+ char foo[100];
+
+ sprintf(foo, "ERR from %s at %d (%d, %d)\n",
+ from, where, ScreenLine(where), ScreenLineOffset(where));
+ OurExitString(stderr, foo, 1);
+ /* NOTREACHED */
+}
+
+/*
+ * Routines to deal with the screen. These routines are lifted
+ * from mskermit.
+ */
+
+#define CRT_STATUS 0x3da /* Color card */
+#define DISPLAY_ENABLE 0x08 /* Enable */
+#define scrseg() ((crt_mode == 7)? 0xb000 : 0xb800)
+#define scrwait() if (crt_mode != 7) { \
+ while ((inp(CRT_STATUS)&DISPLAY_ENABLE) == 0) { \
+ ; \
+ } \
+ }
+static int
+ crt_mode,
+ crt_cols,
+ crt_lins,
+ curpage;
+
+/*
+ * Set the cursor position to where it belongs.
+ */
+
+static void
+setcursor(row, column, page)
+int
+ row,
+ column,
+ page;
+{
+ union REGS inregs, outregs;
+
+ inregs.h.dh = row;
+ inregs.h.dl = column;
+ inregs.h.bh = page;
+ inregs.h.ah = SetCursorPosition;
+
+ int86(BIOS_VIDEO, &inregs, &outregs);
+}
+/*
+ * Read the state of the video system. Put the cursor somewhere
+ * reasonable.
+ */
+
+static void
+scrini()
+{
+ union REGS inregs, outregs;
+
+ inregs.h.ah = CurrentVideoState;
+ int86(BIOS_VIDEO, &inregs, &outregs);
+
+ crt_mode = outregs.h.al;
+ crt_cols = outregs.h.ah;
+ crt_lins = 25;
+ curpage = outregs.h.bh;
+
+ inregs.h.ah = ReadCursorPosition;
+ inregs.h.bh = curpage;
+
+ int86(BIOS_VIDEO, &inregs, &outregs);
+
+ if (outregs.h.dh > crt_lins) {
+ outregs.h.dh = crt_lins;
+ }
+ if (outregs.h.dl > crt_cols) {
+ outregs.h.dl = crt_cols;
+ }
+ inregs.h.dh = outregs.h.dh;
+ inregs.h.dl = outregs.h.dl;
+ inregs.h.bh = curpage;
+
+ inregs.h.ah = SetCursorPosition;
+ int86(BIOS_VIDEO, &inregs, &outregs);
+}
+
+
+static void
+scrwrite(source, length, offset)
+ScreenBuffer *source;
+int
+ length,
+ offset;
+{
+ struct SREGS segregs;
+
+ segread(&segregs); /* read the current segment register */
+
+ scrwait();
+ movedata(segregs.ds, source, scrseg(), sizeof *source*offset,
+ sizeof *source*length);
+}
+
+static void
+scrsave(buffer)
+ScreenBuffer *buffer;
+{
+ struct SREGS segregs;
+
+ segread(&segregs); /* read the current segment register */
+
+ scrwait();
+ movedata(scrseg(), 0, segregs.ds, buffer, crt_cols*crt_lins*2);
+}
+
+static void
+scrrest(buffer)
+ScreenBuffer *buffer;
+{
+ scrwrite(buffer, crt_cols*crt_lins, 0);
+}
+
+static void
+TryToSend()
+{
+#define STANDOUT 0x0a /* Highlighted mode */
+#define NORMAL 0x02 /* Normal mode */
+#define NONDISPLAY 0x00 /* Don't display */
+
+#define DoAttribute(a) \
+ if (screenIsFormatted) { \
+ if (IsNonDisplayAttr(a)) { \
+ a = NONDISPLAY; /* don't display */ \
+ } else if (IsHighlightedAttr(a)) { \
+ a = STANDOUT; \
+ } else { \
+ a = NORMAL; \
+ } \
+ } else { \
+ a = NORMAL; /* do display on unformatted */\
+ }
+ ScreenImage *p, *upper;
+ ScreenBuffer *sp;
+ int fieldattr; /* spends most of its time == 0 or 1 */
+ int screenIsFormatted = FormattedScreen();
+
+/* OK. We want to do this a quickly as possible. So, we assume we
+ * only need to go from Lowest to Highest. However, if we find a
+ * field in the middle, we do the whole screen.
+ *
+ * In particular, we separate out the two cases from the beginning.
+ */
+ if ((Highest != HighestScreen()) || (Lowest != LowestScreen())) {
+ sp = &Screen[Lowest];
+ p = &Host[Lowest];
+ upper = &Host[Highest];
+ fieldattr = FieldAttributes(Lowest);
+ DoAttribute(fieldattr); /* Set standout, non-display status */
+
+ while (p <= upper) {
+ if (IsStartFieldPointer(p)) { /* New field? */
+ Highest = HighestScreen();
+ Lowest = LowestScreen();
+ TryToSend(); /* Recurse */
+ return;
+ } else if (fieldattr) { /* Should we display? */
+ /* Display translated data */
+ sp->data = disp_asc[GetHostPointer(p)];
+ } else {
+ sp->data = ' ';
+ }
+ sp->attr = fieldattr;
+ p++;
+ sp++;
+ }
+ } else { /* Going from Lowest to Highest */
+ ScreenImage *End = &Host[ScreenSize]-1;
+
+ sp = Screen;
+ p = Host;
+ fieldattr = FieldAttributes(LowestScreen());
+ DoAttribute(fieldattr); /* Set standout, non-display status */
+
+ while (p <= End) {
+ if (IsStartFieldPointer(p)) { /* New field? */
+ fieldattr = FieldAttributesPointer(p); /* Get attributes */
+ DoAttribute(fieldattr); /* Set standout, non-display */
+ }
+ if (fieldattr) { /* Should we display? */
+ /* Display translated data */
+ sp->data = disp_asc[GetHostPointer(p)];
+ } else {
+ sp->data = ' ';
+ }
+ sp->attr = fieldattr;
+ p++;
+ sp++;
+ }
+ }
+ terminalCursorAddress = CorrectTerminalCursor();
+ /*
+ * We might be here just to update the cursor address.
+ */
+ if (Highest >= Lowest) {
+ scrwrite(Screen+Lowest, (1+Highest-Lowest), Lowest);
+ }
+ setcursor(ScreenLine(terminalCursorAddress),
+ ScreenLineOffset(terminalCursorAddress), 0);
+ Lowest = HighestScreen()+1;
+ Highest = LowestScreen()-1;
+ if (needToRing) {
+ DataToTerminal("\7", 1);
+ needToRing = 0;
+ }
+ return;
+}
+
+/* InitTerminal - called to initialize the screen, etc. */
+
+void
+InitTerminal()
+{
+ InitMapping(); /* Go do mapping file (MAP3270) first */
+ if (!screenInitd) { /* not initialized */
+ MaxNumberLines = 24; /* XXX */
+ MaxNumberColumns = 80; /* XXX */
+ scrini();
+ scrsave(saveScreen); /* Save the screen buffer away */
+ ClearArray(Screen);
+ terminalCursorAddress = SetBufferAddress(0,0);
+ screenInitd = 1;
+ screenStopped = 0; /* Not stopped */
+ }
+}
+
+
+/* StopScreen - called when we are going away... */
+
+void
+StopScreen(doNewLine)
+int doNewLine;
+{
+ if (screenInitd && !screenStopped) {
+ scrrest(saveScreen);
+ setcursor(NumberLines-1, 1, 0);
+ if (doNewLine) {
+ StringToTerminal("\r\n");
+ }
+ EmptyTerminal();
+ screenStopped = 1;
+ }
+}
+
+
+/* RefreshScreen - called to cause the screen to be refreshed */
+
+void
+RefreshScreen()
+{
+ Highest = HighestScreen();
+ Lowest = LowestScreen();
+ TryToSend();
+}
+
+
+/* ConnectScreen - called to reconnect to the screen */
+
+void
+ConnectScreen()
+{
+ if (screenInitd) {
+ RefreshScreen();
+ screenStopped = 0;
+ }
+}
+
+/* LocalClearScreen() - clear the whole ball of wax, cheaply */
+
+void
+LocalClearScreen()
+{
+ Clear3270();
+ Lowest = LowestScreen(); /* everything in sync... */
+ Highest = HighestScreen();
+ TryToSend();
+}
+
+/*
+ * Implement the bell/error message function.
+ */
+
+int
+ bellwinup = 0; /* If != 0, length of bell message */
+static int
+ bell_len = 0; /* Length of error message */
+
+
+void
+BellOff()
+{
+ ScreenBuffer a[100];
+ int i;
+
+ if (bellwinup) {
+ unsigned char blank = ' ';
+
+ for (i = 0; i < bell_len; i++) {
+ a[i].attr = NORMAL;
+ a[i].data = ' ';
+ }
+ }
+ scrwrite(a, bell_len, 24*80); /* XXX */
+}
+
+
+void
+RingBell(s)
+char *s;
+{
+ needToRing = 1;
+ if (s) {
+ int i;
+ ScreenBuffer bellstring[100];
+
+ bell_len = strlen(s);
+ bellwinup = 1;
+ if (bell_len > sizeof bellstring-1) {
+ OurExitString(stderr, "Bell string too long.", 1);
+ }
+ for (i = 0; i < bell_len; i++) {
+ bellstring[i].attr = STANDOUT;
+ bellstring[i].data = s[i];
+ }
+ scrwrite(bellstring, bell_len, 24*80); /* XXX */
+ }
+}
+
+/*
+ * Update the OIA area.
+ */
+
+void
+ScreenOIA(oia)
+OIA *oia;
+{
+}
+
+
+/* returns a 1 if no more output available (so, go ahead and block),
+ or a 0 if there is more output available (so, just poll the other
+ sources/destinations, don't block).
+ */
+
+int
+DoTerminalOutput()
+{
+ /* called just before a select to conserve IO to terminal */
+ if (!(screenInitd||screenStopped)) {
+ return 1; /* No output if not initialized */
+ }
+ if ((Lowest <= Highest) || needToRing ||
+ (terminalCursorAddress != CorrectTerminalCursor())) {
+ TryToSend();
+ }
+ if (Lowest > Highest) {
+ return 1; /* no more output now */
+ } else {
+ return 0; /* more output for future */
+ }
+}
+
+/*
+ * The following are defined to handle transparent data.
+ */
+
+void
+TransStop()
+{
+ RefreshScreen();
+}
+
+void
+TransOut(buffer, count, kind, control)
+unsigned char *buffer;
+int count;
+int kind; /* 0 or 5 */
+int control; /* To see if we are done */
+{
+ char *ptr;
+
+ while (DoTerminalOutput() == 0) {
+ ;
+ }
+ for (ptr = buffer; ptr < buffer+count; ptr++) {
+ *ptr &= 0x7f; /* Turn off parity bit */
+ }
+ (void) DataToTerminal(buffer, count);
+ if (control && (kind == 0)) { /* Send in AID byte */
+ SendToIBM();
+ } else {
+ TransInput(1, kind); /* Go get some data */
+ }
+}
+
+/*
+ * init_screen()
+ *
+ * Initialize variables used by screen.
+ */
+
+void
+init_screen()
+{
+ bellwinup = 0;
+}
+
+
diff --git a/usr.bin/tn3270/distribution/sys_dos/termout.ext b/usr.bin/tn3270/distribution/sys_dos/termout.ext
new file mode 100644
index 0000000..d3c8fb4
--- /dev/null
+++ b/usr.bin/tn3270/distribution/sys_dos/termout.ext
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)termout.ext 8.1 (Berkeley) 6/6/93
+ */
+
+extern void
+ StartScreen(),
+ StopScreen(),
+ ConnectScreen(),
+ ClearScreen(),
+ LocalClearScreen(),
+ RefreshScreen(),
+ RingBell(),
+ AddHost();
+
+extern int
+ DoTerminalOutput();
diff --git a/usr.bin/tn3270/distribution/sys_dos/video.h b/usr.bin/tn3270/distribution/sys_dos/video.h
new file mode 100644
index 0000000..8fffe6c
--- /dev/null
+++ b/usr.bin/tn3270/distribution/sys_dos/video.h
@@ -0,0 +1,75 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)video.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * This is a header file describing the interface via int 10H to the
+ * video subsystem.
+ */
+
+#define BIOS_VIDEO 0x10
+
+typedef enum {
+ SetMode = 0,
+ SetCursorType,
+ SetCursorPosition,
+ ReadCursorPosition,
+ ReadLightPenPosition,
+ SelectActiveDisplayPage,
+ ScrollActivePageUp,
+ ScrollActivePageDown,
+ ReadAttribute_Character,
+ WriteAttribute_Character,
+ WriteCharacterOnly,
+ SetColorPalette,
+ WriteDot,
+ ReadDot,
+ WriteTeletypeToActivePage,
+ CurrentVideoState,
+ Reserved16,
+ Reserved17,
+ Reserved18,
+ WriteString
+} VideoOperationsType;
+
+typedef enum {
+ bw_40x25 = 0,
+ color_40x25,
+ bw_80x25,
+ color_80x25,
+ color_320x200,
+ bw_320x200,
+ bw_640x200,
+ internal_bw_80x25
+} VideoModeType;
diff --git a/usr.bin/tn3270/distribution/telnet/Makefile_ultrix b/usr.bin/tn3270/distribution/telnet/Makefile_ultrix
new file mode 100644
index 0000000..dbb93ea
--- /dev/null
+++ b/usr.bin/tn3270/distribution/telnet/Makefile_ultrix
@@ -0,0 +1,179 @@
+# @(#)Makefile 1.4 (Berkeley) 5/15/88
+
+# This is the makefile for an Ultrix system. The current Ultrix make(1) doesn't
+# support VPATH, so we expand everything out.
+
+# The following is the telnet makefile for tn3270, using the shared telnet
+# sources.
+
+#
+# TERMCAP Define this if your system is termcap based,
+# otherwise a terminfo based system is assumed.
+#
+# SRCRT Includes code to allow you to specify source routes.
+# Format is:
+# [!]@hop1@hop2...[@|:]dst
+# Leading ! means strict source route.
+#
+# NOSTRNCASECMP Define this if you do not have strncasecmp() in
+# your C libarary.
+#
+# USE_TERMIO Define this if you have System V termio structures.
+# What is here is how things are on Cray computers.
+#
+# KLUDGELINEMODE Define this to get the kludged up version of linemode
+# that was in 4.3BSD. This is a good thing to have
+# around for talking to older systems.
+#
+
+DEFINES= -DTERMCAP -DSRCRT -DKLUDGELINEMODE
+
+
+VPATH = ../../telnet/Source
+XINCLUDES= -I../../telnet/Source
+INCLUDES= -I.
+XDEFINES = -DTN3270
+OPTIMIZE= -O
+CFLAGS = ${OPTIMIZE} ${INCLUDES} ${DEFINES}
+XCFLAGS= ${XINCLUDES} ${XDEFINES}
+LD = ld
+LDFLAGS = -r
+PRINT = print
+ACTION = sccs tell
+LIBC= /lib/libc.a
+SD= ../../telnet/Source/
+ALLH= ${SD}defines.h ${SD}externs.h ${SD}fdset.h ${SD}general.h ${SD}ring.h ${SD}types.h
+SRCS= ${SD}commands.c ${SD}main.c ${SD}network.c ${SD}ring.c \
+ ${SD}sys_bsd.c ${SD}sys_dos.c ${SD}telnet.c ${SD}terminal.c \
+ ${SD}tn3270.c ${SD}utilities.c
+ALLHC= ${ALLH} ${SRCS}
+ALLPRINT = ${ALLHC}
+ALLSOURCE= ${ALLHC} Makefile Makefile_ultrix
+OBJS= commands.o main.o network.o ring.o sys_bsd.o sys_dos.o \
+ telnet.o terminal.o tn3270.o utilities.o
+
+.c.o:
+ ${CC} -c ${CFLAGS} ${XCFLAGS} $<
+
+telprog.o: ${OBJS} ${LIBC}
+ ${LD} ${LDFLAGS} -o $@ ${OBJS}
+
+clean: FRC
+ rm -f ${OBJS} core telnet
+
+depend: FRC ${SRCS}
+ mkdep ${CFLAGS} ${SRCS}
+
+lint: FRC ${SRCS}
+ lint ${CFLAGS} ${SRCS}
+
+tags: FRC ${ALLHC}
+ ctags ${ALLHC}
+
+print: FRC ${ALLPRINT}
+ ${PRINT} ${ALLPRINT}
+
+commands.o: ${SD}commands.c
+ ${CC} -c ${CFLAGS} ${XCFLAGS} ${SD}commands.c
+
+main.o: ${SD}main.c
+ ${CC} -c ${CFLAGS} ${XCFLAGS} ${SD}main.c
+
+network.o: ${SD}network.c
+ ${CC} -c ${CFLAGS} ${XCFLAGS} ${SD}network.c
+
+ring.o: ${SD}ring.c
+ ${CC} -c ${CFLAGS} ${XCFLAGS} ${SD}ring.c
+
+sys_bsd.o: ${SD}sys_bsd.c
+ ${CC} -c ${CFLAGS} ${XCFLAGS} ${SD}sys_bsd.c
+
+sys_dos.o: ${SD}sys_dos.c
+ ${CC} -c ${CFLAGS} ${XCFLAGS} ${SD}sys_dos.c
+
+telnet.o: ${SD}telnet.c
+ ${CC} -c ${CFLAGS} ${XCFLAGS} ${SD}telnet.c
+
+terminal.o: ${SD}terminal.c
+ ${CC} -c ${CFLAGS} ${XCFLAGS} ${SD}terminal.c
+
+tn3270.o: ${SD}tn3270.c
+ ${CC} -c ${CFLAGS} ${XCFLAGS} ${SD}tn3270.c
+
+utilities.o: ${SD}utilities.c
+ ${CC} -c ${CFLAGS} ${XCFLAGS} ${SD}utilities.c
+
+
+action: FRC
+ ${ACTION}
+
+clist: FRC ${SRCS}
+ @for i in ${SRCS} ; \
+ do (echo ${DIRPATH}$$i); done
+
+hclist: FRC ${ALLHC}
+ @for i in ${ALLHC} ; \
+ do (echo ${DIRPATH}$$i); done
+
+sourcelist: FRC ${ALLSOURCE}
+ @for i in ${ALLSOURCE} ../../telnet/Makefile ; \
+ do (echo ${DIRPATH}$$i); done
+
+FRC:
+
+# DO NOT DELETE THIS LINE -- mkdep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
+
+commands.o: ../../telnet/Source/commands.c /usr/include/sys/types.h
+commands.o: /usr/include/sys/socket.h /usr/include/netinet/in.h
+commands.o: /usr/include/signal.h /usr/include/machine/trap.h
+commands.o: /usr/include/netdb.h /usr/include/ctype.h
+commands.o: /usr/include/arpa/telnet.h ../../telnet/Source/ring.h
+commands.o: ../../telnet/Source/externs.h /usr/include/stdio.h
+commands.o: /usr/include/setjmp.h ../../telnet/Source/defines.h
+commands.o: ../../telnet/Source/types.h
+main.o: ../../telnet/Source/main.c /usr/include/sys/types.h
+main.o: ../../telnet/Source/ring.h ../../telnet/Source/externs.h
+main.o: /usr/include/stdio.h /usr/include/setjmp.h
+main.o: ../../telnet/Source/defines.h
+network.o: ../../telnet/Source/network.c /usr/include/sys/types.h
+network.o: /usr/include/sys/socket.h /usr/include/sys/time.h
+network.o: /usr/include/time.h /usr/include/errno.h /usr/include/arpa/telnet.h
+network.o: ../../telnet/Source/ring.h ../../telnet/Source/defines.h
+network.o: ../../telnet/Source/externs.h /usr/include/stdio.h
+network.o: /usr/include/setjmp.h ../../telnet/Source/fdset.h
+ring.o: ../../telnet/Source/ring.c /usr/include/stdio.h /usr/include/errno.h
+ring.o: /usr/include/sys/types.h /usr/include/sys/ioctl.h
+ring.o: /usr/include/sys/ttychars.h /usr/include/sys/ttydev.h
+ring.o: /usr/include/sys/socket.h ../../telnet/Source/ring.h
+ring.o: ../../telnet/Source/general.h
+sys_bsd.o: ../../telnet/Source/sys_bsd.c /usr/include/sys/ioctl.h
+sys_bsd.o: /usr/include/sys/ttychars.h /usr/include/sys/ttydev.h
+sys_bsd.o: /usr/include/sys/types.h /usr/include/sys/time.h /usr/include/time.h
+sys_bsd.o: /usr/include/sys/socket.h /usr/include/signal.h
+sys_bsd.o: /usr/include/machine/trap.h /usr/include/errno.h
+sys_bsd.o: ../../telnet/Source/ring.h ../../telnet/Source/fdset.h
+sys_bsd.o: ../../telnet/Source/defines.h ../../telnet/Source/externs.h
+sys_bsd.o: /usr/include/stdio.h /usr/include/setjmp.h
+sys_bsd.o: ../../telnet/Source/types.h
+sys_dos.o: ../../telnet/Source/sys_dos.c
+telnet.o: ../../telnet/Source/telnet.c /usr/include/sys/types.h
+telnet.o: /usr/include/curses.h /usr/include/stdio.h /usr/include/sgtty.h
+telnet.o: /usr/include/sys/ioctl.h /usr/include/sys/ttychars.h
+telnet.o: /usr/include/sys/ttydev.h /usr/include/arpa/telnet.h
+telnet.o: /usr/include/strings.h ../../telnet/Source/ring.h
+telnet.o: ../../telnet/Source/defines.h ../../telnet/Source/externs.h
+telnet.o: /usr/include/stdio.h /usr/include/setjmp.h
+telnet.o: ../../telnet/Source/types.h ../../telnet/Source/general.h
+telnet.o: /usr/include/varargs.h
+terminal.o: ../../telnet/Source/terminal.c /usr/include/arpa/telnet.h
+terminal.o: /usr/include/sys/types.h ../../telnet/Source/ring.h
+terminal.o: ../../telnet/Source/externs.h /usr/include/stdio.h
+terminal.o: /usr/include/setjmp.h ../../telnet/Source/types.h
+tn3270.o: ../../telnet/Source/tn3270.c ../../telnet/Source/fdset.h
+utilities.o: ../../telnet/Source/utilities.c /usr/include/arpa/telnet.h
+utilities.o: /usr/include/sys/types.h /usr/include/ctype.h
+utilities.o: ../../telnet/Source/ring.h ../../telnet/Source/externs.h
+utilities.o: /usr/include/stdio.h /usr/include/setjmp.h
+
+# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
diff --git a/usr.bin/tn3270/distribution/ultrix.curses b/usr.bin/tn3270/distribution/ultrix.curses
new file mode 100644
index 0000000..f5fcd94
--- /dev/null
+++ b/usr.bin/tn3270/distribution/ultrix.curses
@@ -0,0 +1,46 @@
+Return-Path: mtxinu!kinetics!minshall@ucbvax.Berkeley.EDU
+Received: from ucbvax.berkeley.edu
+ by violet.berkeley.edu (5.54 (CFC 4.22.3)/1.16.17l)
+ id AA23846; Wed, 30 Mar 88 19:54:24 PST
+Received: by ucbvax.berkeley.edu (5.59/1.26)
+ id AA09851; Tue, 29 Mar 88 23:25:19 PST
+Received: by mtxinu.UUCP (5.51/4.7)
+ id AA05135; Tue, 29 Mar 88 17:32:01 PST
+Message-Id: <8803300132.AA05135@mtxinu.UUCP>
+Date: Thu, 17 Mar 88 11:06:10 pst
+From: mtxinu!kinetics!minshall@ucbvax.Berkeley.EDU (Greg Minshall)
+To: mtxinu!minshall
+
+Path: kinetics!zehntel!varian!ptsfa!pacbell!ames!ll-xn!husc6!panda!teddy!jpn
+From: jpn@teddy.UUCP (John P. Nelson)
+Newsgroups: comp.bugs.4bsd
+Subject: Re: Ultrix curses problem
+Keywords: curses ultrix bug fix
+Message-ID: <4668@teddy.UUCP>
+Date: 14 Mar 88 19:43:39 GMT
+References: <535@hscfvax.harvard.edu>
+Reply-To: jpn@teddy.UUCP (John P. Nelson)
+Organization: GenRad, Inc., Concord, Mass.
+Lines: 21
+
+>I have found the bug, fixable as above, in both Ultrix 1.2 and 2.0. Feedback
+>from those brave souls who have brought up 2.2 would be most welcome.
+
+Yup, the bug exists in Ultrix 2.2 as well. I have reported this bug to
+DEC support every time we get a new release. I assume that my bug reports
+are getting filed (in the circular file).
+
+It is clear that whoever made this "fix" at DEC had no understanding
+of curses whatsoever. As in the earlier posting, the bug can be fixed
+by replacing the definitions of the nl() and nonl() macros in curses.h with:
+
+#define nl() (_tty.sg_flags |= CRMOD,_pfast = _rawmode,stty(_tty_ch, &_tty))
+#define nonl() (_tty.sg_flags &= ~CRMOD, _pfast = TRUE, stty(_tty_ch, &_tty))
+
+- john nelson.
+
+P.S. I did reach someone at DEC who would listen (Thanks Chet!) My
+ understanding is that they have no plans to fix this bug, as curses
+ is now "owned" by some group in England, who is working on a port of the
+ terminfo curses for Ultrix 2.4. I'm just pissed that my bug reports
+ submitted for Ultrix 1.2 and 2.0 were ignored.
diff --git a/usr.bin/tn3270/distribution/utilities/adm3a.keys b/usr.bin/tn3270/distribution/utilities/adm3a.keys
new file mode 100644
index 0000000..4e65374
--- /dev/null
+++ b/usr.bin/tn3270/distribution/utilities/adm3a.keys
@@ -0,0 +1,78 @@
+1LSI ADM 3A Key Definitions for IBM 3277 Terminal Emulation 06/18/81
++LSI ADM 3A Key Definitions for IBM 3277 Terminal Emulation 06/18/81
+
+ 3277 Key ADM Key(s) | 3277 Key LSI ADM 3A Key(s)
+ ======== ========== | ======== ====================
+ |
+ Cursor Movement Keys | Command Keys
++______ ________ ____ _______ ____
+ |
+ New Line Ctrl-N -or- | Enter Return
+ Home | Clear Ctrl-Z
+ Tab Ctrl-I |
+ Back Tab Ctrl-B | Program Function Keys
++ _______ ________ ____
+ Cursor Left Ctrl-H |
+ Cursor Right Ctrl-L | PF1 Esc 1
+ Cursor Up Ctrl-K | PF2 Esc 2
+ Cursor Down Ctrl-J -or- | PF3 Esc 3
+ Line Feed | PF4 Esc 4
+ Home Ctrl-@ | PF5 Esc 5
+ | PF6 Esc 6
+ | PF7 Esc 7
+ Edit Control Keys | PF8 Esc 8
++____ _______ ____
+ | PF9 Esc 9
+ Delete Char Ctrl-D -OR- Rub | PF10 Esc 0
+ Erase EOF Ctrl-E | PF11 Esc Colon
+ Erase Input Ctrl-W | PF12 Esc Minus
+ Insert Mode Esc Space | PF13 Ctrl-F 1 3
+ End Insert Esc Space | PF14 Ctrl-F 1 4
+ Dup Ctrl-U | PF15 Ctrl-F 1 5
+ Field Mark Ctrl-Y | PF16 Ctrl-F 1 6
+ | PF17 Ctrl-F 1 7
+ Series-1 Control Keys | PF18 Ctrl-F 1 8
++________ _______ ____
+ | PF19 Ctrl-F 1 9
+ Reset After Error Ctrl-R | PF20 Ctrl-F 2 0
+ Keyboard Unlock Ctrl-T | PF21 Ctrl-F 2 1
+ Purge Input Buffer Ctrl-X | PF22 Ctrl-F 2 2
+ Stop Output Ctrl-S | PF23 Ctrl-F 2 3
+ Start Output Ctrl-Q | PF24 Ctrl-F 2 4
+ Re-Display Screen Ctrl-V |
+ | Program Attention Keys
++ _______ _________ ____
+ Miscellaneous 3277 Keys |
++_____________ ____ ____
+ | PA1 Ctrl-P 1
+ Cursor Select Esc Period | PA2 Ctrl-P 2
+ Test Request (not supported) | PA3 Ctrl-P 3
+
+ Series 1 Local Editing Keys
++______ _ _____ _______ ____
+
+ Set Tab Stop Esc Semicolon
+ Clear (all) Tab Stops Esc Plus
+ Set Left Margin (New Line) Esc LeftParen
+ Set Home (Home) Esc Exclamation
+ Tab to Next Local Tab Stop Esc i (or Esc I)
+ Tab to Previous Local Tab Stop Esc b (or Esc B)
+ Indent (to Next Local Tab Stop - New Line) Esc l (or Esc L)
+ Undent (to Previous Local Tab Stop - New Line) Esc h (or Esc H)
+
+
+ Note: If the terminal hangs up, enter "Ctrl-H" and see if the
+ cursor moves. If it does, you are trying to enter data
+ into a protected field, trying to insert a character when
+ the last character of the field is non-blank, or trying to
+ communicate to a virtual process which is not accepting data.
+ If the cursor did not move, a transmission error or terminal
+ lock has occurred. Enter the following sequence to unhang
+ the terminal: "Ctrl-R Ctrl-T Ctrl-X Ctrl-Q Ctrl-V".
+
+ ********** DRAFT ONLY - SPECIFICATION SUBJECT TO CHANGE **********
++********** DRAFT ONLY - SPECIFICATION SUBJECT TO CHANGE **********
++********** DRAFT ONLY - SPECIFICATION SUBJECT TO CHANGE **********
++********** DRAFT ONLY - SPECIFICATION SUBJECT TO CHANGE **********
+
+
diff --git a/usr.bin/tn3270/distribution/utilities/cross.c b/usr.bin/tn3270/distribution/utilities/cross.c
new file mode 100644
index 0000000..191aac0
--- /dev/null
+++ b/usr.bin/tn3270/distribution/utilities/cross.c
@@ -0,0 +1,55 @@
+/*
+ This program is, essentially, a cross product generator. It takes
+ an input file which is said to consist of a number of lines, and
+ expands each line. A line like
+ (a,b)(c,d)
+ will be expanded to lines like
+ ac
+ ad
+ bc
+ bd
+ (without regard for the ORDER of the output; ie: the lines can appear
+ in any order).
+
+ Parenthesis can be nested, so
+ (a,b)(c(d,e),f)
+ will produce
+ acd
+ ace
+ af
+ bcd
+ bce
+ bf
+ */
+
+
+#include <stdio.h>
+
+char leftParen, /* The left parenthesis character */
+ rightParen; /* The right parenthesis character */
+
+
+/* Finds next occurrence of 'character' at this level of nesting.
+ Returns 0 if no such character found.
+ */
+
+char *
+ThisLevel(string, character)
+char *string, character;
+{
+ int level; /* Level 0 is OUR level */
+
+ level = 0;
+
+ while (*string != '\0') {
+ if (*string == leftParen)
+ level++;
+ else if (*string == rightParen) {
+ level--;
+ if (level < 0)
+ return(0);
+ }
+ if ((level == 0) && (*string == character))
+ return(string);
+ string++;
+ }
diff --git a/usr.bin/tn3270/distribution/utilities/makefile b/usr.bin/tn3270/distribution/utilities/makefile
new file mode 100644
index 0000000..0cb5b3e
--- /dev/null
+++ b/usr.bin/tn3270/distribution/utilities/makefile
@@ -0,0 +1,121 @@
+#
+# Copyright (c) 1988 Regents of the University of California.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms are permitted
+# provided that the above copyright notice and this paragraph are
+# duplicated in all such forms and that any documentation,
+# advertising materials, and other materials related to such
+# distribution and use acknowledge that the software was developed
+# by the University of California, Berkeley. The name of the
+# University may not be used to endorse or promote products derived
+# from this software without specific prior written permission.
+# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+# WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+#
+# @(#)makefile 8.1 (Berkeley) 6/6/93
+#
+# msdos versus unix defines
+O = .o
+#PC_O = .obj
+
+X =
+#PC_X = .exe
+
+L =
+#PC_L = -link
+
+CC = cc
+#PC_CC = cl
+
+MV = mv
+#PC_MV = rename
+
+RM = rm -f
+#PC_RM= erase
+
+LINT_ARGS =
+#PC_LINT_ARGS = -DLINT_ARGS
+
+DEBUG_FLAGS = -g
+#PC_DEBUG_FLAGS = -Zi -Od
+
+AR = ar
+AR1 = cr
+AR2 =
+AR3 =
+#PC_AR = lib
+#PC_AR1 =
+#PC_AR2 = +
+#PC_AR3 = ";"
+
+RANLIB = ranlib
+#PC_RANLIB = echo "Done with "
+
+DEFINES = ${LINT_ARGS}
+
+CFLAGS = ${DEBUG_FLAGS} -I..
+
+PRINT = lpr -p
+
+ALLC = tnrecv.c
+ALLH = tncomp.h
+
+ALLPRINT = ${ALLH} ${ALLC}
+
+ALLSOURCE = ${ALLPRINT} makefile makefile.mak
+
+ALLO = tnrecv$O
+
+.c.obj:
+ ${CC} ${CFLAGS} -c $<
+
+all: tnrecv$X
+
+tnrecv$X: tnrecv$O
+ ${CC} ${CFLAGS} -o $@ tnrecv$O $L ../api/apilib.a
+
+clean:
+ for i in makefile.bak ${ALLO} errs tnrecv$X; \
+ do (${RM} $$i); done
+
+.DEFAULT:
+ sccs get $<
+
+sccsclean:
+ -sccs clean
+ -sccs get makefile
+
+action:
+ ${ACTION}
+
+print:
+ ${PRINT} ${ALLPRINT}
+
+sourcelist: ${ALLSOURCE} tarread.exe
+ @for i in ${ALLSOURCE} tarread.exe; \
+ do (echo ${DIRPATH}$$i); done
+
+depend:
+ grep '^#include' ${ALLC} | grep -v '<' | \
+ sed -e 's/:[^"]*"\([^"]*\)".*/: \1/' \
+ -e 's/\.c/$$O/' | \
+ awk ' { if ($$1 != prev) { print rec; rec = $$0; prev = $$1; } \
+ else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \
+ else rec = rec " " $$2 } } \
+ END { print rec } ' > makedep
+ echo '$$r makedep' >>eddep
+ echo '/^# DO NOT DELETE THIS LINE/+1,$$d' >eddep
+ echo '$$r makedep' >>eddep
+ echo 'w' >>eddep
+ -rm -f makefile.bak
+ cp makefile makefile.bak
+ ed - makefile < eddep
+ rm eddep makedep
+
+# DO NOT DELETE THIS LINE
+
+#include "tncomp.h" "../api/api.h" "../ctlr/function.h" "../ctlr/hostctlr.h"
+#include "../ctlr/oia.h" "../ctlr/screen.h" "../apilib/disp_asc.h"
+#include "../apilib/astosc.h" "../general/general.h"
diff --git a/usr.bin/tn3270/distribution/utilities/srccmd/tar/makefile b/usr.bin/tn3270/distribution/utilities/srccmd/tar/makefile
new file mode 100644
index 0000000..f4618af
--- /dev/null
+++ b/usr.bin/tn3270/distribution/utilities/srccmd/tar/makefile
@@ -0,0 +1,8 @@
+tarread.obj: tarread.c
+ cl /c /Zd tarread.c
+
+tarread.exe: tarread.obj
+ link tarread,,tarread/map/lin;
+
+tarread.sym: tarread.map
+ mapsym /l tarread
diff --git a/usr.bin/tn3270/distribution/utilities/srccmd/tar/tar.h b/usr.bin/tn3270/distribution/utilities/srccmd/tar/tar.h
new file mode 100644
index 0000000..0345756
--- /dev/null
+++ b/usr.bin/tn3270/distribution/utilities/srccmd/tar/tar.h
@@ -0,0 +1,19 @@
+/* tar.h */
+
+#define TBLOCK 512
+#define NAMSIZ 100
+
+union hblock {
+ char dummy[TBLOCK];
+ struct header {
+ char name[NAMSIZ];
+ char mode[8];
+ char gid[8];
+ char uid[8];
+ char size[12];
+ char mtime[12];
+ char chksum[8];
+ char linkflag;
+ char linkname[NAMSIZ];
+ } dbuf;
+};
diff --git a/usr.bin/tn3270/distribution/utilities/srccmd/tar/tarread.c b/usr.bin/tn3270/distribution/utilities/srccmd/tar/tarread.c
new file mode 100644
index 0000000..fedeb69
--- /dev/null
+++ b/usr.bin/tn3270/distribution/utilities/srccmd/tar/tarread.c
@@ -0,0 +1,208 @@
+/* tarread.c */
+/* Copyright (c) 1985, by Carnegie-Mellon University */
+
+#include <stdio.h>
+#include <v2tov3.h>
+#include <sys\types.h>
+#include <sys\stat.h>
+#include "tar.h"
+
+char usage[] = "tarread: usage: tarread tx[vwz] tarfile\n";
+union hblock hbuf;
+
+int verbose = 0;
+int confirm = 0;
+int binary = 0;
+char cmd;
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ FILE *fp;
+ char *cp;
+
+ if (argc != 3) {
+ fprintf(stderr, usage);
+ exit(1);
+ }
+
+ for (cp = argv[1]; *cp; cp++)
+ switch (*cp) {
+ case 't':
+ case 'x':
+ cmd = *cp;
+ break;
+
+ case 'v':
+ verbose++;
+ break;
+ case 'z':
+ binary++;
+ break;
+ case 'w':
+ confirm++;
+ break;
+ default:
+ fprintf(stderr, "tarread: unknown switch %c\n", *cp);
+ fprintf(stderr, usage);
+ exit(1);
+ }
+
+ if ((fp = fopen(argv[2], "rb")) == NULL) {
+ fprintf(stderr, "tarrread: cannot open %s\n", argv[2]);
+ exit(1);
+ }
+
+ for (;;) {
+ if (fread(&hbuf, sizeof(hbuf), 1, fp) != 1) {
+ perror("fread");
+ exit(1);
+ }
+ if (!proc_file(fp))
+ break;
+ }
+}
+
+
+int proc_file(fp)
+FILE *fp;
+{
+ char name[NAMSIZ];
+ unsigned short mode;
+ short uid, gid;
+ long size, mtime;
+ char c;
+ int confrmd;
+ long skip;
+
+ if (hbuf.dbuf.name[0] == '\0')
+ return (NULL);
+
+ strcpy(name, hbuf.dbuf.name);
+ if (sscanf(hbuf.dbuf.mode, "%o", &mode) != 1)
+ fprintf("Couldn't read mode\n");
+ if (sscanf(hbuf.dbuf.uid, "%o", &uid) != 1)
+ fprintf("Couldn't read uid\n");
+ if (sscanf(hbuf.dbuf.gid, "%o", &gid) != 1)
+ fprintf("Couldn't read gid\n");
+ if (sscanf(hbuf.dbuf.size, "%12lo %12lo", &size, &mtime) != 2)
+ fprintf("Couldn't read size or mtime\n");
+
+ skip = (size + TBLOCK - 1) / TBLOCK * TBLOCK;
+
+ switch (cmd) {
+ case 't':
+ if (verbose)
+ printf("%8o %d/%d\t %6ld %.24s %s\n", mode,
+ uid, gid, size, ctime(&mtime), name);
+ else
+ printf("%s\n", name);
+
+ break;
+
+ case 'x':
+ if (verbose)
+ printf("x %s: ", name);
+ confrmd = 1;
+
+ if (confirm) {
+ confrmd = 0;
+ if ((c = getchar()) == 'y')
+ confrmd++;
+ while (c != '\n')
+ c = getchar();
+ if(!confrmd)
+ break;
+ }
+
+ if(extract(name, size, mode, mtime, fp))
+ skip = 0;
+
+ if (verbose)
+ printf("\n");
+ break;
+ }
+ if (fseek(fp, skip, 1)) {
+ perror("fseek");
+ exit(1);
+ }
+ return (1);
+}
+
+
+int extract(fname, size, mode, mtime, ifp)
+char *fname;
+long size;
+unsigned short mode;
+long mtime;
+FILE *ifp;
+{
+ FILE *ofp;
+ char fbuf[TBLOCK];
+ long copied, left;
+ char *s, *np, *strchr();
+ struct stat sbuf;
+
+ for(np = fname; s = strchr(np, '/'); np = s+1) {
+ *s = '\0';
+ if(stat(fname, &sbuf)) {
+ if(mkdir(fname))
+ perror("mkdir");
+ } else if(!(sbuf.st_mode & S_IFDIR)) {
+ fprintf(stderr, "\n%s: Not a directory", fname);
+ *s = '/';
+ fprintf(stderr, "\ntar: %s - cannot create", fname);
+ return (0);
+ }
+ *s = '/';
+ }
+ if(!*np)
+ return (0);
+
+ if (binary) {
+ if ((ofp = fopen(fname, "wb")) == NULL) {
+ perror("extract:");
+ return (0);
+ }
+ } else {
+ if ((ofp = fopen(fname, "w")) == NULL) {
+ perror("extract:");
+ return (0);
+ }
+ }
+
+ for(copied = 0; copied < size; copied += TBLOCK) {
+ if(fread(fbuf, TBLOCK, 1, ifp) != 1) {
+ perror("fread");
+ exit(1);
+ }
+ left = size - copied;
+ if(fwrite(fbuf, (int)min(left, TBLOCK), 1, ofp) != 1) {
+ perror("fwrite");
+ exit(1);
+ }
+ }
+
+ if(fclose(ofp)) {
+ perror("fclose");
+ exit(1);
+ }
+
+ /*
+ * Now, set modification time.
+ */
+ {
+#include <sys\utime.h>
+ struct utimbuf utim;
+
+ utim.modtime = mtime;
+
+ if (utime(fname, &utim) == -1) {
+ perror("utime");
+ exit(1);
+ }
+ }
+
+ return (1);
+}
diff --git a/usr.bin/tn3270/distribution/utilities/tncomp.h b/usr.bin/tn3270/distribution/utilities/tncomp.h
new file mode 100644
index 0000000..c726297
--- /dev/null
+++ b/usr.bin/tn3270/distribution/utilities/tncomp.h
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)tncomp.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * Where the fields fall on the formatted screen used by tncomp, tnrecv,
+ * and tnsend.
+ */
+
+#define SEND_SEQUENCE 1
+#define SEND_SEQUENCE_LENGTH 23
+
+#define ACK_SEQUENCE (SEND_SEQUENCE+SEND_SEQUENCE_LENGTH+1)
+#define ACK_SEQUENCE_LENGTH 22
+
+#define CHECKSUM (ACK_SEQUENCE+ACK_SEQUENCE_LENGTH+1)
+#define CHECKSUM_LENGTH 32
+
+#define DATA (CHECKSUM+CHECKSUM_LENGTH+1)
+#define DATA_LENGTH ((80*22)+79)
diff --git a/usr.bin/tn3270/distribution/utilities/tnrecv.c b/usr.bin/tn3270/distribution/utilities/tnrecv.c
new file mode 100644
index 0000000..4474691
--- /dev/null
+++ b/usr.bin/tn3270/distribution/utilities/tnrecv.c
@@ -0,0 +1,674 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1988, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)tnrecv.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include <stdio.h>
+
+#include <api/apilib.h>
+
+#include "tncomp.h"
+
+
+#include "../ctlr/api.h"
+#include "../ctlr/function.h"
+#include "../ctlr/hostctlr.h"
+#include "../ctlr/oia.h"
+#include "../ctlr/screen.h"
+
+#include "../api/disp_asc.h"
+#include "../api/astosc.h"
+
+#include "../general/general.h"
+
+ScreenImage Host[MAXSCREENSIZE];
+
+static char
+ a_send_sequence[SEND_SEQUENCE_LENGTH+1],
+ a_ack_sequence[ACK_SEQUENCE_LENGTH+1],
+ a_checksum[CHECKSUM_LENGTH+1],
+ data_array[DATA_LENGTH+1];
+
+static int
+ verbose,
+ blocks,
+ enter_index,
+ clear_index,
+ ScreenSize,
+ session_id;
+
+static unsigned int
+ send_sequence,
+ ack_sequence = -1,
+ checksum;
+
+api_perror(string)
+char *string;
+{
+ fprintf(stderr, "Error: [0x%x/0x%x:0x%x/0x%x] from %s.\n",
+ api_sup_fcn_id, api_sup_errno,
+ api_fcn_fcn_id, api_fcn_errno, string);
+}
+
+
+char *
+session_type(type)
+int type;
+{
+ switch (type) {
+ case TYPE_WSCTL:
+ return "work station control";
+ case TYPE_DFT:
+ return "distributed function terminal";
+ case TYPE_CUT:
+ return "control unit terminal";
+ case TYPE_NOTEPAD:
+ return "notepad";
+ case TYPE_PC:
+ return "personal computer";
+ default:
+ return "(UNKNOWN)";
+ }
+}
+
+static int
+wait_for_ps_or_oia()
+{
+#if defined(unix)
+ return api_ps_or_oia_modified();
+#endif /* defined(unix) */
+}
+
+
+static int
+wait_for_unlock()
+{
+ OIA oia;
+ ReadOiaGroupParms re;
+ static char zeroes[sizeof oia.input_inhibited] = { 0 };
+
+ do {
+ re.rc = re.function_id = 0;
+ re.session_id = session_id;
+ re.oia_buffer = (char far *) &oia;
+ re.oia_group_number = API_OIA_ALL_GROUPS;
+ if (api_read_oia_group(&re) == -1) {
+ api_perror("api_read_oia_group");
+ return -1;
+ } else if (verbose) {
+ if (IsOiaReady3274(&oia)) {
+ printf("3274 ready, ");
+ }
+ if (IsOiaMyJob(&oia)) {
+ printf("my job, ");
+ }
+ if (IsOiaInsert(&oia)) {
+ printf("insert mode, ");
+ }
+ if (IsOiaSystemLocked(&oia)) {
+ printf("system locked, ");
+ }
+ if (IsOiaTWait(&oia)) {
+ printf("terminal wait, ");
+ }
+ printf("are some bits from the OIA.\n");
+ }
+ /* We turned this on, so turn it off now */
+ ResetOiaApiInhibit(&oia);
+ if (memcmp(zeroes, oia.input_inhibited, sizeof oia.input_inhibited)) {
+ if (wait_for_ps_or_oia() == -1) {
+ return -1;
+ }
+ }
+ } while (memcmp(zeroes, oia.input_inhibited, sizeof oia.input_inhibited));
+ return 0;
+}
+
+static int
+initialize()
+{
+ QuerySessionIdParms id;
+ QuerySessionParametersParms pa;
+ QuerySessionCursorParms cu;
+ ConnectToKeyboardParms conn;
+ DisableInputParms disable;
+ NameArray namearray;
+
+ if (api_init() == 0) {
+ fprintf(stderr, "API function not available.\n");
+ return -1;
+ }
+
+ id.rc = 0;
+ id.function_id = 0;
+ id.option_code = ID_OPTION_BY_NAME;
+ id.data_code = 'E';
+ id.name_array = &namearray;
+ namearray.length = sizeof namearray;
+ if (api_query_session_id(&id)) {
+ api_perror("api_query_session_id");
+ } else if (namearray.number_matching_session == 0) {
+ fprintf(stderr, "query_session_id: No matching sessions!\n");
+ return -1;
+ } else if (verbose) {
+ printf("Session short name 0x%x, type is ",
+ namearray.name_array_element.short_name);
+ printf("%s", session_type(namearray.name_array_element.type));
+ printf(", session ID is: 0x%x\n",
+ namearray.name_array_element.session_id);
+ }
+ session_id = namearray.name_array_element.session_id;
+
+ pa.rc = pa.function_id = 0;
+ pa.session_id = session_id;
+ if (api_query_session_parameters(&pa) == -1) {
+ api_perror("api_query_session_parameters");
+ return -1;
+ } else if (verbose) {
+ printf("Session type %s, ", session_type(pa.session_type));
+ if (pa.session_characteristics&CHARACTERISTIC_EAB) {
+ printf(" has EAB, ");
+ }
+ if (pa.session_characteristics&CHARACTERISTIC_PSS) {
+ printf(" has PSS, ");
+ }
+ printf("%d rows, %d columns ", pa.rows, pa.columns);
+ if (pa.presentation_space) {
+ printf("presentation space at 0x%x:0x%x.\n",
+ FP_SEG(pa.presentation_space), FP_OFF(pa.presentation_space));
+ } else {
+ printf("(no direct presentation space access).\n");
+ }
+ }
+ ScreenSize = pa.rows*pa.columns;
+ if (pa.session_characteristics&CHARACTERISTIC_EAB) {
+ fprintf(stderr,
+ "tncomp utilities not designed to work with extended attribute buffers.\n");
+ return -1;
+ }
+
+ if (verbose) {
+ cu.rc = cu.function_id = 0;
+ cu.session_id = session_id;
+ if (api_query_session_cursor(&cu) == -1) {
+ api_perror("api_query_session_cursor");
+ } else {
+ printf("cursor");
+ if (cu.cursor_type&CURSOR_INHIBITED_AUTOSCROLL) {
+ printf(" inhibited autoscroll");
+ }
+ if (cu.cursor_type&CURSOR_INHIBITED) {
+ printf(" inhibited");
+ }
+ if (cu.cursor_type&CURSOR_BLINKING) {
+ printf(" blinking");
+ } else {
+ printf(" not blinking");
+ }
+ if (cu.cursor_type&CURSOR_BOX) {
+ printf(" box ");
+ } else {
+ printf(" not box ");
+ }
+ printf("at row %d, column %d.\n",
+ cu.row_address, cu.column_address);
+ }
+ }
+
+ conn.rc = conn.function_id = 0;
+ conn.session_id = session_id;
+ conn.event_queue_id = conn.input_queue_id = 0;
+ conn.intercept_options = 0;
+ if (api_connect_to_keyboard(&conn) == -1) {
+ api_perror("api_connect_to_keyboard");
+ } else if (verbose) {
+ if (conn.first_connection_identifier) {
+ printf("First keyboard connection.\n");
+ } else {
+ printf("Not first keyboard connection.\n");
+ }
+ }
+
+ disable.rc = disable.function_id = 0;
+ disable.session_id = session_id;
+ disable.connectors_task_id = 0;
+ if (api_disable_input(&disable) == -1) {
+ api_perror("api_disable_input");
+ return -1;
+ } else if (verbose) {
+ printf("Disabled.\n");
+ }
+
+ if ((enter_index = ascii_to_index("ENTER")) == -1) {
+ return -1;
+ }
+ if ((clear_index = ascii_to_index("CLEAR")) == -1) {
+ return -1;
+ }
+
+ return 0; /* all ok */
+}
+
+static int
+send_key(index)
+int index;
+{
+ WriteKeystrokeParms wr;
+ extern struct astosc astosc[];
+
+ wait_for_unlock();
+
+ wr.rc = wr.function_id = 0;
+ wr.session_id = session_id;
+ wr.connectors_task_id = 0;
+ wr.options = OPTION_SINGLE_KEYSTROKE;
+ wr.number_of_keys_sent = 0;
+ wr.keystroke_specifier.keystroke_entry.scancode = astosc[index].scancode;
+ wr.keystroke_specifier.keystroke_entry.shift_state
+ = astosc[index].shiftstate;
+ if (api_write_keystroke(&wr) == -1) {
+ api_perror("api_write_keystroke");
+ return -1;
+ } else if (wr.number_of_keys_sent != 1) {
+ fprintf(stderr, "write_keystroke claims to have sent %d keystrokes.\n",
+ wr.number_of_keys_sent);
+ return -1;
+ } else if (verbose) {
+ printf("Keystroke sent.\n");
+ }
+ if (wait_for_ps_or_oia() == -1) {
+ return -1;
+ }
+ return 0;
+}
+
+static int
+terminate()
+{
+ EnableInputParms enable;
+ DisconnectFromKeyboardParms disc;
+
+ enable.rc = enable.function_id = 0;
+ enable.session_id = session_id;
+ enable.connectors_task_id = 0;
+ if (api_enable_input(&enable) == -1) {
+ api_perror("api_enable");
+ return -1;
+ } else if (verbose) {
+ printf("Enabled.\n");
+ }
+
+ disc.rc = disc.function_id = 0;
+ disc.session_id = session_id;
+ disc.connectors_task_id = 0;
+ if (api_disconnect_from_keyboard(&disc) == -1) {
+ api_perror("api_disconnect_from_keyboard");
+ return -1;
+ } else if (verbose) {
+ printf("Disconnected from keyboard.\n");
+ }
+
+ (void) api_finish();
+
+ return 0;
+}
+
+
+static int
+get_screen()
+{
+ CopyStringParms copy;
+ /* Time copy services */
+
+ wait_for_unlock();
+
+ copy.copy_mode = 0;
+ copy.rc = copy.function_id = 0;
+ copy.source.session_id = session_id;
+ copy.source.buffer = 0;
+ copy.source.characteristics = 0;
+ copy.source.session_type = TYPE_DFT;
+ copy.source.begin = 0;
+
+ copy.source_end = ScreenSize;
+
+ copy.target.session_id = 0;
+ copy.target.buffer = (char *) &Host[0];
+ copy.target.characteristics = 0;
+ copy.target.session_type = TYPE_DFT;
+
+ if (api_copy_string(&copy) == -1) {
+ api_perror("api_copy_string");
+ return -1;
+ }
+ return 0;
+}
+
+
+put_at(offset, from, length, attribute)
+int offset;
+char *from;
+int length;
+{
+ CopyStringParms copy;
+
+ wait_for_unlock();
+
+ copy.copy_mode = 0;
+ copy.rc = copy.function_id = 0;
+ copy.source.session_id = 0;
+ copy.source.buffer = from;
+ copy.source.characteristics = 0;
+ copy.source.session_type = TYPE_DFT;
+ copy.source.begin = 0;
+
+ copy.source_end = length-1;
+
+ copy.target.session_id = session_id;
+ copy.target.buffer = 0;
+ copy.target.characteristics = 0;
+ copy.target.session_type = TYPE_DFT;
+ copy.target.begin = offset;
+
+ if (api_copy_string(&copy) == -1) {
+ api_perror("api_copy_string");
+ return -1;
+ }
+ return 0;
+}
+
+static void
+translate(input, output, table, length)
+char *input, *output, table[];
+int length;
+{
+ unsigned char *indices = (unsigned char *) input;
+
+ while (length--) {
+ *output++ = table[*indices++];
+ }
+}
+
+static int
+find_input_area(from)
+int from;
+{
+#define FieldDec(p) (0) /* We don't really use this */
+ register int i, attr;
+
+ for (i = from; i < MAXSCREENSIZE; ) {
+ if (IsStartField(i)) {
+ attr = FieldAttributes(i);
+ i++;
+ if (!IsProtectedAttr(i, attr)) {
+ return i;
+ }
+ } else {
+ i++;
+ }
+ }
+ return -1;
+}
+
+
+static void
+getascii(offset, to, length)
+int offset; /* Where in screen */
+char *to; /* Where it goes to */
+int length; /* Where to put it */
+{
+ translate(Host+offset, to, disp_asc, length);
+}
+
+static int
+putascii(offset, from, length, before)
+int offset; /* Where in screen */
+char *from; /* Where it comes from */
+int length; /* Where to put it */
+int before; /* How much else should go */
+{
+ translate(from, Host+offset, asc_disp, length);
+ if (put_at(offset-before,
+ (char *) Host+offset-before, length+before) == -1) {
+ return -1;
+ }
+ return 0;
+}
+
+static int
+ack()
+{
+ static char ack_blanks[sizeof a_ack_sequence] = {0};
+
+ if (ack_blanks[0] == 0) {
+ int i;
+
+ for (i = 0; i < sizeof ack_blanks; i++) {
+ ack_blanks[i] = ' ';
+ }
+ }
+
+ memcpy(a_ack_sequence, ack_blanks, sizeof a_ack_sequence);
+ sprintf(a_ack_sequence, "%d", ack_sequence);
+ a_ack_sequence[strlen(a_ack_sequence)] = ' ';
+ if (putascii(ACK_SEQUENCE, a_ack_sequence, ACK_SEQUENCE_LENGTH, 0) == -1) {
+ return -1;
+ }
+ return 0;
+}
+
+static int
+formatted_correct()
+{
+ if ((find_input_area(SEND_SEQUENCE-1) != SEND_SEQUENCE) ||
+ (find_input_area(SEND_SEQUENCE) != ACK_SEQUENCE) ||
+ (find_input_area(ACK_SEQUENCE) != CHECKSUM) ||
+ (find_input_area(CHECKSUM) != DATA)) {
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ register int i;
+ int data_length, input_length;
+ char ascii[8]; /* Lots of room */
+ FILE *outfile;
+ char *data;
+ char *argv0 = argv[0];
+
+ argc--;
+ argv++;
+ /* Process any flags */
+ while (argc && (argv[0][0] == '-')) {
+ switch (argv[0][1]) {
+ case 'v':
+ verbose = 1;
+ break;
+ case 'b':
+ blocks = 1;
+ break;
+ }
+ argc--;
+ argv++;
+ }
+
+ if ((argc) < 2) {
+ fprintf(stderr,
+ "usage: %s [-b] [-v] local.file remote.file [remote.options]\n",
+ argv0);
+ exit(1);
+ }
+
+ /* Open the local file */
+ if ((outfile = fopen(argv[0], "w")) == NULL) {
+ perror("fopen");
+ exit(2);
+ }
+ argc--;
+ argv++;
+
+ if (initialize() == -1) {
+ return -1;
+ }
+
+ /* build the command line */
+ data = data_array;
+ strcpy(data, "TNCOMP SEND");
+ data += strlen(data);
+ while (argc--) {
+ *data++ = ' ';
+ strcpy(data, argv[0]);
+ data += strlen(argv[0]);
+ argv++;
+ }
+ if (verbose) {
+ printf("%s\n", data_array);
+ }
+ if (get_screen() == -1) {
+ return -1;
+ }
+ data_length = strlen(data_array);
+ if ((i = find_input_area(0)) == -1) { /* Get an input area */
+ if (send_key(clear_index) == -1) {
+ return -1;
+ }
+ if ((i = find_input_area(0)) == -1) { /* Try again */
+ fprintf(stderr, "Unable to enter command line.\n");
+ return -1;
+ }
+ }
+ if (putascii(i, data_array, data_length, 0) == -1) {
+ return -1;
+ }
+ if (send_key(enter_index) == -1) {
+ return -1;
+ }
+ do {
+ if (get_screen() == -1) {
+ return -1;
+ }
+ } while (formatted_correct() == -1);
+
+ do {
+ if (get_screen() == -1) {
+ return -1;
+ }
+ /* For each screen */
+ if (formatted_correct() == -1) {
+ fprintf(stderr, "Bad screen written by host.\n");
+ return -1;
+ }
+ /* If MDT isn't reset in the sequence number, go around again */
+ if (Host[ACK_SEQUENCE-1]&ATTR_MDT) {
+ if (wait_for_ps_or_oia() == -1) {
+ return -1;
+ }
+ continue;
+ }
+ getascii(SEND_SEQUENCE, a_send_sequence, SEND_SEQUENCE_LENGTH);
+ send_sequence = atoi(a_send_sequence);
+ getascii(CHECKSUM, a_checksum, CHECKSUM_LENGTH);
+ checksum = atoi(a_checksum);
+ getascii(DATA, data_array, DATA_LENGTH);
+ data = data_array;
+ if (send_sequence != (ack_sequence+1)) {
+ if (ack() == -1) {
+ return -1;
+ }
+ data = "1234"; /* Keep loop from failing */
+ if (send_key(enter_index) == -1) {
+ return -1;
+ }
+ if (get_screen() == -1) {
+ return -1;
+ }
+ continue;
+ }
+
+ data_length = DATA_LENGTH;
+ while (data_length && memcmp(data, " EOF", 4)
+ && memcmp(data, " ", 4)) {
+ memcpy(ascii, data, 4);
+ data += 4;
+ data_length -= 4;
+ ascii[4] = 0;
+ input_length = atoi(ascii);
+ /* CMS can't live with zero length records */
+ if ((input_length > 1) ||
+ ((input_length == 1) && (data[0] != ' '))) {
+ if (fwrite(data, sizeof (char),
+ input_length, outfile) == 0) {
+ perror("fwrite");
+ exit(9);
+ }
+ }
+ fprintf(outfile, "\n");
+ data += input_length;
+ data_length -= input_length;
+ }
+
+ ack_sequence = send_sequence;
+ if (blocks) {
+ printf("#");
+ fflush(stdout);
+ }
+ if (ack() == -1) {
+ return -1;
+ }
+ if (send_key(enter_index) == -1) {
+ return -1;
+ }
+ } while (memcmp(data, " EOF", 4));
+
+ if (blocks) {
+ printf("\n");
+ }
+ if (terminate() == -1) {
+ return -1;
+ }
+ return 0;
+}
diff --git a/usr.bin/tn3270/general/genbsubs.c b/usr.bin/tn3270/general/genbsubs.c
new file mode 100644
index 0000000..b5377a6
--- /dev/null
+++ b/usr.bin/tn3270/general/genbsubs.c
@@ -0,0 +1,125 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)genbsubs.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+/* The output of bunequal is the offset of the byte which didn't match;
+ * if all the bytes match, then we return n.
+ * bunequal(s1, s2, n) */
+
+int
+bunequal(s1, s2, n)
+register char *s1, *s2;
+register n;
+{
+ register int i = 0;
+
+ while (i++ < n) {
+ if (*s1++ != *s2++) {
+ break;
+ }
+ }
+ return(i-1);
+}
+
+/* bskip(s1, n, b) : finds the first occurrence of any byte != 'b' in the 'n'
+ * bytes beginning at 's1'.
+ */
+
+int
+bskip(s1, n, b)
+register char *s1;
+register int n;
+register int b;
+{
+ register int i = 0;
+
+ while (i++ < n) {
+ if (*s1++ != b) {
+ break;
+ }
+ }
+ return(i-1);
+}
+
+/*
+ * memNSchr(const void *s, int c, size_t n, int and)
+ *
+ * Like memchr, but the comparison is '((*s)&and) == c',
+ * and we increment our way through s by "stride" ('s += stride').
+ *
+ * We optimize for the most used strides of +1 and -1.
+ */
+
+unsigned char *
+memNSchr(s, c, n, and, stride)
+char *s;
+int c;
+unsigned int n;
+int and;
+int stride;
+{
+ register unsigned char _c, *_s, _and;
+
+ _and = and;
+ _c = (c&_and);
+ _s = (unsigned char *)s;
+ switch (stride) {
+ case 1:
+ while (n--) {
+ if (((*_s)&_and) == _c) {
+ return _s;
+ }
+ _s++;
+ }
+ break;
+ case -1:
+ while (n--) {
+ if (((*_s)&_and) == _c) {
+ return _s;
+ }
+ _s--;
+ }
+ break;
+ default:
+ while (n--) {
+ if (((*_s)&_and) == _c) {
+ return _s;
+ }
+ _s += stride;
+ }
+ }
+ return 0;
+}
diff --git a/usr.bin/tn3270/general/general.h b/usr.bin/tn3270/general/general.h
new file mode 100644
index 0000000..8fee245
--- /dev/null
+++ b/usr.bin/tn3270/general/general.h
@@ -0,0 +1,65 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)general.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * Some general definitions.
+ */
+
+#define numberof(x) (sizeof x/sizeof x[0])
+#define highestof(x) (numberof(x)-1)
+
+#if defined(unix)
+#define ClearElement(x) bzero((char *)&x, sizeof x)
+#define ClearArray(x) bzero((char *)x, sizeof x)
+#else /* defined(unix) */
+#define ClearElement(x) memset((char *)&x, 0, sizeof x)
+#define ClearArray(x) memset((char *)x, 0, sizeof x)
+#endif /* defined(unix) */
+
+#if defined(unix) /* Define BSD equivalent mem* functions */
+#define memcpy(dest,src,n) bcopy(src,dest,n)
+#define memmove(dest,src,n) bcopy(src,dest,n)
+#define memset(s,c,n) if (c == 0) { \
+ bzero(s,n); \
+ } else { \
+ register char *src = s; \
+ register int count = n; \
+ \
+ while (count--) { \
+ *src++ = c; \
+ } \
+ }
+#define memcmp(s1,s2,n) bcmp(s1,s2,n)
+#endif /* defined(unix) */
diff --git a/usr.bin/tn3270/general/globals.c b/usr.bin/tn3270/general/globals.c
new file mode 100644
index 0000000..11e565f
--- /dev/null
+++ b/usr.bin/tn3270/general/globals.c
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)globals.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+/*
+ * Do the defining instances for the globals of tn3270.
+ */
+
+#include "../ctlr/hostctlr.h"
+#include "../ctlr/oia.h"
+#include "../ctlr/options.h"
+#include "../ctlr/screen.h"
+
+
+#define DEFINING_INSTANCES
+
+#include "globals.h"
+
+#include "../general/general.h"
+
+/*
+ * init_system()
+ *
+ * Initialize the global values in case of a restart.
+ */
+
+void
+init_system()
+{
+ OptHome = OptLeftMargin = OptAPLmode = OptNullProcessing = 0;
+ OptZonesMode = OptEnterNL = OptColFieldTab = OptPacing = 0;
+ OptAlphaInNumeric = OptHome = OptLeftMargin = OptWordWrap = 0;
+
+ ClearArray(Host);
+ CursorAddress = BufferAddress = 0;
+
+ Lowest = Highest = 0;
+
+ UnLocked = AidByte = 0;
+
+}
diff --git a/usr.bin/tn3270/general/globals.h b/usr.bin/tn3270/general/globals.h
new file mode 100644
index 0000000..4fb365c
--- /dev/null
+++ b/usr.bin/tn3270/general/globals.h
@@ -0,0 +1,130 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)globals.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * This file contains all the globals used by tn3270.
+ *
+ * Since various files may want to reference this file,
+ * and since they may only want subsets of the globals,
+ * we assume they have #include'd all the other .h files
+ * first, and we only give those globals relevant to
+ * the #include'd .h files.
+ *
+ */
+
+#if defined(DEFINING_INSTANCES)
+#define EXTERN
+#else
+#define EXTERN extern
+#endif
+
+
+EXTERN int
+ /*
+ * shell_active ==>
+ * 1. Don't do input.
+ * 2. Don't do output.
+ * 3. Don't block in select.
+ * 4. When nothing to do, call shell_continue()
+ */
+ shell_active;
+
+
+#if defined(INCLUDED_OPTIONS)
+EXTERN int OptHome; /* where home should send us */
+
+EXTERN int OptLeftMargin; /* where new line should send us */
+
+EXTERN char OptColTabs[80]; /* local tab stops */
+
+EXTERN int OptAPLmode;
+
+EXTERN int OptNullProcessing; /* improved null processing */
+
+EXTERN int OptZonesMode; /* zones mode off */
+
+EXTERN int OptEnterNL; /* regular enter/new line keys */
+
+EXTERN int OptColFieldTab; /* regular column/field tab keys */
+
+EXTERN int OptPacing; /* do pacing */
+
+EXTERN int OptAlphaInNumeric; /* allow alpha in numeric fields */
+
+EXTERN int OptHome;
+
+EXTERN int OptLeftMargin;
+
+EXTERN int OptWordWrap;
+#endif
+
+#if defined(INCLUDED_SCREEN)
+EXTERN ScreenImage
+ Host[MAXSCREENSIZE]; /* host view of screen */
+
+EXTERN char Orders[256]; /* Non-zero for orders */
+
+ /* Run-time screen geometry */
+EXTERN int
+ MaxNumberLines, /* How many rows the 3270 COULD have */
+ MaxNumberColumns, /* How many columns the 3270 COULD have */
+ NumberLines, /* How many lines the 3270 screen contains */
+ NumberColumns, /* How many columns the 3270 screen contains */
+ ScreenSize;
+
+EXTERN int CursorAddress; /* where cursor is */
+EXTERN int BufferAddress; /* where writes are going */
+
+EXTERN int Lowest, Highest;
+
+extern char CIABuffer[];
+
+EXTERN int UnLocked; /* is the keyboard unlocked */
+EXTERN int AidByte;
+
+#endif
+
+#if defined(INCLUDED_STATE)
+#endif
+
+#if defined(INCLUDED_OIA)
+
+EXTERN OIA OperatorInformationArea;
+
+EXTERN int
+ oia_modified, /* Has the oia been modified */
+ ps_modified; /* Has the presentation space been modified */
+
+#endif /* defined(INCLUDED_OIA) */
diff --git a/usr.bin/tn3270/general/vaxbsubs.s b/usr.bin/tn3270/general/vaxbsubs.s
new file mode 100644
index 0000000..096f532
--- /dev/null
+++ b/usr.bin/tn3270/general/vaxbsubs.s
@@ -0,0 +1,101 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)vaxbsubs.s 8.1 (Berkeley) 6/6/93
+ */
+
+/* This is taken from bcmp.s from 4.2.
+ * The output of bunequal is the offset of the byte which didn't match;
+ * if all the bytes match, then we return n.
+ *
+ * BUGNOTE: This has no chance of working for lengths greater than 64K.
+ * (so, if you use this somewhere else, you may need to
+ * fix it...)
+ */
+
+/* bunequal(s1, s2, n) */
+
+#include "defs.h"
+
+ENTRY(bunequal)
+ movl 4(ap),r1
+ movl 8(ap),r3
+ movl 12(ap),r4
+1:
+ movzwl $65535,r0
+ cmpl r4,r0
+ jleq 2f
+ subl2 r0,r4
+ cmpc3 r0,(r1),(r3)
+ jeql 1b
+ addl2 r4,r0
+ /* changes... */
+ subl3 r0,12(ap),r0
+ /* end of changes for bunequal... */
+ ret
+2:
+ cmpc3 r4,(r1),(r3)
+ /* changes... */
+ subl3 r0,12(ap),r0
+ /* end of changes for bunequal... */
+ ret
+
+
+
+
+/* brand new code, using the above as base... */
+/* bskip(s1, n, b) : finds the first occurrence of any byte != 'b' in the 'n'
+ * bytes beginning at 's1'.
+ *
+ * BUGNOTE: This has no chance of working for lengths greater than 64K.
+ * (so, if you use this somewhere else, you may need to
+ * fix it...)
+ */
+
+ENTRY(bskip)
+ movl 4(ap),r1
+ movl 8(ap),r3
+ movl 12(ap),r4
+1:
+ movzwl $65535,r0
+ cmpl r3,r0
+ jleq 2f
+ subl2 r0,r3
+ skpc r4,r0,(r1)
+ jeql 1b
+ addl2 r3,r0
+ subl3 r0,8(ap),r0
+ ret
+2:
+ skpc r4,r3,(r1)
+ subl3 r0,8(ap),r0
+ ret
diff --git a/usr.bin/tn3270/mset/Makefile b/usr.bin/tn3270/mset/Makefile
new file mode 100644
index 0000000..0094fc8
--- /dev/null
+++ b/usr.bin/tn3270/mset/Makefile
@@ -0,0 +1,34 @@
+# @(#)Makefile 8.1 (Berkeley) 6/6/93
+
+PROG= mset
+CFLAGS+=-I${.CURDIR} -I.
+SRCS+= astosc.c map3270.c mset.c
+MAN1= mset.0
+MAN5= map3270.0
+.PATH: ${.CURDIR}/../api ${.CURDIR}/../ascii
+
+CLEANFILES+= astosc.OUT astosc.out
+
+# This and the dependency hacks below to make 'depend' target
+# work right...
+
+DEPSRCS+= astosc.OUT map3270.c mset.c
+
+astosc.o: astosc.OUT
+astosc.OUT: ${.CURDIR}/../ctlr/hostctlr.h ${.CURDIR}/../ctlr/function.h
+astosc.OUT: ${.CURDIR}/../ctlr/${KBD} ${.CURDIR}/../tools/mkastosc/obj/mkastosc
+ ${.CURDIR}/../tools/mkastosc/obj/mkastosc \
+ ${.CURDIR}/../ctlr/hostctlr.h ${.CURDIR}/../ctlr/function.h \
+ < ${.CURDIR}/../ctlr/${KBD} > ${.TARGET}
+ rm -f astosc.out; ln -s astosc.OUT astosc.out
+
+# astosc.out
+${.CURDIR}/../tools/mkastosc/obj/mkastosc:
+ cd ${.CURDIR}/../tools/mkastosc; make
+
+depend: .depend
+.depend:${DEPSRCS}
+ mkdep ${MKDEP} ${CFLAGS:M-[ID]*} ${.ALLSRC:M*.c}
+
+.include <../../Makefile.inc>
+.include <bsd.prog.mk>
diff --git a/usr.bin/tn3270/mset/map3270.5 b/usr.bin/tn3270/mset/map3270.5
new file mode 100644
index 0000000..3904f3a
--- /dev/null
+++ b/usr.bin/tn3270/mset/map3270.5
@@ -0,0 +1,341 @@
+.\" Copyright (c) 1986, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)map3270.5 8.3 (Berkeley) 4/19/94
+.\"
+.TH MAP3270 5 "April 19, 1994"
+.UC 6
+.SH NAME
+map3270 \- database for mapping ascii keystrokes into IBM 3270 keys
+.SH SYNOPSIS
+.B map3270
+.SH DESCRIPTION
+When emulating IBM-style 3270 terminals under \s-1UNIX\s0 (see \fItn3270\fR(1)),
+a mapping must be performed between sequences of keys hit on
+a user's (ascii) keyboard, and the keys that are
+available on a 3270. For example, a 3270 has a key labeled
+.B EEOF
+which erases the contents of the current field from the
+location of the cursor to the end.
+In order to accomplish this function,
+the terminal user and a program emulating a 3270 must
+agree on what keys will be typed
+to invoke the
+.B EEOF
+function.
+.PP
+The requirements for these sequences are:
+.nf
+.ta 4n 9n
+.sp
+ 1) that the first character of the sequence be outside of the
+ standard ascii printable characters;
+.sp
+ 2) that no sequence \fIbe\fR an initial part of another (although
+ sequences may \fIshare\fR initial parts).
+.sp
+.fi
+.SH FORMAT
+The file consists of entries for various keyboards. The first part
+of an entry lists the names of the keyboards which use that entry.
+These names will often be the same as in
+.I /etc/termcap
+(see
+.IR termcap (5));
+however, note that often the terminals from various termcap entries will all
+use the same
+.I map3270
+entry; for example, both 925 and 925vb (for
+925 with visual bells) would probably use the same
+.I map3270
+entry.
+Additionally, there are occasions when the terminal type defines
+a window manager, and it will then be necessary to specify a
+keyboard name (via the
+.B KEYBD
+environment variable) as the name of the entry.
+After the names, separated by vertical bars (`|'), comes a left
+brace (`{'); the definitions; and, finally, a right brace
+(`}').
+.PP
+Each definition consists of a reserved keyword (see list below) which
+identifies the 3270 function (extended as defined below), followed
+by an equal sign (`='), followed by the various ways to generate
+this particular function, followed by a semi-colon (`;').
+Each way is a sequence of strings of
+.I printable
+ascii characters enclosed inside single quotes (`\(aa');
+various ways (alternatives) are separated by vertical bars (`|').
+.PP
+Inside the single quotes, a few characters are special.
+A caret
+(`^') specifies that the next character is
+the ``control'' character of whatever the character is.
+So, `^a'
+represents control-a, ie: hexadecimal 1
+(note that `^A' would generate the same code).
+To generate
+.B rubout
+(DEL),
+one enters `^?'.
+To represent a control character inside a file
+requires using the caret to represent a control sequence;
+simply typing control-A will not work.
+Note: the ctrl-caret sequence
+(to generate a hexadecimal 1E)
+is represented as `^^' (not `^\e^').
+.PP
+In addition to the caret, a letter may be preceded by a backslash (`\e').
+Since this has little effect for most characters,
+its use is usually not recommended.
+For the case of a single quote (`\(aa'), the backslash
+prevents that single quote from terminating the string.
+For the case of a caret (`^'), the backslash prevents
+the caret from having its special meaning.
+To have the backslash be part of the string, it is necessary to
+place two backslashes ('\e\e') in the file.
+.PP
+In addition, the following characters are special:
+.sp
+.nf
+.in +0.5i
+`\eE' means an escape character;
+`\en' means newline;
+`\et' means tab;
+`\er' means carriage return.
+.in -0.5i
+.fi
+.sp
+It is not necessary for each character in a string
+to be enclosed within single quotes.
+`\eE\eE\eE' means three escape characters.
+.PP
+Comments, which may appear anywhere on a line,
+begin with a hash mark (`#'), and terminate
+at the end of that line.
+However, comments cannot begin inside a quoted string;
+a hash mark inside a quoted string has no special meaning.
+.PP
+.SH 3270 KEYS SUPPORTED
+The following is the list of 3270 key names that are supported in this file.
+Note that some of the keys don't really exist on a 3270.
+In particular, the developers of this file have relied
+extensively on the work at the Yale University Computer Center with
+their 3270 emulator which runs in an IBM Series/1 front end.
+The following list corresponds closely to the functions
+that the developers of the Yale code offer in their product.
+.sp
+.B In the following list, the
+.B starred ("*")
+.B functions are not supported by
+.IR tn3270 (1).
+An unsupported function will cause
+.IR tn3270(1)
+to send a (possibly visual) bell sequence to the user's terminal.
+.sp
+.nf
+ 3270 Key Name Functional description
+
+ (*)LPRT local print
+ DP dup character
+ FM field mark character
+ CURSEL cursor select
+ CENTSIGN EBCDIC cent sign
+ RESHOW redisplay the screen
+ EINP erase input
+ EEOF erase end of field
+ DELETE delete character
+ INSRT toggle insert mode
+ TAB field tab
+ BTAB field back tab
+ COLTAB column tab
+ COLBAK column back tab
+ INDENT indent one tab stop
+ UNDENT undent one tab stop
+ NL new line
+ HOME home the cursor
+ UP up cursor
+ DOWN down cursor
+ RIGHT right cursor
+ LEFT left cursor
+ SETTAB set a column tab
+ DELTAB delete a columntab
+ SETMRG set left margin
+ SETHOM set home position
+ CLRTAB clear all column tabs
+ (*)APLON apl on
+ (*)APLOFF apl off
+ (*)APLEND treat input as ascii
+ (*)PCON xon/xoff on
+ (*)PCOFF xon/xoff off
+ DISC disconnect (suspend)
+ (*)INIT new terminal type
+ (*)ALTK alternate keyboard dvorak
+ FLINP flush input
+ ERASE erase last character
+ WERASE erase last word
+ FERASE erase field
+ SYNCH we are in synch with the user
+ RESET reset key-unlock keyboard
+ MASTER_RESET reset, unlock and redisplay
+ (*)XOFF please hold output
+ (*)XON please give me output
+ ESCAPE enter telnet command mode
+ WORDTAB tab to beginning of next word
+ WORDBACKTAB tab to beginning of current/last word
+ WORDEND tab to end of current/next word
+ FIELDEND tab to last non-blank of current/next
+ unprotected (writable) field.
+
+ PA1 program attention 1
+ PA2 program attention 2
+ PA3 program attention 3
+
+ CLEAR local clear of the 3270 screen
+ TREQ test request
+ ENTER enter key
+
+ PFK1 program function key 1
+ PFK2 program function key 2
+ etc. etc.
+ PFK36 program function key 36
+.SH A SAMPLE ENTRY
+The following entry is used by
+tn3270(1) when unable to locate a reasonable version in the
+user's environment and in /etc/map3270:
+.sp
+.nf
+ name { # actual name comes from TERM variable
+ clear = '^z';
+ flinp = '^x';
+ enter = '^m';
+ delete = '^d' | '^?'; # note that '^?' is delete (rubout)
+ synch = '^r';
+ reshow = '^v';
+ eeof = '^e';
+ tab = '^i';
+ btab = '^b';
+ nl = '^n';
+ left = '^h';
+ right = '^l';
+ up = '^k';
+ down = '^j';
+ einp = '^w';
+ reset = '^t';
+ xoff = '^s';
+ xon = '^q';
+ escape = '^c';
+ ferase = '^u';
+ insrt = '\E ';
+ # program attention keys
+ pa1 = '^p1'; pa2 = '^p2'; pa3 = '^p3';
+ # program function keys
+ pfk1 = '\eE1'; pfk2 = '\eE2'; pfk3 = '\eE3'; pfk4 = '\eE4';
+ pfk5 = '\eE5'; pfk6 = '\eE6'; pfk7 = '\eE7'; pfk8 = '\eE8';
+ pfk9 = '\eE9'; pfk10 = '\eE0'; pfk11 = '\eE-'; pfk12 = '\eE=';
+ pfk13 = '\eE!'; pfk14 = '\eE@'; pfk15 = '\eE#'; pfk16 = '\eE$';
+ pfk17 = '\eE%'; pfk18 = '\eE'; pfk19 = '\eE&'; pfk20 = '\eE*';
+ pfk21 = '\eE('; pfk22 = '\eE)'; pfk23 = '\eE_'; pfk24 = '\eE+';
+ }
+.fi
+.SH "IBM 3270 KEY DEFINITONS FOR AN ABOVE DEFINITION"
+The charts below show the proper keys to emulate
+each 3270 function when using the default key mapping supplied
+with
+.IR tn3270 (1)
+and
+.IR mset (1).
+.sp
+.nf
+ Command Keys IBM 3270 Key Default Key(s)
+ Enter RETURN
+ Clear control-z
+ Cursor Movement Keys
+ New Line control-n or
+ Home
+ Tab control-i
+ Back Tab control-b
+ Cursor Left control-h
+ Cursor Right control-l
+ Cursor Up control-k
+ Cursor Down control-j or
+ LINE FEED
+ Edit Control Keys
+ Delete Char control-d or
+ RUB
+ Erase EOF control-e
+ Erase Input control-w
+ Insert Mode ESC Space
+ End Insert ESC Space
+ Program Function Keys
+ PF1 ESC 1
+ PF2 ESC 2
+ ... ...
+ PF10 ESC 0
+ PF11 ESC -
+ PF12 ESC =
+ PF13 ESC !
+ PF14 ESC @
+ ... ...
+ PF24 ESC +
+ Program Attention Keys
+ PA1 control-p 1
+ PA2 control-p 2
+ PA3 control-p 3
+ Local Control Keys
+ Reset After Error control-r
+ Purge Input Buffer control-x
+ Keyboard Unlock control-t
+ Redisplay Screen control-v
+ Other Keys
+ Erase current field control-u
+.fi
+.SH FILES
+/etc/map3270
+.SH SEE ALSO
+tn3270(1), mset(1), \fIYale ASCII Terminal Communication
+System II Program Description/Operator's Manual\fR
+(IBM SB30-1911)
+.SH AUTHOR
+Greg Minshall
+.SH BUGS
+.I Tn3270
+doesn't yet understand how to process all the functions
+available in
+.I map3270;
+when such a function is requested
+.I tn3270
+will beep at you.
+.PP
+The definition of "word" (for "word erase", "word tab") should be a run-time
+option. Currently it is defined as the kernel tty driver defines it (strings
+of non-whitespace); more than one person would rather use the "vi" definition
+(strings of specials, strings of alphanumeric).
diff --git a/usr.bin/tn3270/mset/mset.1 b/usr.bin/tn3270/mset/mset.1
new file mode 100644
index 0000000..a806eaa
--- /dev/null
+++ b/usr.bin/tn3270/mset/mset.1
@@ -0,0 +1,188 @@
+.\" Copyright (c) 1986, 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)mset.1 8.1 (Berkeley) 6/6/93
+.\"
+.Dd June 6, 1993
+.Dt MSET 1
+.Os BSD 4.3
+.Sh NAME
+.Nm mset
+.Nd retrieve
+.Tn ASCII
+to
+.Tn IBM
+3270 keyboard map
+.Sh SYNOPSIS
+.Nm mset
+.Op Fl picky
+.Op Fl shell
+.Op Ar keyboardname
+.Sh DESCRIPTION
+.Nm Mset
+retrieves mapping information
+for the
+.Tn ASCII
+keyboard to
+.Tn IBM
+3270 terminal
+special functions.
+Normally, these mappings are found
+in
+.Pa /usr/share/misc/map3270
+(see
+.Xr map3270 5 ) .
+This information is used by the
+.Xr tn3270
+command (see
+.Xr tn3270 1 ) .
+.Pp
+The default
+.Nm mset
+output can be used to store the mapping information in the process environment
+in order to avoid scanning
+.Nm map3270
+each time
+.Nm tn3270
+is invoked.
+To do this, place the following command in your
+.Pa .login
+file:
+.Bd -literal -offset indent
+set noglob; setenv MAP3270 "\(gamset\(ga"; unset noglob
+.Ed
+.Pp
+If the
+.Ar keyboardname
+argument is not supplied,
+.Nm mset
+attempts to determine the name of the keyboard the user is using,
+by checking the
+.Ev KEYBD
+environment variable.
+If the
+.Ev KEYBD
+environment variable is not set, then
+.Nm mset
+uses the user's terminal type from the environment variable
+.Ev TERM
+as the keyboard name.
+Normally,
+.Nm mset
+then uses the file
+.Xr map3270 5
+to find the keyboard mapping for that terminal.
+However, if the environment variable
+.Ev MAP3270
+exists and contains the entry for the specified keyboard, then that
+definition is used.
+If the value of
+.Ev MAP3270
+begins with a slash (`/') then it is assumed to be the full pathname
+of an alternate mapping file and that file is searched first.
+In any case, if the mapping for the keyboard is not found in
+the environment, nor in an alternate map file, nor in the standard map file,
+then the same search is performed for an entry for a keyboard with the name
+.Ar unknown .
+If that search also fails,
+then a default mapping
+is used.
+.Pp
+The arguments to
+.Nm mset
+are:
+.Pp
+.Bl -tag -width Fl
+.It Fl picky
+When processing the various
+.Pa map3270
+entries (for the user's keyboard,
+and all those encountered before the one for the user's keyboard),
+.Nm mset
+normally will not complain about entries for unknown functions (like
+.Dq PFX1 ;
+the
+.Fl picky
+argument causes
+.Nm mset
+to issue warning messages about these unknown entries.
+.It Fl shell
+If the
+.Pa map3270
+entry is longer than the shell's 1024 environmental variable
+length limit, the default
+.Nm mset
+output cannot be used to store the mapping information in the process
+environment to avoid scanning
+.Pa map3270
+each time
+.Nm tn3270
+is invoked.
+The
+.Fl shell
+argument causes
+.Nm mset
+to generate shell commands to set the environmental variables
+.Ev MAP3270 ,
+.Ev MAP3270A ,
+and so on, breaking up the entry to fit within the shell environmental
+variable length limit.
+To set these variables, place the following command in your
+.Pa .login
+file:
+.Bd -literal -offset indent
+mset -shell > tmp ; source tmp ; /bin/rm tmp
+.Ed
+.It Ar keyboardname
+When searching for the
+.Pa map3270
+entry that matches the user's keyboard,
+.Nm mset
+will use
+.Ar keyboardname
+instead of determining the keyboard name from the
+.Ev KEYBD
+or
+.Ev TERM
+environmental variables.
+.Sh FILES
+.Bl -tag -width /usr/share/misc/map3270 -compact
+.It Pa /usr/share/misc/map3270
+keyboard mapping for known keyboards
+.El
+.Sh SEE ALSO
+.Xr tn3270 1 ,
+.Xr map3270 5
+.Sh HISTORY
+The
+.Nm mset
+command appeared in
+.Bx 4.3 .
diff --git a/usr.bin/tn3270/sys_curses/system.c b/usr.bin/tn3270/sys_curses/system.c
new file mode 100644
index 0000000..14a99bd
--- /dev/null
+++ b/usr.bin/tn3270/sys_curses/system.c
@@ -0,0 +1,753 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)system.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include <sys/types.h>
+
+#if defined(pyr)
+#define fd_set fdset_t
+#endif /* defined(pyr) */
+
+/*
+ * Wouldn't it be nice if these REALLY were in <sys/inode.h>? Or,
+ * equivalently, if <sys/inode.h> REALLY existed?
+ */
+#define IREAD 00400
+#define IWRITE 00200
+
+#include <sys/file.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/wait.h>
+
+#include <errno.h>
+extern int errno;
+
+#include <netdb.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <pwd.h>
+
+#include "../general/general.h"
+#include "../ctlr/api.h"
+#include "../api/api_exch.h"
+
+#include "../general/globals.h"
+
+#ifndef FD_SETSIZE
+/*
+ * The following is defined just in case someone should want to run
+ * this telnet on a 4.2 system.
+ *
+ */
+
+#define FD_SET(n, p) ((p)->fds_bits[0] |= (1<<(n)))
+#define FD_CLR(n, p) ((p)->fds_bits[0] &= ~(1<<(n)))
+#define FD_ISSET(n, p) ((p)->fds_bits[0] & (1<<(n)))
+#define FD_ZERO(p) ((p)->fds_bits[0] = 0)
+
+#endif
+
+static int shell_pid = 0;
+static char key[50]; /* Actual key */
+static char *keyname; /* Name of file with key in it */
+
+static char *ourENVlist[200]; /* Lots of room */
+
+static int
+ sock = -1, /* Connected socket */
+ serversock; /* Server (listening) socket */
+
+static enum { DEAD, UNCONNECTED, CONNECTED } state;
+
+static long
+ storage_location; /* Address we have */
+static short
+ storage_length = 0; /* Length we have */
+static int
+ storage_must_send = 0, /* Storage belongs on other side of wire */
+ storage_accessed = 0; /* The storage is accessed (so leave alone)! */
+
+static long storage[1000];
+
+static union REGS inputRegs;
+static struct SREGS inputSregs;
+
+extern int apitrace;
+
+static void
+kill_connection()
+{
+ state = UNCONNECTED;
+ if (sock != -1) {
+ (void) close(sock);
+ sock = -1;
+ }
+}
+
+
+static int
+nextstore()
+{
+ struct storage_descriptor sd;
+
+ if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
+ storage_length = 0;
+ return -1;
+ }
+ storage_length = sd.length;
+ storage_location = sd.location;
+ if (storage_length > sizeof storage) {
+ fprintf(stderr, "API client tried to send too much storage (%d).\n",
+ storage_length);
+ storage_length = 0;
+ return -1;
+ }
+ if (api_exch_intype(EXCH_TYPE_BYTES, storage_length, (char *)storage)
+ == -1) {
+ storage_length = 0;
+ return -1;
+ }
+ return 0;
+}
+
+
+static int
+doreject(message)
+char *message;
+{
+ struct storage_descriptor sd;
+ int length = strlen(message);
+
+ if (api_exch_outcommand(EXCH_CMD_REJECTED) == -1) {
+ return -1;
+ }
+ sd.length = length;
+ if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
+ return -1;
+ }
+ if (api_exch_outtype(EXCH_TYPE_BYTES, length, message) == -1) {
+ return -1;
+ }
+ return 0;
+}
+
+
+/*
+ * doassociate()
+ *
+ * Negotiate with the other side and try to do something.
+ *
+ * Returns:
+ *
+ * -1: Error in processing
+ * 0: Invalid password entered
+ * 1: Association OK
+ */
+
+static int
+doassociate()
+{
+ struct passwd *pwent;
+ char
+ promptbuf[100],
+ buffer[200];
+ struct storage_descriptor sd;
+ extern char *crypt();
+
+ if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
+ return -1;
+ }
+ sd.length = sd.length;
+ if (sd.length > sizeof buffer) {
+ doreject("(internal error) Authentication key too long");
+ return -1;
+ }
+ if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
+ return -1;
+ }
+ buffer[sd.length] = 0;
+
+ if (strcmp(buffer, key) != 0) {
+#if (!defined(sun)) || defined(BSD) && (BSD >= 43)
+ extern uid_t geteuid();
+#endif /* (!defined(sun)) || defined(BSD) && (BSD >= 43) */
+
+ if ((pwent = getpwuid((int)geteuid())) == 0) {
+ return -1;
+ }
+ sprintf(promptbuf, "Enter password for user %s:", pwent->pw_name);
+ if (api_exch_outcommand(EXCH_CMD_SEND_AUTH) == -1) {
+ return -1;
+ }
+ sd.length = strlen(promptbuf);
+ if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
+ == -1) {
+ return -1;
+ }
+ if (api_exch_outtype(EXCH_TYPE_BYTES, strlen(promptbuf), promptbuf)
+ == -1) {
+ return -1;
+ }
+ sd.length = strlen(pwent->pw_name);
+ if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
+ == -1) {
+ return -1;
+ }
+ if (api_exch_outtype(EXCH_TYPE_BYTES,
+ strlen(pwent->pw_name), pwent->pw_name) == -1) {
+ return -1;
+ }
+ if (api_exch_incommand(EXCH_CMD_AUTH) == -1) {
+ return -1;
+ }
+ if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
+ == -1) {
+ return -1;
+ }
+ sd.length = sd.length;
+ if (sd.length > sizeof buffer) {
+ doreject("Password entered was too long");
+ return -1;
+ }
+ if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
+ return -1;
+ }
+ buffer[sd.length] = 0;
+
+ /* Is this the correct password? */
+ if (strlen(pwent->pw_name)) {
+ char *ptr;
+ int i;
+
+ ptr = pwent->pw_name;
+ i = 0;
+ while (i < sd.length) {
+ buffer[i++] ^= *ptr++;
+ if (*ptr == 0) {
+ ptr = pwent->pw_name;
+ }
+ }
+ }
+ if (strcmp(crypt(buffer, pwent->pw_passwd), pwent->pw_passwd) != 0) {
+ doreject("Invalid password");
+ sleep(10); /* Don't let us do too many of these */
+ return 0;
+ }
+ }
+ if (api_exch_outcommand(EXCH_CMD_ASSOCIATED) == -1) {
+ return -1;
+ } else {
+ return 1;
+ }
+}
+
+
+void
+freestorage()
+{
+ struct storage_descriptor sd;
+
+ if (storage_accessed) {
+ fprintf(stderr, "Internal error - attempt to free accessed storage.\n");
+ fprintf(stderr, "(Encountered in file %s at line %d.)\n",
+ __FILE__, __LINE__);
+ quit();
+ }
+ if (storage_must_send == 0) {
+ return;
+ }
+ storage_must_send = 0;
+ if (api_exch_outcommand(EXCH_CMD_HEREIS) == -1) {
+ kill_connection();
+ return;
+ }
+ sd.length = storage_length;
+ sd.location = storage_location;
+ if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
+ kill_connection();
+ return;
+ }
+ if (api_exch_outtype(EXCH_TYPE_BYTES, storage_length, (char *)storage)
+ == -1) {
+ kill_connection();
+ return;
+ }
+}
+
+
+static int
+getstorage(address, length, copyin)
+long
+ address;
+int
+ length,
+ copyin;
+{
+ struct storage_descriptor sd;
+
+ freestorage();
+ if (storage_accessed) {
+ fprintf(stderr,
+ "Internal error - attempt to get while storage accessed.\n");
+ fprintf(stderr, "(Encountered in file %s at line %d.)\n",
+ __FILE__, __LINE__);
+ quit();
+ }
+ storage_must_send = 0;
+ if (api_exch_outcommand(EXCH_CMD_GIMME) == -1) {
+ kill_connection();
+ return -1;
+ }
+ storage_location = address;
+ storage_length = length;
+ if (copyin) {
+ sd.location = (long)storage_location;
+ sd.length = storage_length;
+ if (api_exch_outtype(EXCH_TYPE_STORE_DESC,
+ sizeof sd, (char *)&sd) == -1) {
+ kill_connection();
+ return -1;
+ }
+ if (api_exch_incommand(EXCH_CMD_HEREIS) == -1) {
+ fprintf(stderr, "Bad data from other side.\n");
+ fprintf(stderr, "(Encountered at %s, %d.)\n", __FILE__, __LINE__);
+ return -1;
+ }
+ if (nextstore() == -1) {
+ kill_connection();
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/*ARGSUSED*/
+void
+movetous(local, es, di, length)
+char
+ *local;
+unsigned int
+ es,
+ di;
+int
+ length;
+{
+ long where = SEG_OFF_BACK(es, di);
+
+ if (length > sizeof storage) {
+ fprintf(stderr, "Internal API error - movetous() length too long.\n");
+ fprintf(stderr, "(detected in file %s, line %d)\n", __FILE__, __LINE__);
+ quit();
+ } else if (length == 0) {
+ return;
+ }
+ getstorage(where, length, 1);
+ memcpy(local, (char *)(storage+((where-storage_location))), length);
+ if (apitrace) {
+ Dump('(', local, length);
+ }
+}
+
+/*ARGSUSED*/
+void
+movetothem(es, di, local, length)
+unsigned int
+ es,
+ di;
+char
+ *local;
+int
+ length;
+{
+ long where = SEG_OFF_BACK(es, di);
+
+ if (length > sizeof storage) {
+ fprintf(stderr, "Internal API error - movetothem() length too long.\n");
+ fprintf(stderr, "(detected in file %s, line %d)\n", __FILE__, __LINE__);
+ quit();
+ } else if (length == 0) {
+ return;
+ }
+ freestorage();
+ memcpy((char *)storage, local, length);
+ if (apitrace) {
+ Dump(')', local, length);
+ }
+ storage_length = length;
+ storage_location = where;
+ storage_must_send = 1;
+}
+
+
+char *
+access_api(location, length, copyin)
+char *
+ location;
+int
+ length,
+ copyin; /* Do we need to copy in initially? */
+{
+ if (storage_accessed) {
+ fprintf(stderr, "Internal error - storage accessed twice\n");
+ fprintf(stderr, "(Encountered in file %s, line %d.)\n",
+ __FILE__, __LINE__);
+ quit();
+ } else if (length != 0) {
+ freestorage();
+ getstorage((long)location, length, copyin);
+ storage_accessed = 1;
+ }
+ return (char *) storage;
+}
+
+/*ARGSUSED*/
+void
+unaccess_api(location, local, length, copyout)
+char *location;
+char *local;
+int length;
+int copyout;
+{
+ if (storage_accessed == 0) {
+ fprintf(stderr, "Internal error - unnecessary unaccess_api call.\n");
+ fprintf(stderr, "(Encountered in file %s, line %d.)\n",
+ __FILE__, __LINE__);
+ quit();
+ }
+ storage_accessed = 0;
+ storage_must_send = copyout; /* if needs to go back */
+}
+
+/*
+ * Accept a connection from an API client, aborting if the child dies.
+ */
+
+static int
+doconnect()
+{
+ fd_set fdset;
+ int i;
+
+ sock = -1;
+ FD_ZERO(&fdset);
+ while (shell_active && (sock == -1)) {
+ FD_SET(serversock, &fdset);
+ if ((i = select(serversock+1, &fdset,
+ (fd_set *)0, (fd_set *)0, (struct timeval *)0)) < 0) {
+ if (errno = EINTR) {
+ continue;
+ } else {
+ perror("in select waiting for API connection");
+ return -1;
+ }
+ } else {
+ i = accept(serversock, (struct sockaddr *)0, (int *)0);
+ if (i == -1) {
+ perror("accepting API connection");
+ return -1;
+ }
+ sock = i;
+ }
+ }
+ /* If the process has already exited, we may need to close */
+ if ((shell_active == 0) && (sock != -1)) {
+ extern void setcommandmode();
+
+ (void) close(sock);
+ sock = -1;
+ setcommandmode(); /* In case child_died sneaked in */
+ }
+ return 0;
+}
+
+/*
+ * shell_continue() actually runs the command, and looks for API
+ * requests coming back in.
+ *
+ * We are called from the main loop in telnet.c.
+ */
+
+int
+shell_continue()
+{
+ int i;
+
+ switch (state) {
+ case DEAD:
+ pause(); /* Nothing to do */
+ break;
+ case UNCONNECTED:
+ if (doconnect() == -1) {
+ kill_connection();
+ return -1;
+ }
+ /* At this point, it is possible that we've gone away */
+ if (shell_active == 0) {
+ kill_connection();
+ return -1;
+ }
+ if (api_exch_init(sock, "server") == -1) {
+ return -1;
+ }
+ while (state == UNCONNECTED) {
+ if (api_exch_incommand(EXCH_CMD_ASSOCIATE) == -1) {
+ kill_connection();
+ return -1;
+ } else {
+ switch (doassociate()) {
+ case -1:
+ kill_connection();
+ return -1;
+ case 0:
+ break;
+ case 1:
+ state = CONNECTED;
+ }
+ }
+ }
+ break;
+ case CONNECTED:
+ switch (i = api_exch_nextcommand()) {
+ case EXCH_CMD_REQUEST:
+ if (api_exch_intype(EXCH_TYPE_REGS, sizeof inputRegs,
+ (char *)&inputRegs) == -1) {
+ kill_connection();
+ } else if (api_exch_intype(EXCH_TYPE_SREGS, sizeof inputSregs,
+ (char *)&inputSregs) == -1) {
+ kill_connection();
+ } else if (nextstore() == -1) {
+ kill_connection();
+ } else {
+ handle_api(&inputRegs, &inputSregs);
+ freestorage(); /* Send any storage back */
+ if (api_exch_outcommand(EXCH_CMD_REPLY) == -1) {
+ kill_connection();
+ } else if (api_exch_outtype(EXCH_TYPE_REGS, sizeof inputRegs,
+ (char *)&inputRegs) == -1) {
+ kill_connection();
+ } else if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof inputSregs,
+ (char *)&inputSregs) == -1) {
+ kill_connection();
+ }
+ /* Done, and it all worked! */
+ }
+ break;
+ case EXCH_CMD_DISASSOCIATE:
+ kill_connection();
+ break;
+ default:
+ if (i != -1) {
+ fprintf(stderr,
+ "Looking for a REQUEST or DISASSOCIATE command\n");
+ fprintf(stderr, "\treceived 0x%02x.\n", i);
+ }
+ kill_connection();
+ break;
+ }
+ }
+ return shell_active;
+}
+
+
+static void
+child_died(code)
+{
+ union wait status;
+ register int pid;
+
+ while ((pid = wait3((int *)&status, WNOHANG, (struct rusage *)0)) > 0) {
+ if (pid == shell_pid) {
+ char inputbuffer[100];
+ extern void setconnmode();
+ extern void ConnectScreen();
+
+ shell_active = 0;
+ if (sock != -1) {
+ (void) close(sock);
+ sock = -1;
+ }
+ printf("[Hit return to continue]");
+ fflush(stdout);
+ (void) gets(inputbuffer);
+ setconnmode();
+ ConnectScreen(); /* Turn screen on (if need be) */
+ (void) close(serversock);
+ (void) unlink(keyname);
+ }
+ }
+ signal(SIGCHLD, child_died);
+}
+
+
+/*
+ * Called from telnet.c to fork a lower command.com. We
+ * use the spint... routines so that we can pick up
+ * interrupts generated by application programs.
+ */
+
+
+int
+shell(argc,argv)
+int argc;
+char *argv[];
+{
+ int length;
+ struct sockaddr_in server;
+ char sockNAME[100];
+ static char **whereAPI = 0;
+ int fd;
+ struct timeval tv;
+ long ikey;
+ extern long random();
+ extern char *mktemp();
+ extern char *strcpy();
+
+ /* First, create verification file. */
+ do {
+ keyname = mktemp(strdup("/tmp/apiXXXXXX"));
+ fd = open(keyname, O_RDWR|O_CREAT|O_EXCL, IREAD|IWRITE);
+ } while ((fd == -1) && (errno == EEXIST));
+
+ if (fd == -1) {
+ perror("open");
+ return 0;
+ }
+
+ /* Now, get seed for random */
+
+ if (gettimeofday(&tv, (struct timezone *)0) == -1) {
+ perror("gettimeofday");
+ return 0;
+ }
+ srandom(tv.tv_usec); /* seed random number generator */
+ do {
+ ikey = random();
+ } while (ikey == 0);
+ sprintf(key, "%lu\n", (unsigned long) ikey);
+ if (write(fd, key, strlen(key)) != strlen(key)) {
+ perror("write");
+ return 0;
+ }
+ key[strlen(key)-1] = 0; /* Get rid of newline */
+
+ if (close(fd) == -1) {
+ perror("close");
+ return 0;
+ }
+
+ /* Next, create the socket which will be connected to */
+ serversock = socket(AF_INET, SOCK_STREAM, 0);
+ if (serversock < 0) {
+ perror("opening API socket");
+ return 0;
+ }
+ server.sin_family = AF_INET;
+ server.sin_addr.s_addr = INADDR_ANY;
+ server.sin_port = 0;
+ if (bind(serversock, (struct sockaddr *)&server, sizeof server) < 0) {
+ perror("binding API socket");
+ return 0;
+ }
+ length = sizeof server;
+ if (getsockname(serversock, (struct sockaddr *)&server, &length) < 0) {
+ perror("getting API socket name");
+ (void) close(serversock);
+ }
+ listen(serversock, 1);
+ /* Get name to advertise in address list */
+ strcpy(sockNAME, "API3270=");
+ gethostname(sockNAME+strlen(sockNAME), sizeof sockNAME-strlen(sockNAME));
+ if (strlen(sockNAME) > (sizeof sockNAME-(10+strlen(keyname)))) {
+ fprintf(stderr, "Local hostname too large; using 'localhost'.\n");
+ strcpy(sockNAME, "localhost");
+ }
+ sprintf(sockNAME+strlen(sockNAME), ":%u", ntohs(server.sin_port));
+ sprintf(sockNAME+strlen(sockNAME), ":%s", keyname);
+
+ if (whereAPI == 0) {
+ char **ptr, **nextenv;
+ extern char **environ;
+
+ ptr = environ;
+ nextenv = ourENVlist;
+ while (*ptr) {
+ if (nextenv >= &ourENVlist[highestof(ourENVlist)-1]) {
+ fprintf(stderr, "Too many environmental variables\n");
+ break;
+ }
+ *nextenv++ = *ptr++;
+ }
+ whereAPI = nextenv++;
+ *nextenv++ = 0;
+ environ = ourENVlist; /* New environment */
+ }
+ *whereAPI = sockNAME;
+
+ child_died(); /* Start up signal handler */
+ shell_active = 1; /* We are running down below */
+ if (shell_pid = vfork()) {
+ if (shell_pid == -1) {
+ perror("vfork");
+ (void) close(serversock);
+ } else {
+ state = UNCONNECTED;
+ }
+ } else { /* New process */
+ register int i;
+
+ for (i = 3; i < 30; i++) {
+ (void) close(i);
+ }
+ if (argc == 1) { /* Just get a shell */
+ char *cmdname;
+ extern char *getenv();
+
+ cmdname = getenv("SHELL");
+ execlp(cmdname, cmdname, 0);
+ perror("Exec'ing new shell...\n");
+ exit(1);
+ } else {
+ execvp(argv[1], &argv[1]);
+ perror("Exec'ing command.\n");
+ exit(1);
+ }
+ /*NOTREACHED*/
+ }
+ return shell_active; /* Go back to main loop */
+}
diff --git a/usr.bin/tn3270/sys_curses/telextrn.h b/usr.bin/tn3270/sys_curses/telextrn.h
new file mode 100644
index 0000000..becf82a2
--- /dev/null
+++ b/usr.bin/tn3270/sys_curses/telextrn.h
@@ -0,0 +1,71 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)telextrn.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * Definitions of external routines and variables for tn3270
+ */
+
+/*
+ * Pieces exported from the telnet susbsection.
+ */
+
+extern int
+#if defined(unix)
+ HaveInput,
+#endif /* defined(unix) */
+ tout,
+ tin;
+
+extern char *transcom;
+
+extern int
+ netflush(),
+ quit(),
+ TtyChars(),
+ DataToTerminal();
+
+extern void
+ outputPurge(),
+ EmptyTerminal(),
+ StringToTerminal(),
+ ExitPerror(),
+ setcommandmode();
+
+/*
+ * Pieces exported from other random locations.
+ */
+
+extern char
+ *strsave();
diff --git a/usr.bin/tn3270/sys_curses/terminal.h b/usr.bin/tn3270/sys_curses/terminal.h
new file mode 100644
index 0000000..d7041b7
--- /dev/null
+++ b/usr.bin/tn3270/sys_curses/terminal.h
@@ -0,0 +1,81 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)terminal.h 8.1 (Berkeley) 6/6/93
+ */
+
+#define INCLUDED_TERMINAL
+
+/*
+ * In the situation where we have a copy of the terminal screen in front
+ * of us, here are some macros to deal with them.
+ */
+
+#define TermAttributes(x) (TermIsStartField(x)? GetTerminal(x)&0xff : \
+ GetTerminal(WhereTermAttrByte(x))&0xff)
+#define TermIsStartField(x) ((GetTerminal(x)&ATTR_MASK) == ATTR_MASK)
+#define TermNewField(p,a) SetTerminal(p, (a)|ATTR_MASK)
+#define TermDeleteField(p) SetTerminal(p, 0)
+#define TermIsNonDisplay(x) \
+ ((TermAttributes(x)&ATTR_DSPD_MASK) == ATTR_DSPD_NONDISPLAY)
+#define TermIsHighlighted(x) \
+ (((TermAttributes(x)&ATTR_DSPD_MASK) == ATTR_DSPD_HIGH) \
+ && !TermIsStartField(x))
+
+#define TerminalCharacterAttr(c,p,a) (IsNonDisplayAttr(a) ? ' ':c)
+#define TerminalCharacter(c,p) TerminalCharacterAttr(c,p,FieldAttributes(p))
+
+ /*
+ * Is the screen formatted? Some algorithms change depending
+ * on whether there are any attribute bytes lying around.
+ */
+#define TerminalFormattedScreen() \
+ ((WhereTermAttrByte(0) != 0) || ((GetTerminal(0)&ATTR_MASK) == ATTR_MASK))
+
+#define NeedToRedisplayFields(p) ((TermIsNonDisplay(p) != IsNonDisplay(p)) || \
+ (TermIsHighlighted(p) != IsHighlighted(p)))
+#define NeedToRedisplayFieldsAttr(p,c) ( \
+ (TermIsNonDisplay(p) != IsNonDisplayAttr(c)) || \
+ (TermIsHighlighted(p) != IsHighlightedAttr(c)))
+
+#define NotVisuallyCompatibleAttributes(p,c,d) ( \
+ (IsNonDisplayAttr(c) != IsNonDisplayAttr(d)) || \
+ (IsHighlightedAttr(c) != IsHighlightedAttr(d)))
+
+#define NeedToRedisplayAttr(c,p,a) \
+ ((c != GetTerminal(p)) || NeedToRedisplayFieldsAttr(p,a))
+#define NeedToRedisplay(c,p) NeedToRedisplayAttr(c,p,FieldAttributes(p))
+
+
+#define GetTerminal(i) GetGeneric(i, Terminal)
+#define GetTerminalPointer(p) GetGenericPointer(p)
+#define SetTerminal(i,c) SetGeneric(i,c,Terminal)
diff --git a/usr.bin/tn3270/sys_curses/termout.c b/usr.bin/tn3270/sys_curses/termout.c
new file mode 100644
index 0000000..5dbe311
--- /dev/null
+++ b/usr.bin/tn3270/sys_curses/termout.c
@@ -0,0 +1,957 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)termout.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#if defined(unix)
+#include <signal.h>
+#include <sgtty.h>
+#endif
+#include <stdio.h>
+#include <curses.h>
+#if defined(ultrix)
+/* Some version of this OS has a bad definition for nonl() */
+#undef nl
+#undef nonl
+
+#define nl() (_tty.sg_flags |= CRMOD,_pfast = _rawmode,stty(_tty_ch, &_tty))
+#define nonl() (_tty.sg_flags &= ~CRMOD, _pfast = TRUE, stty(_tty_ch, &_tty))
+#endif /* defined(ultrix) */
+
+#include "../general/general.h"
+
+#include "terminal.h"
+
+#include "../api/disp_asc.h"
+
+#include "../ctlr/hostctlr.h"
+#include "../ctlr/externs.h"
+#include "../ctlr/declare.h"
+#include "../ctlr/oia.h"
+#include "../ctlr/screen.h"
+#include "../ctlr/scrnctlr.h"
+
+#include "../general/globals.h"
+
+#include "telextrn.h"
+
+#define CorrectTerminalCursor() ((TransparentClock == OutputClock)? \
+ CursorAddress:UnLocked? CursorAddress: HighestScreen())
+
+
+static int terminalCursorAddress; /* where the cursor is on term */
+static int screenInitd; /* the screen has been initialized */
+static int screenStopped; /* the screen has been stopped */
+static int max_changes_before_poll; /* how many characters before looking */
+ /* at terminal and net again */
+
+static int needToRing; /* need to ring terinal bell */
+static char *bellSequence = "\07"; /* bell sequence (may be replaced by
+ * VB during initialization)
+ */
+static WINDOW *bellwin = 0; /* The window the bell message is in */
+int bellwinup = 0; /* Are we up with it or not */
+
+#if defined(unix)
+static char *myKS, *myKE;
+#endif /* defined(unix) */
+
+
+static int inHighlightMode = 0;
+ScreenImage Terminal[MAXSCREENSIZE];
+
+/* Variables for transparent mode */
+#if defined(unix)
+static int tcflag = -1; /* transparent mode command flag */
+static int savefd[2]; /* for storing fds during transcom */
+extern int tin, tout; /* file descriptors */
+#endif /* defined(unix) */
+
+
+/*
+ * init_screen()
+ *
+ * Initialize variables used by screen.
+ */
+
+void
+init_screen()
+{
+ bellwinup = 0;
+ inHighlightMode = 0;
+ ClearArray(Terminal);
+}
+
+
+/* OurExitString - designed to keep us from going through infinite recursion */
+
+static void
+OurExitString(string, value)
+char *string;
+int value;
+{
+ static int recursion = 0;
+
+ if (!recursion) {
+ recursion = 1;
+ ExitString(string, value);
+ }
+}
+
+
+/* DoARefresh */
+
+static void
+DoARefresh()
+{
+ if (ERR == refresh()) {
+ OurExitString("ERR from refresh\n", 1);
+ }
+}
+
+static void
+GoAway(from, where)
+char *from; /* routine that gave error */
+int where; /* cursor address */
+{
+ char foo[100];
+
+ sprintf(foo, "ERR from %s at %d (%d, %d)\n",
+ from, where, ScreenLine(where), ScreenLineOffset(where));
+ OurExitString(foo, 1);
+ /* NOTREACHED */
+}
+
+/* What is the screen address of the attribute byte for the terminal */
+
+static int
+WhereTermAttrByte(p)
+register int p;
+{
+ register int i;
+
+ i = p;
+
+ do {
+ if (TermIsStartField(i)) {
+ return(i);
+ }
+ i = ScreenDec(i);
+ } while (i != p);
+
+ return(LowestScreen()); /* unformatted screen... */
+}
+
+/*
+ * There are two algorithms for updating the screen.
+ * The first, SlowScreen() optimizes the line between the
+ * computer and the screen (say a 9600 baud line). To do
+ * this, we break out of the loop every so often to look
+ * at any pending input from the network (so that successive
+ * screens will only partially print until the final screen,
+ * the one the user possibly wants to see, is displayed
+ * in its entirety).
+ *
+ * The second algorithm tries to optimize CPU time (by
+ * being simpler) at the cost of the bandwidth to the
+ * screen.
+ *
+ * Of course, curses(3X) gets in here also.
+ */
+
+
+#if defined(NOT43)
+static int
+#else /* defined(NOT43) */
+static void
+#endif /* defined(NOT43) */
+SlowScreen()
+{
+ register int is, shouldbe, isattr, shouldattr;
+ register int pointer;
+ register int fieldattr, termattr;
+ register int columnsleft;
+
+#define NORMAL 0
+#define HIGHLIGHT 1 /* Mask bits */
+#define NONDISPLAY 4 /* Mask bits */
+#define UNDETERMINED 8 /* Mask bits */
+
+#define DoAttributes(x) \
+ switch (x&ATTR_DSPD_MASK) { \
+ case ATTR_DSPD_NONDISPLAY: \
+ x = NONDISPLAY; \
+ break; \
+ case ATTR_DSPD_HIGH: \
+ x = HIGHLIGHT; \
+ break; \
+ default: \
+ x = 0; \
+ break; \
+ }
+
+# define SetHighlightMode(x) \
+ { \
+ if ((x)&HIGHLIGHT) { \
+ if (!inHighlightMode) { \
+ inHighlightMode = HIGHLIGHT; \
+ standout(); \
+ } \
+ } else { \
+ if (inHighlightMode) { \
+ inHighlightMode = 0; \
+ standend(); \
+ } \
+ } \
+ }
+
+# define DoCharacterAt(c,p) { \
+ if (p != HighestScreen()) { \
+ c = disp_asc[c&0xff]; \
+ if (terminalCursorAddress != p) { \
+ if (ERR == mvaddch(ScreenLine(p), \
+ ScreenLineOffset(p), c)) {\
+ GoAway("mvaddch", p); \
+ } \
+ } else { \
+ if (ERR == addch(c)) {\
+ GoAway("addch", p); \
+ } \
+ } \
+ terminalCursorAddress = ScreenInc(p); \
+ } \
+ }
+
+
+ /* run through screen, printing out non-null lines */
+
+ /* There are two separate reasons for wanting to terminate this
+ * loop early. One is to respond to new input (either from
+ * the terminal or from the network [host]). For this reason,
+ * we expect to see 'HaveInput' come true when new input comes in.
+ *
+ * The second reason is a bit more difficult (for me) to understand.
+ * Basically, we don't want to get too far ahead of the characters that
+ * appear on the screen. Ideally, we would type out a few characters,
+ * wait until they appeared on the screen, then type out a few more.
+ * The reason for this is that the user, on seeing some characters
+ * appear on the screen may then start to type something. We would
+ * like to look at what the user types at about the same 'time'
+ * (measured by characters being sent to the terminal) that the
+ * user types them. For this reason, what we would like to do
+ * is update a bit, then call curses to do a refresh, flush the
+ * output to the terminal, then wait until the terminal data
+ * has been sent.
+ *
+ * Note that curses is useful for, among other things, deciding whether
+ * or not to send :ce: (clear to end of line), so we should call curses
+ * at end of lines (beginning of next lines).
+ *
+ * The problems here are the following: If we do lots of write(2)s,
+ * we will be doing lots of context switches, thus lots of overhead
+ * (which we have already). Second, if we do a select to wait for
+ * the output to drain, we have to contend with the fact that NOW
+ * we are scheduled to run, but who knows what the scheduler will
+ * decide when the output has caught up.
+ */
+
+ if (Highest >= HighestScreen()) { /* Could be > if screen shrunk... */
+ Highest = ScreenDec(Highest); /* else, while loop will never end */
+ }
+ if (Lowest < LowestScreen()) {
+ Lowest = LowestScreen(); /* could be -1 in some cases with
+ * unformatted screens.
+ */
+ }
+ if (Highest >= (pointer = Lowest)) {
+ /* if there is anything to do, do it. We won't terminate
+ * the loop until we've gone at least to Highest.
+ */
+ while ((pointer <= Highest) && !HaveInput) {
+
+ /* point at the next place of disagreement */
+ pointer += (bunequal(Host+pointer, Terminal+pointer,
+ (Highest-pointer+1)*sizeof Host[0])/sizeof Host[0]);
+
+ /*
+ * How many characters to change until the end of the
+ * current line
+ */
+ columnsleft = NumberColumns - ScreenLineOffset(pointer);
+ /*
+ * Make sure we are where we think we are.
+ */
+ move(ScreenLine(pointer), ScreenLineOffset(pointer));
+
+ /* what is the field attribute of the current position */
+ if (FormattedScreen()) {
+ fieldattr = FieldAttributes(pointer);
+ DoAttributes(fieldattr);
+ } else {
+ fieldattr = NORMAL;
+ }
+ if (TerminalFormattedScreen()) {
+ termattr = TermAttributes(pointer);
+ DoAttributes(termattr);
+ } else {
+ termattr = NORMAL;
+ }
+
+ SetHighlightMode(fieldattr);
+ /*
+ * The following will terminate at least when we get back
+ * to the original 'pointer' location (since we force
+ * things to be equal).
+ */
+ for (;;) {
+ if (IsStartField(pointer)) {
+ shouldbe = DISP_BLANK;
+ shouldattr = 0;
+ fieldattr = GetHost(pointer);
+ DoAttributes(fieldattr);
+ } else {
+ if (fieldattr&NONDISPLAY) {
+ shouldbe = DISP_BLANK;
+ } else {
+ shouldbe = GetHost(pointer);
+ }
+ shouldattr = fieldattr;
+ }
+ if (TermIsStartField(pointer)) {
+ is = DISP_BLANK;
+ isattr = 0;
+ termattr = UNDETERMINED; /* Need to find out AFTER update */
+ } else {
+ if (termattr&NONDISPLAY) {
+ is = DISP_BLANK;
+ } else {
+ is = GetTerminal(pointer);
+ }
+ isattr = termattr;
+ }
+ if ((shouldbe == is) && (shouldattr == isattr)
+ && (GetHost(pointer) == GetTerminal(pointer))
+ && (GetHost(ScreenInc(pointer))
+ == GetTerminal(ScreenInc(pointer)))) {
+ break;
+ }
+
+ if (shouldattr^inHighlightMode) {
+ SetHighlightMode(shouldattr);
+ }
+
+ DoCharacterAt(shouldbe, pointer);
+ if (IsStartField(pointer)) {
+ TermNewField(pointer, FieldAttributes(pointer));
+ termattr = GetTerminal(pointer);
+ DoAttributes(termattr);
+ } else {
+ SetTerminal(pointer, GetHost(pointer));
+ /*
+ * If this USED to be a start field location,
+ * recompute the terminal attributes.
+ */
+ if (termattr == UNDETERMINED) {
+ termattr = WhereTermAttrByte(pointer);
+ if ((termattr != 0) || TermIsStartField(0)) {
+ termattr = GetTerminal(termattr);
+ DoAttributes(termattr);
+ } else { /* Unformatted screen */
+ termattr = NORMAL;
+ }
+ }
+ }
+ pointer = ScreenInc(pointer);
+ if (!(--columnsleft)) {
+ DoARefresh();
+ EmptyTerminal();
+ if (HaveInput) { /* if input came in, take it */
+ int c, j;
+
+ /*
+ * We need to start a new terminal field
+ * at this location iff the terminal attributes
+ * of this location are not what we have had
+ * them as (ie: we've overwritten the terminal
+ * start field, a the previous field had different
+ * display characteristics).
+ */
+
+ isattr = TermAttributes(pointer);
+ DoAttributes(isattr);
+ if ((!TermIsStartField(pointer)) &&
+ (isattr != termattr)) {
+ /*
+ * Since we are going to leave a new field
+ * at this terminal position, we
+ * need to make sure that we get an actual
+ * non-highlighted blank on the screen.
+ */
+ if ((is != DISP_BLANK) || (termattr&HIGHLIGHT)) {
+ SetHighlightMode(0); /* Turn off highlight */
+ c = ScreenInc(pointer);
+ j = DISP_BLANK;
+ DoCharacterAt(j, c);
+ }
+ if (termattr&HIGHLIGHT) {
+ termattr = ATTR_DSPD_HIGH;
+ } else if (termattr&NONDISPLAY) {
+ termattr = ATTR_DSPD_NONDISPLAY;
+ } else {
+ termattr = 0;
+ }
+ TermNewField(pointer, termattr);
+ }
+ break;
+ }
+ move(ScreenLine(pointer), 0);
+ columnsleft = NumberColumns;
+ }
+ } /* end of for (;;) */
+ } /* end of while (...) */
+ }
+ DoARefresh();
+ Lowest = pointer;
+ if (Lowest > Highest) { /* if we finished input... */
+ Lowest = HighestScreen()+1;
+ Highest = LowestScreen()-1;
+ terminalCursorAddress = CorrectTerminalCursor();
+ if (ERR == move(ScreenLine(terminalCursorAddress),
+ ScreenLineOffset(terminalCursorAddress))) {
+ GoAway("move", terminalCursorAddress);
+ }
+ DoARefresh();
+ if (needToRing) {
+ StringToTerminal(bellSequence);
+ needToRing = 0;
+ }
+ }
+ EmptyTerminal(); /* move data along */
+ return;
+}
+
+#if defined(NOT43)
+static int
+#else /* defined(NOT43) */
+static void
+#endif /* defined(NOT43) */
+FastScreen()
+{
+#if defined(MSDOS)
+#define SaveCorner 0
+#else /* defined(MSDOS) */
+#define SaveCorner 1
+#endif /* defined(MSDOS) */
+
+#define DoAttribute(a) if (IsHighlightedAttr(a)) { \
+ standout(); \
+ } else { \
+ standend(); \
+ } \
+ if (IsNonDisplayAttr(a)) { \
+ a = 0; /* zero == don't display */ \
+ } \
+ if (!FormattedScreen()) { \
+ a = 1; /* one ==> do display on unformatted */\
+ }
+ ScreenImage *p, *upper;
+ int fieldattr; /* spends most of its time == 0 or 1 */
+
+/* OK. We want to do this a quickly as possible. So, we assume we
+ * only need to go from Lowest to Highest. However, if we find a
+ * field in the middle, we do the whole screen.
+ *
+ * In particular, we separate out the two cases from the beginning.
+ */
+ if ((Highest != HighestScreen()) || (Lowest != LowestScreen())) {
+ register int columnsleft;
+
+ move(ScreenLine(Lowest), ScreenLineOffset(Lowest));
+ p = &Host[Lowest];
+#if !defined(MSDOS)
+ if (Highest == HighestScreen()) {
+ Highest = ScreenDec(Highest);
+ }
+#endif /* !defined(MSDOS) */
+ upper = &Host[Highest];
+ fieldattr = FieldAttributes(Lowest);
+ DoAttribute(fieldattr); /* Set standout, non-display status */
+ columnsleft = NumberColumns-ScreenLineOffset(p-Host);
+
+ while (p <= upper) {
+ if (IsStartFieldPointer(p)) { /* New field? */
+ Highest = HighestScreen();
+ Lowest = LowestScreen();
+ FastScreen(); /* Recurse */
+ return;
+ } else if (fieldattr) { /* Should we display? */
+ /* Display translated data */
+ addch((char)disp_asc[GetTerminalPointer(p)]);
+ } else {
+ addch(' '); /* Display a blank */
+ }
+ /* If the physical screen is larger than what we
+ * are using, we need to make sure that each line
+ * starts at the beginning of the line. Otherwise,
+ * we will just string all the lines together.
+ */
+ p++;
+ if (--columnsleft == 0) {
+ int i = p-Host;
+
+ move(ScreenLine(i), 0);
+ columnsleft = NumberColumns;
+ }
+ }
+ } else { /* Going from Lowest to Highest */
+ unsigned char tmpbuf[MAXNUMBERCOLUMNS+1];
+ ScreenImage *End = &Host[ScreenSize]-1-SaveCorner;
+ register unsigned char *tmp = tmpbuf, *tmpend = tmpbuf+NumberColumns;
+
+ *tmpend = 0; /* terminate from the beginning */
+ move(0,0);
+ p = Host;
+ fieldattr = FieldAttributes(LowestScreen());
+ DoAttribute(fieldattr); /* Set standout, non-display status */
+
+ while (p <= End) {
+ if (IsStartFieldPointer(p)) { /* New field? */
+ if (tmp != tmpbuf) {
+ *tmp++ = 0; /* close out */
+ addstr((char *)tmpbuf);
+ tmp = tmpbuf;
+ tmpend = tmpbuf+NumberColumns-ScreenLineOffset(p-Host)-1;
+ }
+ standend();
+ addch(' ');
+ fieldattr = FieldAttributesPointer(p); /* Get attributes */
+ DoAttribute(fieldattr); /* Set standout, non-display */
+ } else {
+ if (fieldattr) { /* Should we display? */
+ /* Display translated data */
+ *tmp++ = disp_asc[GetTerminalPointer(p)];
+ } else {
+ *tmp++ = ' ';
+ }
+ }
+ /* If the physical screen is larger than what we
+ * are using, we need to make sure that each line
+ * starts at the beginning of the line. Otherwise,
+ * we will just string all the lines together.
+ */
+ p++;
+ if (tmp == tmpend) {
+ int i = p-Host; /* Be sure the "p++" happened first! */
+
+ *tmp++ = 0;
+ addstr((char *)tmpbuf);
+ tmp = tmpbuf;
+ move(ScreenLine(i), 0);
+ tmpend = tmpbuf + NumberColumns;
+ }
+ }
+ if (tmp != tmpbuf) {
+ *tmp++ = 0;
+ addstr((char *)tmpbuf);
+ tmp = tmpbuf;
+ }
+ }
+ Lowest = HighestScreen()+1;
+ Highest = LowestScreen()-1;
+ terminalCursorAddress = CorrectTerminalCursor();
+ if (ERR == move(ScreenLine(terminalCursorAddress),
+ ScreenLineOffset(terminalCursorAddress))) {
+ GoAway("move", terminalCursorAddress);
+ }
+ DoARefresh();
+ if (needToRing) {
+ StringToTerminal(bellSequence);
+ needToRing = 0;
+ }
+ EmptyTerminal(); /* move data along */
+ return;
+}
+
+
+/* TryToSend - send data out to user's terminal */
+
+#if defined(NOT43)
+int
+#else /* defined(NOT43) */
+void
+#endif /* defined(NOT43) */
+ (*TryToSend)() = FastScreen;
+
+/*ARGSUSED*/
+void
+ScreenOIA(oia)
+OIA *oia;
+{
+}
+
+
+/* InitTerminal - called to initialize the screen, etc. */
+
+void
+InitTerminal()
+{
+#if defined(unix)
+ struct sgttyb ourttyb;
+ static int speeds[] = { 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800,
+ 2400, 4800, 9600 };
+#endif
+ extern void InitMapping();
+
+ InitMapping(); /* Go do mapping file (MAP3270) first */
+ if (!screenInitd) { /* not initialized */
+#if defined(unix)
+ char KSEbuffer[2050];
+ char *lotsofspace = KSEbuffer;
+ extern void abort();
+ extern char *tgetstr();
+#endif /* defined(unix) */
+
+ if (initscr() == ERR) { /* Initialize curses to get line size */
+ ExitString("InitTerminal: Error initializing curses", 1);
+ /*NOTREACHED*/
+ }
+ MaxNumberLines = LINES;
+ MaxNumberColumns = COLS;
+ ClearArray(Terminal);
+ terminalCursorAddress = SetBufferAddress(0,0);
+#if defined(unix)
+ signal(SIGHUP, abort);
+#endif
+
+ TryToSend = FastScreen;
+#if defined(unix)
+ ioctl(1, TIOCGETP, (char *) &ourttyb);
+ if ((ourttyb.sg_ospeed < 0) || (ourttyb.sg_ospeed > B9600)) {
+ max_changes_before_poll = 1920;
+ } else {
+ max_changes_before_poll = speeds[ourttyb.sg_ospeed]/10;
+ if (max_changes_before_poll < 40) {
+ max_changes_before_poll = 40;
+ }
+ TryToSend = SlowScreen;
+ HaveInput = 1; /* get signals going */
+ }
+#endif /* defined(unix) */
+ setcommandmode();
+ /*
+ * By now, initscr() (in curses) has been called (from telnet.c),
+ * and the screen has been initialized.
+ */
+#if defined(unix)
+ nonl();
+ /* the problem is that curses catches SIGTSTP to
+ * be nice, but it messes us up.
+ */
+ signal(SIGTSTP, SIG_DFL);
+ if ((myKS = tgetstr("ks", &lotsofspace)) != 0) {
+ myKS = strsave(myKS);
+ StringToTerminal(myKS);
+ }
+ if ((myKE = tgetstr("ke", &lotsofspace)) != 0) {
+ myKE = strsave(myKE);
+ }
+ if (tgetstr("md", &lotsofspace) && tgetstr("me", &lotsofspace)) {
+ SO = strsave(tgetstr("md", &lotsofspace));
+ SE = strsave(tgetstr("me", &lotsofspace));
+ }
+#endif
+ DoARefresh();
+ setconnmode();
+ if (VB && *VB) {
+ bellSequence = VB; /* use visual bell */
+ }
+ screenInitd = 1;
+ screenStopped = 0; /* Not stopped */
+ }
+}
+
+
+/* StopScreen - called when we are going away... */
+
+void
+StopScreen(doNewLine)
+int doNewLine;
+{
+ if (screenInitd && !screenStopped) {
+ move(NumberLines-1, 1);
+ standend();
+ inHighlightMode = 0;
+ DoARefresh();
+ setcommandmode();
+ endwin();
+ setconnmode();
+#if defined(unix)
+ if (myKE) {
+ StringToTerminal(myKE);
+ }
+#endif /* defined(unix) */
+ if (doNewLine) {
+ StringToTerminal("\r\n");
+ }
+ EmptyTerminal();
+ screenStopped = 1; /* This is stopped */
+ }
+}
+
+
+/* RefreshScreen - called to cause the screen to be refreshed */
+
+void
+RefreshScreen()
+{
+ clearok(curscr, TRUE);
+ (*TryToSend)();
+}
+
+
+/* ConnectScreen - called to reconnect to the screen */
+
+void
+ConnectScreen()
+{
+ if (screenInitd) {
+#if defined(unix)
+ if (myKS) {
+ StringToTerminal(myKS);
+ }
+#endif /* defined(unix) */
+ RefreshScreen();
+ (*TryToSend)();
+ screenStopped = 0;
+ }
+}
+
+/* LocalClearScreen() - clear the whole ball of wax, cheaply */
+
+void
+LocalClearScreen()
+{
+ extern void Clear3270();
+
+ outputPurge(); /* flush all data to terminal */
+ clear(); /* clear in curses */
+ ClearArray(Terminal);
+ Clear3270();
+ Lowest = HighestScreen()+1; /* everything in sync... */
+ Highest = LowestScreen()+1;
+}
+
+
+void
+BellOff()
+{
+ if (bellwinup) {
+ delwin(bellwin);
+ bellwin = 0;
+ bellwinup = 0;
+ touchwin(stdscr);
+ DoARefresh();
+ }
+}
+
+
+void
+RingBell(s)
+char *s;
+{
+ needToRing = 1;
+ if (s) {
+ int len = strlen(s);
+
+ if (len > COLS-2) {
+ len = COLS-2;
+ }
+ if ((bellwin = newwin(3, len+2, LINES/2, 0)) == NULL) {
+ OurExitString("Error from newwin in RingBell", 1);
+ }
+ werase(bellwin);
+ wstandout(bellwin);
+ box(bellwin, '|', '-');
+ if (wmove(bellwin, 1, 1) == ERR) {
+ OurExitString("Error from wmove in RingBell", 1);
+ }
+ while (len--) {
+ if (waddch(bellwin, *s++) == ERR) {
+ OurExitString("Error from waddch in RingBell", 1);
+ }
+ }
+ wstandend(bellwin);
+ if (wrefresh(bellwin) == ERR) {
+ OurExitString("Error from wrefresh in RingBell", 1);
+ }
+ bellwinup = 1;
+ }
+}
+
+
+/* returns a 1 if no more output available (so, go ahead and block),
+ or a 0 if there is more output available (so, just poll the other
+ sources/destinations, don't block).
+ */
+
+int
+DoTerminalOutput()
+{
+ /* called just before a select to conserve IO to terminal */
+ if (!(screenInitd||screenStopped)) {
+ return 1; /* No output if not initialized */
+ }
+ if ((Lowest <= Highest) || needToRing ||
+ (terminalCursorAddress != CorrectTerminalCursor())) {
+ (*TryToSend)();
+ }
+ if (Lowest > Highest) {
+ return 1; /* no more output now */
+ } else {
+ return 0; /* more output for future */
+ }
+}
+
+/*
+ * The following are defined to handle transparent data.
+ */
+
+void
+TransStop()
+{
+#if defined(unix)
+ if (tcflag == 0) {
+ tcflag = -1;
+ (void) signal(SIGCHLD, SIG_DFL);
+ } else if (tcflag > 0) {
+ setcommandmode();
+ (void) close(tin);
+ (void) close(tout);
+ tin = savefd[0];
+ tout = savefd[1];
+ setconnmode();
+ tcflag = -1;
+ (void) signal(SIGCHLD, SIG_DFL);
+ }
+#endif /* defined(unix) */
+ RefreshScreen();
+}
+
+void
+TransOut(buffer, count, kind, control)
+unsigned char *buffer;
+int count;
+int kind; /* 0 or 5 */
+int control; /* To see if we are done */
+{
+#if defined(unix)
+ extern char *transcom;
+ int inpipefd[2], outpipefd[2];
+ static void aborttc();
+#endif /* defined(unix) */
+
+ while (DoTerminalOutput() == 0) {
+#if defined(unix)
+ HaveInput = 0;
+#endif /* defined(unix) */
+ }
+#if defined(unix)
+ if (transcom && tcflag == -1) {
+ while (1) { /* go thru once */
+ if (pipe(outpipefd) < 0) {
+ break;
+ }
+ if (pipe(inpipefd) < 0) {
+ break;
+ }
+ if ((tcflag = fork()) == 0) {
+ (void) close(outpipefd[1]);
+ (void) close(0);
+ if (dup(outpipefd[0]) < 0) {
+ exit(1);
+ }
+ (void) close(outpipefd[0]);
+ (void) close(inpipefd[0]);
+ (void) close(1);
+ if (dup(inpipefd[1]) < 0) {
+ exit(1);
+ }
+ (void) close(inpipefd[1]);
+ if (execl("/bin/csh", "csh", "-c", transcom, (char *) 0)) {
+ exit(1);
+ }
+ }
+ (void) close(inpipefd[1]);
+ (void) close(outpipefd[0]);
+ savefd[0] = tin;
+ savefd[1] = tout;
+ setcommandmode();
+ tin = inpipefd[0];
+ tout = outpipefd[1];
+ (void) signal(SIGCHLD, aborttc);
+ setconnmode();
+ tcflag = 1;
+ break;
+ }
+ if (tcflag < 1) {
+ tcflag = 0;
+ }
+ }
+#endif /* defined(unix) */
+ (void) DataToTerminal((char *)buffer, count);
+ if (control && (kind == 0)) { /* Send in AID byte */
+ SendToIBM();
+ } else {
+ extern void TransInput();
+
+ TransInput(1, kind); /* Go get some data */
+ }
+}
+
+
+#if defined(unix)
+static void
+aborttc(signo)
+ int signo;
+{
+ setcommandmode();
+ (void) close(tin);
+ (void) close(tout);
+ tin = savefd[0];
+ tout = savefd[1];
+ setconnmode();
+ tcflag = 0;
+}
+#endif /* defined(unix) */
diff --git a/usr.bin/tn3270/telnet/Makefile b/usr.bin/tn3270/telnet/Makefile
new file mode 100644
index 0000000..b4095e2
--- /dev/null
+++ b/usr.bin/tn3270/telnet/Makefile
@@ -0,0 +1,87 @@
+# @(#)Makefile 8.1 (Berkeley) 6/6/93
+
+# The following is the telnet makefile for tn3270, using the shared telnet
+# sources.
+
+#
+# TERMCAP Define this if your system is termcap based,
+# otherwise a terminfo based system is assumed.
+#
+# SRCRT Includes code to allow you to specify source routes.
+# Format is:
+# [!]@hop1@hop2...[@|:]dst
+# Leading ! means strict source route.
+#
+# NOSTRNCASECMP Define this if you do not have strncasecmp() in
+# your C libarary.
+#
+# USE_TERMIO Define this if you have System V termio structures.
+# What is here is how things are on Cray computers.
+#
+# KLUDGELINEMODE Define this to get the kludged up version of linemode
+# that was in 4.3BSD. This is a good thing to have
+# around for talking to older systems.
+#
+
+DEFINES= -DTERMCAP -DSRCRT -DKLUDGELINEMODE -DUSE_TERMIO
+
+
+VPATH = ${.CURDIR}/../../telnet
+XINCLUDES= -I${.CURDIR}/../../telnet -I${.CURDIR}
+INCLUDES=
+XDEFINES = -DTN3270
+OPTIMIZE= -O
+CFLAGS = ${OPTIMIZE} ${INCLUDES} ${DEFINES}
+XCFLAGS= ${XINCLUDES} ${XDEFINES}
+LD = ld
+LDFLAGS = -r
+PRINT = print
+ACTION = sccs tell
+LIBC= /usr/lib/libc.a
+ALLH= defines.h externs.h fdset.h general.h ring.h types.h
+SRCS= commands.c main.c network.c ring.c \
+ sys_bsd.c telnet.c terminal.c \
+ tn3270.c utilities.c
+ALLHC= ${ALLH} ${SRCS}
+ALLPRINT = ${ALLHC}
+ALLSOURCE= ${ALLHC} Makefile Makefile_ultrix
+OBJS= commands.o main.o network.o ring.o sys_bsd.o \
+ telnet.o terminal.o tn3270.o utilities.o
+
+.c.o:
+ ${CC} -c ${CFLAGS} ${XCFLAGS} $<
+
+telprog.o: ${OBJS} ${LIBC}
+ ${LD} ${LDFLAGS} -o $@ ${OBJS}
+
+clean: FRC
+ rm -f telprog.o ${OBJS} core telnet
+
+depend: FRC ${SRCS}
+ mkdep ${CFLAGS} ${SRCS}
+
+lint: FRC ${SRCS}
+ lint ${CFLAGS} ${SRCS}
+
+tags: FRC ${ALLHC}
+ ctags ${ALLHC}
+
+print: FRC ${ALLPRINT}
+ ${PRINT} ${ALLPRINT}
+
+action: FRC
+ ${ACTION}
+
+clist: FRC ${SRCS}
+ @for i in ${SRCS} ; \
+ do (echo ${DIRPATH}$$i); done
+
+hclist: FRC ${ALLHC}
+ @for i in ${ALLHC} ; \
+ do (echo ${DIRPATH}$$i); done
+
+sourcelist: FRC ${ALLSOURCE}
+ @for i in ${ALLSOURCE} ../../telnet/Makefile ; \
+ do (echo ${DIRPATH}$$i); done
+
+FRC:
diff --git a/usr.bin/tn3270/tn3270/Makefile b/usr.bin/tn3270/tn3270/Makefile
new file mode 100644
index 0000000..a9f1641
--- /dev/null
+++ b/usr.bin/tn3270/tn3270/Makefile
@@ -0,0 +1,80 @@
+# @(#)Makefile 8.1 (Berkeley) 6/6/93
+
+PROG= tn3270
+CFLAGS+=-I${.CURDIR} -I.
+LDADD+= -lcurses -ltermcap -ltelnet
+DPADD+= ${LIBCURSES} /usr/lib/libtermcap.a /usr/lib/libtelnet.a
+CLEANFILES+= asc_disp.OUT asc_disp.out disp_asc.OUT disp_asc.out TMPfunc.out
+.PATH: ${.CURDIR}/../api ${.CURDIR}/../ascii ${.CURDIR}/../ctlr
+.PATH: ${.CURDIR}/../general ${.CURDIR}/../sys_curses ${.CURDIR}/../../telnet
+
+MAN1= tn3270.0
+
+SRCS+= apilib.c api_bsd.c api_exch.c asc_ebc.c astosc.c dctype.c
+SRCS+= disp_asc.c ebc_disp.c
+SRCS+= map3270.c termin.c
+SRCS+= api.c function.c inbound.c oia.c options.c outbound.c
+SRCS+= genbsubs.c globals.c system.c termout.c
+SRCS+= commands.c main.c network.c ring.c sys_bsd.c telnet.c terminal.c
+SRCS+= tn3270.c utilities.c
+
+# This and the dependency hacks below to make 'depend' target
+# work right...
+
+DEPSRCS+= astosc.OUT asc_disp.OUT disp_asc.OUT kbd.OUT
+DEPSRCS+= apilib.c api_bsd.c api_exch.c asc_ebc.c dctype.c
+DEPSRCS+= ebc_disp.c
+DEPSRCS+= map3270.c termin.c
+DEPSRCS+= api.c function.c inbound.c oia.c options.c outbound.c
+DEPSRCS+= genbsubs.c globals.c system.c termout.c
+DEPSRCS+= commands.c main.c network.c ring.c sys_bsd.c telnet.c terminal.c
+DEPSRCS+= tn3270.c utilities.c
+
+astosc.o: astosc.OUT
+CLEANFILES+= astosc.OUT astosc.out
+astosc.OUT: ${.CURDIR}/../ctlr/hostctlr.h ${.CURDIR}/../ctlr/function.h
+astosc.OUT: ${.CURDIR}/../ctlr/${KBD} ${.CURDIR}/../tools/mkastosc/obj/mkastosc
+ ${.CURDIR}/../tools/mkastosc/obj/mkastosc \
+ ${.CURDIR}/../ctlr/hostctlr.h \
+ ${.CURDIR}/../ctlr/function.h < ${.CURDIR}/../ctlr/${KBD} \
+ > ${.TARGET}
+ rm -f astosc.out; ln -s astosc.OUT astosc.out
+
+disp_asc.o: asc_disp.OUT disp_asc.OUT
+asc_disp.OUT: ${.CURDIR}/../tools/mkastods/obj/mkastods
+ ${.CURDIR}/../tools/mkastods/obj/mkastods > ${.TARGET}
+ rm -f asc_disp.out; ln -s asc_disp.OUT asc_disp.out
+
+disp_asc.OUT: ${.CURDIR}/../tools/mkdstoas/obj/mkdstoas
+ ${.CURDIR}/../tools/mkdstoas/obj/mkdstoas > ${.TARGET}
+ rm -f disp_asc.out; ln -s disp_asc.OUT disp_asc.out
+
+inbound.o: kbd.OUT
+CLEANFILES += kbd.OUT kbd.out
+kbd.OUT: ${.CURDIR}/../ctlr/hostctlr.h ${.CURDIR}/../ctlr/${KBD}
+kbd.OUT: ${.CURDIR}/../tools/mkhits/obj/mkhits
+ ${CC} ${CFLAGS} -E ${.CURDIR}/../ctlr/function.c > TMPfunc.out
+ ${.CURDIR}/../tools/mkhits/obj/mkhits ${.CURDIR}/../ctlr/hostctlr.h \
+ TMPfunc.out < ${.CURDIR}/../ctlr/${KBD} > ${.TARGET}
+ rm -f kbd.out; ln -s kbd.OUT kbd.out
+
+# astosc.out
+# asc_disp.out disp_asc.out
+# default.map
+# kbd.out
+
+${.CURDIR}/../tools/mkastosc/obj/mkastosc:
+ cd ${.CURDIR}/../tools/mkastosc; make
+${.CURDIR}/../tools/mkastods/obj/mkastods:
+ cd ${.CURDIR}/../tools/mkastods; make
+${.CURDIR}/../tools/mkdstoas/obj/mkdstoas:
+ cd ${.CURDIR}/../tools/mkdstoas; make
+${.CURDIR}/../tools/mkhits/obj/mkhits:
+ cd ${.CURDIR}/../tools/mkhits; make
+
+depend: .depend
+.depend: ${DEPSRCS}
+ mkdep ${MKDEP} ${CFLAGS:M-[ID]*} ${.ALLSRC:M*.c}
+
+.include <../../Makefile.inc>
+.include <bsd.prog.mk>
diff --git a/usr.bin/tn3270/tn3270/tn3270.1 b/usr.bin/tn3270/tn3270/tn3270.1
new file mode 100644
index 0000000..778302e
--- /dev/null
+++ b/usr.bin/tn3270/tn3270/tn3270.1
@@ -0,0 +1,339 @@
+.\" Copyright (c) 1986, 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)tn3270.1 8.2 (Berkeley) 4/18/94
+.\"
+.Dd April 18, 1994
+.Dt TN3270 1
+.Os BSD 4.3
+.Sh NAME
+.Nm tn3270
+.Nd full-screen remote login to
+.Tn IBM VM/CMS
+.Sh SYNOPSIS
+.Nm tn3270
+.Op Fl d
+.Op Fl n Ar filename
+.Op Fl t Ar commandname
+.Op Ar sysname Op port
+.Sh DESCRIPTION
+.Nm Tn3270
+permits a full-screen, full-duplex connection
+from a
+.Tn UNIX
+machine
+to an
+.Tn IBM
+(or compatible) machine.
+.Nm Tn3270
+gives the appearance of being logged in
+to the remote machine
+from an
+.Tn IBM
+3270 terminal.
+Of course, you must have an account on the machine
+to which you connect in order to log in.
+.Nm Tn3270
+looks to the user in many respects
+like the Yale
+.Tn ASCII
+Terminal Communication System II.
+.Nm Tn3270
+is actually a modification of the Arpanet
+.Tn TELNET
+user interface (see
+.Xr telnet 1 )
+which will, in certain circumstances, interpret and generate
+raw 3270 control streams.
+.Pp
+The flags to
+.Nm tn3270
+are as follows:
+.Bl -tag -width Fl
+.It Fl d
+Turn on socket-level tracing (for super-user only)
+.Fl n Ns Ar filename
+Specify a file to receive network trace data
+output (from commands "toggle netdata" and
+"toggle options", see
+.Xr telnet 1 ) ;
+the default is for output
+to be directed to the standard error file.
+.Fl t Ns Ar commandname
+Specify a
+.Tn UNIX
+command to process
+.Tn IBM
+4994 style transparent mode
+data received from the remote
+.Tn IBM
+machine.
+.It Ar sysname
+The name of the remote system. If the remote name
+is NOT specified, the user will be prompted for a
+command (see below).
+.It Ar port
+The port to connect to on the remote system.
+Normally,
+.Nm tn3270
+attempts to connect to the
+standard
+.Tn TELNET
+port (port
+23) on the remote machine.
+.El
+.Pp
+When
+.Nm tn3270
+first connects to the remote system, it will negotiate to go into
+3270 mode.
+Part of this negotiation involves telling the remote system what model
+3270 it is emulating.
+In all cases,
+.Nm tn3270
+emulates a 3278 terminal.
+To decide which specific model,
+.Nm tn3270
+looks at the number of lines and columns on the actual terminal (as
+defined in the
+.Ev TERM
+environment variable; see
+.Xr termcap 5 ) .
+The terminal (or window in which
+.Nm tn3270
+is running, on multiple
+window systems) must have at least 80 columns and 24 lines, or
+.Nm tn3270
+will not go into emulation mode.
+If the terminal does have at least 80 columns and at least 24 lines,
+the following table describes the emulation:
+.Pp
+.ne 7v
+.Bd -filled -offset center
+.Bl -column (rows*columns)
+.It minimum_size emulated
+.It (rows*columns) terminal
+.It -------------- ------------
+.It 27*132 3278 model 5
+.It 43*80 3278 model 4
+.It 32*80 3278 model 3
+.It 24*80 3278 model 2.
+.El
+.Ed
+.Pp
+Emulation of the 3270 terminal is done in the
+.Tn UNIX
+process.
+This emulation involves mapping
+3270-style commands from the host
+into appropriate sequences to control the user's terminal screen.
+.Nm Tn3270
+uses
+.Xr curses 3
+and the
+.Pa /usr/share/misc/termcap
+file to do this.
+The emulation also involves simulating the special 3270 keyboard keys
+(program function keys, etc.)
+by mapping sequences of keystrokes
+from the
+.Tn ASCII
+keyboard into appropriate 3270 control strings.
+This mapping is terminal dependent and is specified
+in a description file,
+.Pa /usr/share/misc/map3270 ,
+(see
+.Xr map3270 5 )
+or in an environment variable
+.Ev MAP3270
+(and, if necessary,
+.Ev MAP3270A ,
+.Ev MAP3270B ,
+and so on - see
+.Xr mset 1 ) .
+Any special function keys on the
+.Tn ASCII
+keyboard are used whenever possible.
+If an entry for the user's terminal
+is not found,
+.Nm tn3270
+looks for an entry for the terminal type
+.Em unknown .
+If this is not found,
+.Nm tn3270
+uses a default keyboard mapping
+(see
+.Xr map3270 5 ) .
+.Pp
+The first character of each special keyboard mapping sequence
+is either an
+.Tn ASCII
+escape
+.Pq Tn ESC ,
+a control character, or an
+.Tn ASCII
+delete
+.Pq Tn DEL .
+If the user types an unrecognized function key sequence,
+.Nm tn3270
+sends an
+.Tn ASCII
+bell
+.Pq Tn BEL ,
+or a visual bell if
+defined in the user's termcap entry, to the user's terminal
+and nothing is sent to the
+.Tn IBM
+host.
+.Pp
+If
+.Nm tn3270
+is invoked without specifying a remote host system name,
+it enters local command mode,
+indicated by the prompt
+.Dq Li tn3270>\ .
+In this mode,
+.Nm tn3270
+accepts and executes
+all the commands of
+.Xr telnet 1 ,
+plus one additional command:
+.Pp
+.Bl -tag -width Ar
+.It Ic transcom
+Specify
+.Tn UNIX
+command for
+.Tn IBM
+4994 style transparent mode processing.
+.El
+.Pp
+.Nm Tn3270
+command mode may also be entered, after connecting to a host, by typing
+a special escape sequence.
+If
+.Nm tn3270
+has succeeded in negotiating 3270 mode with the remote host, the
+escape sequence will be as defined by the map3270 (see
+.Xr map3270 5 )
+entry for the user's terminal type
+(typically control-C);
+otherwise the escape sequence will initially be set to the
+single character
+.Sq Li \&^]
+(control right square bracket).
+.Pp
+While in command mode, any host login session is still alive
+but temporarily suspended.
+The host login session may be resumed by entering an empty line
+(press the
+.Tn RETURN
+key)
+in response to the command prompt.
+A session may be terminated by logging off the foreign host,
+or by typing ``quit'' or ``close'' while in local command mode.
+.Sh FILES
+.Bl -tag -width /usr/share/misc/termcap -compact
+.It Pa /usr/share/misc/termcap
+.It Pa /usr/share/misc/map3270
+.El
+.\" .Sh AUTHOR
+.\" Greg Minshall
+.Sh NOTES
+The
+.Tn IBM
+4994 style transparent mode command is invoked when
+.Nm tn3270
+receives
+.Tn IBM
+4994 style transparent output from the remote host.
+Output and input pipes are created for communication between the two
+processes.
+The pipes are closed when a 3270 clear command is received from the remote
+hosts, signaling the end of transparent mode output.
+Transparent mode is necessary for sending
+.Tn ASCII
+control characters over the
+3270 terminal connection;
+.Tn ASCII
+graphics terminal support is accomplished this
+way.
+Developers of
+.Ic transcom
+commands should note that the
+.Ic transcom
+stdin pipe end will be in
+.Dv CBREAK
+mode, with
+.Dv ECHO
+and
+.Dv CRMOD
+turned off.
+.Sh ENVIRONMENT
+.Nm Tn3270
+checks the following environment variables:
+.Ev TERM ,
+.Ev MAP3270 ,
+.Ev MAP3270[A...] .
+Information on these can be found in
+.Xr mset 1 .
+.Nm Tn3270
+also checks
+.Ev SHELL ,
+.Ev KEYBD
+and
+.Ev API3270 .
+.Sh SEE ALSO
+.Xr mset 1 ,
+.Xr telnet 1 ,
+.Xr curses 3 ,
+.Xr termcap 3 ,
+.Xr termcap 5 ,
+.Xr map3270 5 ,
+.Rs
+.%T "Yale ASCII Terminal Communication"
+.%B "System II Program Description/Operator's Manual"
+.%R IBM SB30-1911
+.Re
+.Sh HISTORY
+The
+.Nm tn3270
+command appeared in
+.Bx 4.3 .
+.Sh BUGS
+Tn3270 is slow and uses system resources prodigiously.
+.Pp
+Not all 3270 functions are supported,
+nor all Yale enhancements.
+.Pp
+Error conditions (attempting to enter data in a protected field, for
+example) should cause a message to be sent to the user's terminal
+instead of just ringing a bell.
diff --git a/usr.bin/tn3270/tools/Makefile b/usr.bin/tn3270/tools/Makefile
new file mode 100644
index 0000000..0b64f8f
--- /dev/null
+++ b/usr.bin/tn3270/tools/Makefile
@@ -0,0 +1,5 @@
+# @(#)Makefile 8.1 (Berkeley) 6/6/93
+
+SUBDIR= mkhits mkastosc mkastods mkdstoas mkdctype
+
+.include <bsd.subdir.mk>
diff --git a/usr.bin/tn3270/tools/mkastods/Makefile b/usr.bin/tn3270/tools/mkastods/Makefile
new file mode 100644
index 0000000..a2d36a1
--- /dev/null
+++ b/usr.bin/tn3270/tools/mkastods/Makefile
@@ -0,0 +1,9 @@
+# @(#)Makefile 8.1 (Berkeley) 6/6/93
+
+PROG= mkastods
+SRCS= mkastods.c asc_ebc.c ebc_disp.c
+CFLAGS+=-I${.CURDIR}/.. -I.
+NOMAN= noman
+.PATH: ${.CURDIR}/../../api
+
+.include <bsd.prog.mk>
diff --git a/usr.bin/tn3270/tools/mkastods/mkastods.c b/usr.bin/tn3270/tools/mkastods/mkastods.c
new file mode 100644
index 0000000..6a9f72e
--- /dev/null
+++ b/usr.bin/tn3270/tools/mkastods/mkastods.c
@@ -0,0 +1,77 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1988, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)mkastods.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include <stdio.h>
+#if defined(unix)
+#include <strings.h>
+#else /* defined(unix) */
+#include <string.h>
+#endif /* defined(unix) */
+#include <ctype.h>
+#include "../api/asc_ebc.h"
+#include "../api/ebc_disp.h"
+
+int
+main()
+{
+ int i;
+
+ /* For each ascii code, find the display code that matches */
+
+ printf("unsigned char asc_disp[256] = {");
+ for (i = 0; i < NASCII; i++) {
+ if ((i%8) == 0) {
+ printf("\n");
+ }
+ printf("\t0x%02x,", ebc_disp[asc_ebc[i]]);
+ }
+ for (i = sizeof disp_ebc; i < 256; i++) {
+ if ((i%8) == 0) {
+ printf("\n");
+ }
+ printf("\t0x%02x,", 0);
+ }
+ printf("\n};\n");
+
+ return 0;
+}
diff --git a/usr.bin/tn3270/tools/mkastosc/Makefile b/usr.bin/tn3270/tools/mkastosc/Makefile
new file mode 100644
index 0000000..a6268f5
--- /dev/null
+++ b/usr.bin/tn3270/tools/mkastosc/Makefile
@@ -0,0 +1,9 @@
+# @(#)Makefile 8.1 (Berkeley) 6/6/93
+
+PROG= mkastosc
+SRCS= mkastosc.c dohits.c asc_ebc.c ebc_disp.c
+CFLAGS+=-I${.CURDIR}/../mkhits -I${.CURDIR}/.. -I.
+NOMAN= noman
+.PATH: ${.CURDIR}/../mkhits ${.CURDIR}/../../api
+
+.include <bsd.prog.mk>
diff --git a/usr.bin/tn3270/tools/mkastosc/mkastosc.c b/usr.bin/tn3270/tools/mkastosc/mkastosc.c
new file mode 100644
index 0000000..697122d
--- /dev/null
+++ b/usr.bin/tn3270/tools/mkastosc/mkastosc.c
@@ -0,0 +1,166 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1988, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)mkastosc.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include <stdio.h>
+#if defined(unix)
+#include <strings.h>
+#else /* defined(unix) */
+#include <string.h>
+#endif /* defined(unix) */
+#include <ctype.h>
+
+#include "../general/general.h"
+#include "../ctlr/function.h"
+
+#include "dohits.h"
+
+static struct tbl {
+ unsigned char
+ scancode,
+ used;
+ char
+ *shiftstate;
+} tbl[128];
+
+int
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ int scancode;
+ int asciicode;
+ int empty;
+ int i;
+ int c;
+ int found;
+ struct hits *ph;
+ struct Hits *Ph;
+ struct thing *this;
+ struct thing **attable;
+ struct tbl *Pt;
+ static char *shiftof[] =
+ { "0", "SHIFT_UPSHIFT", "SHIFT_ALT", "SHIFT_ALT|SHIFT_UPSHIFT" };
+ char *aidfile = 0, *fcnfile = 0;
+
+ if (argc > 1) {
+ if (argv[1][0] != '-') {
+ aidfile = argv[1];
+ }
+ }
+ if (argc > 2) {
+ if (argv[2][0] != '-') {
+ fcnfile = argv[2];
+ }
+ }
+
+ dohits(aidfile, fcnfile); /* Set up "Hits" */
+
+ printf("/*\n");
+ printf(" * Ascii to scancode conversion table. First\n");
+ printf(" * 128 bytes (0-127) correspond with actual Ascii\n");
+ printf(" * characters; the rest are functions from ctrl/function.h\n");
+ printf(" */\n");
+ /* Build the ascii part of the table. */
+ for (Ph = Hits, scancode = 0; Ph <= Hits+highestof(Hits);
+ Ph++, scancode++) {
+ ph = &Ph->hits;
+ for (i = 0; i < 4; i++) {
+ if (ph->hit[i].ctlrfcn == FCN_CHARACTER) {
+ c = Ph->name[i][0]; /* "name" of this one */
+ if (tbl[c].used == 0) {
+ tbl[c].used = 1;
+ tbl[c].shiftstate = shiftof[i];
+ tbl[c].scancode = scancode;
+ }
+ }
+ }
+ }
+ /* Now, output the table */
+ for (Pt = tbl, asciicode = 0; Pt <= tbl+highestof(tbl); Pt++, asciicode++) {
+ if (Pt->used == 0) {
+ if (isprint(asciicode) && (asciicode != ' ')) {
+ fprintf(stderr, "Unable to produce scancode sequence for");
+ fprintf(stderr, " ASCII character [%c]!\n", asciicode);
+ }
+ printf("\t{ 0, 0, undefined, 0 },\t");
+ } else {
+ printf("\t{ 0x%02x, %s, FCN_CHARACTER, 0 },",
+ Pt->scancode, Pt->shiftstate);
+ }
+ printf("\t/* 0x%x", asciicode);
+ if (isprint(asciicode)) {
+ printf(" [%c]", asciicode);
+ }
+ printf(" */\n");
+ }
+
+
+ for (attable = &table[0]; attable <= &table[highestof(table)]; attable++) {
+ for (this = *attable; this; this = this->next) {
+ Ph = this->hits;
+ if (Ph == 0) {
+ continue;
+ }
+ for (i = 0; i < 4; i++) {
+ if ((Ph->name[i] != 0) &&
+ (Ph->name[i][0] == this->name[0]) &&
+ (strcmp(Ph->name[i], this->name) == 0)) {
+ printf("\t{ 0x%02x, %s, ",
+ Ph-Hits, shiftof[i]);
+ if (memcmp("AID_", this->name, 4) == 0) { /* AID key */
+ printf("FCN_AID, ");
+ } else {
+ printf("%s, ", Ph->name[i]);
+ }
+ if (memcmp("PF", this->name+4, 2) == 0) {
+ printf("\"PFK%s\" },\n", Ph->name[i]+4+2);
+ } else {
+ printf("\"%s\" },\n", Ph->name[i]+4);
+ }
+ }
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/usr.bin/tn3270/tools/mkdctype/Makefile b/usr.bin/tn3270/tools/mkdctype/Makefile
new file mode 100644
index 0000000..818bb52
--- /dev/null
+++ b/usr.bin/tn3270/tools/mkdctype/Makefile
@@ -0,0 +1,9 @@
+# @(#)Makefile 8.1 (Berkeley) 6/6/93
+
+PROG= mkdctype
+SRCS= mkdctype.c ebc_disp.c ectype.c
+CFLAGS+=-I${.CURDIR}/.. -I.
+NOMAN= noman
+.PATH: ${.CURDIR}/../../api
+
+.include <bsd.prog.mk>
diff --git a/usr.bin/tn3270/tools/mkdctype/ectype.c b/usr.bin/tn3270/tools/mkdctype/ectype.c
new file mode 100644
index 0000000..ebdca0b
--- /dev/null
+++ b/usr.bin/tn3270/tools/mkdctype/ectype.c
@@ -0,0 +1,313 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)ectype.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include "ectype.h"
+
+char ectype[] = {
+/* 0x00 */
+ E_SPACE,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+/* 0x10 */
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+/* 0x20 */
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+/* 0x30 */
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+/* 0x40 */
+ E_SPACE,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ E_PRINT|E_PUNCT,
+ E_PRINT|E_PUNCT,
+ E_PRINT|E_PUNCT,
+ E_PRINT|E_PUNCT,
+ E_PRINT|E_PUNCT,
+ E_PRINT|E_PUNCT,
+/* 0x50 */
+ E_PRINT|E_PUNCT,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ E_PRINT|E_PUNCT,
+ E_PRINT|E_PUNCT,
+ E_PRINT|E_PUNCT,
+ E_PRINT|E_PUNCT,
+ E_PRINT|E_PUNCT,
+ E_PRINT|E_PUNCT,
+/* 0x60 */
+ E_PRINT|E_PUNCT,
+ E_PRINT|E_PUNCT,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ E_PRINT|E_PUNCT,
+ E_PRINT|E_PUNCT,
+ E_PRINT|E_PUNCT,
+ E_PRINT|E_PUNCT,
+ E_PRINT|E_PUNCT,
+ E_PRINT|E_PUNCT,
+/* 0x70 */
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ E_PRINT|E_PUNCT,
+ E_PRINT|E_PUNCT,
+ E_PRINT|E_PUNCT,
+ E_PRINT|E_PUNCT,
+ E_PRINT|E_PUNCT,
+ E_PRINT|E_PUNCT,
+ E_PRINT|E_PUNCT,
+/* 0x80 */
+ 0x00,
+ E_PRINT|E_LOWER,
+ E_PRINT|E_LOWER,
+ E_PRINT|E_LOWER,
+ E_PRINT|E_LOWER,
+ E_PRINT|E_LOWER,
+ E_PRINT|E_LOWER,
+ E_PRINT|E_LOWER,
+ E_PRINT|E_LOWER,
+ E_PRINT|E_LOWER,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+/* 0x90 */
+ 0x00,
+ E_PRINT|E_LOWER,
+ E_PRINT|E_LOWER,
+ E_PRINT|E_LOWER,
+ E_PRINT|E_LOWER,
+ E_PRINT|E_LOWER,
+ E_PRINT|E_LOWER,
+ E_PRINT|E_LOWER,
+ E_PRINT|E_LOWER,
+ E_PRINT|E_LOWER,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+/* 0xA0 */
+ 0x00,
+ E_PRINT|E_PUNCT,
+ E_PRINT|E_LOWER,
+ E_PRINT|E_LOWER,
+ E_PRINT|E_LOWER,
+ E_PRINT|E_LOWER,
+ E_PRINT|E_LOWER,
+ E_PRINT|E_LOWER,
+ E_PRINT|E_LOWER,
+ E_PRINT|E_LOWER,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+/* 0xB0 */
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+/* 0xC0 */
+ E_PRINT|E_PUNCT,
+ E_PRINT|E_UPPER,
+ E_PRINT|E_UPPER,
+ E_PRINT|E_UPPER,
+ E_PRINT|E_UPPER,
+ E_PRINT|E_UPPER,
+ E_PRINT|E_UPPER,
+ E_PRINT|E_UPPER,
+ E_PRINT|E_UPPER,
+ E_PRINT|E_UPPER,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+/* 0xD0 */
+ E_PRINT|E_PUNCT,
+ E_PRINT|E_UPPER,
+ E_PRINT|E_UPPER,
+ E_PRINT|E_UPPER,
+ E_PRINT|E_UPPER,
+ E_PRINT|E_UPPER,
+ E_PRINT|E_UPPER,
+ E_PRINT|E_UPPER,
+ E_PRINT|E_UPPER,
+ E_PRINT|E_UPPER,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+/* 0xE0 */
+ E_PRINT|E_PUNCT,
+ 0x00,
+ E_PRINT|E_UPPER,
+ E_PRINT|E_UPPER,
+ E_PRINT|E_UPPER,
+ E_PRINT|E_UPPER,
+ E_PRINT|E_UPPER,
+ E_PRINT|E_UPPER,
+ E_PRINT|E_UPPER,
+ E_PRINT|E_UPPER,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+/* 0xF0 */
+ E_PRINT|E_DIGIT,
+ E_PRINT|E_DIGIT,
+ E_PRINT|E_DIGIT,
+ E_PRINT|E_DIGIT,
+ E_PRINT|E_DIGIT,
+ E_PRINT|E_DIGIT,
+ E_PRINT|E_DIGIT,
+ E_PRINT|E_DIGIT,
+ E_PRINT|E_DIGIT,
+ E_PRINT|E_DIGIT,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
diff --git a/usr.bin/tn3270/tools/mkdctype/ectype.h b/usr.bin/tn3270/tools/mkdctype/ectype.h
new file mode 100644
index 0000000..15dfb86
--- /dev/null
+++ b/usr.bin/tn3270/tools/mkdctype/ectype.h
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)ectype.h 8.1 (Berkeley) 6/6/93
+ */
+
+#define INCLUDED_ECTYPE
+
+#define E_UPPER 0x01
+#define E_LOWER 0x02
+#define E_DIGIT 0x04
+#define E_SPACE 0x08
+#define E_PUNCT 0x10
+#define E_PRINT 0x20
+
+#define Eisalpha(c) (ectype[(c)&0xff]&(E_UPPER|E_LOWER))
+#define Eisupper(c) (ectype[(c)&0xff]&E_UPPER)
+#define Eislower(c) (ectype[(c)&0xff]&E_LOWER)
+#define Eisdigit(c) (ectype[(c)&0xff]&E_DIGIT)
+#define Eisalnum(c) (ectype[(c)&0xff]&(E_UPPER|E_LOWER|E_DIGIT))
+#define Eisspace(c) (ectype[(c)&0xff]&E_SPACE) /* blank or null */
+#define Eispunct(c) (ectype[(c)&0xff]&E_PUNCT)
+#define Eisprint(c) (ectype[(c)&0xff]&E_PRINT)
diff --git a/usr.bin/tn3270/tools/mkdctype/mkdctype.c b/usr.bin/tn3270/tools/mkdctype/mkdctype.c
new file mode 100644
index 0000000..24ee095
--- /dev/null
+++ b/usr.bin/tn3270/tools/mkdctype/mkdctype.c
@@ -0,0 +1,99 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1988, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)mkdctype.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include "../api/ebc_disp.h"
+#include "ectype.h"
+
+
+extern unsigned char ectype[256];
+
+
+void
+main()
+{
+ static unsigned char dctype[192] = { 0 };
+ int i;
+ char *orbar;
+ int type;
+
+ for (i = 0; i < sizeof ectype; i++) {
+ dctype[ebc_disp[i]] = ectype[i];
+ }
+
+ for (i = 0; i < sizeof dctype; i++) {
+ if ((i%16) == 0) {
+ printf("/*%02x*/\n", i);
+ }
+ printf("\t");
+ type = dctype[i];
+ orbar = "";
+ if (type & E_UPPER) {
+ printf("E_UPPER");
+ orbar = "|";
+ }
+ if (type & E_LOWER) {
+ printf("%sD_LOWER", orbar);
+ orbar = "|";
+ }
+ if (type & E_DIGIT) {
+ printf("%sD_DIGIT", orbar);
+ orbar = "|";
+ }
+ if (type & E_SPACE) {
+ printf("%sD_SPACE", orbar);
+ orbar = "|";
+ }
+ if (type & E_PUNCT) {
+ printf("%sD_PUNCT", orbar);
+ orbar = "|";
+ }
+ if (type & E_PRINT) {
+ printf("%sD_PRINT", orbar);
+ orbar = "|";
+ }
+ if (orbar[0] == 0) {
+ printf("0");
+ }
+ printf(",\n");
+ }
+}
diff --git a/usr.bin/tn3270/tools/mkdstoas/Makefile b/usr.bin/tn3270/tools/mkdstoas/Makefile
new file mode 100644
index 0000000..b2abeb3
--- /dev/null
+++ b/usr.bin/tn3270/tools/mkdstoas/Makefile
@@ -0,0 +1,9 @@
+# @(#)Makefile 8.1 (Berkeley) 6/6/93
+
+PROG= mkdstoas
+SRCS= mkdstoas.c asc_ebc.c ebc_disp.c
+CFLAGS+=-I${.CURDIR}/.. -I.
+NOMAN= noman
+.PATH: ${.CURDIR}/../../api
+
+.include <bsd.prog.mk>
diff --git a/usr.bin/tn3270/tools/mkdstoas/mkdstoas.c b/usr.bin/tn3270/tools/mkdstoas/mkdstoas.c
new file mode 100644
index 0000000..befd3c6
--- /dev/null
+++ b/usr.bin/tn3270/tools/mkdstoas/mkdstoas.c
@@ -0,0 +1,78 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1988, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)mkdstoas.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include <stdio.h>
+#if defined(unix)
+#include <strings.h>
+#else /* defined(unix) */
+#include <string.h>
+#endif /* defined(unix) */
+#include <ctype.h>
+#include "../api/asc_ebc.h"
+#include "../api/ebc_disp.h"
+
+
+int
+main()
+{
+ int i;
+
+ /* For each display code, find the ascii code that matches */
+
+ printf("unsigned char disp_asc[256] = {");
+ for (i = 0; i < sizeof disp_ebc; i++) {
+ if ((i%8) == 0) {
+ printf("\n");
+ }
+ printf("\t0x%02x,", ebc_asc[disp_ebc[i]]);
+ }
+ for (i = sizeof disp_ebc; i < 256; i++) {
+ if ((i%8) == 0) {
+ printf("\n");
+ }
+ printf("\t0x%02x,", ' ');
+ }
+ printf("\n};\n");
+
+ return 0;
+}
diff --git a/usr.bin/tn3270/tools/mkhits/Makefile b/usr.bin/tn3270/tools/mkhits/Makefile
new file mode 100644
index 0000000..c7c8802
--- /dev/null
+++ b/usr.bin/tn3270/tools/mkhits/Makefile
@@ -0,0 +1,9 @@
+# @(#)Makefile 8.1 (Berkeley) 6/6/93
+
+PROG= mkhits
+SRCS= mkhits.c dohits.c asc_ebc.c ebc_disp.c
+CFLAGS+=-I${.CURDIR}/.. -I.
+NOMAN= noman
+.PATH: ${.CURDIR}/../../api
+
+.include <bsd.prog.mk>
diff --git a/usr.bin/tn3270/tools/mkhits/dohits.c b/usr.bin/tn3270/tools/mkhits/dohits.c
new file mode 100644
index 0000000..d2d576e
--- /dev/null
+++ b/usr.bin/tn3270/tools/mkhits/dohits.c
@@ -0,0 +1,295 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)dohits.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+/*
+ * This program scans a file which describes a keyboard. The output
+ * of the program is a series of 'C' declarations which describe a
+ * mapping between (scancode, shiftstate, altstate) and 3270 functions,
+ * characters, and AIDs.
+ *
+ * The format of the input file is as follows:
+ *
+ * keynumber [ scancode [ unshifted [ shifted [ alted [ shiftalted ] ] ] ] ]
+ *
+ * keynumber is in decimal, and starts in column 1.
+ * scancode is hexadecimal.
+ * unshifted, etc. - these are either a single ascii character,
+ * or the name of a function or an AID-generating key.
+ *
+ * all fields are separated by a single space.
+ */
+
+#include <stdio.h>
+#if defined(unix)
+#include <strings.h>
+#else /* defined(unix) */
+#include <string.h>
+#endif /* defined(unix) */
+#include <ctype.h>
+#include "../general/general.h"
+#include "../api/asc_ebc.h"
+#include "../api/ebc_disp.h"
+#include "../ctlr/function.h"
+
+#include "dohits.h"
+
+struct Hits Hits[256]; /* one for each of 0x00-0xff */
+
+struct thing *table[100];
+
+extern char *malloc();
+
+unsigned int
+dohash(seed, string)
+unsigned int seed;
+char *string;
+{
+ register unsigned int i = seed;
+ register unsigned char c;
+
+ while (c = *string++) {
+ if (c >= 0x60) {
+ c -= (0x60+0x20);
+ } else {
+ c -= 0x20;
+ }
+ i = (i>>26) + (i<<6) + (c&0x3f);
+ }
+ return i;
+}
+
+void
+add(first, second, value)
+char *first, *second;
+int value;
+{
+ struct thing **item, *this;
+
+ item = &firstentry(second);
+ this = (struct thing *) malloc(sizeof *this);
+ this->next = *item;
+ *item = this;
+ this->value = value;
+ strcpy(this->name, first);
+ strcpy(this->name+strlen(this->name), second);
+}
+
+void
+scanwhite(file, prefix)
+char *file, /* Name of file to scan for whitespace prefix */
+ *prefix; /* prefix of what should be picked up */
+{
+ FILE *ourfile;
+ char compare[100];
+ char what[100], value[100];
+ char line[200];
+
+ sprintf(compare, " %s%%[^,\t \n]", prefix);
+ if ((ourfile = fopen(file, "r")) == NULL) {
+ perror("fopen");
+ exit(1);
+ }
+ while (!feof(ourfile)) {
+ if (fscanf(ourfile, compare, what) == 1) {
+ add(prefix, what, 0);
+ }
+ do {
+ if (fgets(line, sizeof line, ourfile) == NULL) {
+ if (!feof(ourfile)) {
+ perror("fgets");
+ }
+ break;
+ }
+ } while (line[strlen(line)-1] != '\n');
+ }
+}
+
+void
+scandefine(file, prefix)
+char *file, /* Name of file to scan for #define prefix */
+ *prefix; /* prefix of what should be picked up */
+{
+ FILE *ourfile;
+ char compare[100];
+ char what[100], value[100];
+ char line[200];
+ int whatitis;
+
+ sprintf(compare, "#define %s%%s %%s", prefix);
+ if ((ourfile = fopen(file, "r")) == NULL) {
+ perror("fopen");
+ exit(1);
+ }
+ while (!feof(ourfile)) {
+ if (fscanf(ourfile, compare, what, value) == 2) {
+ if (value[0] == '0') {
+ if ((value[1] == 'x') || (value[1] == 'X')) {
+ sscanf(value, "0x%x", &whatitis);
+ } else {
+ sscanf(value, "0%o", &whatitis);
+ }
+ } else {
+ sscanf(value, "%d", &whatitis);
+ }
+ add(prefix, what, whatitis);
+ }
+ do {
+ if (fgets(line, sizeof line, ourfile) == NULL) {
+ if (!feof(ourfile)) {
+ perror("fgets");
+ }
+ break;
+ }
+ } while (line[strlen(line)-1] != '\n');
+ }
+}
+
+char *savechr(c)
+unsigned char c;
+{
+ char *foo;
+
+ foo = malloc(sizeof c);
+ if (foo == 0) {
+ fprintf(stderr, "No room for ascii characters!\n");
+ exit(1);
+ }
+ *foo = c;
+ return foo;
+}
+
+char *
+doit(hit, type, hits)
+struct hit *hit;
+unsigned char *type;
+struct Hits *hits;
+{
+ struct thing *this;
+
+ hit->ctlrfcn = FCN_NULL;
+ if (type[0] == 0) {
+ return 0;
+ }
+ if (type[1] == 0) { /* character */
+ hit->ctlrfcn = FCN_CHARACTER;
+ hit->code = ebc_disp[asc_ebc[type[0]]];
+ return savechr(*type); /* The character is the name */
+ } else {
+ for (this = firstentry(type); this; this = this->next) {
+ if ((type[0] == this->name[4])
+ && (strcmp(type, this->name+4) == 0)) {
+ this->hits = hits;
+ if (this->name[0] == 'F') {
+ hit->ctlrfcn = FCN_NULL; /* XXX */
+ } else {
+ hit->ctlrfcn = FCN_AID;
+ }
+ return this->name;
+ }
+ }
+ fprintf(stderr, "Error: Unknown type %s.\n", type);
+ return 0;
+ }
+}
+
+
+void
+dohits(aidfile, fcnfile)
+char *aidfile, *fcnfile;
+{
+ unsigned char plain[100], shifted[100], alted[100], shiftalted[100];
+ unsigned char line[200];
+ int keynumber, scancode;
+ int empty;
+ int i;
+ struct hit *hit;
+ struct hits *ph;
+ struct Hits *Ph;
+
+ memset((char *)Hits, 0, sizeof Hits);
+
+ /*
+ * First, we read "host3270.h" to find the names/values of
+ * various AID; then we read kbd3270.h to find the names/values
+ * of various FCNs.
+ */
+
+ if (aidfile == 0) {
+ aidfile = "../ctlr/hostctlr.h";
+ }
+ scandefine(aidfile, "AID_");
+ if (fcnfile == 0) {
+ fcnfile = "../ctlr/function.h";
+ }
+ scanwhite(fcnfile, "FCN_");
+
+ while (gets(line) != NULL) {
+ if (!isdigit(line[0])) {
+ continue;
+ }
+ plain[0] = shifted[0] = alted[0] = shiftalted[0] = 0;
+ keynumber = -1;
+ scancode = -1;
+ (void) sscanf(line, "%d %x %s %s %s %s", &keynumber,
+ &scancode, plain, shifted, alted, shiftalted);
+ if ((keynumber == -1) || (scancode == -1)
+ || ((plain[0] == 0)
+ && (shifted[0] == 0)
+ && (alted[0] == 0)
+ && (shiftalted[0] == 0))) {
+ continue;
+ }
+ if (scancode >= 256) {
+ fprintf(stderr,
+ "Error: scancode 0x%02x for keynumber %d\n", scancode,
+ keynumber);
+ break;
+ }
+ if (Hits[scancode].hits.hit[0].ctlrfcn != undefined) {
+ fprintf(stderr,
+ "Error: duplicate scancode 0x%02x for keynumber %d\n",
+ scancode, keynumber);
+ break;
+ }
+ hit = Hits[scancode].hits.hit;
+ Hits[scancode].hits.keynumber = keynumber;
+ Hits[scancode].name[0] = doit(hit, plain, &Hits[scancode]);
+ Hits[scancode].name[1] = doit(hit+1, shifted, &Hits[scancode]);
+ Hits[scancode].name[2] = doit(hit+2, alted, &Hits[scancode]);
+ Hits[scancode].name[3] = doit(hit+3, shiftalted, &Hits[scancode]);
+ }
+}
diff --git a/usr.bin/tn3270/tools/mkhits/dohits.h b/usr.bin/tn3270/tools/mkhits/dohits.h
new file mode 100644
index 0000000..9c26eca
--- /dev/null
+++ b/usr.bin/tn3270/tools/mkhits/dohits.h
@@ -0,0 +1,56 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)dohits.h 8.1 (Berkeley) 6/6/93
+ */
+
+#define numberof(x) (sizeof x/sizeof x[0])
+#define highestof(x) (numberof(x)-1)
+
+#define firstentry(x) (table[dohash(0, (x))%highestof(table)])
+
+struct Hits {
+ struct hits hits;
+ char *name[4];
+};
+
+struct thing {
+ struct thing *next;
+ struct Hits *hits;
+ unsigned char value;
+ char name[100];
+};
+
+extern struct Hits Hits[256]; /* one for each of 0x00-0xff */
+extern struct thing *table[100];
+
+extern unsigned int dohash();
diff --git a/usr.bin/tn3270/tools/mkhits/mkhits.c b/usr.bin/tn3270/tools/mkhits/mkhits.c
new file mode 100644
index 0000000..0fafb8f
--- /dev/null
+++ b/usr.bin/tn3270/tools/mkhits/mkhits.c
@@ -0,0 +1,147 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1988, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)mkhits.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+/*
+ * This program scans a file which describes a keyboard. The output
+ * of the program is a series of 'C' declarations which describe a
+ * mapping between (scancode, shiftstate, altstate) and 3270 functions,
+ * characters, and AIDs.
+ *
+ * The format of the input file is as follows:
+ *
+ * keynumber [ scancode [ unshifted [ shifted [ alted [ shiftalted ] ] ] ] ]
+ *
+ * keynumber is in decimal, and starts in column 1.
+ * scancode is hexadecimal.
+ * unshifted, etc. - these are either a single ascii character,
+ * or the name of a function or an AID-generating key.
+ *
+ * all fields are separated by a single space.
+ */
+
+#include <stdio.h>
+#if defined(unix)
+#include <strings.h>
+#else /* defined(unix) */
+#include <string.h>
+#endif /* defined(unix) */
+#include <ctype.h>
+#include "../ctlr/function.h"
+
+#include "dohits.h"
+
+
+int
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ int scancode;
+ int empty;
+ int i;
+ struct hits *ph;
+ struct Hits *Ph;
+ char *aidfile = 0, *fcnfile = 0;
+
+ if (argc > 1) {
+ if (argv[1][0] != '-') {
+ aidfile = argv[1];
+ }
+ }
+ if (argc > 2) {
+ if (argv[2][0] != '-') {
+ fcnfile = argv[2];
+ }
+ }
+
+ dohits(aidfile, fcnfile); /* Set up "Hits" */
+
+ printf("struct hits hits[] = {\n");
+ empty = 0;
+ scancode = -1;
+ for (Ph = Hits; Ph < Hits+(sizeof Hits/sizeof Hits[0]); Ph++) {
+ ph = &Ph->hits;
+ scancode++;
+ if ((ph->hit[0].ctlrfcn == undefined)
+ && (ph->hit[1].ctlrfcn == undefined)
+ && (ph->hit[2].ctlrfcn == undefined)
+ && (ph->hit[3].ctlrfcn == undefined)) {
+ empty++;
+ continue;
+ } else {
+ while (empty) {
+ printf("\t{ 0, { {undefined}, {undefined}");
+ printf(", {undefined}, {undefined} } },\n");
+ empty--;
+ }
+ }
+ printf("\t{ %d, {\t/* 0x%02x */\n\t", ph->keynumber, scancode);
+ for (i = 0; i < 4; i++) {
+ printf("\t{ ");
+ switch (ph->hit[i].ctlrfcn) {
+ case undefined:
+ printf("undefined");
+ break;
+ case FCN_CHARACTER:
+ printf("FCN_CHARACTER, 0x%02x", ph->hit[i].code);
+ break;
+ case FCN_AID:
+ printf("FCN_AID, %s", Ph->name[i]);
+ break;
+ case FCN_NULL:
+ default:
+ if ((Ph->name[i] != 0)
+ && (strcmp(Ph->name[i], "FCN_NULL") != 0)) {
+ printf("%s", Ph->name[i]);
+ } else {
+ printf("undefined");
+ }
+ break;
+ }
+ printf(" },\n\t");
+ }
+ printf("} },\n");
+ }
+ printf("};\n");
+ return 0;
+}
diff --git a/usr.bin/tn3270/tools/mkmake.y b/usr.bin/tn3270/tools/mkmake.y
new file mode 100644
index 0000000..e9c2c6b
--- /dev/null
+++ b/usr.bin/tn3270/tools/mkmake.y
@@ -0,0 +1,1097 @@
+%{
+
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)mkmake.y 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+typedef struct string {
+ int
+ hashval,
+ length;
+ char
+ *string;
+ struct string
+ *next;
+} string_t;
+
+/*
+ * The deal with these is that they exist on various lists.
+ *
+ * First off, they are on a temporary list during the time they
+ * are in the active focus of the parser.
+ *
+ * Secondly, they live on one of three queues:
+ * 1. Variables
+ * 2. Targets
+ * 3. Actions
+ * (and, we restrict any given one to live on one and only one such list)
+ *
+ * Also, they may live on the list of values for someone else's variable,
+ * or as someone's dependancy.
+ */
+
+typedef struct same {
+ string_t
+ *string; /* My name */
+ struct same
+ *nexttoken, /* Next pointer */
+ *lasttoken, /* Back pointer */
+ *depend_list, /* If target, dependancies */
+ *action_list, /* If target, actions */
+ *value_list, /* If variable, value list */
+ *shell_item; /* If a shell variable, current value */
+} same_t;
+
+%}
+
+%union {
+ string_t *string;
+ same_t *same;
+ int intval;
+ }
+
+%start makefile
+%token <string> TOKEN QUOTED_STRING
+%token <intval> FOR IN DO DONE
+%token <intval> MACRO_CHAR NL WHITE_SPACE
+%token <intval> ':' '=' '$' '{' '}' ';' '-' '@' '(' ')' ' ' '\t'
+%type <same> target target1 assignment assign1 actions action
+%type <same> command_list list list_element
+%type <same> for_statement maybe_at_minus tokens token
+%type <same> maybe_white_space
+%type <intval> white_space macro_char
+%%
+
+makefile : lines;
+
+lines : line
+ | lines line
+ ;
+
+line : NL
+ | assignment
+ | target_action
+ ;
+
+assignment : assign1 tokens NL
+ {
+ assign($1, $2);
+ }
+ | assign1 NL
+ {
+ assign($1, same_copy(null));
+ }
+ ;
+
+assign1: token maybe_white_space '=' maybe_white_space
+ ;
+
+target_action: target actions
+ {
+ add_targets_actions($1, $2);
+ }
+ | target
+ {
+ add_targets_actions($1, 0);
+ }
+ ;
+
+target : target1 tokens NL
+ {
+ $$ = add_depends($1, $2);
+ }
+ | target1 NL
+ {
+ $$ = add_depends($1, same_copy(null));
+ }
+ ;
+
+target1: tokens maybe_white_space ':' maybe_white_space
+ {
+ $$ = ws_merge($1);
+ }
+ ;
+
+actions: action
+ | actions action
+ {
+ $$ = same_cat(same_cat($1, same_copy(newline)), $2);
+ }
+ ;
+
+action: white_space command_list NL
+ {
+ $$ = $2;
+ }
+ | white_space for_statement do command_list semi_colon done NL
+ {
+ $$ = do_command($2, $4);
+ }
+ ;
+
+for_statement: maybe_at_minus FOR white_space token
+ in tokens semi_colon
+ {
+ $$ = for_statement($1, $4, ws_merge(expand_variables($6, 0)));
+ }
+ ;
+
+in: white_space IN white_space
+do: white_space DO white_space
+ ;
+
+done: white_space DONE
+ ;
+
+semi_colon: ';'
+ ;
+
+command_list: list
+ | '(' list maybe_white_space ')'
+ {
+ $$ = same_cat($2, same_copy(cwd_line));
+ }
+ ;
+
+list: token
+ | list list_element
+ {
+ $$ = same_cat($1, $2);
+ }
+ | list white_space list_element
+ {
+ $$ = same_cat($1, same_cat(same_copy(blank), $3));
+ }
+ ;
+
+list_element: token
+ | semi_colon
+ {
+ $$ = same_copy(newline);
+ }
+ ;
+
+maybe_at_minus: /* empty */
+ {
+ $$ = same_copy(null);
+ }
+ | '@'
+ {
+ char buffer[2];
+
+ buffer[0] = $1;
+ buffer[1] = 0;
+ $$ = same_item(string_lookup(buffer));
+ }
+ | '-'
+ {
+ char buffer[2];
+
+ buffer[0] = $1;
+ buffer[1] = 0;
+ $$ = same_item(string_lookup(buffer));
+ }
+ ;
+
+tokens : token
+ | tokens maybe_white_space token
+ {
+ $$ = same_cat($1, same_cat($2, $3));
+ }
+ ;
+
+token: TOKEN
+ {
+ $$ = same_item($1);
+ }
+ | QUOTED_STRING
+ {
+ $$ = same_item($1);
+ }
+ | '$' macro_char
+ {
+ char buffer[3];
+
+ buffer[0] = '$';
+ buffer[1] = $2;
+ buffer[2] = 0;
+
+ $$ = same_item(string_lookup(buffer));
+ }
+ | '$' '$' TOKEN
+ {
+ $$ = shell_variable(same_item($3));
+ }
+ | MACRO_CHAR
+ {
+ $$ = same_char($1);
+ }
+ | '$' '{' TOKEN '}'
+ {
+ $$ = variable(same_item($3));
+ }
+ | '$' '(' TOKEN ')'
+ {
+ $$ = variable(same_item($3));
+ }
+ | '$' TOKEN
+ {
+ $$ = variable(same_item($2));
+ }
+ | '-'
+ {
+ $$ = same_char('-');
+ }
+ | '@'
+ {
+ $$ = same_char('@');
+ }
+ ;
+
+macro_char: MACRO_CHAR
+ | '@'
+ ;
+
+maybe_white_space:
+ {
+ $$ = same_copy(null);
+ }
+ | white_space
+ {
+ $$ = same_char($1);
+ }
+ ;
+
+white_space : WHITE_SPACE
+ | white_space WHITE_SPACE
+ ;
+%%
+#include <stdio.h>
+#include <ctype.h>
+
+static int last_char, last_saved = 0;
+static int column = 0, lineno = 1;
+
+
+static string_t
+ *strings = 0;
+
+static same_t
+ *shell_variables = 0,
+ *shell_special = 0,
+ *variables = 0,
+ *targets = 0,
+ *actions = 0;
+
+static same_t
+ *null,
+ *blank,
+ *cwd_line,
+ *newline;
+
+extern char *malloc();
+
+static unsigned int
+ clock = -1;
+
+struct {
+ same_t *first;
+ int next;
+} visit_stack[20]; /* 20 maximum */
+
+#define visit(what,via) \
+ (visit_stack[++clock].next = 0, visit_stack[clock].first = via = what)
+#define visited(via) (visitcheck(via) || ((via) == 0) \
+ || (visit_stack[clock].next && (via == visit_stack[clock].first)))
+#define visit_next(via) (visit_stack[clock].next = 1, (via) = (via)->nexttoken)
+#define visit_end() (clock--)
+
+yyerror(s)
+char *s;
+{
+ fprintf(stderr, "line %d, character %d: %s\n", lineno, column, s);
+ do_dump();
+}
+
+int
+visitcheck(same)
+same_t *same;
+{
+ if (same->string == 0) {
+ yyerror("BUG - freed 'same' in use...");
+ exit(1);
+ }
+ return 0;
+}
+
+int
+string_hashof(string, length)
+char *string;
+int length;
+{
+ register int i = 0;
+
+ while (length--) {
+ i = (i<<3) + *string ^ ((i>>28)&0x7);
+ }
+ return i;
+}
+
+int
+string_same(s1, s2)
+string_t
+ *s1, *s2;
+{
+ if ((s1->hashval == s2->hashval) && (s1->length == s2->length)
+ && (memcmp(s1->string, s2->string, s1->length) == 0)) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+string_t *
+string_lookup(string)
+char *string;
+{
+ string_t ours;
+ string_t *ptr;
+
+ ours.length = strlen(string);
+ ours.hashval = string_hashof(string, ours.length);
+ ours.string = string;
+
+ for (ptr = strings; ptr; ptr = ptr->next) {
+ if (string_same(&ours, ptr)) {
+ return ptr;
+ }
+ }
+ if ((ptr = (string_t *)malloc(sizeof *ptr)) == 0) {
+ fprintf(stderr, "No space to add string *%s*!\n", string);
+ exit(1);
+ }
+ ptr->hashval = ours.hashval;
+ ptr->length = ours.length;
+ if ((ptr->string = malloc(ours.length+1)) == 0) {
+ fprintf(stderr, "No space to add literal *%s*!\n", string);
+ exit(1);
+ }
+ memcpy(ptr->string, string, ours.length+1);
+ ptr->next = strings;
+ strings = ptr;
+ return ptr;
+}
+
+#define same_singleton(s) ((s)->nexttoken == (s))
+
+same_t *
+same_search(list, token)
+same_t
+ *list,
+ *token;
+{
+ same_t *ptr;
+
+ ptr = list;
+ for (visit(list, ptr); !visited(ptr); visit_next(ptr)) {
+ string_t *string;
+
+ string = ptr->string;
+ if (string_same(string, token->string)) {
+ visit_end();
+ return ptr;
+ }
+ }
+ visit_end();
+ return 0;
+}
+
+same_t *
+same_cat(list, tokens)
+same_t
+ *list,
+ *tokens;
+{
+ same_t *last;
+
+ if (tokens == 0) {
+ return list;
+ }
+ if (list) {
+ last = tokens->lasttoken;
+ tokens->lasttoken = list->lasttoken;
+ list->lasttoken = last;
+ tokens->lasttoken->nexttoken = tokens;
+ last->nexttoken = list;
+ return list;
+ } else {
+ return tokens;
+ }
+}
+
+same_t *
+same_item(string)
+string_t *string;
+{
+ same_t *ptr;
+
+ if ((ptr = (same_t *)malloc(sizeof *ptr)) == 0) {
+ fprintf(stderr, "No more space for tokens!\n");
+ exit(1);
+ }
+ memset((char *)ptr, 0, sizeof *ptr);
+ ptr->nexttoken = ptr->lasttoken = ptr;
+ ptr->string = string;
+ return ptr;
+}
+
+same_t *
+same_copy(same)
+same_t *same;
+{
+ same_t *head, *copy;
+
+ head = 0;
+ for (visit(same, copy); !visited(copy); visit_next(copy)) {
+ same_t *ptr;
+
+ ptr = same_item(copy->string);
+ head = same_cat(head, ptr);
+ }
+ visit_end();
+ return head;
+}
+
+
+same_t *
+same_merge(t1, t2)
+same_t
+ *t1,
+ *t2;
+{
+ if (same_singleton(t1) && same_singleton(t2)) {
+ int length = strlen(t1->string->string)+strlen(t2->string->string);
+ char *buffer = malloc(length+1);
+ same_t *value;
+
+ if (buffer == 0) {
+ yyerror("No space to merge strings in same_merge!");
+ exit(1);
+ }
+ strcpy(buffer, t1->string->string);
+ strcat(buffer, t2->string->string);
+ value = same_item(string_lookup(buffer));
+ free(buffer);
+ return value;
+ } else {
+ yyerror("Internal error - same_merge with non-singletons");
+ exit(1);
+ }
+}
+
+
+void
+same_free(list)
+same_t *list;
+{
+ same_t *token, *ptr;
+
+ if (list == 0) {
+ return;
+ }
+
+ token = list;
+ do {
+ ptr = token->nexttoken;
+ token->string = 0;
+ (void) free((char *)token);
+ token = ptr;
+ } while (token != list);
+}
+
+same_t *
+same_unlink(token)
+same_t
+ *token;
+{
+ same_t *tmp;
+
+ if (token == 0) {
+ return 0;
+ }
+ if ((tmp = token->nexttoken) == token) {
+ tmp = 0;
+ }
+ token->lasttoken->nexttoken = token->nexttoken;
+ token->nexttoken->lasttoken = token->lasttoken;
+ token->nexttoken = token->lasttoken = token;
+ return tmp;
+}
+
+void
+same_replace(old, new)
+same_t
+ *old,
+ *new;
+{
+ new->lasttoken->nexttoken = old->nexttoken;
+ old->nexttoken->lasttoken = new->lasttoken;
+ new->lasttoken = old->lasttoken;
+ /* rather than
+ * old->lasttoken->nexttoken = new
+ * we update in place (for the case where there isn't anything else)
+ */
+ *old = *new;
+}
+
+
+same_t *
+same_char(ch)
+char ch;
+{
+ char buffer[2];
+
+ buffer[0] = ch;
+ buffer[1] = 0;
+
+ return same_item(string_lookup(buffer));
+}
+
+
+void
+add_target(target, actions)
+same_t
+ *target,
+ *actions;
+{
+ same_t *ptr;
+
+ if ((ptr = same_search(targets, target)) == 0) {
+ targets = same_cat(targets, target);
+ ptr = target;
+ } else {
+ ptr->depend_list = same_cat(ptr->depend_list, target->depend_list);
+ }
+ if (actions) {
+ if (ptr->action_list) {
+ same_free(ptr->action_list);
+ }
+ ptr->action_list = same_copy(actions);
+ }
+}
+
+
+same_t *
+add_targets_actions(target, actions)
+same_t
+ *target,
+ *actions;
+{
+ same_t *ptr;
+
+ if (target == 0) {
+ return 0;
+ }
+ do {
+ ptr = same_unlink(target);
+ add_target(target, actions);
+ target = ptr;
+ } while (target);
+
+ same_free(actions);
+ return 0;
+}
+
+same_t *
+add_depends(target, depends)
+same_t
+ *target,
+ *depends;
+{
+ same_t *original = target;
+
+ depends = same_cat(depends, same_copy(blank)); /* Separator */
+
+ for (visit(original, target); !visited(target); visit_next(target)) {
+ target->depend_list = same_cat(target->depend_list, same_copy(depends));
+ }
+ visit_end();
+ same_free(depends);
+
+ return original;
+}
+
+
+/*
+ * We know that variable is a singleton
+ */
+
+void
+assign(variable, value)
+same_t
+ *variable,
+ *value;
+{
+ same_t *ptr;
+
+ if ((ptr = same_search(variables, variable)) != 0) {
+ same_free(ptr->value_list);
+ variables = same_unlink(ptr);
+ same_free(ptr);
+ }
+ variable->value_list = value;
+ variables = same_cat(variables, variable);
+}
+
+same_t *
+value_of(variable)
+same_t *variable;
+{
+ same_t *ptr = same_search(variables, variable);
+
+ if (ptr == 0) {
+ return same_copy(null);
+ } else {
+ return same_copy(ptr->value_list);
+ }
+}
+
+
+same_t *
+expand_variables(token, free)
+same_t *token;
+int free;
+{
+ same_t *head = 0;
+
+ if (!free) {
+ token = same_copy(token); /* Get our private copy */
+ }
+
+ while (token) {
+ char *string = token->string->string;
+ same_t *tmp = same_unlink(token);
+
+ if ((string[0] == '$') && (string[1] == '{')) { /* Expand time */
+ int len = strlen(string);
+
+ string[len-1] = 0;
+ head = same_cat(head, expand_variables(
+ value_of(same_item(string_lookup(string+2))), 1));
+ string[len-1] = '}';
+ } else {
+ head = same_cat(head, token);
+ }
+ token = tmp;
+ }
+ return head;
+}
+
+
+same_t *
+ws_merge(list)
+same_t *list;
+{
+ same_t *newlist = 0, *item;
+ int what = 0;
+
+ while (list) {
+ switch (what) {
+ case 0:
+ if (isspace(list->string->string[0])) {
+ ;
+ } else {
+ item = same_item(list->string);
+ what = 1;
+ }
+ break;
+ case 1:
+ if (isspace(list->string->string[0])) {
+ newlist = same_cat(newlist, item);
+ item = 0;
+ what = 0;
+ } else {
+ item = same_merge(item, same_item(list->string));
+ what = 1;
+ }
+ break;
+ }
+ list = same_unlink(list);
+ }
+ return same_cat(newlist, item);
+}
+
+
+same_t *
+variable(var_name)
+same_t *var_name;
+{
+ int length = strlen(var_name->string->string);
+ same_t *resolved;
+ char *newname;
+
+ if ((newname = malloc(length+1+3)) == 0) {
+ fprintf("Out of space for a variable name.\n");
+ exit(1);
+ }
+ newname[0] = '$';
+ newname[1] = '{';
+ strcpy(newname+2, var_name->string->string);
+ strcat(newname, "}");
+ resolved = same_item(string_lookup(newname));
+ free(newname);
+
+ return resolved;
+}
+
+
+same_t *
+shell_variable(var_name)
+same_t *var_name;
+{
+ int length = strlen(var_name->string->string);
+ same_t *resolved;
+ char *newname;
+
+ if ((newname = malloc(length+1+2)) == 0) {
+ fprintf("Out of space for a variable name.\n");
+ exit(1);
+ }
+ newname[0] = '$';
+ newname[1] = '$';
+ strcpy(newname+2, var_name->string->string);
+ resolved = same_item(string_lookup(newname));
+ free(newname);
+
+ return resolved;
+}
+
+same_t *
+for_statement(special, variable, list)
+same_t
+ *special,
+ *variable,
+ *list;
+{
+ variable->shell_item = special;
+ variable->value_list = list;
+ return variable;
+}
+
+same_t *
+do_command(forlist, commands)
+same_t
+ *forlist,
+ *commands;
+{
+ same_t
+ *special,
+ *command_list = 0,
+ *new_commands,
+ *tmp,
+ *shell_item,
+ *value_list = forlist->value_list;
+ char
+ *tmpstr,
+ *variable_name = forlist->string->string;
+
+ special = forlist->shell_item;
+ if (same_unlink(forlist->shell_item) != 0) {
+ yyerror("Unexpected second item in special part of do_command");
+ exit(1);
+ }
+
+ while ((shell_item = value_list) != 0) {
+ value_list = same_unlink(shell_item);
+ /* Visit each item in commands. For each shell variable which
+ * matches ours, replace it with ours.
+ */
+ new_commands = same_copy(commands);
+ for (visit(new_commands, tmp); !visited(tmp); visit_next(tmp)) {
+ tmpstr = tmp->string->string;
+ if ((tmpstr[0] == '$') && (tmpstr[1] == '$')) {
+ if (strcmp(tmpstr+2, variable_name) == 0) {
+ same_replace(tmp, same_copy(shell_item));
+ }
+ }
+ }
+ visit_end();
+ command_list = same_cat(command_list, new_commands);
+ }
+ return same_cat(command_list, same_copy(newline));
+}
+
+
+int
+Getchar()
+{
+ if (last_saved) {
+ last_saved = 0;
+ return last_char;
+ } else {
+ int c;
+ c = getchar();
+ switch (c) {
+ case '\n':
+ lineno++;
+ column = 0;
+ break;
+ default:
+ column++;
+ }
+ return c;
+ }
+}
+
+
+int
+token_type(string)
+char *string;
+{
+ switch (string[0]) {
+ case 'f':
+ if (strcmp(string, "for") == 0) {
+ return FOR;
+ }
+ break;
+ case 'd':
+ if (string[1] == 'o') {
+ if (strcmp(string, "do") == 0) {
+ return DO;
+ } else if (strcmp(string, "done") == 0) {
+ return DONE;
+ }
+ }
+ break;
+ case 'i':
+ if (strcmp(string, "in") == 0) {
+ return IN;
+ }
+ break;
+ default:
+ break;
+ }
+ return TOKEN;
+}
+
+
+yylex()
+{
+#define ret_token(c) if (bufptr != buffer) { \
+ save(c); \
+ *bufptr = 0; \
+ bufptr = buffer; \
+ yylval.string = string_lookup(buffer); \
+ return token_type(buffer); \
+ }
+#define save(c) { last_char = c; last_saved = 1; }
+#if defined(YYDEBUG)
+#define Return(c) if (yydebug) { \
+ printf("[%d]", c); \
+ fflush(stdout); \
+ } \
+ yyval.intval = c; \
+ return c;
+#else /* defined(YYDEBUG) */
+#define Return(y,c) { yylval.intval = c; return y; }
+#endif /* defined(YYDEBUG) */
+
+
+ static char buffer[500], *bufptr = buffer;
+ static int eof_found = 0;
+ int c;
+
+ if (eof_found != 0) {
+ eof_found++;
+ if (eof_found > 2) {
+ fprintf(stderr, "End of file ignored.\n");
+ exit(1);
+ }
+ Return(EOF,0);
+ }
+ while ((c = Getchar()) != EOF) {
+ switch (c) {
+ case '#':
+ ret_token(c);
+ while (((c = Getchar()) != EOF) && (c != '\n')) {
+ ;
+ }
+ save(c);
+ break;
+ case '<':
+ case '?':
+ ret_token(c);
+ Return(MACRO_CHAR, c);
+ case '\t':
+ case ' ':
+ ret_token(c);
+ Return(WHITE_SPACE, c);
+ case '-':
+ case '@':
+ case ':':
+ case ';':
+ case '=':
+ case '$':
+ case '{':
+ case '}':
+ case '(':
+ case ')':
+ ret_token(c);
+ Return(c,c);
+ case '\'':
+ case '"':
+ if (bufptr != buffer) {
+ if (bufptr[-1] == '\\') {
+ bufptr[-1] = c;
+ }
+ break;
+ } else {
+ int newc;
+
+ ret_token(c);
+ *bufptr++ = c;
+ while (((newc = Getchar()) != EOF) && (newc != c)) {
+ *bufptr++ = newc;
+ }
+ *bufptr++ = c;
+ *bufptr = 0;
+ bufptr = buffer;
+ yylval.string = string_lookup(buffer);
+ return QUOTED_STRING;
+ }
+ case '\n':
+ if (bufptr != buffer) {
+ if (bufptr[-1] == '\\') {
+ bufptr--;
+ if ((c = Getchar()) != '\t') {
+ yyerror("continuation line doesn't begin with a tab");
+ save(c);
+ }
+ ret_token(c);
+ Return(WHITE_SPACE, c);
+ }
+ }
+ ret_token(c);
+ Return(NL, 0);
+ default:
+ *bufptr++ = c;
+ break;
+ }
+ }
+
+ eof_found = 1;
+
+ ret_token(' ');
+ Return(EOF, 0);
+}
+
+main()
+{
+#define YYDEBUG
+ extern int yydebug;
+
+ null = same_item(string_lookup(""));
+ newline = same_item(string_lookup("\n"));
+ blank = same_item(string_lookup(" "));
+ cwd_line = same_cat(same_copy(newline),
+ same_cat(same_item(string_lookup("cd ${CWD}")),
+ same_copy(newline)));
+
+ yyparse();
+
+ do_dump();
+
+ return 0;
+}
+
+#if defined(YYDEBUG)
+dump_same(same)
+same_t *same;
+{
+ same_t *same2;
+
+ for (visit(same, same2); !visited(same2); visit_next(same2)) {
+ printf(same2->string->string);
+ }
+ visit_end();
+}
+#endif /* YYDEBUG */
+
+do_dump()
+{
+ string_t *string;
+ same_t *same, *same2;
+
+ if (yydebug > 1) {
+ printf("strings...\n");
+ for (string = strings; string; string = string->next) {
+ printf("\t%s\n", string->string);
+ }
+ }
+
+ printf("# variables...\n");
+ for (visit(variables, same); !visited(same); visit_next(same)) {
+ printf("%s =\t", same->string->string);
+ for (visit(same->value_list, same2); !visited(same2);
+ visit_next(same2)) {
+ printf(same2->string->string);
+ }
+ visit_end();
+ printf("\n");
+ }
+ visit_end();
+
+ printf("\n\n#targets...\n");
+ for (visit(targets, same); !visited(same); visit_next(same)) {
+ printf("\n%s:\t", same->string->string);
+ for (visit(same->depend_list, same2); !visited(same2);
+ visit_next(same2)) {
+ printf(same2->string->string);
+ }
+ visit_end();
+ printf("\n\t");
+ for (visit(same->action_list, same2); !visited(same2);
+ visit_next(same2)) {
+ printf(same2->string->string);
+ if (same2->string->string[0] == '\n') {
+ printf("\t");
+ }
+ }
+ visit_end();
+ printf("\n");
+ }
+ visit_end();
+}
diff --git a/usr.bin/tn3270/tools/prt3270.c b/usr.bin/tn3270/tools/prt3270.c
new file mode 100644
index 0000000..55d72d5
--- /dev/null
+++ b/usr.bin/tn3270/tools/prt3270.c
@@ -0,0 +1,620 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1988, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)prt3270.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#if defined(unix)
+#endif
+#include <stdio.h>
+#include <ctype.h>
+
+#include "../general/general.h"
+
+#include "../api/asc_ebc.h"
+#include "../ctlr/hostctlr.h"
+#include "../ctlr/screen.h"
+#include "../ctlr/function.h"
+#include "../api/astosc.h"
+#include "../general/globals.h"
+
+#include "../ctlr/kbd.out"
+
+
+int NumberColumns = 80;
+
+int direction;
+
+int column = 1;
+int indenting = 0;
+int direction = '?';
+
+unsigned char printBuffer[200], *print = printBuffer;
+
+#define ColsLeft() (79-column) /* A little room for error */
+
+
+void
+putSpace()
+{
+ extern void Column1();
+ unsigned char *ourPrint = print;
+
+ print = printBuffer; /* For mutual calls */
+ *ourPrint = 0;
+ if (ColsLeft() < 0) {
+ Column1();
+ }
+ if (column != (indenting*8+1)) {
+ putchar(' ');
+ } else {
+ int i;
+
+ putchar(direction);
+ putchar(' ');
+ for (i = 0; i < indenting; i++) {
+ putchar('\t');
+ }
+ }
+ printf("%s", printBuffer);
+ column += strlen(printBuffer);
+}
+
+void
+Column1()
+{
+ if (print != printBuffer) {
+ putSpace();
+ }
+ if (column != (indenting*8+1)) {
+ putchar('\n');
+ column = indenting*8+1;
+ }
+}
+
+void
+Indent()
+{
+ if ((column != (indenting*8+1)) || (print != printBuffer)) {
+ Column1();
+ }
+ indenting++;
+ column = indenting*8+1;
+}
+
+void
+Undent()
+{
+ if ((column != (indenting*8+1)) || (print != printBuffer)) {
+ Column1();
+ }
+ indenting--;
+ if (indenting < 0) {
+ fflush(stdout);
+ fprintf(stderr, "INTERNAL ERROR: indenting < 0.\n");
+ fflush(stderr);
+ } else {
+ column = indenting*8+1;
+ }
+}
+
+void
+putChar(character)
+int character;
+{
+ *print++ = character;
+ column++;
+}
+
+void
+putstr(s)
+char *s;
+{
+ while (*s) {
+ putChar(*s++);
+ }
+}
+
+void
+put2hex(i)
+int i;
+{
+ char place[40];
+
+ sprintf(place, "%02x", i);
+ putstr(place);
+}
+
+
+void
+putdecimal(i)
+int i;
+{
+ char place[40];
+
+ sprintf(place, "%d", i);
+ putstr(place);
+}
+
+void
+puthex(i)
+int i;
+{
+ char place[40];
+
+ sprintf(place, "%x", i);
+ putstr(place);
+}
+
+void
+putEChar(character)
+int character;
+{
+ putChar(ebc_asc[character]);
+ if (ColsLeft() < 10) {
+ Column1();
+ }
+}
+
+void
+PrintAid(i)
+int i;
+{
+ struct astosc *this;
+
+ for (this = &astosc[0]; this <= &astosc[highestof(astosc)]; this++) {
+ if (this->function == FCN_AID) {
+ int j;
+
+ switch (this->shiftstate) {
+ case 0:
+ j = 0;
+ break;
+ case SHIFT_UPSHIFT:
+ j = 1;
+ break;
+ case SHIFT_ALT:
+ j = 2;
+ break;
+ case (SHIFT_UPSHIFT|SHIFT_ALT):
+ j = 3;
+ break;
+ default:
+ fprintf(stderr, "Bad shiftstate 0x%x.\n", this->shiftstate);
+ exit(1);
+ }
+ if (hits[this->scancode].hit[j].code == i) {
+ putstr(this->name);
+ return;
+ }
+ }
+ }
+
+ putstr("Unknown AID 0x");
+ put2hex(i);
+}
+
+void
+PrintAddr(i)
+int i;
+{
+ if (ColsLeft() < 9) {
+ Column1();
+ }
+ putChar('(');
+ putdecimal(ScreenLine(i));
+ putChar(',');
+ putdecimal(ScreenLineOffset(i));
+ putChar(')');
+}
+
+
+/* returns the number of characters consumed */
+int
+DataFromNetwork(buffer, count, control)
+register unsigned char *buffer; /* what the data is */
+register int count; /* and how much there is */
+int control; /* this buffer ended block? */
+{
+ int origCount;
+ register int c;
+ register int i;
+ static int Command;
+ static int Wcc;
+ static int LastWasTerminated = 1; /* was "control" = 1 last time? */
+
+ if (count == 0) {
+ Column1();
+ return 0;
+ }
+
+ origCount = count;
+
+ if (LastWasTerminated) {
+
+ if (count < 2) {
+ if (count == 0) {
+ fflush(stdout);
+ fprintf(stderr, "Short count received from host!\n");
+ fflush(stderr);
+ return(count);
+ }
+ Command = buffer[0];
+ switch (Command) { /* This had better be a read command */
+ case CMD_READ_MODIFIED:
+ putstr("read_modified command\n");
+ break;
+ case CMD_SNA_READ_MODIFIED:
+ putstr("sna_read_modified command\n");
+ break;
+ case CMD_SNA_READ_MODIFIED_ALL:
+ putstr("sna_read_modified_all command\n");
+ break;
+ case CMD_READ_BUFFER:
+ putstr("read_buffer command\n");
+ break;
+ case CMD_SNA_READ_BUFFER:
+ putstr("sna_read_buffer command\n");
+ break;
+ default:
+ break;
+ }
+ return(1); /* We consumed everything */
+ }
+ Command = buffer[0];
+ Wcc = buffer[1];
+ switch (Command) {
+ case CMD_ERASE_WRITE:
+ putstr("erase write command ");
+ break;
+ case CMD_ERASE_WRITE_ALTERNATE:
+ putstr("erase write alternate command ");
+ break;
+ case CMD_SNA_ERASE_WRITE:
+ putstr("sna erase write command ");
+ break;
+ case CMD_SNA_ERASE_WRITE_ALTERNATE:
+ putstr("erase write alternate command ");
+ break;
+ case CMD_ERASE_ALL_UNPROTECTED:
+ putstr("erase all unprotected command ");
+ break;
+ case CMD_SNA_ERASE_ALL_UNPROTECTED:
+ putstr("sna erase write command ");
+ break;
+ case CMD_WRITE:
+ putstr("write command ");
+ break;
+ case CMD_SNA_WRITE:
+ putstr("sna write command ");
+ break;
+ default:
+ putstr("Unexpected command code 0x");
+ puthex(Command);
+ putstr(" received.");
+ Column1();
+ break;
+ }
+ putstr("WCC is 0x");
+ puthex(Wcc);
+ Column1();
+
+ count -= 2; /* strip off command and wcc */
+ buffer += 2;
+
+ }
+ LastWasTerminated = 0; /* then, reset at end... */
+
+ while (count) {
+ count--;
+ c = *buffer++;
+ if (IsOrder(c)) {
+ /* handle an order */
+ switch (c) {
+# define Ensure(x) if (count < x) { \
+ if (!control) { \
+ return(origCount-(count+1)); \
+ } else { \
+ /* XXX - should not occur */ \
+ count = 0; \
+ break; \
+ } \
+ }
+ case ORDER_SF:
+ Ensure(1);
+ c = *buffer++;
+ count--;
+ putstr("SF (0x");
+ put2hex(c);
+ putstr(") ");
+ break;
+ case ORDER_SBA:
+ Ensure(2);
+ i = buffer[0];
+ c = buffer[1];
+ buffer += 2;
+ count -= 2;
+ putstr("SBA to ");
+ PrintAddr(Addr3270(i,c));
+ putSpace();
+ break;
+ case ORDER_IC:
+ putstr("IC");
+ putSpace();
+ break;
+ case ORDER_PT:
+ putstr("PT");
+ putSpace();
+ break;
+ case ORDER_RA:
+ Ensure(3);
+ i = Addr3270(buffer[0], buffer[1]);
+ c = buffer[2];
+ buffer += 3;
+ count -= 3;
+ putstr("RA to ");
+ PrintAddr(i);
+ putstr(" of 0x");
+ put2hex(c);
+ putSpace();
+ break;
+ case ORDER_EUA: /* (from [here,there), ie: half open interval] */
+ Ensure(2);
+ putstr("EUA to ");
+ PrintAddr(Addr3270(buffer[0], buffer[1]));
+ putSpace();
+ buffer += 2;
+ count -= 2;
+ break;
+ case ORDER_YALE: /* special YALE defined order */
+ Ensure(2); /* need at least two characters */
+ putstr("YALE order");
+ putSpace();
+ break;
+ default:
+ putstr("UNKNOWN ORDER: 0x");
+ put2hex(c);
+ putSpace();
+ break;
+ }
+ if (count < 0) {
+ count = 0;
+ }
+ } else {
+ /* Data comes in large clumps - take it all */
+ putstr("DATA:");
+ Indent();
+ putEChar(c);
+ c = *buffer;
+ while (count && !IsOrder(c)) {
+ putEChar(c);
+ count--;
+ buffer++;
+ c = *buffer;
+ }
+ Undent();
+ }
+ }
+ LastWasTerminated = control;
+ return origCount - count;
+}
+
+int
+DataToNetwork(buffer, count, control)
+unsigned char *buffer;
+int count;
+int control;
+{
+#define NEED_AID 0
+#define JUST_GOT_AID 1
+#define DATA 2
+#define DATA_CONTINUE 3
+ static int state = NEED_AID;
+ static int aid;
+ int origCount = count;
+
+ if (count == 0) {
+ if (control) {
+ state = NEED_AID;
+ }
+ Column1();
+ return 0;
+ }
+
+ switch (state) {
+ case NEED_AID:
+ aid = buffer[0];
+ buffer++;
+ count--;
+ PrintAid(aid);
+ putSpace();
+ if (aid == AID_TREQ) {
+ state = DATA;
+ } else {
+ state = JUST_GOT_AID;
+ }
+ return origCount - count + DataToNetwork(buffer, count, control);
+ case JUST_GOT_AID:
+ Ensure(2);
+ PrintAddr(Addr3270(buffer[0], buffer[1]));
+ putSpace();
+ buffer += 2;
+ count -= 2;
+ state = DATA;
+ return origCount - count + DataToNetwork(buffer, count, control);
+ case DATA:
+ case DATA_CONTINUE:
+ while (count) {
+ if (*buffer == ORDER_SBA) {
+ if (state == DATA_CONTINUE) {
+ Undent();
+ state = DATA;
+ }
+ putstr("SBA ");
+ PrintAddr(Addr3270(buffer[1], buffer[2]));
+ putSpace();
+ buffer += 3;
+ count -= 3;
+ } else {
+ if (state == DATA) {
+ putstr("DATA:");
+ Indent();
+ state = DATA_CONTINUE;
+ }
+ putEChar(*buffer);
+ buffer++;
+ count--;
+ }
+ }
+ if (control) {
+ if (state == DATA_CONTINUE) {
+ Undent();
+ }
+ state = NEED_AID;
+ }
+ return origCount-count;
+ }
+}
+
+int
+GetXValue(c)
+int c;
+{
+ if (!isascii(c)) {
+ fflush(stdout);
+ fprintf(stderr, "Non-hex digit 0x%x.\n");
+ fflush(stderr);
+ return 0;
+ } else {
+ if (islower(c)) {
+ return (c-'a')+10;
+ } else if (isupper(c)) {
+ return (c-'A')+10;
+ } else {
+ return c-'0';
+ }
+ }
+}
+
+unsigned char outbound[8192], inbound[8192],
+ *outnext = outbound, *innext = inbound, *p = 0;
+
+void
+termblock(old, new, control)
+int old,
+ new; /* old and new directions */
+{
+ int count;
+
+ if (p) {
+ if (old == '<') {
+ outnext = p;
+ count = DataFromNetwork(outbound, outnext-outbound, control);
+ if (outbound+count == outnext) {
+ outnext = outbound;
+ } else {
+ memcpy(outbound, outbound+count, outnext-(outbound+count));
+ outnext = outbound+count;
+ }
+ } else {
+ innext = p;
+ count = DataToNetwork(inbound, innext-inbound, control);
+ if (inbound+count == innext) {
+ innext = inbound;
+ } else {
+ memcpy(inbound, inbound+count, innext-(inbound+count));
+ innext = inbound+count;
+ }
+ }
+ }
+ if (new == '<') {
+ p = outnext;
+ } else if (new == '>') {
+ p = innext;
+ } else {
+ fprintf(stderr, "Bad direction character '%c'.\n", new);
+ exit(1);
+ }
+}
+
+main()
+{
+ int location;
+ char new;
+ int c, c1;
+
+ memset(Orders, 0, sizeof Orders);
+ Orders[ORDER_SF] = Orders[ORDER_SBA] = Orders[ORDER_IC]
+ = Orders[ORDER_PT] = Orders[ORDER_RA] = Orders[ORDER_EUA]
+ = Orders[ORDER_YALE] = 1;
+
+ while (scanf("%c 0x%x\t", &new, &location) != EOF) {
+ if (new != direction) {
+ termblock(direction, new, 0);
+ direction = new;
+ }
+ while (((c = getchar()) != EOF) && (c != '\n') && (isxdigit(c))) {
+#define NORMAL 0
+#define GOT0XFF 0xff
+ static int state = NORMAL;
+
+ c1 = getchar();
+ c = (GetXValue(c) << 4) + GetXValue(c1);
+ switch (state) {
+ case NORMAL:
+ if (c == 0xff) {
+ state = GOT0XFF;
+ } else {
+ *p++ = c;
+ }
+ break;
+ case GOT0XFF:
+ if (c == 0xef) {
+ termblock(direction, direction, 1);
+ } else {
+ *p++ = 0xff;
+ *p++ = c;
+ }
+ state = NORMAL;
+ }
+ }
+ }
+ return 0;
+}
OpenPOWER on IntegriCloud