Sun Jan 17 01:33:33 2010 UTC ()
Import tn3270 from base as of 20100114, just before its removal. This
is just the sources, and they're unchanged from base except that the
rcsids have been preserved. The package will be along shortly.

Status:

Vendor Tag:	TNF
Release Tags:	src-20100114


(dholland)
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/Makefile
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/Makefile.inc
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/api/api.order
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/api/api_bsd.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/api/api_exch.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/api/api_exch.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/api/apilib.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/api/apilib.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/api/asc_ebc.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/api/asc_ebc.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/api/astosc.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/api/astosc.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/api/dctype.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/api/dctype.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/api/disp_asc.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/api/disp_asc.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/api/ebc_disp.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/api/ebc_disp.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/ascii/ascii.order
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/ascii/default.map
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/ascii/map3270.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/ascii/map3270.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/ascii/mset.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/ascii/state.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/ascii/termin.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/ctlr/3270pc.kbd
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/ctlr/3180.kbd
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/ctlr/ctlr.order
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/ctlr/api.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/ctlr/api.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/ctlr/declare.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/ctlr/function.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/ctlr/function.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/ctlr/hostctlr.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/ctlr/inbound.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/ctlr/oia.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/ctlr/oia.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/ctlr/options.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/ctlr/options.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/ctlr/outbound.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/ctlr/screen.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/ctlr/scrnctlr.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/ctlr/unix.kbd
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/general/general.order
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/general/genbsubs.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/general/general.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/general/globals.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/general/globals.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/general/vaxbsubs.s
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/mset/map3270.5
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/mset/Makefile
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/mset/map3270
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/mset/mset.1
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/sys_curses/telextrn.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/sys_curses/system.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/sys_curses/terminal.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/sys_curses/termout.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/tn3270/Makefile
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/tn3270/tn3270.1
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/tools/Makefile
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/tools/Makefile.inc
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/tools/mkastods/mkastods.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/tools/mkastods/Makefile
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/tools/mkastosc/mkastosc.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/tools/mkastosc/Makefile
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/tools/mkdctype/mkdctype.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/tools/mkdctype/Makefile
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/tools/mkdctype/ectype.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/tools/mkdctype/ectype.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/tools/mkdstoas/mkdstoas.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/tools/mkdstoas/Makefile
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/tools/mkhits/Makefile
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/tools/mkhits/dohits.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/tools/mkhits/dohits.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/tools/mkhits/mkhits.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/tools/mkmake/Makefile
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/tools/mkmake/mkmake.y
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/tools/prt3270/prt3270.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/tools/prt3270/Makefile
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/telnet/commands.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/telnet/defines.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/telnet/externs.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/telnet/general.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/telnet/main.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/telnet/network.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/telnet/ring.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/telnet/ring.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/telnet/sys_bsd.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/telnet/telnet.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/telnet/terminal.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/telnet/tn3270.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/telnet/types.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/telnet/utilities.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/telnet/libtelnet/genget.c
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/telnet/libtelnet/misc-proto.h
diff -r0 -r1.1.1.1 pkgsrc/comms/tn3270/files/telnet/libtelnet/misc.h

File Added: pkgsrc/comms/tn3270/files/Attic/Makefile
#	$NetBSD: Makefile,v 1.1.1.1 2010/01/17 01:33:16 dholland Exp $
#	From NetBSD: Makefile,v 1.8 2005/09/17 16:52:02 chs Exp 

SUBDIR = tools .WAIT tn3270 mset

.include <bsd.subdir.mk>

File Added: pkgsrc/comms/tn3270/files/Attic/Makefile.inc
#	$NetBSD: Makefile.inc,v 1.1.1.1 2010/01/17 01:33:16 dholland Exp $
#	From NetBSD: Makefile.inc,v 1.12 2009/04/14 22:15:27 lukem Exp 

WARNS?=	1	# XXX -Wcast-qual -Wshadow issues

USE_FORT?= yes	# network client

CPPFLAGS+=-DTERMCAP -DSRCRT -DKLUDGELINEMODE -DUSE_TERMIO -DTN3270 -Dunix
CPPFLAGS+=-I${.CURDIR} -I.
KBD=	unix.kbd

.if exists(${.CURDIR}/../../Makefile.inc)
.include "${.CURDIR}/../../Makefile.inc"
.endif

File Added: pkgsrc/comms/tn3270/files/api/Attic/api.order
ebc_disp.o
disp_asc.o
dctype.o
astosc.o
asc_ebc.o
apilib.o
api_bsd.o
api_exch.o

File Added: pkgsrc/comms/tn3270/files/api/Attic/api_bsd.c
/*	$NetBSD: api_bsd.c,v 1.1.1.1 2010/01/17 01:33:16 dholland Exp $	*/
/*	From NetBSD: api_bsd.c,v 1.13 2006/05/24 16:57:12 christos Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 */

#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
#if 0
static char sccsid[] = "@(#)api_bsd.c	4.2 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: api_bsd.c,v 1.1.1.1 2010/01/17 01:33:16 dholland Exp $");
#endif
#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 <stdlib.h>
#include <string.h>
#include <unistd.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;
    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:%99s", 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;
    }
    if (sizeof(server.sin_addr.s_addr) < hp->h_length)
	    hp->h_length = sizeof(server.sin_addr.s_addr);
    (void)memcpy(&server.sin_addr.s_addr, hp->h_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, "%99s\n", inkey) != 1) {
	perror("fscanf");
	goto out;
    }
    sd.length = strlen(inkey)+1;
    if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
	goto out;
    }
    if (api_exch_outtype(EXCH_TYPE_BYTES, sd.length, inkey) == -1) {
	goto out;
    }
    while ((i = api_exch_nextcommand()) != EXCH_CMD_ASSOCIATED) {
	int passwd_length;
	char *passwd;
	char buffer[200];

	switch (i) {
	case EXCH_CMD_REJECTED:
	    if (api_exch_intype(EXCH_TYPE_STORE_DESC,
					sizeof sd, (char *)&sd) == -1) {
		goto out;
	    }
	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
		goto out;
	    }
	    buffer[sd.length] = 0;
	    fprintf(stderr, "%s\n", buffer);
	    if (api_exch_outcommand(EXCH_CMD_ASSOCIATE) == -1) {
		goto out;
	    }
	    break;
	case EXCH_CMD_SEND_AUTH:
	    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
		goto out;
	    }
	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
		goto out;
	    }
	    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) {
		goto out;
	    }
	    if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
		goto out;
	    }
	    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) {
		goto out;
	    }
	    if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
		goto out;
	    }
	    if (api_exch_outtype(EXCH_TYPE_BYTES, passwd_length, passwd) == -1) {
		goto out;
	    }
	    break;
	case -1:
	    goto out;
	default:
	    fprintf(stderr,
		    "Waiting for connection indicator, received 0x%x.\n", i);
	    break;
	}
    }
    /* YEAH */
    fclose(keyfile);
    return 0;		/* Happiness! */
    /* NOPE */
out:
    fclose(keyfile);
    return -1;
}


int
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 */

File Added: pkgsrc/comms/tn3270/files/api/Attic/api_exch.c
/*	$NetBSD: api_exch.c,v 1.1.1.1 2010/01/17 01:33:17 dholland Exp $	*/
/*	From NetBSD: api_exch.c,v 1.8 2003/08/07 11:16:24 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 */

#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
#if 0
static char sccsid[] = "@(#)api_exch.c	4.2 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: api_exch.c,v 1.1.1.1 2010/01/17 01:33:17 dholland Exp $");
#endif
#endif /* not lint */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.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(void);
static int iget(char *, int);
static char *exch_to_ascii(int);
static int send_state(void);
static int receive_state(void);
static int enter_receive(void);
static int enter_send(void);

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;
    case RECEIVE:
	abort();	/* Unhandled case; remove abort if we die here */
    }
    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;
	}
    case SEND:
	abort();	/* Unhandled case; remove abort if we die here */
    }
    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;
const 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;
{
    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;
}

File Added: pkgsrc/comms/tn3270/files/api/Attic/api_exch.h
/*	$NetBSD: api_exch.h,v 1.1.1.1 2010/01/17 01:33:17 dholland Exp $	*/
/*	From NetBSD: api_exch.h,v 1.7 2003/08/07 11:16:24 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 *
 *	from: @(#)api_exch.h	4.2 (Berkeley) 4/26/91
 */

/*
 * 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 */
};

int api_exch_nextcommand(void);
int api_exch_incommand(int);
int api_exch_outcommand(int);
int api_exch_outtype(int, int , const char *);
int api_exch_intype(int, int , char *);
int api_exch_flush(void);
int api_exch_init(int, char *);

File Added: pkgsrc/comms/tn3270/files/api/Attic/apilib.c
/*	$NetBSD: apilib.c,v 1.1.1.1 2010/01/17 01:33:17 dholland Exp $	*/
/*	From NetBSD: apilib.c,v 1.7 2003/08/07 11:16:24 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 */

#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
#if 0
static char sccsid[] = "@(#)apilib.c	4.2 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: apilib.c,v 1.1.1.1 2010/01/17 01:33:17 dholland Exp $");
#endif
#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;


/* apilib.c */
static int api_issue_regs(int, int , int , int , int , int , char *, int,
    union REGS *, struct SREGS *);
static int api_issue(int, int , int , int , int , int , char *, int);

/*
 * 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
 */

int
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;
    }
}


int
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;
    }
}

int
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
 */

int
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;
    }
}


int
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;
    }
}


int
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;
    }
}


int
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;
    }
}

int
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
 */

int
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
 */

int
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.
 */

int
api_finish()
{
#if	defined(unix)
    if (api_close_api() == -1) {
	return -1;
    } else {
	return 0;
    }
#else
    return 0;
#endif	/* defined(unix) */
}


/*
 * The initialization routine.  Be sure to call this first.
 */

int
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;
}

File Added: pkgsrc/comms/tn3270/files/api/Attic/apilib.h
/*	$NetBSD: apilib.h,v 1.1.1.1 2010/01/17 01:33:17 dholland Exp $	*/
/*	From NetBSD: apilib.h,v 1.6 2003/08/07 11:16:24 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 *
 *	from: @(#)apilib.h	4.2 (Berkeley) 4/26/91
 */

/*
 * 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.) */

int api_name_resolve(char *);
int api_ps_or_oia_modified(void);
int api_query_session_id(QuerySessionIdParms *);
int api_query_session_parameters(QuerySessionParametersParms *);
int api_query_session_cursor(QuerySessionCursorParms *);
int api_connect_to_keyboard(ConnectToKeyboardParms *);
int api_disconnect_from_keyboard(DisconnectFromKeyboardParms *);
int api_write_keystroke(WriteKeystrokeParms *);
int api_disable_input(DisableInputParms *);
int api_enable_input(EnableInputParms *);
int api_copy_string(CopyStringParms *);
int api_read_oia_group(ReadOiaGroupParms *);
int api_finish(void);
int api_init(void);

File Added: pkgsrc/comms/tn3270/files/api/Attic/asc_ebc.c
/*	$NetBSD: asc_ebc.c,v 1.1.1.1 2010/01/17 01:33:17 dholland Exp $	*/
/*	From NetBSD: asc_ebc.c,v 1.7 2003/08/07 11:16:25 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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 HOST_TOOL
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
#if 0
static char sccsid[] = "@(#)asc_ebc.c	4.2 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: asc_ebc.c,v 1.1.1.1 2010/01/17 01:33:17 dholland Exp $");
#endif
#endif /* not lint */
#endif /* ! HOST_TOOL */

/*
 * 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',  ' ',  ' ',  ' ',  ' ',  ' ',  ' ',
};

File Added: pkgsrc/comms/tn3270/files/api/Attic/asc_ebc.h
/*	$NetBSD: asc_ebc.h,v 1.1.1.1 2010/01/17 01:33:17 dholland Exp $	*/
/*	From NetBSD: asc_ebc.h,v 1.5 2003/08/07 11:16:25 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 *
 *	from: @(#)asc_ebc.h	4.2 (Berkeley) 4/26/91
 */

/*
 * 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];

File Added: pkgsrc/comms/tn3270/files/api/Attic/astosc.c
/*	$NetBSD: astosc.c,v 1.1.1.1 2010/01/17 01:33:17 dholland Exp $	*/
/*	From NetBSD: astosc.c,v 1.8 2006/03/20 01:34:49 gdamore Exp 	*/

/*-
 * Copyright (c) 1988 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. 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 HOST_TOOL
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
#if 0
static char sccsid[] = "@(#)astosc.c	4.2 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: astosc.c,v 1.1.1.1 2010/01/17 01:33:17 dholland Exp $");
#endif
#endif /* not lint */
#endif

#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 int ustrcmp(char *, char *);

static int
ustrcmp(string1, string2)
char *string1;
char *string2;
{
    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)
char *string;
{
    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;
}

File Added: pkgsrc/comms/tn3270/files/api/Attic/astosc.h
/*	$NetBSD: astosc.h,v 1.1.1.1 2010/01/17 01:33:18 dholland Exp $	*/
/*	From NetBSD: astosc.h,v 1.6 2003/08/07 11:16:25 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 *
 *	from: @(#)astosc.h	4.2 (Berkeley) 4/26/91
 */

/*
 * 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(char *);	/* Function to feed InitControl() */

extern struct astosc astosc[256];

File Added: pkgsrc/comms/tn3270/files/api/Attic/dctype.c
/*	$NetBSD: dctype.c,v 1.1.1.1 2010/01/17 01:33:18 dholland Exp $	*/
/*	From NetBSD: dctype.c,v 1.6 2003/08/07 11:16:25 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 */

#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
#if 0
static char sccsid[] = "@(#)dctype.c	4.2 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: dctype.c,v 1.1.1.1 2010/01/17 01:33:18 dholland Exp $");
#endif
#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,
};

File Added: pkgsrc/comms/tn3270/files/api/Attic/dctype.h
/*	$NetBSD: dctype.h,v 1.1.1.1 2010/01/17 01:33:18 dholland Exp $	*/
/*	From NetBSD: dctype.h,v 1.5 2003/08/07 11:16:26 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 *
 *	from: @(#)dctype.h	4.2 (Berkeley) 4/26/91
 */

#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];

File Added: pkgsrc/comms/tn3270/files/api/Attic/disp_asc.c
/*	$NetBSD: disp_asc.c,v 1.1.1.1 2010/01/17 01:33:18 dholland Exp $	*/
/*	From NetBSD: disp_asc.c,v 1.6 2003/08/07 11:16:26 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 */

#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
#if 0
static char sccsid[] = "@(#)disp_asc.c	4.2 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: disp_asc.c,v 1.1.1.1 2010/01/17 01:33:18 dholland Exp $");
#endif
#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"

File Added: pkgsrc/comms/tn3270/files/api/Attic/disp_asc.h
/*	$NetBSD: disp_asc.h,v 1.1.1.1 2010/01/17 01:33:18 dholland Exp $	*/
/*	From NetBSD: disp_asc.h,v 1.5 2003/08/07 11:16:26 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 *
 *	from: @(#)disp_asc.h	4.2 (Berkeley) 4/26/91
 */

/*
 * 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 */

File Added: pkgsrc/comms/tn3270/files/api/Attic/ebc_disp.c
/*	$NetBSD: ebc_disp.c,v 1.1.1.1 2010/01/17 01:33:18 dholland Exp $	*/
/*	From NetBSD: ebc_disp.c,v 1.7 2003/08/07 11:16:26 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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 HOST_TOOL
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
#if 0
static char sccsid[] = "@(#)ebc_disp.c	4.2 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: ebc_disp.c,v 1.1.1.1 2010/01/17 01:33:18 dholland Exp $");
#endif
#endif /* not lint */
#endif /* ! HOST_TOOL */

/*
 * 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,
};

File Added: pkgsrc/comms/tn3270/files/api/Attic/ebc_disp.h
/*	$NetBSD: ebc_disp.h,v 1.1.1.1 2010/01/17 01:33:18 dholland Exp $	*/
/*	From NetBSD: ebc_disp.h,v 1.5 2003/08/07 11:16:26 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 *
 *	from: @(#)ebc_disp.h	4.2 (Berkeley) 4/26/91
 */

extern unsigned char
			ebc_disp[256],
			disp_ebc[192];

File Added: pkgsrc/comms/tn3270/files/ascii/Attic/ascii.order
map3270.o
termin.o

File Added: pkgsrc/comms/tn3270/files/ascii/Attic/default.map
/*-
 * Copyright (c) 1988 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. 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	4.2 (Berkeley) 4/26/91
 */

/* 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 /usr/share/misc/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) */

File Added: pkgsrc/comms/tn3270/files/ascii/Attic/map3270.c
/*	$NetBSD: map3270.c,v 1.1.1.1 2010/01/17 01:33:18 dholland Exp $	*/
/*	From NetBSD: map3270.c,v 1.15 2006/04/30 23:49:34 christos Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 */

#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)map3270.c	4.2 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: map3270.c,v 1.1.1.1 2010/01/17 01:33:18 dholland Exp $");
#endif
#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 <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define	IsPrint(c)	((isprint((unsigned char)c) && !isspace((unsigned char)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 dependency... */
#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", 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 available.
 */

#ifdef	DEBUG
static int debug = 0;		/* debug flag (for debuggin tables) */
#endif	/* DEBUG */

static int (*GetTc)(char *);
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];		/* character stack for parser */
static	int	rp = 0,			/* read pointer into lifo */
		wp = 0;			/* write pointer into lifo */

static int GetC(void);
static lexicon Get(void);
static void UnGet(lexicon);
static stringWithLength *GetQuotedString(void);
#ifdef NOTUSED
static stringWithLength *GetCharString(void);
#endif
static int GetCharacter(int);
#ifdef NOTUSED
static int GetString(char *);
#endif
static stringWithLength *GetAlphaMericString(void);
static lexicon EatToNL(void);
static void GetWS(void);
static void FreeState(state *);
static state *GetState(void);
static state *FindMatchAtThisLevel(state *, int);
static state *PasteEntry(state *, char *, int, char *);
static int GetInput(int, char *);
static int GetDefinition(void);
static int GetDefinitions(void);
static int GetBegin(void);
static int GetEnd(void);
static int GetName(void);
static int GetNames(void);
static int GetEntry0(void);
static int GetEntry(void);

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];

		(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()
{
    lexicon c;
    lexicon *pC = &c;
    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)
	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 */

int
ustrcmp(string1, string2)
char *string1;
char *string2;
{
    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;
    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;
	}
	if ((lex.type == LEX_CHAR) && !IsPrint(lex.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 int
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 int
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;
    static stringWithLength output = { 0 };
    char *pointer = output.array;
#   define	IsAlnum(c)	(isalnum(c) || (c == '_') \
					|| (c == '-') || (c == '.'))

    lex = Get();

    if ((lex.type != LEX_CHAR) || !IsAlnum(lex.value)) {
	UnGet(lex);
	return(0);
    }

    while ((lex.type == LEX_CHAR) && IsAlnum(lex.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;

    lex = Get();

    while ((lex.type == LEX_CHAR) &&
			(isspace(lex.value) || (lex.value == '#'))) {
	if (lex.value == '#') {
	    lex = EatToNL();
	} else {
	    lex = Get();
	}
    }
    UnGet(lex);
}

static void
FreeState(pState)
state *pState;
{
    free((char *)pState);
}


static state *
GetState()
{
    state *pState;

    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 int
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 int
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 int
GetDefinitions()
{
    if (!GetDefinition()) {
	return(0);
    } else {
	while (GetDefinition()) {
	    ;
	}
    }
    return(1);
}

static int
GetBegin()
{
    GetWS();
    if (!GetCharacter('{')) {
	return(0);
    }
    return(1);
}

static int
GetEnd()
{
    GetWS();
    if (!GetCharacter('}')) {
	return(0);
    }
    return(1);
}

static int
GetName()
{
    if (!GetAlphaMericString()) {
	return(0);
    }
    GetWS();
    while (GetAlphaMericString()) {
	GetWS();
    }
    return(1);
}

static int
GetNames()
{
    GetWS();
    if (!GetName()) {
	return(0);
    } else {
	GetWS();
	while (GetCharacter('|')) {
	    GetWS();
	    if (!GetName()) {
		return(0);
	    }
	}
    }
    return(1);
}

static int
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 int
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
 */

int
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;

    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)(char *);	/* Translates ascii string to integer */
{
    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 (keybdPointer && 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("/usr/share/misc/map3270", keybdPointer);
	    }
	}
	if (!GotIt) {
	    if (environPointer) {
		GotIt = Position(environPointer, "unknown");
	    }
	    if (!GotIt && keybdPointer) {
		GotIt = Position("/usr/share/misc/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();
    free(keybdPointer);
    return(firstentry.address);
}

File Added: pkgsrc/comms/tn3270/files/ascii/Attic/map3270.h
/*	$NetBSD: map3270.h,v 1.1.1.1 2010/01/17 01:33:18 dholland Exp $	*/
/*	From NetBSD: map3270.h,v 1.6 2003/08/07 11:16:28 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 *
 *	from: @(#)map3270.h	4.2 (Berkeley) 4/26/91
 */

/*
 * Declaration for map3270.c.
 */

/* map3270.c */
char *uncontrol(int);
int ustrcmp(char *, char *);
int Position(char *, char *);
char *strsave(char *);
state *InitControl(char *, int, int (*)(char *));

File Added: pkgsrc/comms/tn3270/files/ascii/Attic/mset.c
/*	$NetBSD: mset.c,v 1.1.1.1 2010/01/17 01:33:19 dholland Exp $	*/
/*	From NetBSD: mset.c,v 1.8 2008/07/21 14:19:26 lukem Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 */

#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1988\
 The Regents of the University of California.  All rights reserved.");
#endif /* not lint */

#ifndef lint
#if 0
static char sccsid[] = "@(#)mset.c	4.2 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: mset.c,v 1.1.1.1 2010/01/17 01:33:19 dholland Exp $");
#endif
#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>
#include <stdlib.h>
#include <string.h>
#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(char *, char *);
static void forwRegister(struct regstate *, struct regstate *);
static void backRegister(struct regstate *, struct regstate *);
static struct regstate *doRegister(struct regstate *);
static char *addString(int, int);
static void printString(char *, char *, char *);
static void recurse(int, state *);

int main(int, char *[]);

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)
struct regstate *regptr;
{
    static struct regstate *pivot = regstates;
    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)
char *string;
char *begin, *tc_name;
{
    char *st1, *st2;
    int pchar;
    static char suffix = 'A';
    int new = strcmp(savename, tc_name);
    char delim = new ? ';' : '|';

    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;
}


int
main(argc, argv)
int argc;
char *argv[];
{
    state *head;
    char *keybdPointer = (char *) 0;
    char *commandName = argv[0];
    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);
}

File Added: pkgsrc/comms/tn3270/files/ascii/Attic/state.h
/*	$NetBSD: state.h,v 1.1.1.1 2010/01/17 01:33:19 dholland Exp $	*/
/*	From NetBSD: state.h,v 1.6 2003/08/07 11:16:28 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 *
 *	from: @(#)state.h	4.2 (Berkeley) 4/26/91
 */

#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 */
};

/* termin.c */
void init_keyboard(void);
void InitMapping(void);
void TransInput(int, int);
int TerminalIn(void);
int DataFromTerminal(char *, int);

File Added: pkgsrc/comms/tn3270/files/ascii/Attic/termin.c
/*	$NetBSD: termin.c,v 1.1.1.1 2010/01/17 01:33:19 dholland Exp $	*/
/*	From NetBSD: termin.c,v 1.8 2003/08/07 11:16:28 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 */

#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)termin.c	4.2 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: termin.c,v 1.1.1.1 2010/01/17 01:33:19 dholland Exp $");
#endif
#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/declare.h"
#include "../sys_curses/telextrn.h"

#include "../api/astosc.h"
#include "state.h"
#include "externs.h"
#include "map3270.h"

#include "../general/globals.h"

extern cc_t escape;			/* Escape to command mode */

#define IsControl(c)	(!isprint((unsigned char)c) || (isspace((unsigned char)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)


static void AddChar(int);
static void FlushChar(void);


/*
 * init_keyboard()
 *
 * Initialize the keyboard variables.
 */

void
init_keyboard()
{
    ourPHead = ourPTail = ourBuffer;
    InControl = 0;
    WaitingForSynch = 0;
}


/*
 * Initialize the keyboard mapping file.
 */

void
InitMapping()
{
    struct astosc *ptr;

    if (!headOfControl) {
	/* need to initialize */
	headOfControl = InitControl((char *)0, 0, ascii_to_index);
	if (!headOfControl) {		/* should not occur */
	    quit(0, NULL);
	}
	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;
    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)
char	*buffer;		/* the data read in */
int	count;			/* how many bytes in this buffer */
{
    state *regControlPointer;
    int c;
    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) {
	BellOff();
    }

    origCount = count;

    while (count) {
	c = *buffer++&0x7f;
	count--;

	if (c == escape) {
		if (count && (*buffer&0x7f) == escape) {
			buffer++;
			count--;
		} else {
			command(0, (char *)0, 0);
			RefreshScreen();
			continue;
		}
	}

	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 {
			    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);
}

File Added: pkgsrc/comms/tn3270/files/ctlr/Attic/3270pc.kbd
/*-
 * Copyright (c) 1988 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. 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	4.2 (Berkeley) 4/26/91
 */

/*
 * 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

File Added: pkgsrc/comms/tn3270/files/ctlr/Attic/3180.kbd
/*-
 * Copyright (c) 1988 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. 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	4.2 (Berkeley) 4/26/91
 */

/*
 * 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

File Added: pkgsrc/comms/tn3270/files/ctlr/Attic/ctlr.order
api.o
inbound.o
oia.o
options.o
outbound.o

File Added: pkgsrc/comms/tn3270/files/ctlr/Attic/api.c
/*	$NetBSD: api.c,v 1.1.1.1 2010/01/17 01:33:20 dholland Exp $	*/
/*	From NetBSD: api.c,v 1.7 2003/08/07 11:16:29 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 */

#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)api.c	4.5 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: api.c,v 1.1.1.1 2010/01/17 01:33:20 dholland Exp $");
#endif
#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 "declare.h"

#include "externs.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


/* api.c */
#if	defined(MSDOS)
static void movetous(char *, int, int , int);
static void movetothem(int, int , char *, int);
#else
#include "../sys_curses/telextrn.h"
#endif
static void name_resolution(union REGS *, struct SREGS *);
static void query_session_id(union REGS *, struct SREGS *);
static void query_session_parameters(union REGS *, struct SREGS *);
static void query_session_cursor(union REGS *, struct SREGS *);
static void connect_to_keyboard(union REGS *, struct SREGS *);
static void disconnect_from_keyboard(union REGS *, struct SREGS *);
static void write_keystroke(union REGS *, struct SREGS *);
static void disable_input(union REGS *, struct SREGS *);
static void enable_input(union REGS *, struct SREGS *);
static void copy_subroutine(BufferDescriptor *, BufferDescriptor *,
    CopyStringParms *, int, int);
static void copy_string(union REGS *, struct SREGS *);
static void read_oia_group(union REGS *, struct SREGS *);
static void unknown_op(union REGS *, struct SREGS *);

/*
 * General utility routines.
 */

#if	defined(MSDOS)

#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) */

/*
 * 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 void
copy_subroutine(target, source, parms, what_is_user, length)
BufferDescriptor *target, *source;
CopyStringParms *parms;
int what_is_user;
int length;
#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;
    unsigned 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 = (unsigned 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 = (unsigned char far *)
	    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) {
	    /* XXX: So why are we doing this? (bug) */
	    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;
}


void
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 */
    }
}

File Added: pkgsrc/comms/tn3270/files/ctlr/Attic/api.h
/*	$NetBSD: api.h,v 1.1.1.1 2010/01/17 01:33:20 dholland Exp $	*/
/*	From NetBSD: api.h,v 1.7 2003/08/07 11:16:30 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 *
 *	from: @(#)api.h	4.4 (Berkeley) 4/26/91
 */

/*
 * 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 preceding.
 */

#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) */

/* Interface */
int api_close_api(void);
int api_open_api(char *);
int api_exch_api(union REGS *, struct SREGS *, char *, int);

/* api.c */
void handle_api(union REGS *, struct SREGS *);

File Added: pkgsrc/comms/tn3270/files/ctlr/Attic/declare.h
/*	$NetBSD: declare.h,v 1.1.1.1 2010/01/17 01:33:20 dholland Exp $	*/
/*	From NetBSD: declare.h,v 1.6 2003/08/07 11:16:30 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 *
 *	from: @(#)declare.h	4.2 (Berkeley) 4/26/91
 */

/*
 * Declarations of routines from the controller.
 */


/* outbound.c */
void init_ctlr(void);
int FieldInc(int);
int FieldDec(int);
void Clear3270(void);
void AddHost(int, int);
int DataFromNetwork(char *, int, int);
void Init3270(void);
void Stop3270(void);

/* inbound.c */
void init_inbound(void);
void ModifyMdt(int, int);
void DoReadModified(int);
void DoReadBuffer(void);
void SendTransparent(char *, int);
void SendToIBM(void);
int AcceptKeystroke(unsigned int, unsigned int );
int DataFrom3270(unsigned char *, int);

File Added: pkgsrc/comms/tn3270/files/ctlr/Attic/function.c
/*	$NetBSD: function.c,v 1.1.1.1 2010/01/17 01:33:20 dholland Exp $	*/
/*	From NetBSD: function.c,v 1.6 2006/03/20 01:34:49 gdamore Exp 	*/

/*-
 * Copyright (c) 1988 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. 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 HOST_TOOL
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)function.c	4.2 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: function.c,v 1.1.1.1 2010/01/17 01:33:20 dholland Exp $");
#endif
#endif /* not lint */
#endif

/*
 * 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"

File Added: pkgsrc/comms/tn3270/files/ctlr/Attic/function.h
/*	$NetBSD: function.h,v 1.1.1.1 2010/01/17 01:33:20 dholland Exp $	*/
/*	From NetBSD: function.h,v 1.5 2003/08/07 11:16:30 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 *
 *	from: @(#)function.h	4.2 (Berkeley) 4/26/91
 */

/*
 * 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 */

File Added: pkgsrc/comms/tn3270/files/ctlr/Attic/hostctlr.h
/*	$NetBSD: hostctlr.h,v 1.1.1.1 2010/01/17 01:33:20 dholland Exp $	*/
/*	From NetBSD: hostctlr.h,v 1.5 2003/08/07 11:16:31 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 *
 *	from: @(#)hostctlr.h	4.2 (Berkeley) 4/26/91
 */

#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

File Added: pkgsrc/comms/tn3270/files/ctlr/Attic/inbound.c
/*	$NetBSD: inbound.c,v 1.1.1.1 2010/01/17 01:33:21 dholland Exp $	*/
/*	From NetBSD: inbound.c,v 1.7 2003/08/07 11:16:31 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 */

#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)inbound.c	4.3 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: inbound.c,v 1.1.1.1 2010/01/17 01:33:21 dholland Exp $");
#endif
#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 "../sys_curses/telextrn.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? */


static void Tab(void);
static void BackTab(void);
static void EraseEndOfField(void);
static void Delete(int, int );
static void ColBak(void);
static void ColTab(void);
static void Home(void);
static int LastOfField(int);
static void FlushChar(void);
static void AddChar(int);
static void SendUnformatted(void);
static int SendField(int, int);
static void OneCharacter(int, int);

/*
 * 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()
{
    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()
{
    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).
 */

void
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()
{
    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)
int	where,		/* Where to start deleting from */
		from;		/* Where to pull back from */
{
    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()
{
    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()
{
    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()
{
    int i;
    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 int
LastOfField(i)
int	i;	/* position to start from */
{
    int j;
    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()
{
    int i, j;
    int Nulls;
    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 int
SendField(i, cmd)
int i;			/* where we saw MDT bit */
int	cmd;			/* The command code (type of read) */
{
    int j;
    int k;
    int Nulls;
    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 */
{
    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()
{
    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? */
{
    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 */
{
    int c;
    int i;
    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, NULL, 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, NULL, 0);
	    if (shell_active == 0) {
		ConnectScreen();
	    }
	    break;

	case FCN_DISC:
	    StopScreen(1);
	    suspend(0, NULL);
	    setconnmode(0);
	    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);
}

File Added: pkgsrc/comms/tn3270/files/ctlr/Attic/oia.c
/*	$NetBSD: oia.c,v 1.1.1.1 2010/01/17 01:33:21 dholland Exp $	*/
/*	From NetBSD: oia.c,v 1.5 2003/08/07 11:16:31 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 */

#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)oia.c	4.2 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: oia.c,v 1.1.1.1 2010/01/17 01:33:21 dholland Exp $");
#endif
#endif /* not lint */

/*
 * Routines to maintain the Operator Information Area.
 */

#include "../general/general.h"

#include "oia.h"
#include "../general/globals.h"


void
init_oia()
{
    ClearElement(OperatorInformationArea);
}

File Added: pkgsrc/comms/tn3270/files/ctlr/Attic/oia.h
/*	$NetBSD: oia.h,v 1.1.1.1 2010/01/17 01:33:21 dholland Exp $	*/
/*	From NetBSD: oia.h,v 1.6 2003/08/07 11:16:32 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 *
 *	from: @(#)oia.h	4.2 (Berkeley) 4/26/91
 */

/*
 * 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

/* oia.c */
void init_oia(void);

File Added: pkgsrc/comms/tn3270/files/ctlr/Attic/options.c
/*	$NetBSD: options.c,v 1.1.1.1 2010/01/17 01:33:21 dholland Exp $	*/
/*	From NetBSD: options.c,v 1.6 2005/02/11 06:21:22 simonb Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 */

#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)options.c	4.2 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: options.c,v 1.1.1.1 2010/01/17 01:33:21 dholland Exp $");
#endif
#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()
{
    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;
}

int
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);
}

File Added: pkgsrc/comms/tn3270/files/ctlr/Attic/options.h
/*	$NetBSD: options.h,v 1.1.1.1 2010/01/17 01:33:21 dholland Exp $	*/
/*	From NetBSD: options.h,v 1.6 2003/08/07 11:16:32 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 *
 *	from: @(#)options.h	4.2 (Berkeley) 4/26/91
 */

/*
 * the various options that run our life.  Very few of these are implemented
 *	as yet.
 */

#define	INCLUDED_OPTIONS

void OptInit(void);
int OptOrder(unsigned char *, int, int);

File Added: pkgsrc/comms/tn3270/files/ctlr/Attic/outbound.c
/*	$NetBSD: outbound.c,v 1.1.1.1 2010/01/17 01:33:22 dholland Exp $	*/
/*	From NetBSD: outbound.c,v 1.6 2006/04/30 23:38:34 christos Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 */

#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)outbound.c	4.3 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: outbound.c,v 1.1.1.1 2010/01/17 01:33:22 dholland Exp $");
#endif
#endif /* not lint */

#include <stdio.h>

#include "../general/general.h"

#include "hostctlr.h"
#include "oia.h"
#include "screen.h"
#include "options.h"
#include "../api/ebc_disp.h"
#include "../ascii/state.h"
#include "../sys_curses/telextrn.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();
}


int
FieldInc(position)
int	position;		/* Position in previous field */
{
    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;
}

int
FieldDec(position)
int	position;
{
    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 */
int	count;				/* and how much there is */
int	control;				/* this buffer ended block? */
{
    int origCount;
    unsigned char *buffer = (unsigned char *)Buffer;
    int c;
    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 0
    if (count == 0) {
#endif
	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);
#if 0
    } else {
	return(origCount-count);
    }
#endif
}

/*
 * 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);
}

File Added: pkgsrc/comms/tn3270/files/ctlr/Attic/screen.h
/*	$NetBSD: screen.h,v 1.1.1.1 2010/01/17 01:33:22 dholland Exp $	*/
/*	From NetBSD: screen.h,v 1.5 2003/08/07 11:16:32 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 *
 *	from: @(#)screen.h	4.3 (Berkeley) 4/26/91
 */

#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 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)

File Added: pkgsrc/comms/tn3270/files/ctlr/Attic/scrnctlr.h
/*	$NetBSD: scrnctlr.h,v 1.1.1.1 2010/01/17 01:33:22 dholland Exp $	*/
/*	From NetBSD: scrnctlr.h,v 1.5 2003/08/07 11:16:33 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 *
 *	from: @(#)scrnctlr.h	4.2 (Berkeley) 4/26/91
 */

/*
 * 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

File Added: pkgsrc/comms/tn3270/files/ctlr/Attic/unix.kbd
/*-
 * Copyright (c) 1988 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. 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	4.2 (Berkeley) 4/26/91
 */

/*
 * 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

File Added: pkgsrc/comms/tn3270/files/general/Attic/general.order
globals.o
genbsubs.o

File Added: pkgsrc/comms/tn3270/files/general/Attic/genbsubs.c
/*	$NetBSD: genbsubs.c,v 1.1.1.1 2010/01/17 01:33:22 dholland Exp $	*/
/*	From NetBSD: genbsubs.c,v 1.6 2003/08/07 11:16:33 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 */

#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)genbsubs.c	4.2 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: genbsubs.c,v 1.1.1.1 2010/01/17 01:33:22 dholland Exp $");
#endif
#endif /* not lint */

#include "general.h"

/* 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)
char *s1, *s2;
int n;
{
    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)
char *s1;
int n;
int b;
{
    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;
ssize_t stride;
{
    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;
}

File Added: pkgsrc/comms/tn3270/files/general/Attic/general.h
/*	$NetBSD: general.h,v 1.1.1.1 2010/01/17 01:33:22 dholland Exp $	*/
/*	From NetBSD: general.h,v 1.10 2003/08/07 11:16:34 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 *
 *	from: @(#)general.h	4.2 (Berkeley) 4/26/91
 */

/*
 * Some general definitions.
 */

#include <sys/types.h>

#define	numberof(x)	(sizeof x/sizeof x[0])
#define	highestof(x)	(numberof(x)-1)

#define	ClearElement(x)		memset((char *)&x, 0, sizeof x)
#define	ClearArray(x)		memset((char *)x, 0, sizeof x)

#include <string.h>

/* genbsubs.c */
int bunequal(char *, char *, int);
int bskip(char *, int, int);
unsigned char *memNSchr(char *, int, unsigned int, int, ssize_t);

File Added: pkgsrc/comms/tn3270/files/general/Attic/globals.c
/*	$NetBSD: globals.c,v 1.1.1.1 2010/01/17 01:33:22 dholland Exp $	*/
/*	From NetBSD: globals.c,v 1.5 2003/08/07 11:16:34 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 */

#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)globals.c	4.2 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: globals.c,v 1.1.1.1 2010/01/17 01:33:22 dholland Exp $");
#endif
#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;

}

File Added: pkgsrc/comms/tn3270/files/general/Attic/globals.h
/*	$NetBSD: globals.h,v 1.1.1.1 2010/01/17 01:33:22 dholland Exp $	*/
/*	From NetBSD: globals.h,v 1.6 2003/08/07 11:16:34 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 *
 *	from: @(#)globals.h	4.2 (Berkeley) 4/26/91
 */

/*
 *	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

void init_system(void);

#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) */

File Added: pkgsrc/comms/tn3270/files/general/Attic/vaxbsubs.s
/*	$NetBSD: vaxbsubs.s,v 1.1.1.1 2010/01/17 01:33:22 dholland Exp $	*/
/*	From NetBSD: vaxbsubs.s,v 1.4 2003/08/07 11:16:34 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 *
 *	from: @(#)vaxbsubs.s	4.2 (Berkeley) 4/26/91
 *	$NetBSD: vaxbsubs.s,v 1.1.1.1 2010/01/17 01:33:22 dholland Exp $
 */

/* 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

File Added: pkgsrc/comms/tn3270/files/mset/Attic/map3270.5
.\"	$NetBSD: map3270.5,v 1.1.1.1 2010/01/17 01:33:23 dholland Exp $
.\"	From NetBSD: map3270.5,v 1.12 2003/08/07 11:16:35 agc Exp 
.\"
.\" Copyright (c) 1986 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. 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.
.\"
.\"	from: @(#)map3270.5	4.5 (Berkeley) 7/31/91
.\"	$NetBSD: map3270.5,v 1.1.1.1 2010/01/17 01:33:23 dholland Exp $
.\"
.TH MAP3270 5  "July 31, 1991"
.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 /usr/share/misc/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            alternative 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 /usr/share/misc/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\*[Am]'; pfk20 = '\eE*';
        pfk21 = '\eE('; pfk22 = '\eE)'; pfk23 = '\eE_'; pfk24 = '\eE+';
        }
.fi
.SH "IBM 3270 KEY DEFINITIONS 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
/usr/share/misc/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).

File Added: pkgsrc/comms/tn3270/files/mset/Attic/Makefile
#	$NetBSD: Makefile,v 1.1.1.1 2010/01/17 01:33:23 dholland Exp $
#	From NetBSD: Makefile,v 1.26 2003/10/21 10:01:22 lukem Exp 

.include <bsd.own.mk>

PROG=	mset
MAN=	mset.1 map3270.5
SRCS=	astosc.c map3270.c mset.c
DPSRCS=	astosc.out

MKASTOSCDIR!=cd $(.CURDIR)/../tools/mkastosc && ${PRINTOBJDIR}
MKASTOSC=${MKASTOSCDIR}/mkastosc

${MKASTOSC}:
	@cd ${.CURDIR}/../tools/mkastosc && ${MAKE}

CLEANFILES+= astosc.out
astosc.out: ${.CURDIR}/../ctlr/hostctlr.h ${.CURDIR}/../ctlr/function.h \
	    ${.CURDIR}/../ctlr/${KBD} ${MKASTOSC}
	${_MKTARGET_CREATE}
	${MKASTOSC} \
	    ${.CURDIR}/../ctlr/hostctlr.h ${.CURDIR}/../ctlr/function.h \
	    < ${.CURDIR}/../ctlr/${KBD} > tmp
	mv -f tmp ${.TARGET}

.include <bsd.prog.mk>

.PATH: ${.CURDIR}/../api ${.CURDIR}/../ascii

astosc.o:	astosc.out

File Added: pkgsrc/comms/tn3270/files/mset/Attic/map3270
#	$NetBSD: map3270,v 1.1.1.1 2010/01/17 01:33:24 dholland Exp $
#	From NetBSD: map3270,v 1.4 1999/09/06 20:28:20 perry Exp
#
# Copyright (c) 1989, 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	8.2 (Berkeley) 4/1/94
#

# This file contains mappings between characters entered from the keyboard,
# and 3270 keys, for use by programs (like tn3270) doing 3270 emulation
# from unix.
#
# Inside the single quotes, a caret ("^") introduces a control character
# sequence (rub out = ^?, by the way).  Also inside the single quotes,
# a backslash ('\') introduces an escaped character.  Also, \n, \r, \t,
# are all as in C, and \E is another way of representing escape.
#
#	NOTE that while we are defining lots of function, much of that
# function (ie: local editing keys) may not yet be available from tn3270.
#
# Please e-mail changes to termcap@berkeley.edu or uunet!ucbvax!termcap.
#

3a | adm3a {
    enter = '^m';
    clear = '^z';

    nl = '^n';
    tab = '^i';
    btab = '^b' | '\E^i';
    left = '^h';
    right = '^l';
    up = '^k';
    down = '^j';
    home = '^@';

    delete = '^d' | '^?';		# rubout
    eeof = '^e';
    einp = '^w';
    insrt = '\E ';
    dp = '^u';
    fm = '^y';

    # pf keys
    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 = '^f13'; pfk14 = '^f14'; pfk15 = '^f15'; pfk16 = '^f16';
    pfk17 = '^f17'; pfk18 = '^f18'; pfk19 = '^f19'; pfk20 = '^f20';
    pfk21 = '^f21'; pfk22 = '^f22'; pfk23 = '^f23'; pfk24 = '^f24';

    # program attention keys
    pa1 = '^p1';
    pa2 = '^p2';
    pa3 = '^p3';

    # other keys
    cursel = '\E.';
    centsign = '^\';

    # local control keys

    reset = '^t';	# well, there is a little confusion here...
    master_reset = '^g';
    flinp = '^x';
    reshow = '^v';	# redisplay screen
    escape = '^c';	# escape to telnet command mode

    # local editing keys
    settab = '\E;';
    deltab = '\E\'';
    clrtab = '\E+';
    setmrg = '\E(';
    sethom = '\E!';
    coltab = '\Ei';
    colbak = '\Eb';
    indent = '\El';
    undent = '\Eh';

} # end of adm3a

920c | tvi920c | 920b {	# tvi920c definitions...

    # command keys
    enter = '^m';
    clear = '^z';

    # cursor movement keys
    nl = '^^' | '^n';		# home
    tab = '^i';
    btab = '^b' | '\E^i';
    left = '^h';
    right = '^l';
    up = '^k';
    down = '^j';
    home = '^@';

    # edit control keys
    delete = '^?' | '^d';	# delete
    eeof = '^e';
    einp = '^w';
    insrt = '\E ';
    dp = '^u';
    fm = '^y';

    # program function keys

    # F1 to F11
    pfk1 = '^a@^m'; pfk2 = '^aA^m'; pfk3 = '^aB^m'; pfk4 = '^aC^m';
    pfk5 = '^aD^m'; pfk6 = '^aE^m'; pfk7 = '^aF^m'; pfk8 = '^aG^m';
    pfk9 = '^aH^m'; pfk10 = '^aI^m'; pfk11 = '^aJ^m';

    # SHIFT-F11
    pfk12 = '^aj^m';

    # ESC F1 to ESC F11
    pfk11 = '\E^a@^m'; pfk12 = '\E^aA^m';
    pfk13 = '\E^aB^m'; pfk14 = '\E^aC^m'; pfk15 = '\E^aD^m'; pfk16 = '\E^aE^m';
    pfk17 = '\E^aF^m'; pfk18 = '\E^aG^m'; pfk19 = '\E^aH^m'; pfk20 = '\E^aI^m';
    pfk21 = '\E^a`^m';

    # ESC SHIFT-F1 to ESC SHIFT-F4
    pfk21 = '\E^a`^m'; pfk22 = '\E^aa^m'; pfk23 = '\E^ab^m'; pfk24 = '\E^ac^m';

    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 = '^f13'; pfk14 = '^f14'; pfk15 = '^f15'; pfk16 = '^f16';
    pfk17 = '^f17'; pfk18 = '^f18'; pfk19 = '^f19'; pfk20 = '^f20';
    pfk21 = '^f21'; pfk22 = '^f22'; pfk23 = '^f23'; pfk24 = '^f24';

    # program attention keys

    pa1 = '^a`^m' | '^p1';
    pa2 = '^aa^m' | '^p2';
    pa3 = '^ab^m' | '^p3';

    # miscellaneous 3270 keys

    cursel = '\E.';
    centsign = '^\';

    # local control keys

    reset = '^t';		# there is some confusion here...
    master_reset = '^g';
    flinp = '^x';
    reshow = '^v';
    escape = '^c';	# escape to telnet command mode

    # local editing keys

    settab = '\E;';
    deltab = '\E\'';
    clrtab = '\E:';
    setmrg = '\E*';
    sethom = '\E!';
    coltab = '\Ei' | '\EI';
    colbak = '\Eb' | '\EB';
    indent = '\El' | '\EL';
    undent = '\Eh' | '\EH';
} # end of tvi920c table...

925 | tvi925 | 925vb | tvi925vb | televideo 925 {

    # command keys

    enter = '^m';
    clear = '^z';

    # cursor movement keys

    nl = '^j' | '^n';
    tab = '^i';
    btab = '\EI';
    left = '^h';
    right = '^l';
    up = '^k';
    down = '^v';
    home = '^^';

    # edit control keys

    delete = '^?';	# that's rubout...
    eeof = '^e';
    einp = '^w';
    insrt = '\E ' | '\EW';

    # program function keys

    pfk1 = '^a@^m';
    pfk2 = '^aA^m';
    pfk3 = '^aB^m';
    pfk4 = '^aC^m';
    pfk5 = '^aD^m';
    pfk6 = '^aE^m';
    pfk7 = '^aF^m';
    pfk8 = '^aG^m';
    pfk9 = '^aH^m';
    pfk10 = '^aI^m';
    pfk11 = '^aJ^m';
    pfk12 = '\EQ';
    pfk13 = '\E^a@^m';
    pfk14 = '\E^aA^m';
    pfk15 = '\E^aB^m';
    pfk16 = '\E^aC^m';
    pfk17 = '\E^aD^m';
    pfk18 = '\E^aE^m';
    pfk19 = '\E^aF^m';
    pfk20 = '\E^aG^m';
    pfk21 = '\E^aH^m';
    pfk22 = '\E^aI^m';
    pfk23 = '\E^aJ^m';
    pfk24 = '\E\EQ';

    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 = '^f13'; pfk14 = '^f14'; pfk15 = '^f15'; pfk16 = '^f16';
    pfk17 = '^f17'; pfk18 = '^f18'; pfk19 = '^f19'; pfk20 = '^f20';
    pfk21 = '^f21'; pfk22 = '^f22'; pfk23 = '^f23'; pfk24 = '^f24';

    # program attention keys

    pa1 = '^a`^m';
    pa2 = '^aa^m';
    pa3 = '^ab^m';

    # other keys
    centsign = '^\';

    # local control keys

    reset = '^t';		# again, there is some confusion here...
    master_reset = '^g';
    flinp = '^x';
    reshow = '^b';
    escape = '^c';	# escape to telnet command mode

# local editing keys

    settab = '\EY';
    deltab = '\Ey';
    clrtab = '\E:';
    setmrg = '\ET';
    sethom = '\Et';
    coltab = '^p';
    colbak = '^o';
    indent = '\ER';
    undent = '\EE';
}


924 | tvi924 {

    # command keys

    enter = '^m';
    clear = '^z';

    # cursor movement keys

    nl = '^j';
    tab = '^i';
    btab = '\EI';
    left = '^h';
    right = '^l';
    up = '^k';
    down = '^v';
    home = '^^';

    # edit control keys

    delete = '^?';	# that's rubout...
    eeof = '^e';
    einp = '^w';
    insrt = '\E ' | '\EW';
    dp = '^u';
    fm = '^y';

    # program function keys

    pfk1 = '^a@^m';
    pfk2 = '^aA^m';
    pfk3 = '^aB^m';
    pfk4 = '^aC^m';
    pfk5 = '^aD^m';
    pfk6 = '^aE^m';
    pfk7 = '^aF^m';
    pfk8 = '^aG^m';
    pfk9 = '^aH^m';
    pfk10 = '^aI^m';
    pfk11 = '^aJ^m';
    pfk12 = '^aK^m';
    pfk13 = '^aL^m';
    pfk14 = '^aM^m';
    pfk15 = '^aN^m';
    pfk16 = '^aO^m';
    pfk17 = '^af^m';
    pfk18 = '^ag^m';
    pfk19 = '^ah^m';
    pfk20 = '^ai^m';
    pfk21 = '^aj^m';
    pfk22 = '^ak^m';
    pfk23 = '^al^m';
    pfk24 = '^am^m';

    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 = '^f13'; pfk14 = '^f14'; pfk15 = '^f15'; pfk16 = '^f16';
    pfk17 = '^f17'; pfk18 = '^f18'; pfk19 = '^f19'; pfk20 = '^f20';
    pfk21 = '^f21'; pfk22 = '^f22'; pfk23 = '^f23'; pfk24 = '^f24';

    # program attention keys

    pa1 = '^a`^m';
    pa2 = '^aa^m';
    pa3 = '^ab^m';

    # other keys
    centsign = '^\';

    # local control keys

    reset = '^t';		# again, there is some confusion here...
    master_reset = '^g';
    flinp = '^x';
    reshow = '^b';
    escape = '^c';	# escape to telnet command mode

    # local editing keys

    settab = '\EY';
    deltab = '\Ey';
    clrtab = '\E:';
    setmrg = '\ET';
    sethom = '\Et';
    coltab = '^p';
    colbak = '^o';
    indent = '\ER';
    undent = '\EE';
}

h19 | heath | h19b | heathkit | heath-19 | z19 | zenith {
enter = '^m';
clear = '^z';

nl = '^n' | '^?';
tab = '^i';
btab = '^b';
left = '^h';
right = '^l';
up = '^k';
down = '^j';
home = '^@';

delete = '^d';
eeof = '^e';
einp = '^w';
insrt = '\E ';

# pf keys
pfk1 = '\E?p\E?q'; pfk2 = '\E?p\E?r'; pfk3 = '\E?p\E?s'; pfk4 = '\E?p\E?t';
pfk5 = '\E?p\E?u'; pfk6 = '\E?p\E?v'; pfk7 = '\E?p\E?w'; pfk8 = '\E?p\E?x';
pfk9 = '\E?p\E?y'; pfk10 = '\E?q\E?p'; pfk11 = '\E?q\E?q'; pfk12 = '\E?q\E?r';
pfk13 = '\E?q\E?s'; pfk14 = '\E?q\E?t'; pfk15 = '\E?q\E?u'; pfk16 = '\E?q\E?v';
pfk17 = '\E?q\E?w'; pfk18 = '\E?q\E?x'; pfk19 = '\E?q\E?y'; pfk20 = '\E?r\E?p';
pfk21 = '\E?r\E?q'; pfk22 = '\E?r\E?r'; pfk23 = '\E?r\E?s'; pfk24 = '\E?r\E?t';

    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 = '^f13'; pfk14 = '^f14'; pfk15 = '^f15'; pfk16 = '^f16';
    pfk17 = '^f17'; pfk18 = '^f18'; pfk19 = '^f19'; pfk20 = '^f20';
    pfk21 = '^f21'; pfk22 = '^f22'; pfk23 = '^f23'; pfk24 = '^f24';

# program attention keys
pa1 = '\EP';
pa2 = '\EQ';
pa3 = '\ER';

# other keys

    centsign = '^\';
# cursel = '\E.'; # find out what this does
master_reset = '^g';

# local control keys

reset = '^t';	# well, there is a little confusion here...
flinp = '^x';
reshow = '^v';	# redisplay screen
escape = '^c';	# escape to telnet command mode

# local editing keys
settab = '\E;';
clrtab = '\E:';
setmrg = '\E\'';
sethom = '\E!';
coltab = '\Ei';
colbak = '\Eb';
indent = '\El';
undent = '\Eh';

} # end of h19


co | c100 | concept | c100-4p | concept100 {
enter = '^m';
clear = '^z' | '^\2';

nl = '^n';
tab = '^i';
btab = '^b';
left = '^h' | '\E>';
right = '^l' | '\E=';
up = '^k' | '\E;';
down = '^j' | '\E<';
home = '\E?';

delete = '^d' | '^?' | '^\1';
eeof = '^e' | '^\3';
einp = '^w';
insrt = '^\0';

# pf keys
pfk1 = '\E\E1' | '^\5'; pfk2 = '\E\E2' | '^\6'; pfk3 = '\E\E3' | '^\7';
pfk4 = '\E\E4' | '^\8'; pfk5 = '\E\E5' | '^\9'; pfk6 = '\E\E6' | '^\:';
pfk7 = '\E\E7' | '^\;'; pfk8 = '\E\E8' | '^\<'; pfk9 = '\E\E9' | '^\=';
pfk10 = '\E\E0' | '^\>'; pfk11 = '\E\E-' | '^\?'; pfk12 = '^\@';
pfk13 = '^\A'; pfk14 = '^\B'; pfk15 = '^\)'; pfk16 = '^\*';
pfk17 = '^\+'; pfk18 = '^\,'; pfk19 = '^\-'; pfk20 = '^\.';
pfk21 = '^\/'; pfk22 = '^\C'; pfk23 = '^\D'; pfk24 = '^\E';

    pfk1 = '\E1'; pfk2 = '\E2'; pfk3 = '\E3'; pfk4 = '\E4';
    pfk5 = '\E5'; pfk6 = '\E6'; pfk7 = '\E7'; pfk8 = '\E8';
    pfk9 = '\E9'; pfk10 = '\E0'; pfk11 = '\E-'; pfk12 = '^f12';
    pfk13 = '^f13'; pfk14 = '^f14'; pfk15 = '^f15'; pfk16 = '^f16';
    pfk17 = '^f17'; pfk18 = '^f18'; pfk19 = '^f19'; pfk20 = '^f20';
    pfk21 = '^f21'; pfk22 = '^f22'; pfk23 = '^f23'; pfk24 = '^f24';

# program attention keys
pa1 = '^\%';
pa2 = '^\&' | '\E+';
pa3 = '^\\'';

# other keys
cursel = '\E.';
aplon = '\E{';
aplend = '\E}';
aploff = '\E_';
master_reset = '^g';
centsign = '\E\\';

# local control keys

reset = '^t';	# well, there is a little confusion here...
flinp = '^x';
reshow = '^v';	# redisplay screen
escape = '^c';	# escape to telnet command mode

# local editing keys
settab = '\E\E;';
clrtab = '\E\E:';
setmrg = '\E\E*';
sethom = '\E\E!';
coltab = '\E\Ei';
colbak = '\E\Eb';
indent = '\E\El';
undent = '\E\Eh';

} # end of concept
avt | avt-8p-s | avt-4p-s | avt-rv {
enter = '^m';
clear = '^z' | '\EOM';

nl = '^?';
tab = '^i';
btab = '^b';
left = '^h' | '\E[D';
right = '^l' | '\E[C';
up = '^k' | '\E[A';
down = '^j' | '\E[B';
home = '\EOn';

delete = '^d';
eeof = '^e';
einp = '^w';
insrt = '^ ' | '\E ';

# pf keys
pfk1 = '\EOq' | '\E1'; pfk2 = '\EOr' | '\E2'; pfk3 = '\EOs' | '\E3';
pfk4 = '\EOt' | '\E4'; pfk5 = '\EOu' | '\E5'; pfk6 = '\EOv' | '\E6';
pfk7 = '\EOw' | '\E7'; pfk8 = '\EOx' | '\E8'; pfk9 = '\EOy' | '\E9';
pfk10 = '\EOP\EOp' | '\E0'; pfk11 = '\EOP\EOq' | '\E-';
pfk12 = '\EOP\EOr' | '\E='; pfk13 = '\EOP\EOs' | '^f13';
pfk14 = '\EOP\EOt' | '^f14'; pfk15 = '\EOP\EOu' | '^f15';
pfk16 = '\EOP\EOv' | '^f16'; pfk17 = '\EOP\EOw' | '^f17';
pfk18 = '\EOP\EOx' | '^f18'; pfk19 = '\EOP\EOy' | '^f19';
pfk20 = '\EOQ\EOp' | '^f20'; pfk21 = '\EOQ\EOq' | '^f21';

    pfk22 = '^f22'; pfk23 = '^f23'; pfk24 = '^f24';

# program attention keys
pa1 = '\E\EOP' | '^p1';
pa2 = '\E\EOQ' | '^p2';

# local control keys

escape = '^c';	# escape to telnet command mode
master_reset = '^g';
    centsign = '^\';

# local editing keys
settab = '\E;';
deltab = '\E\'';
clrtab = '\E:';
setmrg = '\E,';
sethom = '\E.';
coltab = '\E\E[B';
colbak = '\E\E[A';
indent = '\E\E[C';
undent = '\E\E[D';
}    # end of avt, etc.

tvipt | vp | televideopt {
    enter = '^m';
    clear = '^z';

 nl = '^n';
    tab = '^i';
    btab = '^b';
    left = '^h';
    right = '^l';
    up = '^k';
    down = '^j';
    home = '^^';

    delete = '^?';
    eeof = '^e';
    einp = '^w';
    insrt = '\E ';

    # pf keys
    pfk1 = '\E1' | '^A@^m';
    pfk2 = '\E2' | '^AA^m';
    pfk3 = '\E3' | '^AB^m';
    pfk4 = '\E4' | '^AC^m';
    pfk5 = '\E5' | '^AD^m';
    pfk6 = '\E6' | '^AE^m';
    pfk7 = '\E7' | '^AF^m';
    pfk8 = '\E8';
    pfk9 = '\E9';
    pfk10 = '\E0';
    pfk11 = '\E!' | '\E^A@^m';
    pfk12 = '\E@' | '\E^AA^m';
    pfk13 = '\E#' | '\E^AB^m';
    pfk14 = '\E$' | '\E^AC^m';
    pfk15 = '\E%' | '\E^AD^m';
    pfk16 = '\E^AE^m' | '\E\^';
    pfk17 = '\E&' | '\E^AF^m';
    pfk18 = '\E*';
    pfk19 = '\E(';
    pfk20 = '\E)';

    # program attention keys
    pa1 = '^AG^m';
    pa2 = '^AH^m';
    pa3 = '^AI^m';

    # other keys
#    # cursel = '\E.';
    centsign = '^\';

    # local control keys

    reset = '^t';	# well, there is a little confusion here...
    master_reset = '^g';
    flinp = '^x';
    reshow = '^v';	# redisplay screen
    escape = '^c';	# escape to telnet command mode

    # local editing keys
    settab = '\E;';
    clrtab = '\E:';
    setmrg = '\E[';
    sethom = '\E+';
    coltab = '\Ei' | '\EI';
    colbak = '\Eb' | '\EB';
    indent = '\El' | '\EL';
    undent = '\Eh' | '\EH';
} # end of tvipt
vt100 | vt100nam | pt100 | vt125 | vt102 | direct831 | tek4125 | pcplot |        microvax | vt220 | vt320 | xterm{
enter = '^m';
clear = '^z' | '\EOM';

nl = '^j';
tab = '^i';
btab = '^b';
left = '^h' | '\E[D' | '\EOD';
right = '^l' | '\E[C' | '\EOC';
up = '^k' | '\E[A' | '\EOA';
down = '\E[B' | '\EOB';
home = '\EOn';

delete = '^d' | '^?';
eeof = '^e';
einp = '^w';
insrt = '^ ' | '\E ';

# pf keys
pfk1 = '\EOq' | '\E1'; pfk2 = '\EOr' | '\E2'; pfk3 = '\EOs' | '\E3';
pfk4 = '\EOt' | '\E4'; pfk5 = '\EOu' | '\E5'; pfk6 = '\EOv' | '\E6';
pfk7 = '\EOw' | '\E7'; pfk8 = '\EOx' | '\E8'; pfk9 = '\EOy' | '\E9';
pfk10 = '\EOP\EOp' | '\E0'; pfk11 = '\EOP\EOq' | '\E-';
pfk12 = '\EOP\EOr' | '\E='; pfk13 = '\EOP\EOs' | '^f13';
pfk14 = '\EOP\EOt' | '^f14'; pfk15 = '\EOP\EOu' | '^f15';
pfk16 = '\EOP\EOv' | '^f16'; pfk17 = '\EOP\EOw' | '^f17';
pfk18 = '\EOP\EOx' | '^f18'; pfk19 = '\EOP\EOy' | '^f19';
pfk20 = '\EOQ\EOp' | '^f20'; pfk21 = '\EOQ\EOq' | '^f21';

# program attention keys
pa1 = '\E\EOP' | '^p1';
pa2 = '\E\EOQ' | '^p2';

# local control keys

escape = '^c';	# escape to telnet command mode
master_reset = '^g';
    centsign = '^\';

# local editing keys
settab = '\E;';
deltab = '\E\'';
clrtab = '\E:';
setmrg = '\E,';
sethom = '\E.';
coltab = '\E\E[B';
colbak = '\E\E[A';
indent = '\E\E[C';
undent = '\E\E[D';
}    # end of vt100, etc.

sun  {
    enter = '^m';
    clear = '^z' | '\E[222z';

    nl = '^j';
    tab = '^i';
    btab = '^b' | '\E[195z' | '\E[216z';
    left = '^h' | '\E[D' | '\EOD';
    right = '^l' | '\E[C' | '\EOC';
    up = '^k' | '\E[A' | '\EOA';
    down = '\E[B' | '\EOB';
    home = '\E[218z';

    delete = '^d' | '^?';
    eeof = '^e' | '\E[214z';
    einp = '^w' | '\E[213z';
    insrt = '\E ' | '\E[220z';
    dp = '^u';
    fm = '^y';

    # pf keys
    pfk1 = '\E[224z' | '\E1'; pfk2 = '\E[225z' | '\E2';
    pfk3 = '\E[226z' | '\E3'; pfk4 = '\E[227z' | '\E4';
    pfk5 = '\E[228z' | '\E5'; pfk6 = '\E[229z' | '\E6';
    pfk7 = '\E[230z' | '\E7'; pfk8 = '\E[231z' | '\E8';
    pfk9 = '\E[232z' | '\E9'; pfk10 = '\E[208z' | '\E0';
    pfk11 = '\E[209z' | '\E-'; pfk12 = '\E[210z' | '\E=';
    pfk13 = '^f13'; pfk14 = '^f14'; pfk15 = '^f15'; pfk16 = '^f16';
    pfk17 = '^f17'; pfk18 = '^f18'; pfk19 = '^f19'; pfk20 = '^f20';
    pfk21 = '^f21'; pfk22 = '^f22'; pfk23 = '^f23'; pfk24 = '^f24';

    # program attention keys
    pa1 = '^p1' | '\E[211z';
    pa2 = '^p2' | '\E[212z';
    pa3 = '^p3';

    # other keys
    cursel = '\E.';
    centsign = '^\';

    # local control keys

    reset = '^t';	# well, there is a little confusion here...
    master_reset = '^g';
    flinp = '^x';
    reshow = '^v';	# redisplay screen
    escape = '^c';	# escape to telnet command mode

    # local editing keys
    settab = '\E;';
    clrtab = '\E+';
    setmrg = '\E(';
    sethom = '\E!';
    coltab = '\Ei';
    colbak = '\Eb';
    indent = '\El';
    undent = '\Eh';
} # end of sun
#
# Works with /usr/ucb/tn3270 except tn3270pc which requires /usr/new/tn3270.
#
msk22714 | mskermit22714 | msk227 | mskermit227 {
#
# 9-5-86 gts
# MS-Kermit UCB 227.14 to Unix then tn3270 to CMS.
# Includes underlying ADM3A keystrokes for full S/1 compatibiliy.
# Attempts to work for both "do unix" and "do cms" keyboards.  Differences are
# marked with (C) for CMS only or (U) for Unix only.  Incidental effects are
# enclosed in square brackets [].
# New functions WERASE Ctrl-\  and FERASE Ctrl-_.

    enter = '^m';					# <--'
    clear = '^z';					# keypad + (C)

    nl    = '^n';					# keypad End (C)
    tab   = '^i';					# --->|
    btab  = '^b'  | '\E^I';				# |<--- (C|U)
    left  = '^h';					# keypad Left
    right = '^l';					# keypad Right
    up    = '^k';					# keypad Up
    down  = '^j'  | '\EB';				# keypad Down (U|C)
							# [ keypad End (U) ]
    home  = '^^'  | '^@';				# keypad Home (U|C)
    dp    = '^u'  | '^a';				# [ keypad PgUp (U) ]
    fm    = '^y';

    delete = '^d' | '^?';				# keypad Del
							# [ keypad PgDn (U) ]
    eeof   = '^e';
    einp   = '^w';					# keypad - (C)
    insrt  = '\E ' | '\Ei';				# keypad Ins (C|U)

    # pf keys IBM PC/XT/AT and ADM3A Esc d
    pfk1 = '\E1'; pfk2 = '\E2'; pfk3 = '\E3'; pfk4 = '\E4'; pfk5 = '\E5';
    pfk6 = '\E6'; pfk7 = '\E7'; pfk8 = '\E8'; pfk9 = '\E9'; pfk10= '\E0';
    # pf keys IBM PC/XT/AT Shift and ADM3A Ctrl-F nn
    pfk11='^f11'; pfk12='^f12'; pfk13='^f13'; pfk14='^f14'; pfk15='^f15';
    pfk16='^f16'; pfk17='^f17'; pfk18='^f18'; pfk19='^f19'; pfk20='^f20';
    # pf keys IBM PC/XT/AT Ctrl- and ADM3A Ctrl-F nn
    pfk21='^f21'; pfk22='^f22'; pfk23='^f23'; pfk24='^f24'; pfk25='^f25';
    pfk26='^f26'; pfk27='^f27'; pfk28='^f28'; pfk29='^f29'; pfk30='^f30';
    # pf keys IBM PC/XT/AT Ctrl-Shift- and ADM3A Ctrl-F nn
    pfk31='^f31'; pfk32='^f32'; pfk33='^f33'; pfk34='^f34'; pfk35='^f35';
    pfk36='^f36';
    # pf keys IBM PC/XT/AT Alt-1 to Alt-= (generated as, Esc d, ^F 11, ^F 12)
    # pf keys ADM3A Esc d           (d = 1 to 0 interpreted as above)
    pfk11 = '\E-'; pfk12 = '\E=';

    # program attention keys (same as ADM3A)
    pa1 = '^p1';					# Alt-F1
    pa2 = '^p2';					# Alt-F2
    pa3 = '^p3';					# Alt-F3
   #pa4 = '^p4';					# Alt-F3
   #testreq = '^pr' | '^pR';				# Alt-F5

    # other keys
    cursel = '\E.';
    werase = '^\';
    ferase = '^_';

    # local control keys
    master_reset = '^g';
    reset  = '^r'  | '^t';
    flinp  = '^x';
    reshow = '^v';
    escape = '^c';					# escape to telnet

    # local editing keys
    settab = '\E;';
    deltab = '\E\'';
    clrtab = '\E:' | '\E+';
    setmrg = '\E(';
    sethom = '\E!';
    coltab = '\EI';
   #coltab = '\Ei' | '\EI';				# cannot use Esc i
    colbak = '\Eb';					# on S/1 \EB is down
   #colbak = '\Eb' | '\EB';				# cannot use Esc B
    indent = '\El' | '\EL';
    undent = '\Eh' | '\EH';				# on S/1 \EH is Home

} # end of msk22714
#
ansisys | ansisysk | nansisys | nansisysk {
#
# 9-5-86 gts
# IBM PC/XT/AT using the ansi.sys | ansi.sysk | nansi.sys | nansi.sysk termcaps.
#
# PROBLEM: cannot use periods in termcap name until mset fixed (gts 9-5-86).
#
# PROBLEM: cannot use eval `mset ...` until Unix csh changed to allow more
# than 1024 characters in an environment string or until mset changed to
# return only the filename if the resulting string is longer than 1024.
#
# PROBLEM when NUL (^@) immediately follows a Return:  Unix telent apparently
# ignores the NUL!  (Can tn3270 negotiate a different newline?)
#
# Nearly identical to the map3270 for the IBM PC TN3270, which itself is nearly
# identical to the MS-Kermit UCB 227.14 keyboard which in turn was a  modest
# improvement of the BIJOU Yterm keyboard.  See HELP TN3270PC on CMS.
# Includes the underlying ADM3A keystrokes for full S/1 compatibility.
# Adds some Ctrl-keypad keys to compensate for TN3270 ROMBIOS dependency
# which prevents separate use of the keypad plus and minus keys.
# Adds new functions WERASE and FERASE.
#

    enter = '^m';					# <--'
    clear = '^z' | '^@w';				# Ctrl-Home

    nl    = '^n'  | '^@O';				# keypad End
    tab   = '^i';					# --->|
    btab  = '^b'  | '^@^O';				# |<---
    left  = '^h'  | '^@K';				# keypad Left
    right = '^l'  | '^@M';				# keypad Right
    up    = '^k'  | '^@H';				# keypad Up
    down  = '^j'  | '^@P';				# keypad Down
    home  = '^^'  | '^@G';				# keypad Home
							# (cannot use Ctrl-@)
    dp    = '^u';
    fm    = '^y';

    delete = '^d'  | '^?'  | '^@S';			# keypad Del
    eeof   = '^e'  | '^@u';				# keypad Ctrl-End
    einp   = '^w';
    insrt  = '\E ' | '^@R' | '\E\Ei';			# keypad Ins

    # pf keys IBM PC/XT/AT
    pfk1 = '^@;'; pfk2 = '^@<'; pfk3 = '^@='; pfk4 = '^@>'; pfk5 = '^@?';
    pfk6 = '^@@'; pfk7 = '^@A'; pfk8 = '^@B'; pfk9 = '^@C'; pfk10= '^@D';
    # pf keys IBM PC/XT/AT Shift
    pfk11 = '^@T'; pfk12 = '^@U'; pfk13 = '^@V'; pfk14 = '^@W';  pfk15 = '^@X';
    pfk16 = '^@Y'; pfk17 = '^@Z'; pfk18 = '^@['; pfk19 = '^@\\'; pfk20 = '^@]';
    # pf keys IBM PC/XT/AT Ctrl-
    pfk21 = '^@\^';pfk22 = '^@_'; pfk23 = '^@`'; pfk24 = '^@a';  pfk25 = '^@b';
    pfk26 = '^@c'; pfk27 = '^@d'; pfk28 = '^@e'; pfk29 = '^@\f'; pfk30 = '^@g';
    # pf keys IBM PC/XT/AT Ctrl-Shift-   (cannot be done yet with  PC tn3270)
    # pf keys IBM PC/XT/AT Alt-d
    pfk1 = '^@x'; pfk2 = '^@y'; pfk3 = '^@z'; pfk4 = '^@{'; pfk5 = '^@|';
    pfk6 = '^@}'; pfk7 = '^@~'; pfk8 = '^@^?';pfk9 = '^@^@';pfk10= '^@^A';
    pfk11='^@^B'; pfk12= '^@^C';

    # pf keys ADM3A Esc d
    pfk1 = '\E1'; pfk2 = '\E2'; pfk3 = '\E3'; pfk4 = '\E4'; pfk5 = '\E5';
    pfk6 = '\E6'; pfk7 = '\E7'; pfk8 = '\E8'; pfk9 = '\E9'; pfk10= '\E0';
    pfk11 = '\E-'; pfk12 = '\E=';
    # pf keys ADM3A Ctrl-F n n
    pfk1 = '^f01'; pfk2 = '^f02'; pfk3 = '^f03'; pfk4 = '^f04'; pfk5= '^f05';
    pfk6 = '^f06'; pfk7 = '^f07'; pfk8 = '^f08'; pfk9 = '^f09'; pfk10= '^f10';
    pfk11= '^f11'; pfk12= '^f12'; pfk13= '^f13'; pfk14= '^f14'; pfk15= '^f15';
    pfk16= '^f16'; pfk17= '^f17'; pfk18= '^f18'; pfk19= '^f19'; pfk20= '^f20';
    pfk21= '^f21'; pfk22= '^f22'; pfk23= '^f23'; pfk24= '^f24'; pfk25= '^f25';
    pfk26= '^f26'; pfk27= '^f27'; pfk28= '^f28'; pfk29= '^f29'; pfk30= '^f30';
    pfk31= '^f31'; pfk32= '^f32'; pfk33= '^f33'; pfk34= '^f34'; pfk35= '^f35';
    pfk36= '^f36';

    # program attention keys
    pa1 = '^p1' | '^@h';				# Alt-F1
    pa2 = '^p2' | '^@i';				# Alt-F2
    pa3 = '^p3' | '^@j';				# Alt-F3
   #pa4 = '^p4' | '^@k';				# Alt-F4
   #testreq = '^pr' | '^pR' | '^@l'			# Alt-F5

    # other keys
    cursel = '\E.';
    werase = '^\';
    ferase = '^_';
    pfk7 = '^@I'    | '\E^U';				# keypad PgUp
    pfk8 = '^@Q'    | '\E^D';				# keypad PgDn

    # local control keys
    reset  = '^r' | '^t';
    master_reset = '^g';
    flinp  = '^x';
    reshow = '^v';
    escape = '^c';		# escape to TN3270 command prompt

    # local editing keys
    settab = '\E;';
    deltab = '\E\'';
    clrtab = '\E:' | '\E+';
    setmrg = '\E(';
    sethom = '\E!';
    coltab = '\Ei' | '\EI';
    colbak = '\Eb' | '\EB';		# on S/1 \EB is down
    indent = '\El' | '\EL';
    undent = '\Eh' | '\EH';		# on S/1 \EH is Home

} # end of ansi.sys
#
tn3270pc | ibm-3278-2 {
#
# 2-14-87 gts
#
# MAP3270 for the IBM PC logged into Unix with PC TN3270 with TERM=nansisys,
# nansisysk, ansisys or ansisysk, hence requires KETBD=tn3270pc.
#
# MAP3270 for the IBM PC
# Nearly identical to the MS-Kermit UCB 227.14 keyboard which in turn was
# an modest improvement of the BIJOU Yterm keyboard.
# Includes underlying ADM3A keystrokes for full S/1 compatibiliy.
# Adds some Ctrl-keypad keys to compensate for TN3270 ROMBIOS dependency
# which prevents separate use of the keypad plus and minus keys, and adds
# new functions WERASE, FERASE, WORDTAB, WORDBACKTAB, WORDEND and FIELDEND.
# Where possible these extensions are compatible with IBM PC keystroke usage
# (see XT technical reference manual Keyboard Usage Guidelines).
# Includes F11 and F12 keys from the new IBM PC/XT/AT keyboard.
#

    centsign = '\Ec' | '\EC';				# CentSign for input
    enter = '^m';					# <--'
    clear = '^z' | '^Aw';				# Ctrl-Home

    nl    = '^n'  | '^AO';				# keypad End
    tab   = '^i';					# --->|
    btab  = '^b'  | '\E^I' | '^A^O';			# |<---
    left  = '^h'  | '^AK';				# keypad Left
    right = '^l'  | '^AM';				# keypad Right
    up    = '^k'  | '^AH';				# keypad Up
    down  = '^j'  | '^AP';				# keypad Down
    home  = '^^'  | '^AG'  | '^@';			# keypad Home
    dp    = '^u';
    fm    = '^y';

    delete = '^d' | '^AS';				# keypad Del
    eeof = '^e'  | '^Au';				# keypad End
    einp = '^w';
    insrt = '\E ' | '^AR';				# keypad Ins

    # pf keys IBM PC/XT/AT
    pfk1 = '^A;'; pfk2 = '^A<'; pfk3 = '^A='; pfk4 = '^A>'; pfk5 = '^A?';
    pfk6 = '^A@'; pfk7 = '^AA'; pfk8 = '^AB'; pfk9 = '^AC'; pfk10= '^AD';
    # pf keys IBM PC/XT/AT Shift
    pfk11 = '^AT'; pfk12 = '^AU'; pfk13 = '^AV'; pfk14 = '^AW';  pfk15 = '^AX';
    pfk16 = '^AY'; pfk17 = '^AZ'; pfk18 = '^A['; pfk19 = '^A\\'; pfk20 = '^A]';
    # pf keys IBM PC/XT/AT Ctrl-
    pfk21 = '^A\^';pfk22 = '^A_'; pfk23 = '^A`'; pfk24 = '^Aa'; pfk25 = '^Ab';
    pfk26 = '^Ac'; pfk27 = '^Ad'; pfk28 = '^Ae'; pfk29 = '^Af'; pfk30 = '^Ag';
    # pf keys IBM PC/XT/AT Alt-d
    pfk1 = '^Ax'; pfk2 = '^Ay'; pfk3 = '^Az'; pfk4 = '^A{'; pfk5 = '^A|';
    pfk6 = '^A}'; pfk7 = '^A~'; pfk8 = '^A^?';pfk9 = '^A^A^@';pfk10= '^A^A^A';
    pfk11='^A^A^b'; pfk12= '^A^A^c';
    # pf keys NEW IBM PC/XT/AT Keyboard
    pfk11='^A^A^e'; pfk12= '^A^A^f';

    # pf keys ADM3A Esc d
    pfk1 = '\E1'; pfk2 = '\E2'; pfk3 = '\E3'; pfk4 = '\E4'; pfk5 = '\E5';
    pfk6 = '\E6'; pfk7 = '\E7'; pfk8 = '\E8'; pfk9 = '\E9'; pfk10= '\E0';
    pfk11 = '\E-'; pfk12 = '\E=';
    # pf keys ADM3A Ctrl-F n n
    pfk1 = '^f01'; pfk2 = '^f02'; pfk3 = '^f03'; pfk4 = '^f04'; pfk5= '^f05';
    pfk6 = '^f06'; pfk7 = '^f07'; pfk8 = '^f08'; pfk9 = '^f09'; pfk10= '^f10';
    pfk11= '^f11'; pfk12= '^f12'; pfk13= '^f13'; pfk14= '^f14'; pfk15= '^f15';
    pfk16= '^f16'; pfk17= '^f17'; pfk18= '^f18'; pfk19= '^f19'; pfk20= '^f20';
    pfk21= '^f21'; pfk22= '^f22'; pfk23= '^f23'; pfk24= '^f24'; pfk25= '^f25';
    pfk26= '^f26'; pfk27= '^f27'; pfk28= '^f28'; pfk29= '^f29'; pfk30= '^f30';
    pfk31= '^f31'; pfk32= '^f32'; pfk33= '^f33'; pfk34= '^f34'; pfk35= '^f35';
    pfk36= '^f36';

    # program attention keys
    pa1 = '^p1' | '^Ah';				# Alt-F1
    pa2 = '^p2' | '^Ai';				# Alt-F2
    pa3 = '^p3' | '^Aj';				# Alt-F3
    treq = '^pr' | '^pR' | '^Al';			# Alt-F5

    # other keys
    cursel = '\E.';
    werase = '^\';
    ferase = '^_';
    wordtab = '^At';					# Ctrl-Right
    wordbacktab = '^As';				# Ctrl-Left
    wordend = '^A^A^d';					# Ctrl-PgUp
    fieldend = '^Av';					# Ctrl-PgDn
    pfk7 = '^AI';					# keypad PgUp
    pfk8 = '^AQ';					# keypad PgDn

    # local control keys
    reset  = '^r' | '^t';
    master_reset = '^g';
    flinp  = '^x';
    reshow = '^v';
    escape = '^c';					# to command prompt
    disc   = '^pS1D';					# disconnect (suspend)?
    sync   = '^pS1S';					# in sync with user?

    # local editing keys
    settab = '\E;';
    deltab = '\E\'';
    clrtab = '\E:' | '\E+';
    setmrg = '\E(';
    sethom = '\E!';
    coltab = '\Ei' | '\EI';
    colbak = '\Eb' | '\EB';				# on S/1 \EB is down
    indent = '\El' | '\EL';
    undent = '\Eh' | '\EH';				# on S/1 \EH is Home

} # end of tn3270pc

File Added: pkgsrc/comms/tn3270/files/mset/Attic/mset.1
.\"	$NetBSD: mset.1,v 1.1.1.1 2010/01/17 01:33:24 dholland Exp $
.\"	From NetBSD: mset.1,v 1.11 2003/08/07 11:16:36 agc Exp 
.\"
.\" Copyright (c) 1986, 1990 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. 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.
.\"
.\"	from: @(#)mset.1	4.6 (Berkeley) 7/27/91
.\"	$NetBSD: mset.1,v 1.1.1.1 2010/01/17 01:33:24 dholland Exp $
.\"
.Dd July 27, 1991
.Dt MSET 1
.Os
.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
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
.Ic tn3270
command (see
.Xr tn3270  1  ) .
.Pp
The default
.Nm
output can be used to store the mapping information in the process environment
in order to avoid scanning
.Pa map3270
each time
.Ic 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
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
uses the user's terminal type from the environment variable
.Ev TERM
as the keyboard name.
Normally,
.Nm
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 alternative 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 alternative 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
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
normally will not complain about entries for unknown functions (like
.Dq PFX1 ) ;
the
.Fl picky
argument causes
.Nm
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
output cannot be used to store the mapping information in the process
environment to avoid scanning
.Pa map3270
each time
.Ic tn3270
is invoked.
The
.Fl shell
argument causes
.Nm
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 \*[Gt] tmp ; source tmp ; /bin/rm tmp
.Ed
.It Ar keyboardname
When searching for the
.Pa map3270
entry that matches the user's keyboard,
.Nm
will use
.Ar keyboardname
instead of determining the keyboard name from the
.Ev KEYBD
or
.Ev TERM
environmental variables.
.El
.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
command appeared in
.Bx 4.3 .

File Added: pkgsrc/comms/tn3270/files/sys_curses/Attic/telextrn.h
/*	$NetBSD: telextrn.h,v 1.1.1.1 2010/01/17 01:33:24 dholland Exp $	*/
/*	From NetBSD: telextrn.h,v 1.7 2003/08/07 11:16:37 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 *
 *	from: @(#)telextrn.h	4.2 (Berkeley) 4/26/91
 */

/*
 * 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;

/* system.c */
void freestorage(void);
void movetous(char *, unsigned int, unsigned int , int);
void movetothem(unsigned int, unsigned int , char *, int);
char *access_api(char *, int, int );
void unaccess_api(char *, char *, int, int);
int shell_continue(void);
int shell(int, char *[]);

/* termout.c */
void init_screen(void);
void InitTerminal(void);
void StopScreen(int);
void RefreshScreen(void);
void ConnectScreen(void);
void LocalClearScreen(void);
void BellOff(void);
void RingBell(char *);
int DoTerminalOutput(void);
void TransStop(void);
void TransOut(unsigned char *, int, int, int);

File Added: pkgsrc/comms/tn3270/files/sys_curses/Attic/system.c
/*	$NetBSD: system.c,v 1.1.1.1 2010/01/17 01:33:24 dholland Exp $	*/
/*	From NetBSD: system.c,v 1.21 2006/10/07 17:27:57 elad Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 */

#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)system.c	4.5 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: system.c,v 1.1.1.1 2010/01/17 01:33:24 dholland Exp $");
#endif
#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/time.h>
#include <sys/socket.h>
#include <sys/poll.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "../general/general.h"
#include "../ctlr/api.h"
#include "../api/api_exch.h"
#include "telextrn.h"
#include "externs.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(void);
static int nextstore(void);
static int doreject(char *);
static int doassociate(void);
static int getstorage(long, int, int);
static int doconnect(void);
static void child_died(int);

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;

    if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
	return -1;
    }
    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 ((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)) {
	    const 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(0, NULL);
    }
    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(0, NULL);
    }
    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(0, NULL);
    } 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(0, NULL);
    } 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(0, NULL);
    } 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(0, NULL);
    }
    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()
{
    struct pollfd set[1];
    int i;

    sock = -1;
    set[0].fd = serversock;
    set[0].events = POLLIN;
    while (shell_active && (sock == -1)) {
	if ((i = poll(set, 1, INFTIM)) < 0) {
	    if (errno == EINTR) {
		continue;
	    } else {
		perror("in poll waiting for API connection");
		return -1;
	    }
	} else {
	    i = accept(serversock, (struct sockaddr *)0, (socklen_t *)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)) {

	(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)
    int code;
{
    int pid, status;

    while ((pid = waitpid((pid_t) -1, &status, WNOHANG)) > 0) {
	if (pid == shell_pid) {
	    char inputbuffer[100];

	    shell_active = 0;
	    if (sock != -1) {
		(void) close(sock);
		sock = -1;
	    }
	    printf("[Hit return to continue]");
	    fflush(stdout);
	    (void) fgets(inputbuffer, sizeof(inputbuffer), stdin);
	    setconnmode(0);
	    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 sprint... routines so that we can pick up
 * interrupts generated by application programs.
 */


int
shell(argc,argv)
int	argc;
char	*argv[];
{
    socklen_t length;
    struct sockaddr_in server;
    char sockNAME[128];
    static char **whereAPI = 0;
    int fd;
    struct timeval tv;
    long ikey;

    /* First, create verification file. */
#if	defined(BSD4_4)
    if (keyname != NULL)
	free(keyname);
    keyname = strdup("/tmp/apiXXXXXX");
    fd = mkstemp(keyname);
#else
    do {
	if (keyname != NULL)
	    free(keyname);
	keyname = mktemp(strdup("/tmp/apiXXXXXX")); /* NetBSD: NOT USED */
	fd = open(keyname, O_RDWR|O_CREAT|O_EXCL, IREAD|IWRITE);
    } while ((fd == -1) && (errno == EEXIST));
#endif	/* defined(BSD4_4) */

    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));
    sockNAME[sizeof(sockNAME) - 1] = '\0';
    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(0);			/* Start up signal handler */
    shell_active = 1;			/* We are running down below */
    if ((shell_pid = vfork()) != 0) {
	if (shell_pid == -1) {
	    perror("vfork");
	    (void) close(serversock);
	} else {
	    state = UNCONNECTED;
	}
    } else {				/* New process */
	int i;

	for (i = 3; i < 30; i++) {
	    (void) close(i);
	}
	if (argc == 1) {		/* Just get a shell */
	    char *cmdname;

	    cmdname = getenv("SHELL");
	    execlp(cmdname, cmdname, NULL);
	    perror("Exec'ing new shell");
	    _exit(1);
	} else {
	    execvp(argv[1], &argv[1]);
	    perror("Exec'ing command");
	    _exit(1);
	}
	/*NOTREACHED*/
    }
    return shell_active;		/* Go back to main loop */
}

File Added: pkgsrc/comms/tn3270/files/sys_curses/Attic/terminal.h
/*	$NetBSD: terminal.h,v 1.1.1.1 2010/01/17 01:33:24 dholland Exp $	*/
/*	From NetBSD: terminal.h,v 1.5 2003/08/07 11:16:37 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 *
 *	from: @(#)terminal.h	4.3 (Berkeley) 4/26/91
 */

#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)

File Added: pkgsrc/comms/tn3270/files/sys_curses/Attic/termout.c
/*	$NetBSD: termout.c,v 1.1.1.1 2010/01/17 01:33:25 dholland Exp $	*/
/*	From NetBSD: termout.c,v 1.15 2007/01/17 00:21:44 hubertf Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 */

#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)termout.c	4.3 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: termout.c,v 1.1.1.1 2010/01/17 01:33:25 dholland Exp $");
#endif
#endif /* not lint */

#if defined(unix)
#include <signal.h>
#include <termios.h>
#include <unistd.h>
#ifdef __NetBSD__
#include <termcap.h>
#else
extern char *tgetstr(char *, char **);
#endif
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.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/declare.h"
#include "../ctlr/oia.h"
#include "../ctlr/screen.h"
#include "../ctlr/scrnctlr.h"

#include "../ascii/state.h"
#include "../ascii/map3270.h"

#include "../general/globals.h"

#include "telextrn.h"
#include "externs.h"

extern int TransparentClock, OutputClock;

#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[1024];		/* bell sequence */
static WINDOW *bellwin = 0;		/* The window the bell message is in */
int	bellwinup = 0;			/* Are we up with it or not */


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 */

static void aborttc(int);
#endif	/* defined(unix) */

static void OurExitString(char *, int);
static void DoARefresh(void);
static void GoAway(char *, int);
static int WhereTermAttrByte(int);
static void SlowScreen(void);
static void FastScreen(void);
#if 0
static void ScreenOIA(OIA *);
#endif


/*
 * 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)
int	p;
{
    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()
{
    int is, shouldbe, isattr, shouldattr;
    int pointer;
    int fieldattr, termattr;
    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())) {
	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;
	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)(void) = FastScreen;

#if 0
/*ARGSUSED*/
static void
ScreenOIA(oia)
OIA *oia;
{
}
#endif


/* InitTerminal - called to initialize the screen, etc. */

void
InitTerminal()
{
#if defined(unix)
    struct termios term;
    speed_t speed;
#endif
    char termbuf[1024];
    char *bsp;
    
    InitMapping();		/* Go do mapping file (MAP3270) first */
    if (!screenInitd) { 	/* not initialized */
	if (initscr() == NULL) {	/* 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, (void (*)(int))abort);
#endif

	TryToSend = FastScreen;
#if defined(unix)
	tcgetattr(1, &term);
	speed = cfgetospeed(&term);
	if ((speed < 0) || (speed > 9600)) {
	    max_changes_before_poll = 1920;
	} else {
	    max_changes_before_poll = speed/10;
	    if (max_changes_before_poll < 40) {
		max_changes_before_poll = 40;
	    }
	    TryToSend = SlowScreen;
	    HaveInput = 1;		/* get signals going */
	}
#endif	/* defined(unix) */
	setcommandmode();
#if defined(unix)
	nonl();
#endif
	DoARefresh();
	setconnmode(0);
	if (tgetent(termbuf, getenv("TERM")) == 1) {
	    bsp = bellSequence;
	    if ((bsp = tgetstr("vb", &bsp)) == NULL) {	/* use visual bell */
	        bsp = bellSequence;
		if ((bsp = tgetstr("bl", &bsp)) == NULL) {
		    strcpy (bellSequence, "\07");
		}
	    }
	}
	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();
	endwin();
	setcommandmode();
	setconnmode(0);
	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) {
	RefreshScreen();
	(*TryToSend)();
	screenStopped = 0;
    }
}

/* LocalClearScreen() - clear the whole ball of wax, cheaply */

void
LocalClearScreen()
{
    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(0);
       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];
#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(0);
	     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 {
	TransInput(1, kind);			/* Go get some data */
    }
}


#if	defined(unix)
static void
aborttc(n)
	int n;
{
	setcommandmode();
	(void) close(tin);
	(void) close(tout);
	tin = savefd[0];
	tout = savefd[1];
	setconnmode(0);
	tcflag = 0;
}
#endif	/* defined(unix) */

File Added: pkgsrc/comms/tn3270/files/tn3270/Attic/Makefile
#	$NetBSD: Makefile,v 1.1.1.1 2010/01/17 01:33:25 dholland Exp $
#	From NetBSD: Makefile,v 1.38 2008/08/29 00:02:24 gmcgarry Exp 

.include <bsd.own.mk>

CPPFLAGS+=-I${NETBSDSRCDIR}/lib -I${NETBSDSRCDIR}/usr.bin/telnet
LDADD+=	-lcurses -lcrypt
DPADD+=	${LIBCURSES} ${LIBCRYPT}

PROG=	tn3270
SRCS=	api.c api_bsd.c api_exch.c apilib.c asc_ebc.c astosc.c commands.c \
	dctype.c disp_asc.c ebc_disp.c function.c genbsubs.c genget.c \
	globals.c inbound.c main.c map3270.c network.c oia.c options.c \
	outbound.c ring.c sys_bsd.c system.c telnet.c termin.c terminal.c \
	termout.c tn3270.c utilities.c
DPSRCS=	asc_disp.out astosc.out disp_asc.out kbd.out

MKASTOSCDIR !=cd $(.CURDIR)/../tools/mkastosc && ${PRINTOBJDIR}
MKASTOSC= ${MKASTOSCDIR}/mkastosc

${MKASTOSC}:
	@cd ${.CURDIR}/../tools/mkastosc && ${MAKE}

MKASTODSDIR!=cd $(.CURDIR)/../tools/mkastods && ${PRINTOBJDIR}
MKASTODS= ${MKASTODSDIR}/mkastods

${MKASTODS}:
	@cd ${.CURDIR}/../tools/mkastods && ${MAKE}

MKDSTOASDIR!=cd $(.CURDIR)/../tools/mkdstoas && ${PRINTOBJDIR}
MKDSTOAS= ${MKDSTOASDIR}/mkdstoas

${MKDSTOAS}:
	@cd ${.CURDIR}/../tools/mkdstoas && ${MAKE}

MKHITSDIR!=cd $(.CURDIR)/../tools/mkhits && ${PRINTOBJDIR}
MKHITS= ${MKHITSDIR}/mkhits

${MKHITS}:
	@cd ${.CURDIR}/../tools/mkhits && ${MAKE}

astosc.out: ${.CURDIR}/../ctlr/hostctlr.h ${.CURDIR}/../ctlr/function.h \
	    ${.CURDIR}/../ctlr/${KBD} ${MKASTOSC}
	${_MKTARGET_CREATE}
	${MKASTOSC} \
	    ${.CURDIR}/../ctlr/hostctlr.h ${.CURDIR}/../ctlr/function.h \
	    < ${.CURDIR}/../ctlr/${KBD} > astosc.tmp
	mv -f astosc.tmp ${.TARGET}
CLEANFILES+=	astosc.tmp astosc.out

asc_disp.out: ${MKASTODS}
	${_MKTARGET_CREATE}
	${MKASTODS} > asc_disp.tmp
	mv -f asc_disp.tmp ${.TARGET}
CLEANFILES+=	asc_disp.tmp asc_disp.out

disp_asc.out: ${MKDSTOAS}
	${_MKTARGET_CREATE}
	${MKDSTOAS} > disp_asc.tmp
	mv -f disp_asc.tmp ${.TARGET}
CLEANFILES+=	disp_asc.tmp disp_asc.out

kbd.out: ${.CURDIR}/../ctlr/hostctlr.h ${.CURDIR}/../ctlr/${KBD} ${MKHITS}
	${_MKTARGET_CREATE}
	${CC} ${CPPFLAGS} -E ${.CURDIR}/../ctlr/function.c > TMPfunc.out
	${MKHITS} \
	    ${.CURDIR}/../ctlr/hostctlr.h TMPfunc.out \
	    < ${.CURDIR}/../ctlr/${KBD} > kbd.tmp
	rm -f TMPFunc.out
	mv -f kbd.tmp ${.TARGET}
CLEANFILES+=	TMPfunc.out kbd.tmp kbd.out

.include <bsd.prog.mk>

.if (defined(HAVE_GCC) && ${HAVE_GCC} == 4) || defined(HAVE_PCC)
.for f in api commands system telnet terminal termout tn3270 utilities
COPTS.${f}.c+=  -Wno-pointer-sign
.endfor
.endif

.PATH: ${.CURDIR}/../api ${.CURDIR}/../ascii ${.CURDIR}/../ctlr
.PATH: ${.CURDIR}/../general ${.CURDIR}/../sys_curses ${.CURDIR}/../../telnet
.PATH: ${NETBSDSRCDIR}/lib/libtelnet

astosc.o:	astosc.out
disp_asc.o:	asc_disp.out disp_asc.out
inbound.o:	kbd.out

File Added: pkgsrc/comms/tn3270/files/tn3270/Attic/tn3270.1
.\"	$NetBSD: tn3270.1,v 1.1.1.1 2010/01/17 01:33:25 dholland Exp $
.\"	From NetBSD: tn3270.1,v 1.14 2006/06/17 02:11:29 reed Exp 
.\"
.\" Copyright (c) 1986, 1990 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. 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.
.\"
.\"	from: @(#)tn3270.1	4.6 (Berkeley) 7/27/91
.\"	$NetBSD: tn3270.1,v 1.1.1.1 2010/01/17 01:33:25 dholland Exp $
.\"
.Dd July 27, 1991
.Dt TN3270 1
.Os
.Sh NAME
.Nm tn3270
.Nd full-screen remote login to
.Tn IBM VM/CMS
.Sh SYNOPSIS
.Nm
.Op Fl d
.Op Fl n Ar filename
.Op Fl t Ar commandname
.Op Ar sysname Op port
.Sh DESCRIPTION
.Nm
permits a full-screen, full-duplex connection
from a
.Ux
machine
to an
.Tn IBM
(or compatible) machine.
.Nm
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
looks to the user in many respects
like the Yale
.Tn ASCII
Terminal Communication System II.
.Nm
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
are as follows:
.Bl -tag -width indent
.It Fl d
Turn on socket-level tracing (for super-user only)
.It Fl n 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.
.It Fl t Ar commandname
Specify a
.Ux
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
attempts to connect to the
standard
.Tn TELNET
port (port
23) on the remote machine.
.El
.Pp
When
.Nm
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
emulates a 3278 terminal.
To decide which specific model,
.Nm
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
is running, on multiple
window systems) must have at least 80 columns and 24 lines, or
.Nm
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
.Ux
process.
This emulation involves mapping
3270-style commands from the host
into appropriate sequences to control the user's terminal screen.
.Nm
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
looks for an entry for the terminal type
.Em unknown .
If this is not found,
.Nm
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
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
is invoked without specifying a remote host system name,
it enters local command mode,
indicated by the prompt
.Dq Li tn3270\*[Gt]\  .
In this mode,
.Nm
accepts and executes
all the commands of
.Xr telnet  1  ,
plus one additional command:
.Pp
.Bl -tag -width Ar
.It Ic transcom
Specify
.Ux
command for
.Tn IBM
4994 style transparent mode processing.
.El
.Pp
.Nm
command mode may also be entered, after connecting to a host, by typing
a special escape sequence.
If
.Nm
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
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
checks the following environment variables:
.Ev TERM ,
.Ev MAP3270 ,
.Ev MAP3270[A...] .
Information on these can be found in
.Xr mset 1 .
.Nm
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 map3270 5 ,
.Xr termcap 5
.Rs
.%T "Yale ASCII Terminal Communication"
.%B "System II Program Description/Operator's Manual"
.%R IBM SB30-1911
.Re
.Sh HISTORY
The
.Nm
command appeared in
.Bx 4.3 .
.Sh BUGS
.Nm
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.

File Added: pkgsrc/comms/tn3270/files/tools/Attic/Makefile
#	$NetBSD: Makefile,v 1.1.1.1 2010/01/17 01:33:25 dholland Exp $
#	From NetBSD: Makefile,v 1.6 2005/09/17 16:52:02 chs Exp 

SUBDIR = mkhits mkastosc mkastods mkdstoas mkdctype mkmake .WAIT prt3270

.include <bsd.subdir.mk>

File Added: pkgsrc/comms/tn3270/files/tools/Attic/Makefile.inc
#	$NetBSD: Makefile.inc,v 1.1.1.1 2010/01/17 01:33:25 dholland Exp $
#	From NetBSD: Makefile.inc,v 1.8 2002/09/18 14:00:42 lukem Exp 

NOMAN=	# defined

HOST_CPPFLAGS+=-I${.CURDIR}/../../api
KBD= unix.kbd

.PATH: ${.CURDIR}/../../api

.if exists(${.CURDIR}/../../../Makefile.inc)
.include "${.CURDIR}/../../../Makefile.inc"
.endif

File Added: pkgsrc/comms/tn3270/files/tools/mkastods/Attic/mkastods.c
/*	$NetBSD: mkastods.c,v 1.1.1.1 2010/01/17 01:33:25 dholland Exp $	*/
/*	From NetBSD: mkastods.c,v 1.11 2008/07/21 14:19:26 lukem Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 */

#include <stdio.h>
#include <string.h>

#if defined(__COPYRIGHT) && !defined(lint)
__COPYRIGHT("@(#) Copyright (c) 1988\
 The Regents of the University of California.  All rights reserved.");
#endif /* not lint */

#if defined(__RCSID) && !defined(lint)
#if 0
static char sccsid[] = "@(#)mkastods.c	4.2 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: mkastods.c,v 1.1.1.1 2010/01/17 01:33:25 dholland Exp $");
#endif
#endif /* not lint */

#include "../api/asc_ebc.h"
#include "../api/ebc_disp.h"

int main(int, char *[]);

int
main(int argc, char *argv[])
{
    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;
}

File Added: pkgsrc/comms/tn3270/files/tools/mkastods/Attic/Makefile
#	$NetBSD: Makefile,v 1.1.1.1 2010/01/17 01:33:25 dholland Exp $
#	From NetBSD: Makefile,v 1.10 2002/09/15 01:27:45 thorpej Exp 

HOSTPROG=	mkastods
HOST_CPPFLAGS+=	-DHOST_TOOL
SRCS=	mkastods.c asc_ebc.c ebc_disp.c

.include <bsd.hostprog.mk>

File Added: pkgsrc/comms/tn3270/files/tools/mkastosc/Attic/mkastosc.c
/*	$NetBSD: mkastosc.c,v 1.1.1.1 2010/01/17 01:33:25 dholland Exp $	*/
/*	From NetBSD: mkastosc.c,v 1.12 2008/07/21 14:19:26 lukem Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 */

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#if defined(__COPYRIGHT) && !defined(lint)
__COPYRIGHT("@(#) Copyright (c) 1988\
 The Regents of the University of California.  All rights reserved.");
#endif /* not lint */

#if defined(__RCSID) && !defined(lint)
#if 0
static char sccsid[] = "@(#)mkastosc.c	4.2 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: mkastosc.c,v 1.1.1.1 2010/01/17 01:33:25 dholland Exp $");
#endif
#endif /* not lint */

#include "../general/general.h"
#include "../ctlr/function.h"

#include "dohits.h"

static struct tbl {
    unsigned char
	scancode,
	used;
    const char
	*shiftstate;
} tbl[128];


int main(int, char *[]);

int
main(argc, argv)
int	argc;
char	*argv[];
{
    int scancode;
    int asciicode;
    int i;
    int c;
    struct hits *ph;
    struct Hits *Ph;
    struct thing *this;
    struct thing **attable;
    struct tbl *Pt;
    static const 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, "mkastosc: Unable to produce scancode sequence"
		    " for ASCII character [%c]!", 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%02lx, %s, ",
				(u_long)(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;
}

File Added: pkgsrc/comms/tn3270/files/tools/mkastosc/Attic/Makefile
#	$NetBSD: Makefile,v 1.1.1.1 2010/01/17 01:33:25 dholland Exp $
#	From NetBSD: Makefile,v 1.10 2002/09/15 01:27:46 thorpej Exp 

HOSTPROG=	mkastosc
HOST_CPPFLAGS+=	-DHOST_TOOL
SRCS=	mkastosc.c dohits.c asc_ebc.c ebc_disp.c

HOST_CPPFLAGS+=-I${.CURDIR}/../mkhits
.PATH: ${.CURDIR}/../mkhits

.include <bsd.hostprog.mk>


File Added: pkgsrc/comms/tn3270/files/tools/mkdctype/Attic/mkdctype.c
/*	$NetBSD: mkdctype.c,v 1.1.1.1 2010/01/17 01:33:25 dholland Exp $	*/
/*	From NetBSD: mkdctype.c,v 1.10 2008/07/21 14:19:26 lukem Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 */

#if defined(__COPYRIGHT) && !defined(lint)
__COPYRIGHT("@(#) Copyright (c) 1988\
 The Regents of the University of California.  All rights reserved.");
#endif /* not lint */

#if defined(__RCSID) && !defined(lint)
#if 0
static char sccsid[] = "@(#)mkdctype.c	4.2 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: mkdctype.c,v 1.1.1.1 2010/01/17 01:33:25 dholland Exp $");
#endif
#endif /* not lint */

#include <stdio.h>
#include "../api/ebc_disp.h"
#include "ectype.h"


int main(int, char *[]);


int
main(argc, argv)
    int argc;
    char *argv[];
{
    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");
    }
    return 0;
}

File Added: pkgsrc/comms/tn3270/files/tools/mkdctype/Attic/Makefile
#	$NetBSD: Makefile,v 1.1.1.1 2010/01/17 01:33:25 dholland Exp $
#	From NetBSD: Makefile,v 1.11 2002/09/15 01:27:46 thorpej Exp 

HOSTPROG=	mkdctype
HOST_CPPFLAGS+=	-DHOST_TOOL
SRCS=	mkdctype.c asc_ebc.c ebc_disp.c ectype.c

.include <bsd.hostprog.mk>

File Added: pkgsrc/comms/tn3270/files/tools/mkdctype/Attic/ectype.c
/*	$NetBSD: ectype.c,v 1.1.1.1 2010/01/17 01:33:26 dholland Exp $	*/
/*	From NetBSD: ectype.c,v 1.7 2006/03/20 01:34:49 gdamore Exp 	*/

/*-
 * Copyright (c) 1988 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. 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 HOST_TOOL
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
#if 0
static char sccsid[] = "from: @(#)ectype.c	4.2 (Berkeley) 4/26/91";*/
#else
__RCSID("$NetBSD: ectype.c,v 1.1.1.1 2010/01/17 01:33:26 dholland Exp $");
#endif
#endif /* not lint */
#endif

#include "ectype.h"

unsigned char	ectype[ECMAXCHAR] = {
/* 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
};

File Added: pkgsrc/comms/tn3270/files/tools/mkdctype/Attic/ectype.h
/*	$NetBSD: ectype.h,v 1.1.1.1 2010/01/17 01:33:26 dholland Exp $	*/
/*	From NetBSD: ectype.h,v 1.5 2003/08/07 11:16:40 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 *
 *	from: @(#)ectype.h	4.2 (Berkeley) 4/26/91
 */

#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)

#define ECMAXCHAR 256
extern unsigned char ectype[ECMAXCHAR];

File Added: pkgsrc/comms/tn3270/files/tools/mkdstoas/Attic/mkdstoas.c
/*	$NetBSD: mkdstoas.c,v 1.1.1.1 2010/01/17 01:33:26 dholland Exp $	*/
/*	From NetBSD: mkdstoas.c,v 1.11 2008/07/21 14:19:26 lukem Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 */

#include <stdio.h>
#include <string.h>

#if defined(__COPYRIGHT) && !defined(lint)
__COPYRIGHT("@(#) Copyright (c) 1988\
 The Regents of the University of California.  All rights reserved.");
#endif /* not lint */

#if defined(__RCSID) && !defined(lint)
#if 0
static char sccsid[] = "@(#)mkdstoas.c	4.2 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: mkdstoas.c,v 1.1.1.1 2010/01/17 01:33:26 dholland Exp $");
#endif
#endif /* not lint */

#include "../api/asc_ebc.h"
#include "../api/ebc_disp.h"

int main(int, char *[]);

int
main(int argc, char *argv[])
{
    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;
}

File Added: pkgsrc/comms/tn3270/files/tools/mkdstoas/Attic/Makefile
#	$NetBSD: Makefile,v 1.1.1.1 2010/01/17 01:33:26 dholland Exp $
#	From NetBSD: Makefile,v 1.10 2002/09/15 01:27:47 thorpej Exp 

HOSTPROG=	mkdstoas
HOST_CPPFLAGS+=	-DHOST_TOOL
SRCS=	mkdstoas.c asc_ebc.c ebc_disp.c

.include <bsd.hostprog.mk>

File Added: pkgsrc/comms/tn3270/files/tools/mkhits/Attic/Makefile
#	$NetBSD: Makefile,v 1.1.1.1 2010/01/17 01:33:26 dholland Exp $
#	From NetBSD: Makefile,v 1.10 2002/09/15 01:27:47 thorpej Exp 

HOSTPROG=	mkhits
HOST_CPPFLAGS+=	-DHOST_TOOL
SRCS=	mkhits.c dohits.c asc_ebc.c ebc_disp.c

.include <bsd.hostprog.mk>

File Added: pkgsrc/comms/tn3270/files/tools/mkhits/Attic/dohits.c
/*	$NetBSD: dohits.c,v 1.1.1.1 2010/01/17 01:33:26 dholland Exp $	*/
/*	From NetBSD: dohits.c,v 1.14 2006/04/22 18:02:26 christos Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 */

#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#if defined(__RCSID) && !defined(lint)
#if 0
static char sccsid[] = "@(#)dohits.c	4.2 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: dohits.c,v 1.1.1.1 2010/01/17 01:33:26 dholland Exp $");
#endif
#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 "../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];

static void add(const char *, const char *, int);
static void scanwhite(const char *, const char *);
static void scandefine(const char *, const char *);
static char *savechr(unsigned int);
static char *doit(struct hit *, unsigned char *, struct Hits *);

unsigned int
dohash(seed, string)
unsigned int seed;
const char *string;
{
    unsigned int i = seed;
    unsigned char c;

    while ((c = *string++) != '\0') {
	if (c >= 0x60) {
	    c -= (0x60+0x20);
	} else {
	    c -= 0x20;
	}
	i = (i>>26) + (i<<6) + (c&0x3f);
    }
    return i;
}

static void
add(first, second, value)
const char *first, *second;
int value;
{
    struct thing **item, *this;

    item = &firstentry(second);
    this = (struct thing *) malloc(sizeof *this);
    this->hits = 0;
    this->next = *item;
    *item = this;
    this->value = value;
    strcpy(this->name, first);
    strcpy(this->name+strlen(this->name), second);
}

static void
scanwhite(file, prefix)
const 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];
    char line[200];

    (void) snprintf(compare, sizeof(compare), " %s%%[^,\t \n]", prefix);
    if ((ourfile = fopen(file, "r")) == NULL) {
	fprintf(stderr, "Cannot open `%s': %s\n", file, strerror(errno));
	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)) {
		    fprintf(stderr, "fgets failed: %s\n", strerror(errno));
		}
		break;
	    }
	} while (line[strlen(line)-1] != '\n');
    }
    (void)fclose(ourfile);
}

static void
scandefine(file, prefix)
const 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;

    snprintf(compare, sizeof(compare), "#define %s%%s %%s", prefix);
    if ((ourfile = fopen(file, "r")) == NULL) {
	fprintf(stderr, "Cannot open `%s': %s\n", file, strerror(errno));
	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)) {
		    fprintf(stderr, "End of file with error: %s\n",
			strerror(errno));
		}
		break;
	    }
	} while (line[strlen(line)-1] != '\n');
    }
    (void)fclose(ourfile);
}

static char *savechr(c)
unsigned int c;
{
    char *foo = malloc(sizeof(unsigned char));
    if (foo == NULL) {
	fprintf(stderr, "No room for ascii characters\n");
	exit(1);
    }
    *foo = c;
    return foo;
}

static 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, "Unknown type %s.\n", type);
	return 0;
    }
}


void
dohits(aidfile, fcnfile)
const char *aidfile, *fcnfile;
{
    unsigned char plain[100], shifted[100], alted[100], shiftalted[100];
    unsigned char line[200];
    int keynumber, scancode;
    struct hit *hit;

    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 (fgets(line, sizeof(line), stdin) != NULL) {
	if (line[strlen(line)-1] == '\n')
		line[strlen(line)-1] = '\0';
	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, "Scancode 0x%02x for keynumber %d\n", scancode,
		keynumber);
	    break;
	}
	if (Hits[scancode].hits.hit[0].ctlrfcn != undefined) {
	    fprintf(stderr, "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]);
    }
}

File Added: pkgsrc/comms/tn3270/files/tools/mkhits/Attic/dohits.h
/*	$NetBSD: dohits.h,v 1.1.1.1 2010/01/17 01:33:26 dholland Exp $	*/
/*	From NetBSD: dohits.h,v 1.7 2003/08/07 11:16:42 agc Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 *
 *	from: @(#)dohits.h	4.2 (Berkeley) 4/26/91
 */

#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];

void dohits(const char *, const char *);
unsigned int dohash(unsigned int, const char *);

File Added: pkgsrc/comms/tn3270/files/tools/mkhits/Attic/mkhits.c
/*	$NetBSD: mkhits.c,v 1.1.1.1 2010/01/17 01:33:26 dholland Exp $	*/
/*	From NetBSD: mkhits.c,v 1.11 2008/07/21 14:19:27 lukem Exp 	*/

/*-
 * Copyright (c) 1988 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. 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.
 */

#include <stdio.h>
#include <string.h>

#if defined(__COPYRIGHT) && !defined(lint)
__COPYRIGHT("@(#) Copyright (c) 1988\
 The Regents of the University of California.  All rights reserved.");
#endif /* not lint */

#if defined(__RCSID) && !defined(lint)
#if 0
static char sccsid[] = "@(#)mkhits.c	4.2 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: mkhits.c,v 1.1.1.1 2010/01/17 01:33:26 dholland Exp $");
#endif
#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 "../ctlr/function.h"

#include "dohits.h"

int main(int, char *[]);

int
main(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;
}

File Added: pkgsrc/comms/tn3270/files/tools/mkmake/Attic/Makefile
#	$NetBSD: Makefile,v 1.1.1.1 2010/01/17 01:33:26 dholland Exp $
#	From NetBSD: Makefile,v 1.4 2006/03/20 01:34:49 gdamore Exp 

HOSTPROG=	mkmake
HOST_CPPFLAGS+= -DHOST_TOOL
SRCS=	mkmake.y

.include <bsd.hostprog.mk>

.PATH: ${.CURDIR}/../../api ${.CURDIR}/../../ascii

File Added: pkgsrc/comms/tn3270/files/tools/mkmake/Attic/mkmake.y
%{
/*	$NetBSD: mkmake.y,v 1.1.1.1 2010/01/17 01:33:27 dholland Exp $	*/
/*	From NetBSD: mkmake.y,v 1.14 2009/10/30 15:09:24 uebayasi Exp 	*/
/*-
 * Copyright (c) 1988 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. 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 HOST_TOOL
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
#if 0
static char sccsid[] = "@(#)mkmake.y	4.2 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: mkmake.y,v 1.1.1.1 2010/01/17 01:33:27 dholland Exp $");
#endif
#endif /* not lint */
#endif

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 dependency.
 */

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 <string.h>
#include <ctype.h>

/* mkmake.y */
void yyerror(char *);
void assign(same_t *, same_t *);
int yylex(void);
extern int yyparse(void);
int main(int, char *[]);

static int visitcheck(same_t *);
static int string_hashof(char *, int);
static int string_same(string_t *, string_t *);
static string_t *string_lookup(char *);
static same_t *same_search(same_t *, same_t *);
static same_t *same_cat(same_t *, same_t *);
static same_t *same_item(string_t *);
static same_t *same_copy(same_t *);
static same_t *same_merge(same_t *, same_t *);
static void same_free(same_t *);
static same_t *same_unlink(same_t *);
static void same_replace(same_t *, same_t *);
static same_t *same_char(int);
static void add_target(same_t *, same_t *);
static same_t *add_targets_actions(same_t *, same_t *);
static same_t *add_depends(same_t *, same_t *);
static same_t *value_of(same_t *);
static same_t *expand_variables(same_t *, int);
static same_t *ws_merge(same_t *);
static same_t *variable(same_t *);
static same_t *shell_variable(same_t *);
static same_t *for_statement(same_t *, same_t *, same_t *);
static same_t *do_command(same_t *, same_t *);
static int Getchar(void);
static int token_type(char *);
#if 0
static void dump_same(same_t *);
#endif
static void do_dump(void);
static int last_char, last_saved = 0;
static int column = 0, lineno = 1;


static string_t
    *strings = 0;

static same_t
    *variables = 0,
    *targets = 0;

static same_t
    *null,
    *blank,
    *cwd_line,
    *newline;

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--)

void
yyerror(s)
char *s;
{
    fprintf(stderr, "line %d, character %d: %s\n", lineno, column, s);
    do_dump();
}

static int
visitcheck(same)
same_t *same;
{
    if (same->string == 0) {
	yyerror("BUG - freed 'same' in use...");
	exit(1);
    }
    return 0;
}

static int
string_hashof(string, length)
char *string;
int length;
{
    register int i = 0;

    while (length--) {
	i = ((i<<3) + *string) ^ ((i>>28)&0x7);
    }
    return i;
}

static 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;
    }
}

static 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))

static 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;
}

static 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;
    }
}

static 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;
}

static 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;
}


static 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);
    }
}


static 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);
}

static 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;
}

static 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;
}


static same_t *
same_char(ch)
char ch;
{
    char buffer[2];

    buffer[0] = ch;
    buffer[1] = 0;

    return same_item(string_lookup(buffer));
}


static 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);
    }
}


static 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;
}

static 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);
}

static 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);
    }
}


static 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;
}


static same_t *
ws_merge(list)
same_t *list;
{
    same_t *newlist = 0, *item = NULL;
    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);
}


static 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(stderr, "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;
}


static 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(stderr, "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;
}

static same_t *
for_statement(special, variable, list)
same_t
    *special,
    *variable,
    *list;
{
    variable->shell_item = special;
    variable->value_list = list;
    return variable;
}

static 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));
}


static 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;
    }
}


static 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;
}


int
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(y,c)	if (yydebug) { \
			    printf("[%d]", c); \
			    fflush(stdout); \
			} \
			yylval.intval = c; \
			return y;
#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);
}

int
main(argc, argv)
    int argc;
    char *argv[];
{
    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 0
static void
dump_same(same)
same_t *same;
{
    same_t *same2;

    for (visit(same, same2); !visited(same2); visit_next(same2)) {
	printf("%s", same2->string->string);
    }
    visit_end();
}
#endif

static void
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("%s", 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("%s", same2->string->string);
	}
	visit_end();
	printf("\n\t");
	for (visit(same->action_list, same2); !visited(same2);
					    visit_next(same2)) {
	    printf("%s", same2->string->string);
	    if (same2->string->string[0] == '\n') {
		printf("\t");
	    }
	}
	visit_end();
	printf("\n");
    }
    visit_end();
}

File Added: pkgsrc/comms/tn3270/files/tools/prt3270/Attic/prt3270.c
/*	$NetBSD: prt3270.c,v 1.1.1.1 2010/01/17 01:33:27 dholland Exp $	*/
/*	From NetBSD: prt3270.c,v 1.11 2008/07/21 14:19:27 lukem Exp 	*/

/*-
 * Copyright (c) 1988 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. 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 HOST_TOOL
#include <sys/cdefs.h>
#if defined(__COPYRIGHT) && !defined(lint)
__COPYRIGHT("@(#) Copyright (c) 1988\
 The Regents of the University of California.  All rights reserved.");
#endif /* not lint */
#endif

#if defined(__RCSID) && !defined(lint)
#if 0
static char sccsid[] = "@(#)prt3270.c	4.2 (Berkeley) 4/26/91";
#else
__RCSID("$NetBSD: prt3270.c,v 1.1.1.1 2010/01/17 01:33:27 dholland Exp $");
#endif
#endif /* not lint */

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>

#define DEFINING_INSTANCES
#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 "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 */


/* prt3270.c */
void putSpace(void);
void Column1(void);
void Indent(void);
void Undent(void);
void putChar(int);
void putstr(char *);
void put2hex(int);
void putdecimal(int);
void puthex(int);
void putEChar(int);
void PrintAid(int);
void PrintAddr(int);
int DataFromNetwork(unsigned char *, int, int);
int DataToNetwork(unsigned char *, int, int);
int GetXValue(int);
void termblock(int, int , int);
int main(int, char *[]);

void
putSpace()
{
    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)
unsigned char	*buffer;		/* what the data is */
int	count;				/* and how much there is */
int	control;			/* this buffer ended block? */
{
    int origCount;
    int c;
    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;
    }
    return 0;
}

int
GetXValue(c)
int	c;
{
    if (!isascii(c)) {
	fflush(stdout);
	fprintf(stderr, "Non-hex digit 0x%x.\n", c);
	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);
    }
}

int
main(argc, argv)
    int argc;
    char *argv[];
{
    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;
}

File Added: pkgsrc/comms/tn3270/files/tools/prt3270/Attic/Makefile
#	$NetBSD: Makefile,v 1.1.1.1 2010/01/17 01:33:27 dholland Exp $
#	From NetBSD: Makefile,v 1.11 2006/03/20 01:34:49 gdamore Exp 

NOMAN=		# defined

.include <bsd.own.mk>

HOSTPROG=	prt3270
SRCS=	prt3270.c asc_ebc.c ebc_disp.c astosc.c
DPSRCS=	kbd.out astosc.out
HOST_CPPFLAGS+=-I. -DHOST_TOOL

MKHITSDIR!=cd $(.CURDIR)/../mkhits && ${PRINTOBJDIR}
MKHITS=${MKHITSDIR}/mkhits

${MKHITS}:
	cd ${.CURDIR}/../mkhits; ${MAKE}

kbd.out: ${.CURDIR}/../../ctlr/hostctlr.h ${.CURDIR}/../../ctlr/${KBD} ${MKHITS}
	${HOST_CC} ${HOST_CPPFLAGS} -E ${.CURDIR}/../../ctlr/function.c > TMPfunc.out
	${MKHITS} \
	    ${.CURDIR}/../../ctlr/hostctlr.h TMPfunc.out \
	    < ${.CURDIR}/../../ctlr/${KBD} > kbd.tmp
	rm -f TMPfunc.out
	mv -f kbd.tmp ${.TARGET}
CLEANFILES+=	TMPfunc.out kbd.tmp kbd.out

MKASTOSCDIR!=cd ${.CURDIR}/../mkastosc && ${PRINTOBJDIR}
MKASTOSC= ${MKASTOSCDIR}/mkastosc

${MKASTOSC}:
	cd ${.CURDIR}/../mkastosc; ${MAKE}

astosc.out: ${.CURDIR}/../../ctlr/hostctlr.h ${.CURDIR}/../../ctlr/function.h \
	    ${.CURDIR}/../../ctlr/${KBD} ${MKASTOSC}
	${MKASTOSC} \
	    ${.CURDIR}/../../ctlr/hostctlr.h ${.CURDIR}/../../ctlr/function.h \
	    < ${.CURDIR}/../../ctlr/${KBD} > astosc.tmp
	mv -f astosc.tmp ${.TARGET}
CLEANFILES+=	astosc.tmp astosc.out

.include <bsd.hostprog.mk>

.PATH: ${.CURDIR}/../../api ${.CURDIR}/../../ascii

astosc.o:	astosc.out
prt3270.o:	kbd.out

File Added: pkgsrc/comms/tn3270/files/telnet/Attic/commands.c
/*	$NetBSD: commands.c,v 1.1.1.1 2010/01/17 01:33:29 dholland Exp $	*/
/*	From NetBSD: commands.c,v 1.67 2006/12/18 14:18:40 christos Exp 	*/

/*
 * Copyright (C) 1997 and 1998 WIDE Project.
 * 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. Neither the name of the project 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 PROJECT 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 PROJECT 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.
 */

/*
 * Copyright (c) 1988, 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. 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.
 */

#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)commands.c	8.4 (Berkeley) 5/30/95";
#else
__RCSID("$NetBSD: commands.c,v 1.1.1.1 2010/01/17 01:33:29 dholland Exp $");
#endif
#endif /* not lint */

#include <sys/param.h>
#include <sys/file.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <pwd.h>
#include <signal.h>
#include <stdarg.h>
#include <unistd.h>

#include <arpa/telnet.h>

#include "general.h"
#include "ring.h"
#include "externs.h"
#include "defines.h"
#include "types.h"
#include <libtelnet/misc.h>
#ifdef AUTHENTICATION
#include <libtelnet/auth.h>
#endif
#ifdef ENCRYPTION
#include <libtelnet/encrypt.h>
#endif

#include <netinet/in_systm.h>
#include <netinet/ip.h>


#if	defined(IPPROTO_IP) && defined(IP_TOS)
int tos = -1;
#endif	/* defined(IPPROTO_IP) && defined(IP_TOS) */

char	*hostname;
static char _hostname[MAXHOSTNAMELEN];

typedef struct {
	char	*name;		/* command name */
	char	*help;		/* help string (NULL for no help) */
	int	(*handler)	/* routine which executes command */
			(int, char *[]);
	int	needconnect;	/* Do we need to be connected to execute? */
} Command;

static char line[256];
static char saveline[256];
static int margc;
static char *margv[20];

static void makeargv(void);
static int special(char *);
static char *control(cc_t);
static int sendcmd(int, char **);
static int send_esc(char *);
static int send_docmd(char *);
static int send_dontcmd(char *);
static int send_willcmd(char *);
static int send_wontcmd(char *);
static int send_help(char *);
static int lclchars(int);
static int togdebug(int);
static int togcrlf(int);
static int togbinary(int);
static int togrbinary(int);
static int togxbinary(int);
static int togglehelp(int);
static void settogglehelp(int);
static int toggle(int, char *[]);
static struct setlist *getset(char *);
static int setcmd(int, char *[]);
static int unsetcmd(int, char *[]);
static int dokludgemode(int);
static int dolinemode(int);
static int docharmode(int);
static int dolmmode(int, int );
static int modecmd(int, char *[]);
static int display(int, char *[]);
static int setescape(int, char *[]);
static int togcrmod(int, char *[]);
static int bye(int, char *[]);
static void slc_help(int);
static struct slclist *getslc(char *);
static int slccmd(int, char *[]);
static struct env_lst *env_help(unsigned char *, unsigned char *);
static struct envlist *getenvcmd(char *);
#ifdef AUTHENTICATION
static int auth_help(char *);
#endif
#ifdef TN3270
static void filestuff(int);
#endif
static int status(int, char *[]);
static const char *sockaddr_ntop (struct sockaddr *);
typedef int (*intrtn_t)(int, char **);
static int call(intrtn_t, ...);
static Command *getcmd(char *);
static int help(int, char *[]);

static void
makeargv(void)
{
    char *cp, *cp2, c;
    char **argp = margv;

    margc = 0;
    cp = line;
    if (*cp == '!') {		/* Special case shell escape */
	strlcpy(saveline, line, sizeof(saveline)); /* save for shell command */
	*argp++ = "!";		/* No room in string to get this */
	margc++;
	cp++;
    }
    while ((c = *cp) != '\0') {
	int inquote = 0;
	while (isspace((unsigned char)c))
	    c = *++cp;
	if (c == '\0')
	    break;
	*argp++ = cp;
	margc += 1;
	for (cp2 = cp; c != '\0'; c = *++cp) {
	    if (inquote) {
		if (c == inquote) {
		    inquote = 0;
		    continue;
		}
	    } else {
		if (c == '\\') {
		    if ((c = *++cp) == '\0')
			break;
		} else if (c == '"') {
		    inquote = '"';
		    continue;
		} else if (c == '\'') {
		    inquote = '\'';
		    continue;
		} else if (isspace((unsigned char)c))
		    break;
	    }
	    *cp2++ = c;
	}
	*cp2 = '\0';
	if (c == '\0')
	    break;
	cp++;
    }
    *argp++ = 0;
}

/*
 * Make a character string into a number.
 *
 * Todo:  1.  Could take random integers (12, 0x12, 012, 0b1).
 */

static int
special(char *s)
{
	char c;
	char b;

	switch (*s) {
	case '^':
		b = *++s;
		if (b == '?') {
		    c = b | 0x40;		/* DEL */
		} else {
		    c = b & 0x1f;
		}
		break;
	default:
		c = *s;
		break;
	}
	return c;
}

/*
 * Construct a control character sequence
 * for a special character.
 */
static char *
control(cc_t c)
{
	static char buf[5];
	/*
	 * The only way I could get the Sun 3.5 compiler
	 * to shut up about
	 *	if ((unsigned int)c >= 0x80)
	 * was to assign "c" to an unsigned int variable...
	 * Arggg....
	 */
	unsigned int uic = (unsigned int)c;

	if (uic == 0x7f)
		return ("^?");
	if (c == (cc_t)_POSIX_VDISABLE) {
		return "off";
	}
	if (uic >= 0x80) {
		buf[0] = '\\';
		buf[1] = ((c>>6)&07) + '0';
		buf[2] = ((c>>3)&07) + '0';
		buf[3] = (c&07) + '0';
		buf[4] = 0;
	} else if (uic >= 0x20) {
		buf[0] = c;
		buf[1] = 0;
	} else {
		buf[0] = '^';
		buf[1] = '@'+c;
		buf[2] = 0;
	}
	return (buf);
}



/*
 *	The following are data structures and routines for
 *	the "send" command.
 *
 */

struct sendlist {
    char	*name;		/* How user refers to it (case independent) */
    char	*help;		/* Help information (0 ==> no help) */
    int		needconnect;	/* Need to be connected */
    int		narg;		/* Number of arguments */
    int		(*handler)	/* Routine to perform (for special ops) */
			(char *);
    int		nbyte;		/* Number of bytes to send this command */
    int		what;		/* Character to be sent (<0 ==> special) */
};


static struct sendlist Sendlist[] = {
    { "ao",	"Send Telnet Abort output",		1, 0, 0, 2, AO },
    { "ayt",	"Send Telnet 'Are You There'",		1, 0, 0, 2, AYT },
    { "brk",	"Send Telnet Break",			1, 0, 0, 2, BREAK },
    { "break",	0,					1, 0, 0, 2, BREAK },
    { "ec",	"Send Telnet Erase Character",		1, 0, 0, 2, EC },
    { "el",	"Send Telnet Erase Line",		1, 0, 0, 2, EL },
    { "escape",	"Send current escape character",	1, 0, send_esc, 1, 0 },
    { "ga",	"Send Telnet 'Go Ahead' sequence",	1, 0, 0, 2, GA },
    { "ip",	"Send Telnet Interrupt Process",	1, 0, 0, 2, IP },
    { "intp",	0,					1, 0, 0, 2, IP },
    { "interrupt", 0,					1, 0, 0, 2, IP },
    { "intr",	0,					1, 0, 0, 2, IP },
    { "nop",	"Send Telnet 'No operation'",		1, 0, 0, 2, NOP },
    { "eor",	"Send Telnet 'End of Record'",		1, 0, 0, 2, EOR },
    { "abort",	"Send Telnet 'Abort Process'",		1, 0, 0, 2, ABORT },
    { "susp",	"Send Telnet 'Suspend Process'",	1, 0, 0, 2, SUSP },
    { "eof",	"Send Telnet End of File Character",	1, 0, 0, 2, xEOF },
    { "synch",	"Perform Telnet 'Synch operation'",	1, 0, dosynch, 2, 0 },
    { "getstatus", "Send request for STATUS",		1, 0, get_status, 6, 0 },
    { "?",	"Display send options",			0, 0, send_help, 0, 0 },
    { "help",	0,					0, 0, send_help, 0, 0 },
    { "do",	0,					0, 1, send_docmd, 3, 0 },
    { "dont",	0,					0, 1, send_dontcmd, 3, 0 },
    { "will",	0,					0, 1, send_willcmd, 3, 0 },
    { "wont",	0,					0, 1, send_wontcmd, 3, 0 },
    { 0 }
};

#define	GETSEND(name) ((struct sendlist *) genget(name, (char **) Sendlist, \
				sizeof(struct sendlist)))

static int
sendcmd(int  argc, char **argv)
{
    int count;		/* how many bytes we are going to need to send */
    int i;
    struct sendlist *s;	/* pointer to current command */
    int success = 0;
    int needconnect = 0;

    if (argc < 2) {
	printf("need at least one argument for 'send' command\n");
	printf("'send ?' for help\n");
	return 0;
    }
    /*
     * First, validate all the send arguments.
     * In addition, we see how much space we are going to need, and
     * whether or not we will be doing a "SYNCH" operation (which
     * flushes the network queue).
     */
    count = 0;
    for (i = 1; i < argc; i++) {
	s = GETSEND(argv[i]);
	if (s == 0) {
	    printf("Unknown send argument '%s'\n'send ?' for help.\n",
			argv[i]);
	    return 0;
	} else if (Ambiguous(s)) {
	    printf("Ambiguous send argument '%s'\n'send ?' for help.\n",
			argv[i]);
	    return 0;
	}
	if (i + s->narg >= argc) {
	    fprintf(stderr,
	    "Need %d argument%s to 'send %s' command.  'send %s ?' for help.\n",
		s->narg, s->narg == 1 ? "" : "s", s->name, s->name);
	    return 0;
	}
	count += s->nbyte;
	if (s->handler == send_help) {
	    send_help(NULL);
	    return 0;
	}

	i += s->narg;
	needconnect += s->needconnect;
    }
    if (!connected && needconnect) {
	printf("?Need to be connected first.\n");
	printf("'send ?' for help\n");
	return 0;
    }
    /* Now, do we have enough room? */
    if (NETROOM() < count) {
	printf("There is not enough room in the buffer TO the network\n");
	printf("to process your request.  Nothing will be done.\n");
	printf("('send synch' will throw away most data in the network\n");
	printf("buffer, if this might help.)\n");
	return 0;
    }
    /* OK, they are all OK, now go through again and actually send */
    count = 0;
    for (i = 1; i < argc; i++) {
	if ((s = GETSEND(argv[i])) == 0) {
	    fprintf(stderr, "Telnet 'send' error - argument disappeared!\n");
	    (void) quit(0, NULL);
	    /*NOTREACHED*/
	}
	if (s->handler) {
	    count++;
	    success += (*s->handler)(argv[i+1]);
	    i += s->narg;
	} else {
	    NET2ADD(IAC, s->what);
	    printoption("SENT", IAC, s->what);
	}
    }
    return (count == success);
}

static int
send_esc(char *s)
{
    NETADD(escape);
    return 1;
}

static int
send_docmd(char *name)
{
    return(send_tncmd(send_do, "do", name));
}

static int
send_dontcmd(char *name)
{
    return(send_tncmd(send_dont, "dont", name));
}
static int
send_willcmd(char *name)
{
    return(send_tncmd(send_will, "will", name));
}
static int
send_wontcmd(char *name)
{
    return(send_tncmd(send_wont, "wont", name));
}

int
send_tncmd(void	(*func)(int, int), char	*cmd, char *name)
{
    const char **cpp;
    int val = 0;

    if (isprefix(name, "?")) {
	int col, len;

	printf("usage: send %s <value|option>\n", cmd);
	printf("\"value\" must be from 0 to 255\n");
	printf("Valid options are:\n\t");

	col = 8;
	for (cpp = telopts; *cpp; cpp++) {
	    len = strlen(*cpp) + 3;
	    if (col + len > 65) {
		printf("\n\t");
		col = 8;
	    }
	    printf(" \"%s\"", *cpp);
	    col += len;
	}
	printf("\n");
	return 0;
    }
    cpp = (const char **)genget(name, (char **)telopts, sizeof(char *));
    if (Ambiguous(cpp)) {
	fprintf(stderr,"'%s': ambiguous argument ('send %s ?' for help).\n",
					name, cmd);
	return 0;
    }
    if (cpp) {
	val = cpp - telopts;
    } else {
	char *cp = name;

	while (*cp >= '0' && *cp <= '9') {
	    val *= 10;
	    val += *cp - '0';
	    cp++;
	}
	if (*cp != 0) {
	    fprintf(stderr, "'%s': unknown argument ('send %s ?' for help).\n",
					name, cmd);
	    return 0;
	} else if (val < 0 || val > 255) {
	    fprintf(stderr, "'%s': bad value ('send %s ?' for help).\n",
					name, cmd);
	    return 0;
	}
    }
    if (!connected) {
	printf("?Need to be connected first.\n");
	return 0;
    }
    (*func)(val, 1);
    return 1;
}

static int
send_help(char *n)
{
    struct sendlist *s;	/* pointer to current command */
    for (s = Sendlist; s->name; s++) {
	if (s->help)
	    printf("%-15s %s\n", s->name, s->help);
    }
    return(0);
}

/*
 * The following are the routines and data structures referred
 * to by the arguments to the "toggle" command.
 */

static int
lclchars(int n)
{
    donelclchars = 1;
    return 1;
}

static int
togdebug(int n)
{
    if (net > 0 &&
	(SetSockOpt(net, SOL_SOCKET, SO_DEBUG, telnet_debug)) < 0) {
	    perror("setsockopt (SO_DEBUG)");
    }
    return 1;
}

static int
togcrlf(int n)
{
    if (crlf) {
	printf("Will send carriage returns as telnet <CR><LF>.\n");
    } else {
	printf("Will send carriage returns as telnet <CR><NUL>.\n");
    }
    return 1;
}

int binmode;

static int
togbinary(int val)
{
    donebinarytoggle = 1;

    if (val >= 0) {
	binmode = val;
    } else {
	if (my_want_state_is_will(TELOPT_BINARY) &&
				my_want_state_is_do(TELOPT_BINARY)) {
	    binmode = 1;
	} else if (my_want_state_is_wont(TELOPT_BINARY) &&
				my_want_state_is_dont(TELOPT_BINARY)) {
	    binmode = 0;
	}
	val = binmode ? 0 : 1;
    }

    if (val == 1) {
	if (my_want_state_is_will(TELOPT_BINARY) &&
					my_want_state_is_do(TELOPT_BINARY)) {
	    printf("Already operating in binary mode with remote host.\n");
	} else {
	    printf("Negotiating binary mode with remote host.\n");
	    tel_enter_binary(3);
	}
    } else {
	if (my_want_state_is_wont(TELOPT_BINARY) &&
					my_want_state_is_dont(TELOPT_BINARY)) {
	    printf("Already in network ascii mode with remote host.\n");
	} else {
	    printf("Negotiating network ascii mode with remote host.\n");
	    tel_leave_binary(3);
	}
    }
    return 1;
}

static int
togrbinary(int val)
{
    donebinarytoggle = 1;

    if (val == -1)
	val = my_want_state_is_do(TELOPT_BINARY) ? 0 : 1;

    if (val == 1) {
	if (my_want_state_is_do(TELOPT_BINARY)) {
	    printf("Already receiving in binary mode.\n");
	} else {
	    printf("Negotiating binary mode on input.\n");
	    tel_enter_binary(1);
	}
    } else {
	if (my_want_state_is_dont(TELOPT_BINARY)) {
	    printf("Already receiving in network ascii mode.\n");
	} else {
	    printf("Negotiating network ascii mode on input.\n");
	    tel_leave_binary(1);
	}
    }
    return 1;
}

static int
togxbinary(int val)
{
    donebinarytoggle = 1;

    if (val == -1)
	val = my_want_state_is_will(TELOPT_BINARY) ? 0 : 1;

    if (val == 1) {
	if (my_want_state_is_will(TELOPT_BINARY)) {
	    printf("Already transmitting in binary mode.\n");
	} else {
	    printf("Negotiating binary mode on output.\n");
	    tel_enter_binary(2);
	}
    } else {
	if (my_want_state_is_wont(TELOPT_BINARY)) {
	    printf("Already transmitting in network ascii mode.\n");
	} else {
	    printf("Negotiating network ascii mode on output.\n");
	    tel_leave_binary(2);
	}
    }
    return 1;
}

#ifdef	ENCRYPTION
extern int EncryptAutoEnc(int);
extern int EncryptAutoDec(int);
extern int EncryptDebug(int);
extern int EncryptVerbose(int);
#endif	/* ENCRYPTION */

struct togglelist {
    char	*name;		/* name of toggle */
    char	*help;		/* help message */
    int		(*handler)	/* routine to do actual setting */
			(int);
    int		*variable;
    char	*actionexplanation;
};

static struct togglelist Togglelist[] = {
    { "autoflush",
	"flushing of output when sending interrupt characters",
	    0,
		&autoflush,
		    "flush output when sending interrupt characters" },
    { "autosynch",
	"automatic sending of interrupt characters in urgent mode",
	    0,
		&autosynch,
		    "send interrupt characters in urgent mode" },
#ifdef AUTHENTICATION
    { "autologin",
	"automatic sending of login and/or authentication info",
	    0,
		&autologin,
		    "send login name and/or authentication information" },
    { "authdebug",
	"Toggle authentication debugging",
	    auth_togdebug,
		0,
		     "print authentication debugging information" },
#endif
#ifdef	ENCRYPTION
    { "autoencrypt",
      "automatic encryption of data stream",
	    EncryptAutoEnc,
		0,
		     "automatically encrypt output" },
    { "autodecrypt",
      "automatic decryption of data stream",
	    EncryptAutoDec,
		0,
		     "automatically decrypt input" },
    { "verbose_encrypt",
      "Toggle verbose encryption output",
	    EncryptVerbose,
		0,
		     "print verbose encryption output" },
    { "encdebug",
      "Toggle encryption debugging",
	    EncryptDebug,
		0,
		     "print encryption debugging information" },
#endif	/* ENCRYPTION */
    { "skiprc",
	"don't read ~/.telnetrc file",
	    0,
		&skiprc,
		    "skip reading of ~/.telnetrc file" },
    { "binary",
	"sending and receiving of binary data",
	    togbinary,
		0,
		    0 },
    { "inbinary",
	"receiving of binary data",
	    togrbinary,
		0,
		    0 },
    { "outbinary",
	"sending of binary data",
	    togxbinary,
		0,
		    0 },
    { "crlf",
	"sending carriage returns as telnet <CR><LF>",
	   togcrlf,
		&crlf,
		    0 },
    { "crmod",
	"mapping of received carriage returns",
	    0,
		&crmod,
		    "map carriage return on output" },
    { "localchars",
	"local recognition of certain control characters",
	    lclchars,
		&localchars,
		    "recognize certain control characters" },
    { " ", "", 0 },		/* empty line */
#ifdef TN3270
    { "apitrace",
	"(debugging) toggle tracing of API transactions",
	    0,
		&apitrace,
		    "trace API transactions" },
    { "cursesdata",
	"(debugging) toggle printing of hexadecimal curses data",
	    0,
		&cursesdata,
		    "print hexadecimal representation of curses data" },
#endif	/* defined(TN3270) */
    { "debug",
	"debugging",
	    togdebug,
		&telnet_debug,
		    "turn on socket level debugging" },
    { "netdata",
	"printing of hexadecimal network data (debugging)",
	    0,
		&netdata,
		    "print hexadecimal representation of network traffic" },
    { "prettydump",
	"output of \"netdata\" to user readable format (debugging)",
	    0,
		&prettydump,
		    "print user readable output for \"netdata\"" },
    { "options",
	"viewing of options processing (debugging)",
	    0,
		&showoptions,
		    "show option processing" },
    { "termdata",
	"(debugging) toggle printing of hexadecimal terminal data",
	    0,
		&termdata,
		    "print hexadecimal representation of terminal traffic" },
    { "?",
	0,
	    togglehelp },
    { "help",
	0,
	    togglehelp },
    { 0 }
};

static int
togglehelp(int n)
{
    struct togglelist *c;

    for (c = Togglelist; c->name; c++) {
	if (c->help) {
	    if (*c->help)
		printf("%-15s toggle %s\n", c->name, c->help);
	    else
		printf("\n");
	}
    }
    printf("\n");
    printf("%-15s %s\n", "?", "display help information");
    return 0;
}

static void
settogglehelp(int set)
{
    struct togglelist *c;

    for (c = Togglelist; c->name; c++) {
	if (c->help) {
	    if (*c->help)
		printf("%-15s %s %s\n", c->name, set ? "enable" : "disable",
						c->help);
	    else
		printf("\n");
	}
    }
}

#define	GETTOGGLE(name) (struct togglelist *) \
		genget(name, (char **) Togglelist, sizeof(struct togglelist))

static int
toggle(int  argc, char *argv[])
{
    int retval = 1;
    char *name;
    struct togglelist *c;

    if (argc < 2) {
	fprintf(stderr,
	    "Need an argument to 'toggle' command.  'toggle ?' for help.\n");
	return 0;
    }
    argc--;
    argv++;
    while (argc--) {
	name = *argv++;
	c = GETTOGGLE(name);
	if (Ambiguous(c)) {
	    fprintf(stderr, "'%s': ambiguous argument ('toggle ?' for help).\n",
					name);
	    return 0;
	} else if (c == 0) {
	    fprintf(stderr, "'%s': unknown argument ('toggle ?' for help).\n",
					name);
	    return 0;
	} else {
	    if (c->variable) {
		*c->variable = !*c->variable;		/* invert it */
		if (c->actionexplanation) {
		    printf("%s %s.\n", *c->variable? "Will" : "Won't",
							c->actionexplanation);
		}
	    }
	    if (c->handler) {
		retval &= (*c->handler)(-1);
	    }
	}
    }
    return retval;
}

/*
 * The following perform the "set" command.
 */

struct termios new_tc = { 0 };

struct setlist {
    char *name;				/* name */
    char *help;				/* help information */
    void (*handler)(char *);
    cc_t *charp;			/* where it is located at */
};

static struct setlist Setlist[] = {
#ifdef	KLUDGELINEMODE
    { "echo", 	"character to toggle local echoing on/off", 0, &echoc },
#endif
    { "escape",	"character to escape back to telnet command mode", 0, &escape },
    { "rlogin", "rlogin escape character", 0, &rlogin },
    { "tracefile", "file to write trace information to", SetNetTrace, (cc_t *)NetTraceFile},
    { " ", "" },
    { " ", "The following need 'localchars' to be toggled true", 0, 0 },
    { "flushoutput", "character to cause an Abort Output", 0, termFlushCharp },
    { "interrupt", "character to cause an Interrupt Process", 0, termIntCharp },
    { "quit",	"character to cause an Abort process", 0, termQuitCharp },
    { "eof",	"character to cause an EOF ", 0, termEofCharp },
    { " ", "" },
    { " ", "The following are for local editing in linemode", 0, 0 },
    { "erase",	"character to use to erase a character", 0, termEraseCharp },
    { "kill",	"character to use to erase a line", 0, termKillCharp },
    { "lnext",	"character to use for literal next", 0, termLiteralNextCharp },
    { "susp",	"character to cause a Suspend Process", 0, termSuspCharp },
    { "reprint", "character to use for line reprint", 0, termRprntCharp },
    { "worderase", "character to use to erase a word", 0, termWerasCharp },
    { "start",	"character to use for XON", 0, termStartCharp },
    { "stop",	"character to use for XOFF", 0, termStopCharp },
    { "forw1",	"alternate end of line character", 0, termForw1Charp },
    { "forw2",	"alternate end of line character", 0, termForw2Charp },
    { "ayt",	"alternate AYT character", 0, termAytCharp },
    { 0 }
};

static struct setlist *
getset(char *name)
{
    return (struct setlist *)
		genget(name, (char **) Setlist, sizeof(struct setlist));
}

void
set_escape_char(char *s)
{
	if (rlogin != _POSIX_VDISABLE) {
		rlogin = (s && *s) ? special(s) : _POSIX_VDISABLE;
		printf("Telnet rlogin escape character is '%s'.\n",
					control(rlogin));
	} else {
		escape = (s && *s) ? special(s) : _POSIX_VDISABLE;
		printf("Telnet escape character is '%s'.\n", control(escape));
	}
}

static int
setcmd(int  argc, char *argv[])
{
    int value;
    struct setlist *ct;
    struct togglelist *c;

    if (argc < 2 || argc > 3) {
	printf("Format is 'set Name Value'\n'set ?' for help.\n");
	return 0;
    }
    if ((argc == 2) && (isprefix(argv[1], "?") || isprefix(argv[1], "help"))) {
	for (ct = Setlist; ct->name; ct++)
	    printf("%-15s %s\n", ct->name, ct->help);
	printf("\n");
	settogglehelp(1);
	printf("%-15s %s\n", "?", "display help information");
	return 0;
    }

    ct = getset(argv[1]);
    if (ct == 0) {
	c = GETTOGGLE(argv[1]);
	if (c == 0) {
	    fprintf(stderr, "'%s': unknown argument ('set ?' for help).\n",
			argv[1]);
	    return 0;
	} else if (Ambiguous(c)) {
	    fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\n",
			argv[1]);
	    return 0;
	}
	if (c->variable) {
	    if ((argc == 2) || (strcmp("on", argv[2]) == 0))
		*c->variable = 1;
	    else if (strcmp("off", argv[2]) == 0)
		*c->variable = 0;
	    else {
		printf("Format is 'set togglename [on|off]'\n'set ?' for help.\n");
		return 0;
	    }
	    if (c->actionexplanation) {
		printf("%s %s.\n", *c->variable? "Will" : "Won't",
							c->actionexplanation);
	    }
	}
	if (c->handler)
	    (*c->handler)(1);
    } else if (argc != 3) {
	printf("Format is 'set Name Value'\n'set ?' for help.\n");
	return 0;
    } else if (Ambiguous(ct)) {
	fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\n",
			argv[1]);
	return 0;
    } else if (ct->handler) {
	(*ct->handler)(argv[2]);
	printf("%s set to \"%s\".\n", ct->name, (char *)ct->charp);
    } else {
	if (strcmp("off", argv[2])) {
	    value = special(argv[2]);
	} else {
	    value = _POSIX_VDISABLE;
	}
	*(ct->charp) = (cc_t)value;
	printf("%s character is '%s'.\n", ct->name, control(*(ct->charp)));
    }
    slc_check();
    return 1;
}

static int
unsetcmd(int  argc, char *argv[])
{
    struct setlist *ct;
    struct togglelist *c;
    char *name;

    if (argc < 2) {
	fprintf(stderr,
	    "Need an argument to 'unset' command.  'unset ?' for help.\n");
	return 0;
    }
    if (isprefix(argv[1], "?") || isprefix(argv[1], "help")) {
	for (ct = Setlist; ct->name; ct++)
	    printf("%-15s %s\n", ct->name, ct->help);
	printf("\n");
	settogglehelp(0);
	printf("%-15s %s\n", "?", "display help information");
	return 0;
    }

    argc--;
    argv++;
    while (argc--) {
	name = *argv++;
	ct = getset(name);
	if (ct == 0) {
	    c = GETTOGGLE(name);
	    if (c == 0) {
		fprintf(stderr, "'%s': unknown argument ('unset ?' for help).\n",
			name);
		return 0;
	    } else if (Ambiguous(c)) {
		fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\n",
			name);
		return 0;
	    }
	    if (c->variable) {
		*c->variable = 0;
		if (c->actionexplanation) {
		    printf("%s %s.\n", *c->variable? "Will" : "Won't",
							c->actionexplanation);
		}
	    }
	    if (c->handler)
		(*c->handler)(0);
	} else if (Ambiguous(ct)) {
	    fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\n",
			name);
	    return 0;
	} else if (ct->handler) {
	    (*ct->handler)(0);
	    printf("%s reset to \"%s\".\n", ct->name, (char *)ct->charp);
	} else {
	    *(ct->charp) = _POSIX_VDISABLE;
	    printf("%s character is '%s'.\n", ct->name, control(*(ct->charp)));
	}
    }
    return 1;
}

/*
 * The following are the data structures and routines for the
 * 'mode' command.
 */
#ifdef	KLUDGELINEMODE
extern int kludgelinemode;

static int
dokludgemode(int n)
{
    kludgelinemode = 1;
    send_wont(TELOPT_LINEMODE, 1);
    send_dont(TELOPT_SGA, 1);
    send_dont(TELOPT_ECHO, 1);
    return 1;
}
#endif

static int
dolinemode(int n)
{
#ifdef	KLUDGELINEMODE
    if (kludgelinemode)
	send_dont(TELOPT_SGA, 1);
#endif
    send_will(TELOPT_LINEMODE, 1);
    send_dont(TELOPT_ECHO, 1);
    return 1;
}

static int
docharmode(int n)
{
#ifdef	KLUDGELINEMODE
    if (kludgelinemode)
	send_do(TELOPT_SGA, 1);
    else
#endif
    send_wont(TELOPT_LINEMODE, 1);
    send_do(TELOPT_ECHO, 1);
    return 1;
}

static int
dolmmode(int bit, int on)
{
    unsigned char c;
    extern int linemode;

    if (my_want_state_is_wont(TELOPT_LINEMODE)) {
	printf("?Need to have LINEMODE option enabled first.\n");
	printf("'mode ?' for help.\n");
	return 0;
    }

    if (on)
	c = (linemode | bit);
    else
	c = (linemode & ~bit);
    lm_mode(&c, 1, 1);
    return 1;
}

int
set_mode(int bit)
{
    return dolmmode(bit, 1);
}

int
clear_mode(int bit)
{
    return dolmmode(bit, 0);
}

struct modelist {
	char	*name;		/* command name */
	char	*help;		/* help string */
	int	(*handler)	/* routine which executes command */
			(int);
	int	needconnect;	/* Do we need to be connected to execute? */
	int	arg1;
};

static struct modelist ModeList[] = {
    { "character", "Disable LINEMODE option",	docharmode, 1 },
#ifdef	KLUDGELINEMODE
    { "",	"(or disable obsolete line-by-line mode)", 0 },
#endif
    { "line",	"Enable LINEMODE option",	dolinemode, 1 },
#ifdef	KLUDGELINEMODE
    { "",	"(or enable obsolete line-by-line mode)", 0 },
#endif
    { "", "", 0 },
    { "",	"These require the LINEMODE option to be enabled", 0 },
    { "isig",	"Enable signal trapping",	set_mode, 1, MODE_TRAPSIG },
    { "+isig",	0,				set_mode, 1, MODE_TRAPSIG },
    { "-isig",	"Disable signal trapping",	clear_mode, 1, MODE_TRAPSIG },
    { "edit",	"Enable character editing",	set_mode, 1, MODE_EDIT },
    { "+edit",	0,				set_mode, 1, MODE_EDIT },
    { "-edit",	"Disable character editing",	clear_mode, 1, MODE_EDIT },
    { "softtabs", "Enable tab expansion",	set_mode, 1, MODE_SOFT_TAB },
    { "+softtabs", 0,				set_mode, 1, MODE_SOFT_TAB },
    { "-softtabs", "Disable character editing",	clear_mode, 1, MODE_SOFT_TAB },
    { "litecho", "Enable literal character echo", set_mode, 1, MODE_LIT_ECHO },
    { "+litecho", 0,				set_mode, 1, MODE_LIT_ECHO },
    { "-litecho", "Disable literal character echo", clear_mode, 1, MODE_LIT_ECHO },
    { "help",	0,				modehelp, 0 },
#ifdef	KLUDGELINEMODE
    { "kludgeline", 0,				dokludgemode, 1 },
#endif
    { "", "", 0 },
    { "?",	"Print help information",	modehelp, 0 },
    { 0 },
};


int
modehelp(int n)
{
    struct modelist *mt;

    printf("format is:  'mode Mode', where 'Mode' is one of:\n\n");
    for (mt = ModeList; mt->name; mt++) {
	if (mt->help) {
	    if (*mt->help)
		printf("%-15s %s\n", mt->name, mt->help);
	    else
		printf("\n");
	}
    }
    return 0;
}

#define	GETMODECMD(name) (struct modelist *) \
		genget(name, (char **) ModeList, sizeof(struct modelist))

static int
modecmd(int  argc, char *argv[])
{
    struct modelist *mt;

    if (argc != 2) {
	printf("'mode' command requires an argument\n");
	printf("'mode ?' for help.\n");
    } else if ((mt = GETMODECMD(argv[1])) == 0) {
	fprintf(stderr, "Unknown mode '%s' ('mode ?' for help).\n", argv[1]);
    } else if (Ambiguous(mt)) {
	fprintf(stderr, "Ambiguous mode '%s' ('mode ?' for help).\n", argv[1]);
    } else if (mt->needconnect && !connected) {
	printf("?Need to be connected first.\n");
	printf("'mode ?' for help.\n");
    } else if (mt->handler) {
	return (*mt->handler)(mt->arg1);
    }
    return 0;
}

/*
 * The following data structures and routines implement the
 * "display" command.
 */

static int
display(int  argc, char *argv[])
{
    struct togglelist *tl;
    struct setlist *sl;

#define	dotog(tl)	if (tl->variable && tl->actionexplanation) { \
			    if (*tl->variable) { \
				printf("will"); \
			    } else { \
				printf("won't"); \
			    } \
			    printf(" %s.\n", tl->actionexplanation); \
			}

#define	doset(sl)   if (sl->name && *sl->name != ' ') { \
			if (sl->handler == 0) \
			    printf("%-15s [%s]\n", sl->name, control(*sl->charp)); \
			else \
			    printf("%-15s \"%s\"\n", sl->name, (char *)sl->charp); \
		    }

    if (argc == 1) {
	for (tl = Togglelist; tl->name; tl++) {
	    dotog(tl);
	}
	printf("\n");
	for (sl = Setlist; sl->name; sl++) {
	    doset(sl);
	}
    } else {
	int i;

	for (i = 1; i < argc; i++) {
	    sl = getset(argv[i]);
	    tl = GETTOGGLE(argv[i]);
	    if (Ambiguous(sl) || Ambiguous(tl)) {
		printf("?Ambiguous argument '%s'.\n", argv[i]);
		return 0;
	    } else if (!sl && !tl) {
		printf("?Unknown argument '%s'.\n", argv[i]);
		return 0;
	    } else {
		if (tl) {
		    dotog(tl);
		}
		if (sl) {
		    doset(sl);
		}
	    }
	}
    }
/*@*/optionstatus();
#ifdef	ENCRYPTION
    EncryptStatus();
#endif	/* ENCRYPTION */
    return 1;
#undef	doset
#undef	dotog
}

/*
 * The following are the data structures, and many of the routines,
 * relating to command processing.
 */

/*
 * Set the escape character.
 */
static int
setescape(int argc, char *argv[])
{
	char *arg;
	char buf[50];

	printf(
	    "Deprecated usage - please use 'set escape%s%s' in the future.\n",
				(argc > 2)? " ":"", (argc > 2)? argv[1]: "");
	if (argc > 2)
		arg = argv[1];
	else {
		printf("new escape character: ");
		(void) fgets(buf, sizeof(buf), stdin);
		arg = buf;
	}
	if (arg[0] != '\0')
		escape = arg[0];
	if (!In3270) {
		printf("Escape character is '%s'.\n", control(escape));
	}
	(void) fflush(stdout);
	return 1;
}

/*VARARGS*/
static int
togcrmod(int argc, char *argv[])
{
    crmod = !crmod;
    printf("Deprecated usage - please use 'toggle crmod' in the future.\n");
    printf("%s map carriage return on output.\n", crmod ? "Will" : "Won't");
    (void) fflush(stdout);
    return 1;
}

/*VARARGS*/
int
suspend(int argc, char *argv[])
{
    setcommandmode();
    {
	long oldrows, oldcols, newrows, newcols, err;

	err = (TerminalWindowSize(&oldrows, &oldcols) == 0) ? 1 : 0;
	(void) kill(0, SIGTSTP);
	/*
	 * If we didn't get the window size before the SUSPEND, but we
	 * can get them now (?), then send the NAWS to make sure that
	 * we are set up for the right window size.
	 */
	if (TerminalWindowSize(&newrows, &newcols) && connected &&
	    (err || ((oldrows != newrows) || (oldcols != newcols)))) {
		sendnaws();
	}
    }
    /* reget parameters in case they were changed */
    TerminalSaveState();
    setconnmode(0);
    return 1;
}

#ifndef TN3270
/*ARGSUSED*/
int
shell(int argc, char *argv[])
{
    long oldrows, oldcols, newrows, newcols;
    long volatile err;	/* Avoid vfork clobbering */

    setcommandmode();

    err = (TerminalWindowSize(&oldrows, &oldcols) == 0) ? 1 : 0;
    switch(vfork()) {
    case -1:
	perror("Fork failed");
	break;

    case 0:
	{
	    /*
	     * Fire up the shell in the child.
	     */
	    char *shellp, *shellname;

	    shellp = getenv("SHELL");
	    if (shellp == NULL)
		shellp = "/bin/sh";
	    if ((shellname = strrchr(shellp, '/')) == 0)
		shellname = shellp;
	    else
		shellname++;
	    if (argc > 1)
		execl(shellp, shellname, "-c", &saveline[1], NULL);
	    else
		execl(shellp, shellname, NULL);
	    perror("execl");
	    _exit(1);
	}
    default:
	    (void)wait((int *)0);	/* Wait for the shell to complete */

	    if (TerminalWindowSize(&newrows, &newcols) && connected &&
		(err || ((oldrows != newrows) || (oldcols != newcols)))) {
		    sendnaws();
	    }
	    break;
    }
    return 1;
}
#endif	/* !defined(TN3270) */

/*VARARGS*/
static int
bye(int  argc, char *argv[])
{
    extern int resettermname;

    if (connected) {
	(void) shutdown(net, 2);
	printf("Connection closed.\n");
	(void) NetClose(net);
	connected = 0;
	resettermname = 1;
#if	defined(AUTHENTICATION) || defined(ENCRYPTION)
	auth_encrypt_connect(connected);
#endif	/* defined(AUTHENTICATION) */
	/* reset options */
	tninit();
#ifdef TN3270
	SetIn3270();		/* Get out of 3270 mode */
#endif	/* defined(TN3270) */
    }
    if ((argc != 2) || (strcmp(argv[1], "fromquit") != 0)) {
	longjmp(toplevel, 1);
	/* NOTREACHED */
    }
    return 1;			/* Keep lint, etc., happy */
}

/*VARARGS*/
int
quit(int argc, char *argv[])
{
	(void) call(bye, "bye", "fromquit", 0);
	Exit(0);
	/*NOTREACHED*/
}

/*VARARGS*/
int
logout(int argc, char *argv[])
{
	send_do(TELOPT_LOGOUT, 1);
	(void) netflush();
	return 1;
}


/*
 * The SLC command.
 */

struct slclist {
	char	*name;
	char	*help;
	void	(*handler)(int);
	int	arg;
};

struct slclist SlcList[] = {
    { "export",	"Use local special character definitions",
						slc_mode_export,	0 },
    { "import",	"Use remote special character definitions",
						slc_mode_import,	1 },
    { "check",	"Verify remote special character definitions",
						slc_mode_import,	0 },
    { "help",	0,				slc_help,		0 },
    { "?",	"Print help information",	slc_help,		0 },
    { 0 },
};

static void
slc_help(int n)
{
    struct slclist *c;

    for (c = SlcList; c->name; c++) {
	if (c->help) {
	    if (*c->help)
		printf("%-15s %s\n", c->name, c->help);
	    else
		printf("\n");
	}
    }
}

static struct slclist *
getslc(char *name)
{
    return (struct slclist *)
		genget(name, (char **) SlcList, sizeof(struct slclist));
}

static int
slccmd(int  argc, char *argv[])
{
    struct slclist *c;

    if (argc != 2) {
	fprintf(stderr,
	    "Need an argument to 'slc' command.  'slc ?' for help.\n");
	return 0;
    }
    c = getslc(argv[1]);
    if (c == 0) {
	fprintf(stderr, "'%s': unknown argument ('slc ?' for help).\n",
    				argv[1]);
	return 0;
    }
    if (Ambiguous(c)) {
	fprintf(stderr, "'%s': ambiguous argument ('slc ?' for help).\n",
    				argv[1]);
	return 0;
    }
    (*c->handler)(c->arg);
    slcstate();
    return 1;
}

/*
 * The ENVIRON command.
 */

struct envlist {
	char	*name;
	char	*help;
	struct env_lst *(*handler)(unsigned char *, unsigned char *);
	int	narg;
};

struct envlist EnvList[] = {
    { "define",	"Define an environment variable",
						env_define,	2 },
    { "undefine", "Undefine an environment variable",
						env_undefine,	1 },
    { "export",	"Mark an environment variable for automatic export",
						env_export,	1 },
    { "unexport", "Don't mark an environment variable for automatic export",
						env_unexport,	1 },
    { "send",	"Send an environment variable", env_send,	1 },
    { "list",	"List the current environment variables",
						env_list,	0 },
#if defined(OLD_ENVIRON) && defined(ENV_HACK)
    { "varval", "Reverse VAR and VALUE (auto, right, wrong, status)",
						env_varval,    1 },
#endif
    { "help",	0,				env_help,		0 },
    { "?",	"Print help information",	env_help,		0 },
    { 0 },
};

static struct env_lst *
env_help( unsigned char *us1, unsigned char *us2)
{
    struct envlist *c;

    for (c = EnvList; c->name; c++) {
	if (c->help) {
	    if (*c->help)
		printf("%-15s %s\n", c->name, c->help);
	    else
		printf("\n");
	}
    }
    return NULL;
}

static struct envlist *
getenvcmd(char *name)
{
    return (struct envlist *)
		genget(name, (char **) EnvList, sizeof(struct envlist));
}

int
env_cmd(int  argc, char *argv[])
{
    struct envlist *c;

    if (argc < 2) {
	fprintf(stderr,
	    "Need an argument to 'environ' command.  'environ ?' for help.\n");
	return 0;
    }
    c = getenvcmd(argv[1]);
    if (c == 0) {
	fprintf(stderr, "'%s': unknown argument ('environ ?' for help).\n",
    				argv[1]);
	return 0;
    }
    if (Ambiguous(c)) {
	fprintf(stderr, "'%s': ambiguous argument ('environ ?' for help).\n",
    				argv[1]);
	return 0;
    }
    if (c->narg + 2 != argc) {
	fprintf(stderr,
	    "Need %s%d argument%s to 'environ %s' command.  'environ ?' for help.\n",
		c->narg < argc + 2 ? "only " : "",
		c->narg, c->narg == 1 ? "" : "s", c->name);
	return 0;
    }
    (*c->handler)(argv[2], argv[3]);
    return 1;
}

struct env_lst {
	struct env_lst *next;	/* pointer to next structure */
	struct env_lst *prev;	/* pointer to previous structure */
	unsigned char *var;	/* pointer to variable name */
	unsigned char *value;	/* pointer to variable value */
	int export;		/* 1 -> export with default list of variables */
	int welldefined;	/* A well defined variable */
};

struct env_lst envlisthead;

struct env_lst *
env_find(unsigned char *var)
{
	struct env_lst *ep;

	for (ep = envlisthead.next; ep; ep = ep->next) {
		if (strcmp((char *)ep->var, (char *)var) == 0)
			return(ep);
	}
	return(NULL);
}

void
env_init(void)
{
	extern char **environ;
	char **epp, *cp;
	struct env_lst *ep;

	for (epp = environ; *epp; epp++) {
		if ((cp = strchr(*epp, '=')) != NULL) {
			*cp = '\0';
			ep = env_define((unsigned char *)*epp,
					(unsigned char *)cp+1);
			ep->export = 0;
			*cp = '=';
		}
	}
	/*
	 * Special case for DISPLAY variable.  If it is ":0.0" or
	 * "unix:0.0", we have to get rid of "unix" and insert our
	 * hostname.
	 */
	if ((ep = env_find("DISPLAY"))
	    && ((*ep->value == ':')
		|| (strncmp((char *)ep->value, "unix:", 5) == 0))) {
		char hbuf[MAXHOSTNAMELEN + 1];
		char *cp2 = strchr((char *)ep->value, ':');

		gethostname(hbuf, sizeof hbuf);
		hbuf[sizeof(hbuf) - 1] = '\0';
		cp = (char *)malloc(strlen(hbuf) + strlen(cp2) + 1);
		sprintf((char *)cp, "%s%s", hbuf, cp2);
		free(ep->value);
		ep->value = (unsigned char *)cp;
	}
	/*
	 * If USER is not defined, but LOGNAME is, then add
	 * USER with the value from LOGNAME.  By default, we
	 * don't export the USER variable.
	 */
	if ((env_find("USER") == NULL) && (ep = env_find("LOGNAME"))) {
		env_define((unsigned char *)"USER", ep->value);
		env_unexport((unsigned char *)"USER", NULL);
	}
	env_export((unsigned char *)"DISPLAY", NULL);
	env_export((unsigned char *)"PRINTER", NULL);
}

struct env_lst *
env_define(unsigned char *var, unsigned char *value)
{
	struct env_lst *ep;

	if ((ep = env_find(var)) != NULL) {
		if (ep->var)
			free(ep->var);
		if (ep->value)
			free(ep->value);
	} else {
		ep = (struct env_lst *)malloc(sizeof(struct env_lst));
		ep->next = envlisthead.next;
		envlisthead.next = ep;
		ep->prev = &envlisthead;
		if (ep->next)
			ep->next->prev = ep;
	}
	ep->welldefined = opt_welldefined(var);
	ep->export = 1;
	ep->var = (unsigned char *)strdup((char *)var);
	ep->value = (unsigned char *)strdup((char *)value);
	return(ep);
}

struct env_lst *
env_undefine(unsigned char *var, unsigned char *d)
{
	struct env_lst *ep;

	if ((ep = env_find(var)) != NULL) {
		ep->prev->next = ep->next;
		if (ep->next)
			ep->next->prev = ep->prev;
		if (ep->var)
			free(ep->var);
		if (ep->value)
			free(ep->value);
		free(ep);
	}
	return NULL;
}

struct env_lst *
env_export(unsigned char *var, unsigned char *d)
{
	struct env_lst *ep;

	if ((ep = env_find(var)) != NULL)
		ep->export = 1;
	return NULL;
}

struct env_lst *
env_unexport(unsigned char *var, unsigned char *d)
{
	struct env_lst *ep;

	if ((ep = env_find(var)) != NULL)
		ep->export = 0;
	return NULL;
}

struct env_lst *
env_send(unsigned char *var, unsigned char *d)
{
	struct env_lst *ep;

	if (my_state_is_wont(TELOPT_NEW_ENVIRON)
#ifdef	OLD_ENVIRON
	    && my_state_is_wont(TELOPT_OLD_ENVIRON)
#endif
		) {
		fprintf(stderr,
		    "Cannot send '%s': Telnet ENVIRON option not enabled\n",
									var);
		return NULL;
	}
	ep = env_find(var);
	if (ep == 0) {
		fprintf(stderr, "Cannot send '%s': variable not defined\n",
									var);
		return NULL;
	}
	env_opt_start_info();
	env_opt_add(ep->var);
	env_opt_end(0);
	return NULL;
}

struct env_lst *
env_list(unsigned char *d1, unsigned char *d2)
{
	struct env_lst *ep;

	for (ep = envlisthead.next; ep; ep = ep->next) {
		printf("%c %-20s %s\n", ep->export ? '*' : ' ',
					ep->var, ep->value);
	}
	return NULL;
}

unsigned char *
env_default(int init, int welldefined)
{
	static struct env_lst *nep = NULL;

	if (init) {
		nep = &envlisthead;
		return NULL;
	}
	if (nep) {
		while ((nep = nep->next) != NULL) {
			if (nep->export && (nep->welldefined == welldefined))
				return(nep->var);
		}
	}
	return(NULL);
}

unsigned char *
env_getvalue(unsigned char *var)
{
	struct env_lst *ep;

	if ((ep = env_find(var)) != NULL)
		return(ep->value);
	return(NULL);
}

#if defined(OLD_ENVIRON) && defined(ENV_HACK)
void
env_varval(unsigned char *what)
{
	extern int old_env_var, old_env_value, env_auto;
	int len = strlen((char *)what);

	if (len == 0)
		goto unknown;

	if (strncasecmp((char *)what, "status", len) == 0) {
		if (env_auto)
			printf("%s%s", "VAR and VALUE are/will be ",
					"determined automatically\n");
		if (old_env_var == OLD_ENV_VAR)
			printf("VAR and VALUE set to correct definitions\n");
		else
			printf("VAR and VALUE definitions are reversed\n");
	} else if (strncasecmp((char *)what, "auto", len) == 0) {
		env_auto = 1;
		old_env_var = OLD_ENV_VALUE;
		old_env_value = OLD_ENV_VAR;
	} else if (strncasecmp((char *)what, "right", len) == 0) {
		env_auto = 0;
		old_env_var = OLD_ENV_VAR;
		old_env_value = OLD_ENV_VALUE;
	} else if (strncasecmp((char *)what, "wrong", len) == 0) {
		env_auto = 0;
		old_env_var = OLD_ENV_VALUE;
		old_env_value = OLD_ENV_VAR;
	} else {
unknown:
		printf("Unknown \"varval\" command. (\"auto\", \"right\", \"wrong\", \"status\")\n");
	}
}
#endif

#ifdef AUTHENTICATION
/*
 * The AUTHENTICATE command.
 */

struct authlist {
	char	*name;
	char	*help;
	int	(*handler)(char *);
	int	narg;
};

struct authlist AuthList[] = {
    { "status",	"Display current status of authentication information",
						auth_status,	0 },
    { "disable", "Disable an authentication type ('auth disable ?' for more)",
						auth_disable,	1 },
    { "enable", "Enable an authentication type ('auth enable ?' for more)",
						auth_enable,	1 },
    { "help",	0,				auth_help,		0 },
    { "?",	"Print help information",	auth_help,		0 },
    { 0 },
};

static int
auth_help(char *s)
{
    struct authlist *c;

    for (c = AuthList; c->name; c++) {
	if (c->help) {
	    if (*c->help)
		printf("%-15s %s\n", c->name, c->help);
	    else
		printf("\n");
	}
    }
    return 0;
}

int
auth_cmd(int  argc, char *argv[])
{
    struct authlist *c;

    if (argc < 2) {
	fprintf(stderr,
	    "Need an argument to 'auth' command.  'auth ?' for help.\n");
	return 0;
    }

    c = (struct authlist *)
		genget(argv[1], (char **) AuthList, sizeof(struct authlist));
    if (c == 0) {
	fprintf(stderr, "'%s': unknown argument ('auth ?' for help).\n",
    				argv[1]);
	return 0;
    }
    if (Ambiguous(c)) {
	fprintf(stderr, "'%s': ambiguous argument ('auth ?' for help).\n",
    				argv[1]);
	return 0;
    }
    if (c->narg + 2 != argc) {
	fprintf(stderr,
	    "Need %s%d argument%s to 'auth %s' command.  'auth ?' for help.\n",
		c->narg < argc + 2 ? "only " : "",
		c->narg, c->narg == 1 ? "" : "s", c->name);
	return 0;
    }
    return((*c->handler)(argv[2]));
}
#endif

#ifdef	ENCRYPTION
/*
 * The ENCRYPT command.
 */

struct encryptlist {
	char	*name;
	char	*help;
	int	(*handler)(char *, char *);
	int	needconnect;
	int	minarg;
	int	maxarg;
};

static int
	EncryptHelp(char *, char *);
typedef int (*encrypthandler)(char *, char *);

struct encryptlist EncryptList[] = {
    { "enable", "Enable encryption. ('encrypt enable ?' for more)",
						EncryptEnable, 1, 1, 2 },
    { "disable", "Disable encryption. ('encrypt enable ?' for more)",
						EncryptDisable, 0, 1, 2 },
    { "type", "Set encryption type. ('encrypt type ?' for more)",
						EncryptType, 0, 1, 1 },
    { "start", "Start encryption. ('encrypt start ?' for more)",
				(encrypthandler) EncryptStart, 1, 0, 1 },
    { "stop", "Stop encryption. ('encrypt stop ?' for more)",
				(encrypthandler) EncryptStop, 1, 0, 1 },
    { "input", "Start encrypting the input stream",
				(encrypthandler) EncryptStartInput, 1, 0, 0 },
    { "-input", "Stop encrypting the input stream",
				(encrypthandler) EncryptStopInput, 1, 0, 0 },
    { "output", "Start encrypting the output stream",
				(encrypthandler) EncryptStartOutput, 1, 0, 0 },
    { "-output", "Stop encrypting the output stream",
				(encrypthandler) EncryptStopOutput, 1, 0, 0 },

    { "status",       "Display current status of authentication information",
				(encrypthandler) EncryptStatus,	0, 0, 0 },
    { "help", 0,				 EncryptHelp,	0, 0, 0 },
    { "?",    "Print help information",		 EncryptHelp,	0, 0, 0 },
    { 0 },
};

static int
EncryptHelp(char *s1, char *s2)
{
	struct encryptlist *c;

	for (c = EncryptList; c->name; c++) {
		if (c->help) {
			if (*c->help)
				printf("%-15s %s\n", c->name, c->help);
			else
				printf("\n");
		}
	}
	return (0);
}

int
encrypt_cmd(int argc, char *argv[])
{
	struct encryptlist *c;

	if (argc < 2) {
		fprintf(stderr,
		    "Need an argument to 'encrypt' command.  "
		    "'encrypt ?' for help.\n");
		return (0);
	}

	c = (struct encryptlist *)
	    genget(argv[1], (char **) EncryptList, sizeof(struct encryptlist));
	if (c == NULL) {
		fprintf(stderr,
		    "'%s': unknown argument ('encrypt ?' for help).\n",
		    argv[1]);
		return (0);
	}
	if (Ambiguous(c)) {
		fprintf(stderr,
		    "'%s': ambiguous argument ('encrypt ?' for help).\n",
		    argv[1]);
		return (0);
	}
	argc -= 2;
	if (argc < c->minarg || argc > c->maxarg) {
		if (c->minarg == c->maxarg) {
			fprintf(stderr, "Need %s%d argument%s ",
			    c->minarg < argc ? "only " : "", c->minarg,
			    c->minarg == 1 ? "" : "s");
		} else {
			fprintf(stderr, "Need %s%d-%d arguments ",
			    c->maxarg < argc ? "only " : "", c->minarg,
			    c->maxarg);
		}
		fprintf(stderr,
		    "to 'encrypt %s' command.  'encrypt ?' for help.\n",
		    c->name);
		return (0);
	}
	if (c->needconnect && !connected) {
		if (!(argc && (isprefix(argv[2], "help") ||
		    isprefix(argv[2], "?")))) {
			printf("?Need to be connected first.\n");
			return (0);
		}
	}
	return ((*c->handler)(argv[2], argv[3]));
}
#endif	/* ENCRYPTION */

#ifdef TN3270
static void
filestuff(int fd)
{
    int res;

    setconnmode(0);
    res = fcntl(fd, F_GETOWN, 0);
    setcommandmode();

    if (res == -1) {
	perror("fcntl");
	return;
    }
    printf("\tOwner is %d.\n", res);

    setconnmode(0);
    res = fcntl(fd, F_GETFL, 0);
    setcommandmode();

    if (res == -1) {
	perror("fcntl");
	return;
    }
#ifdef notdef
    printf("\tFlags are 0x%x: %s\n", res, decodeflags(res));
#endif
}
#endif /* defined(TN3270) */

/*
 * Print status about the connection.
 */
/*ARGSUSED*/
static int
status(int argc, char *argv[])
{
    if (connected) {
	printf("Connected to %s.\n", hostname);
	if ((argc < 2) || strcmp(argv[1], "notmuch")) {
	    int mode = getconnmode();

	    if (my_want_state_is_will(TELOPT_LINEMODE)) {
		printf("Operating with LINEMODE option\n");
		printf("%s line editing\n", (mode&MODE_EDIT) ? "Local" : "No");
		printf("%s catching of signals\n",
					(mode&MODE_TRAPSIG) ? "Local" : "No");
		slcstate();
#ifdef	KLUDGELINEMODE
	    } else if (kludgelinemode && my_want_state_is_dont(TELOPT_SGA)) {
		printf("Operating in obsolete linemode\n");
#endif
	    } else {
		printf("Operating in single character mode\n");
		if (localchars)
		    printf("Catching signals locally\n");
	    }
	    printf("%s character echo\n", (mode&MODE_ECHO) ? "Local" : "Remote");
	    if (my_want_state_is_will(TELOPT_LFLOW))
		printf("%s flow control\n", (mode&MODE_FLOW) ? "Local" : "No");
#ifdef	ENCRYPTION
	    encrypt_display();
#endif	/* ENCRYPTION */
	}
    } else {
	printf("No connection.\n");
    }
#   ifndef TN3270
    printf("Escape character is '%s'.\n", control(escape));
    (void) fflush(stdout);
#   else /* !defined(TN3270) */
    if ((!In3270) && ((argc < 2) || strcmp(argv[1], "notmuch"))) {
	printf("Escape character is '%s'.\n", control(escape));
    }
    if ((argc >= 2) && !strcmp(argv[1], "everything")) {
	printf("SIGIO received %d time%s.\n",
				sigiocount, (sigiocount == 1)? "":"s");
	if (In3270) {
	    printf("Process ID %d, process group %d.\n",
					    getpid(), getpgrp());
	    printf("Terminal input:\n");
	    filestuff(tin);
	    printf("Terminal output:\n");
	    filestuff(tout);
	    printf("Network socket:\n");
	    filestuff(net);
	}
    }
    if (In3270 && transcom) {
	printf("Transparent mode command is '%s'.\n", transcom);
    }
    (void) fflush(stdout);
    if (In3270) {
	return 0;
    }
#   endif /* defined(TN3270) */
    return 1;
}

/*
 * Function that gets called when SIGINFO is received.
 */
int
ayt_status(void)
{
    return call(status, "status", "notmuch", 0);
}

static const char *
sockaddr_ntop(struct sockaddr *sa)
{
    static char addrbuf[NI_MAXHOST];
    const int niflags = NI_NUMERICHOST;

    if (getnameinfo(sa, sa->sa_len, addrbuf, sizeof(addrbuf),
	    NULL, 0, niflags) == 0)
	return addrbuf;
    else
	return NULL;
}

#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
static int setpolicy (int, struct addrinfo *, char *);

static int
setpolicy(int net, struct addrinfo *res, char *policy)
{
	char *buf;
	int level;
	int optname;

	if (policy == NULL)
		return 0;

	buf = ipsec_set_policy(policy, strlen(policy));
	if (buf == NULL) {
		printf("%s\n", ipsec_strerror());
		return -1;
	}
	level = res->ai_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
	optname = res->ai_family == AF_INET ? IP_IPSEC_POLICY : IPV6_IPSEC_POLICY;
	if (setsockopt(net, level, optname, buf, ipsec_get_policylen(buf)) < 0){
		perror("setsockopt");
		return -1;
	}

	free(buf);
	return 0;
}
#endif

int
tn(int argc, char *argv[])
{
    struct addrinfo hints, *res, *res0;
    char *cause = "telnet: unknown";
    int error;
#if	defined(IP_OPTIONS) && defined(IPPROTO_IP)
    char *srp = 0;
    unsigned long srlen;
    int proto, opt;
#endif
    char *cmd, *hostp = 0, *portp = 0;
    const char *user = 0;

    if (connected) {
	printf("?Already connected to %s\n", hostname);
	return 0;
    }
    if (argc < 2) {
	(void) strlcpy(line, "open ", sizeof(line));
	printf("(to) ");
	(void) fgets(&line[strlen(line)], sizeof(line) - strlen(line), stdin);
	makeargv();
	argc = margc;
	argv = margv;
    }
    cmd = *argv;
    --argc; ++argv;
    while (argc) {
	if (strcmp(*argv, "help") == 0 || isprefix(*argv, "?"))
	    goto usage;
	if (strcmp(*argv, "-l") == 0) {
	    --argc; ++argv;
	    if (argc == 0)
		goto usage;
	    user = *argv++;
	    --argc;
	    continue;
	}
	if (strcmp(*argv, "-a") == 0) {
	    --argc; ++argv;
	    autologin = 1;
	    continue;
	}
	if (hostp == 0) {
	    hostp = *argv++;
	    --argc;
	    continue;
	}
	if (portp == 0) {
	    portp = *argv++;
	    --argc;
	    continue;
	}
    usage:
	printf("usage: %s [-l user] [-a] host-name [port]\n", cmd);
	return 0;
    }
    if (hostp == 0)
	goto usage;

    (void) strlcpy(_hostname, hostp, sizeof(_hostname));
    if (hostp[0] == '@' || hostp[0] == '!') {
	char *p;
	hostname = NULL;
	for (p = hostp + 1; *p; p++) {
	    if (*p == ',' || *p == '@')
		hostname = p;
	}
	if (hostname == NULL) {
	    fprintf(stderr, "%s: bad source route specification\n", hostp);
	    return 0;
	}
	*hostname++ = '\0';
    } else
	hostname = hostp;

    if (!portp) {
	telnetport = 1;
	portp = "telnet";
    } else if (portp[0] == '-') {
	/* use telnet negotiation if port number/name preceded by minus sign */
	telnetport = 1;
	portp++;
    } else
	telnetport = 0;

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = family;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = 0;
    hints.ai_flags = AI_NUMERICHOST;	/* avoid forward lookup */
    error = getaddrinfo(hostname, portp, &hints, &res0);
    if (!error) {
	/* numeric */
	if (doaddrlookup &&
	    getnameinfo(res0->ai_addr, res0->ai_addrlen,
		_hostname, sizeof(_hostname), NULL, 0, NI_NAMEREQD) == 0)
	    ; /* okay */
	else
	    strlcpy(_hostname, hostname, sizeof(_hostname));
    } else {
	/* FQDN - try again with forward DNS lookup */
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = family;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = 0;
	hints.ai_flags = AI_CANONNAME;
	error = getaddrinfo(hostname, portp, &hints, &res0);
	if (error == EAI_SERVICE) {
	    fprintf(stderr, "tcp/%s: unknown service\n", portp);
	    return 0;
	} else if (error) {
	    fprintf(stderr, "%s: %s\n", hostname, gai_strerror(error));
	    return 0;
	}
	if (res0->ai_canonname)
	    (void)strlcpy(_hostname, res0->ai_canonname, sizeof(_hostname));
	else
	    (void)strlcpy(_hostname, hostname, sizeof(_hostname));
    }
    hostname = _hostname;

    net = -1;
    for (res = res0; res; res = res->ai_next) {
	printf("Trying %s...\n", sockaddr_ntop(res->ai_addr));
	net = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
	if (net < 0) {
	    cause = "telnet: socket";
	    continue;
	}

	if (telnet_debug && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 1) < 0) {
	    perror("setsockopt (SO_DEBUG)");
	}
	if (hostp[0] == '@' || hostp[0] == '!') {
	    if ((srlen = sourceroute(res, hostp, &srp, &proto, &opt)) < 0) {
		(void) NetClose(net);
		net = -1;
		continue;
	    }
	    if (srp && setsockopt(net, proto, opt, srp, srlen) < 0)
		perror("setsockopt (source route)");
	}

#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
	if (setpolicy(net, res, ipsec_policy_in) < 0) {
	    (void) NetClose(net);
	    net = -1;
	    continue;
	}
	if (setpolicy(net, res, ipsec_policy_out) < 0) {
	    (void) NetClose(net);
	    net = -1;
	    continue;
	}
#endif

	if (connect(net, res->ai_addr, res->ai_addrlen) < 0) {
	    if (res->ai_next) {
		int oerrno = errno;

		fprintf(stderr, "telnet: connect to address %s: ",
						sockaddr_ntop(res->ai_addr));
		errno = oerrno;
		perror((char *)0);
	    }
	    cause = "telnet: Unable to connect to remote host";
	    (void) NetClose(net);
	    net = -1;
	    continue;
	}

	connected++;
#if	defined(AUTHENTICATION) || defined(ENCRYPTION)
	auth_encrypt_connect(connected);
#endif	/* defined(AUTHENTICATION) || defined(ENCRYPTION) */
	break;
    }
    freeaddrinfo(res0);
    if (net < 0 || connected == 0) {
	perror(cause);
	return 0;
    }

    cmdrc(hostp, hostname);
    if (autologin && user == NULL) {
	struct passwd *pw;

	user = getenv("USER");
	if (user == NULL ||
	    ((pw = getpwnam(user)) && pw->pw_uid != getuid())) {
		if ((pw = getpwuid(getuid())) != NULL)
			user = pw->pw_name;
		else
			user = NULL;
	}
    }
    if (user) {
	env_define((unsigned char *)"USER", (unsigned char *)user);
	env_export((unsigned char *)"USER", NULL);
    }
    (void) call(status, "status", "notmuch", 0);
    telnet(user); 
    (void) NetClose(net);
    ExitString("Connection closed by foreign host.\n",1);
    /*NOTREACHED*/
}

#define HELPINDENT ((int)sizeof ("connect"))

static char
	openhelp[] =	"connect to a site",
	closehelp[] =	"close current connection",
	logouthelp[] =	"forcibly logout remote user and close the connection",
	quithelp[] =	"exit telnet",
	statushelp[] =	"print status information",
	helphelp[] =	"print help information",
	sendhelp[] =	"transmit special characters ('send ?' for more)",
	sethelp[] = 	"set operating parameters ('set ?' for more)",
	unsethelp[] = 	"unset operating parameters ('unset ?' for more)",
	togglestring[] ="toggle operating parameters ('toggle ?' for more)",
	slchelp[] =	"change state of special characters ('slc ?' for more)",
	displayhelp[] =	"display operating parameters",
#ifdef TN3270
	transcomhelp[] = "specify Unix command for transparent mode pipe",
#endif	/* defined(TN3270) */
#ifdef AUTHENTICATION
	authhelp[] =	"turn on (off) authentication ('auth ?' for more)",
#endif
#ifdef	ENCRYPTION
	encrypthelp[] = "turn on (off) encryption ('encrypt ?' for more)",
#endif	/* ENCRYPTION */
	zhelp[] =	"suspend telnet",
	shellhelp[] =	"invoke a subshell",
	envhelp[] =	"change environment variables ('environ ?' for more)",
	modestring[] = "try to enter line or character mode ('mode ?' for more)";

static Command cmdtab[] = {
	{ "close",	closehelp,	bye,		1 },
	{ "logout",	logouthelp,	logout,		1 },
	{ "display",	displayhelp,	display,	0 },
	{ "mode",	modestring,	modecmd,	0 },
	{ "open",	openhelp,	tn,		0 },
	{ "quit",	quithelp,	quit,		0 },
	{ "send",	sendhelp,	sendcmd,	0 },
	{ "set",	sethelp,	setcmd,		0 },
	{ "unset",	unsethelp,	unsetcmd,	0 },
	{ "status",	statushelp,	status,		0 },
	{ "toggle",	togglestring,	toggle,		0 },
	{ "slc",	slchelp,	slccmd,		0 },
#ifdef TN3270
	{ "transcom",	transcomhelp,	settranscom,	0 },
#endif	/* defined(TN3270) */
#ifdef AUTHENTICATION
	{ "auth",	authhelp,	auth_cmd,	0 },
#endif
#ifdef	ENCRYPTION
	{ "encrypt",	encrypthelp,	encrypt_cmd,	0 },
#endif
	{ "z",		zhelp,		suspend,	0 },
#ifdef TN3270
	{ "!",		shellhelp,	shell,		1 },
#else
	{ "!",		shellhelp,	shell,		0 },
#endif
	{ "environ",	envhelp,	env_cmd,	0 },
	{ "?",		helphelp,	help,		0 },
	{ NULL,		NULL,		NULL,		0 }
};

static char	crmodhelp[] =	"deprecated command -- use 'toggle crmod' instead";
static char	escapehelp[] =	"deprecated command -- use 'set escape' instead";

static Command cmdtab2[] = {
	{ "help",	0,		help,		0 },
	{ "escape",	escapehelp,	setescape,	0 },
	{ "crmod",	crmodhelp,	togcrmod,	0 },
	{ NULL,		NULL,		NULL,		0 }
};


/*
 * Call routine with argc, argv set from args (terminated by 0).
 */

/*VARARGS1*/
static int
call(intrtn_t routine, ...)
{
    va_list ap;
    char *args[100];
    int argno = 0;

    va_start(ap, routine);
    while ((args[argno++] = va_arg(ap, char *)) != 0) {
	;
    }
    va_end(ap);
    return (*routine)(argno-1, args);
}


static Command *
getcmd(char *name)
{
    Command *cm;

    if ((cm = (Command *) genget(name, (char **) cmdtab, sizeof(Command))) != NULL)
	return cm;
    return (Command *) genget(name, (char **) cmdtab2, sizeof(Command));
}

void
command(int top, char *tbuf, int cnt)
{
    Command *c;

    setcommandmode();
    if (!top) {
	putchar('\n');
    } else {
	(void) signal(SIGINT, SIG_DFL);
	(void) signal(SIGQUIT, SIG_DFL);
    }
    for (;;) {
	if (rlogin == _POSIX_VDISABLE)
		printf("%s> ", prompt);
	if (tbuf) {
	    char *cp;
	    cp = line;
	    while (cnt > 0 && (*cp++ = *tbuf++) != '\n')
		cnt--;
	    tbuf = 0;
	    if (cp == line || *--cp != '\n' || cp == line)
		goto getline;
	    *cp = '\0';
	    if (rlogin == _POSIX_VDISABLE)
		printf("%s\n", line);
	} else {
	getline:
	    if (rlogin != _POSIX_VDISABLE)
		printf("%s> ", prompt);
#ifdef TN3270
	    fflush(stdout);
#endif
	    if (fgets(line, sizeof(line), stdin) == NULL) {
		if (feof(stdin) || ferror(stdin)) {
		    (void) quit(0, NULL);
		    /*NOTREACHED*/
		}
		break;
	    }
	}
	if (line[0] == 0)
	    break;
	makeargv();
	if (margv[0] == 0) {
	    break;
	}
	c = getcmd(margv[0]);
	if (Ambiguous(c)) {
	    printf("?Ambiguous command\n");
	    continue;
	}
	if (c == 0) {
	    printf("?Invalid command\n");
	    continue;
	}
	if (c->needconnect && !connected) {
	    printf("?Need to be connected first.\n");
	    continue;
	}
	if ((*c->handler)(margc, margv)) {
	    break;
	}
    }
    if (!top) {
	if (!connected) {
	    longjmp(toplevel, 1);
	    /*NOTREACHED*/
	}
#ifdef TN3270
	if (shell_active == 0) {
	    setconnmode(0);
	}
#else	/* defined(TN3270) */
	setconnmode(0);
#endif	/* defined(TN3270) */
    }
}

/*
 * Help command.
 */
static int
help(int argc, char *argv[])
{
	Command *c;

	if (argc == 1) {
		printf("Commands may be abbreviated.  Commands are:\n\n");
		for (c = cmdtab; c->name; c++)
			if (c->help) {
				printf("%-*s\t%s\n", HELPINDENT, c->name,
								    c->help);
			}
		return 0;
	}
	while (--argc > 0) {
		char *arg;
		arg = *++argv;
		c = getcmd(arg);
		if (Ambiguous(c))
			printf("?Ambiguous help command %s\n", arg);
		else if (c == (Command *)0)
			printf("?Invalid help command %s\n", arg);
		else
			printf("%s\n", c->help);
	}
	return 0;
}

static char *rcname = 0;
static char rcbuf[128];

void
cmdrc(const char *m1, const char *m2)
{
    Command *c;
    FILE *rcfile;
    int gotmachine = 0;
    int l1 = strlen(m1);
    int l2 = strlen(m2);
    char m1save[MAXHOSTNAMELEN + 1];

    if (skiprc)
	return;

    strlcpy(m1save, m1, sizeof(m1save));
    m1 = m1save;

    if (rcname == 0) {
	rcname = getenv("HOME");
	if (rcname)
	    strlcpy(rcbuf, rcname, sizeof(rcbuf));
	else
	    rcbuf[0] = '\0';
	strlcat(rcbuf, "/.telnetrc", sizeof(rcbuf));
	rcname = rcbuf;
    }

    if ((rcfile = fopen(rcname, "r")) == 0) {
	return;
    }

    for (;;) {
	if (fgets(line, sizeof(line), rcfile) == NULL)
	    break;
	if (line[0] == 0)
	    break;
	if (line[0] == '#')
	    continue;
	if (gotmachine) {
	    if (!isspace((unsigned char)line[0]))
		gotmachine = 0;
	}
	if (gotmachine == 0) {
	    if (isspace((unsigned char)line[0]))
		continue;
	    if (strncasecmp(line, m1, l1) == 0)
		strncpy(line, &line[l1], sizeof(line) - l1);
	    else if (strncasecmp(line, m2, l2) == 0)
		strncpy(line, &line[l2], sizeof(line) - l2);
	    else if (strncasecmp(line, "DEFAULT", 7) == 0)
		strncpy(line, &line[7], sizeof(line) - 7);
	    else
		continue;
	    if (line[0] != ' ' && line[0] != '\t' && line[0] != '\n')
		continue;
	    gotmachine = 1;
	}
	makeargv();
	if (margv[0] == 0)
	    continue;
	c = getcmd(margv[0]);
	if (Ambiguous(c)) {
	    printf("?Ambiguous command: %s\n", margv[0]);
	    continue;
	}
	if (c == 0) {
	    printf("?Invalid command: %s\n", margv[0]);
	    continue;
	}
	/*
	 * This should never happen...
	 */
	if (c->needconnect && !connected) {
	    printf("?Need to be connected first for %s.\n", margv[0]);
	    continue;
	}
	(*c->handler)(margc, margv);
    }
    fclose(rcfile);
}

/*
 * Source route is handed in as
 *	[!]@hop1@hop2...@dst
 *
 * If the leading ! is present, it is a strict source route, otherwise it is
 * assmed to be a loose source route.  Note that leading ! is effective
 * only for IPv4 case.
 *
 * We fill in the source route option as
 *	hop1,hop2,hop3...dest
 * and return a pointer to hop1, which will
 * be the address to connect() to.
 *
 * Arguments:
 *	ai:	The address (by struct addrinfo) for the final destination.
 *
 *	arg:	Pointer to route list to decipher
 *
 *	cpp: 	Pointer to a pointer, so that sourceroute() can return
 *		the address of result buffer (statically alloc'ed).
 *
 *	protop/optp:
 *		Pointer to an integer.  The pointed variable
 *	lenp:	pointer to an integer that contains the
 *		length of *cpp if *cpp != NULL.
 *
 * Return values:
 *
 *	Returns the length of the option pointed to by *cpp.  If the
 *	return value is -1, there was a syntax error in the
 *	option, either arg contained unknown characters or too many hosts,
 *	or hostname cannot be resolved.
 *
 *	The caller needs to pass return value (len), *cpp, *protop and *optp
 *	to setsockopt(2).
 *
 *	*cpp:	Points to the result buffer.  The region is statically
 *		allocated by the function.
 *
 *	*protop:
 *		protocol # to be passed to setsockopt(2).
 *
 *	*optp:	option # to be passed to setsockopt(2).
 *
 */
int
sourceroute(struct addrinfo *ai, char *arg, char **cpp, int *protop, int *optp)
{
	char *cp, *cp2, *lsrp, *lsrep;
	struct addrinfo hints, *res;
	int len, error;
	struct sockaddr_in *sin;
	char c;
	static char lsr[44];
#ifdef INET6
	struct cmsghdr *cmsg;
	struct sockaddr_in6 *sin6;
	static char rhbuf[1024];
#endif

	/*
	 * Verify the arguments.
	 */
	if (cpp == NULL)
		return -1;

	cp = arg;

	*cpp = NULL;

	  /* init these just in case.... */
	lsrp = NULL;
	lsrep = NULL;
#ifdef INET6
	cmsg = NULL;
#endif
	
	switch (ai->ai_family) {
	case AF_INET:
		lsrp = lsr;
		lsrep = lsrp + sizeof(lsr);

		/*
		 * Next, decide whether we have a loose source
		 * route or a strict source route, and fill in
		 * the begining of the option.
		 */
		if (*cp == '!') {
			cp++;
			*lsrp++ = IPOPT_SSRR;
		} else
			*lsrp++ = IPOPT_LSRR;
		if (*cp != '@')
			return -1;
		lsrp++;		/* skip over length, we'll fill it in later */
		*lsrp++ = 4;
		cp++;
		*protop = IPPROTO_IP;
		*optp = IP_OPTIONS;
		break;
#ifdef INET6
	case AF_INET6:
#ifdef IPV6_PKTOPTIONS
		/* RFC2292 */
		cmsg = inet6_rthdr_init(rhbuf, IPV6_RTHDR_TYPE_0);
		if (*cp != '@')
			return -1;
		cp++;
		*protop = IPPROTO_IPV6;
		*optp = IPV6_PKTOPTIONS;
		break;
#else
		/* no RFC2292 */
		return -1;
#endif
#endif
	default:
		return -1;
	}

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = ai->ai_family;
	hints.ai_socktype = SOCK_STREAM;

	for (c = 0;;) {
		if (c == ':')
			cp2 = 0;
		else for (cp2 = cp; (c = *cp2) != '\0'; cp2++) {
			if (c == ',') {
				*cp2++ = '\0';
				if (*cp2 == '@')
					cp2++;
			} else if (c == '@') {
				*cp2++ = '\0';
			}
#if 0	/*colon conflicts with IPv6 address*/
			else if (c == ':') {
				*cp2++ = '\0';
			}
#endif
			else
				continue;
			break;
		}
		if (!c)
			cp2 = 0;

		error = getaddrinfo(cp, NULL, &hints, &res);
		if (error) {
			fprintf(stderr, "%s: %s\n", cp, gai_strerror(error));
			return -1;
		}
		if (ai->ai_family != res->ai_family) {
			freeaddrinfo(res);
			return -1;
		}
		if (ai->ai_family == AF_INET) {
			/*
			 * Check to make sure there is space for address
			 */
			if (lsrp + 4 > lsrep) {
				freeaddrinfo(res);
				return -1;
			}
			sin = (struct sockaddr_in *)res->ai_addr;
			memcpy(lsrp, &sin->sin_addr, sizeof(struct in_addr));
			lsrp += sizeof(struct in_addr);
		}
#ifdef INET6
		else if (ai->ai_family == AF_INET6) {
			sin6 = (struct sockaddr_in6 *)res->ai_addr;
			inet6_rthdr_add(cmsg, &sin6->sin6_addr,
				IPV6_RTHDR_LOOSE);
		}
#endif
		else {
			freeaddrinfo(res);
			return -1;
		}
		freeaddrinfo(res);
		if (cp2)
			cp = cp2;
		else
			break;
	}
	switch (ai->ai_family) {
	case AF_INET:
		/* record the last hop */
		if (lsrp + 4 > lsrep)
			return -1;
		sin = (struct sockaddr_in *)ai->ai_addr;
		memcpy(lsrp, &sin->sin_addr, sizeof(struct in_addr));
		lsrp += sizeof(struct in_addr);
		lsr[IPOPT_OLEN] = lsrp - lsr;
		if (lsr[IPOPT_OLEN] <= 7 || lsr[IPOPT_OLEN] > 40)
			return -1;
		*lsrp++ = IPOPT_NOP;	/*32bit word align*/
		len = lsrp - lsr;
		*cpp = lsr;
		break;
#ifdef INET6
	case AF_INET6:
		inet6_rthdr_lasthop(cmsg, IPV6_RTHDR_LOOSE);
		len = cmsg->cmsg_len;
		*cpp = rhbuf;
		break;
#endif
	default:
		return -1;
	}
	return len;
}

File Added: pkgsrc/comms/tn3270/files/telnet/Attic/defines.h
/*	$NetBSD: defines.h,v 1.1.1.1 2010/01/17 01:33:29 dholland Exp $	*/
/*	From NetBSD: defines.h,v 1.8 2003/08/07 11:16:09 agc Exp 	*/

/*
 * 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. 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.
 *
 *	from: @(#)defines.h	8.1 (Berkeley) 6/6/93
 */

#define	settimer(x)	clocks.x = clocks.system++

#ifndef TN3270

#define	SetIn3270()

#endif	/* !defined(TN3270) */

#define	NETADD(c)	{ *netoring.supply = (c); ring_supplied(&netoring, 1); }
#define	NET2ADD(c1,c2)	{ NETADD((c1)); NETADD((c2)); }
#define	NETBYTES()	(ring_full_count(&netoring))
#define	NETROOM()	(ring_empty_count(&netoring))

#define	TTYADD(c)	if (!(SYNCHing||flushout)) { \
				*ttyoring.supply = c; \
				ring_supplied(&ttyoring, 1); \
			}
#define	TTYBYTES()	(ring_full_count(&ttyoring))
#define	TTYROOM()	(ring_empty_count(&ttyoring))

/*	Various modes */
#define	MODE_LOCAL_CHARS(m)	((m)&(MODE_EDIT|MODE_TRAPSIG))
#define	MODE_LOCAL_ECHO(m)	((m)&MODE_ECHO)
#define	MODE_COMMAND_LINE(m)	((m)==-1)

#define	CONTROL(x)	((x)&0x1f)		/* CTRL(x) is not portable */

File Added: pkgsrc/comms/tn3270/files/telnet/Attic/externs.h
/*	$NetBSD: externs.h,v 1.1.1.1 2010/01/17 01:33:29 dholland Exp $	*/
/*	From NetBSD: externs.h,v 1.34 2006/02/02 19:33:12 he Exp 	*/

/*
 * Copyright (c) 1988, 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. 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.
 *
 *	from: @(#)externs.h	8.3 (Berkeley) 5/30/95
 */

#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <sys/termios.h>

#include <string.h>

#if defined(IPSEC)
#include <netinet6/ipsec.h>
#if defined(IPSEC_POLICY_IPSEC)
extern char *ipsec_policy_in;
extern char *ipsec_policy_out;
#endif
#endif

#ifndef	_POSIX_VDISABLE
# ifdef sun
#  include <sys/param.h>	/* pick up VDISABLE definition, mayby */
# endif
# ifdef VDISABLE
#  define _POSIX_VDISABLE VDISABLE
# else
#  define _POSIX_VDISABLE ((cc_t)'\377')
# endif
#endif

#define	SUBBUFSIZE	256

#include <sys/cdefs.h>

extern int
    autologin,		/* Autologin enabled */
    skiprc,		/* Don't process the ~/.telnetrc file */
    eight,		/* use eight bit mode (binary in and/or out */
    family,		/* address family of peer */
    flushout,		/* flush output */
    connected,		/* Are we connected to the other side? */
    globalmode,		/* Mode tty should be in */
    In3270,		/* Are we in 3270 mode? */
    telnetport,		/* Are we connected to the telnet port? */
    localflow,		/* Flow control handled locally */
    restartany,		/* If flow control, restart output on any character */
    localchars,		/* we recognize interrupt/quit */
    donelclchars,	/* the user has set "localchars" */
    showoptions,
    net,		/* Network file descriptor */
    tin,		/* Terminal input file descriptor */
    tout,		/* Terminal output file descriptor */
    crlf,		/* Should '\r' be mapped to <CR><LF> (or <CR><NUL>)? */
    autoflush,		/* flush output when interrupting? */
    autosynch,		/* send interrupt characters with SYNCH? */
    SYNCHing,		/* Is the stream in telnet SYNCH mode? */
    donebinarytoggle,	/* the user has put us in binary */
    dontlecho,		/* do we suppress local echoing right now? */
    crmod,
    netdata,		/* Print out network data flow */
    prettydump,		/* Print "netdata" output in user readable format */
#ifdef TN3270
    cursesdata,		/* Print out curses data flow */
    apitrace,		/* Trace API transactions */
#endif	/* defined(TN3270) */
    termdata,		/* Print out terminal data flow */
    telnet_debug,	/* Debug level */
    doaddrlookup,	/* do a reverse address lookup? */
    clienteof;		/* Client received EOF */

extern cc_t escape;	/* Escape to command mode */
extern cc_t rlogin;	/* Rlogin mode escape character */
#ifdef	KLUDGELINEMODE
extern cc_t echoc;	/* Toggle local echoing */
#endif

extern char
    *prompt;		/* Prompt for command. */

extern char
    doopt[],
    dont[],
    will[],
    wont[],
    options[],		/* All the little options */
    *hostname;		/* Who are we connected to? */

#ifdef	ENCRYPTION
extern void (*encrypt_output)(unsigned char *, int);
extern int (*decrypt_input)(int);
#endif	/* ENCRYPTION */

/*
 * We keep track of each side of the option negotiation.
 */

#define	MY_STATE_WILL		0x01
#define	MY_WANT_STATE_WILL	0x02
#define	MY_STATE_DO		0x04
#define	MY_WANT_STATE_DO	0x08

/*
 * Macros to check the current state of things
 */

#define	my_state_is_do(opt)		(options[opt]&MY_STATE_DO)
#define	my_state_is_will(opt)		(options[opt]&MY_STATE_WILL)
#define my_want_state_is_do(opt)	(options[opt]&MY_WANT_STATE_DO)
#define my_want_state_is_will(opt)	(options[opt]&MY_WANT_STATE_WILL)

#define	my_state_is_dont(opt)		(!my_state_is_do(opt))
#define	my_state_is_wont(opt)		(!my_state_is_will(opt))
#define my_want_state_is_dont(opt)	(!my_want_state_is_do(opt))
#define my_want_state_is_wont(opt)	(!my_want_state_is_will(opt))

#define	set_my_state_do(opt)		{options[opt] |= MY_STATE_DO;}
#define	set_my_state_will(opt)		{options[opt] |= MY_STATE_WILL;}
#define	set_my_want_state_do(opt)	{options[opt] |= MY_WANT_STATE_DO;}
#define	set_my_want_state_will(opt)	{options[opt] |= MY_WANT_STATE_WILL;}

#define	set_my_state_dont(opt)		{options[opt] &= ~MY_STATE_DO;}
#define	set_my_state_wont(opt)		{options[opt] &= ~MY_STATE_WILL;}
#define	set_my_want_state_dont(opt)	{options[opt] &= ~MY_WANT_STATE_DO;}
#define	set_my_want_state_wont(opt)	{options[opt] &= ~MY_WANT_STATE_WILL;}

/*
 * Make everything symmetrical
 */

#define	HIS_STATE_WILL			MY_STATE_DO
#define	HIS_WANT_STATE_WILL		MY_WANT_STATE_DO
#define HIS_STATE_DO			MY_STATE_WILL
#define HIS_WANT_STATE_DO		MY_WANT_STATE_WILL

#define	his_state_is_do			my_state_is_will
#define	his_state_is_will		my_state_is_do
#define his_want_state_is_do		my_want_state_is_will
#define his_want_state_is_will		my_want_state_is_do

#define	his_state_is_dont		my_state_is_wont
#define	his_state_is_wont		my_state_is_dont
#define his_want_state_is_dont		my_want_state_is_wont
#define his_want_state_is_wont		my_want_state_is_dont

#define	set_his_state_do		set_my_state_will
#define	set_his_state_will		set_my_state_do
#define	set_his_want_state_do		set_my_want_state_will
#define	set_his_want_state_will		set_my_want_state_do

#define	set_his_state_dont		set_my_state_wont
#define	set_his_state_wont		set_my_state_dont
#define	set_his_want_state_dont		set_my_want_state_wont
#define	set_his_want_state_wont		set_my_want_state_dont


extern FILE
    *NetTrace;		/* Where debugging output goes */
extern char
    NetTraceFile[];	/* Name of file where debugging output goes */

extern jmp_buf
    toplevel;		/* For error conditions. */


/* authenc.c */
int telnet_net_write(unsigned char *, int);
void net_encrypt(void);
int telnet_spin(void);
char *telnet_getenv(char *);
char *telnet_gets(char *, char *, int, int);

/* commands.c */
int send_tncmd(void (*)(int, int), char *, char *);
void _setlist_init(void);
void set_escape_char(char *);
int set_mode(int);
int clear_mode(int);
int modehelp(int);
int suspend(int, char *[]);
int shell(int, char *[]);
int quit(int, char *[]);
int logout(int, char *[]);
int env_cmd(int, char *[]);
struct env_lst *env_find(unsigned char *);
void env_init(void);
struct env_lst *env_define(unsigned char *, unsigned char *);
struct env_lst *env_undefine(unsigned char *, unsigned char *);
struct env_lst *env_export(unsigned char *, unsigned char *);
struct env_lst *env_unexport(unsigned char *, unsigned char *);
struct env_lst *env_send(unsigned char *, unsigned char *);
struct env_lst *env_list(unsigned char *, unsigned char *);
unsigned char *env_default(int, int );
unsigned char *env_getvalue(unsigned char *);
void env_varval(unsigned char *);
int auth_cmd(int, char *[]);
int ayt_status(void);
int encrypt_cmd(int, char *[]);
int tn(int, char *[]);
void command(int, char *, int);
void cmdrc(const char *, const char *);
struct addrinfo;
int sourceroute(struct addrinfo *, char *, char **, int *, int*);

/* main.c */
void tninit(void);
void usage(void);

/* network.c */
void init_network(void);
int stilloob(void);
void setneturg(void);
int netflush(void);

/* sys_bsd.c */
void init_sys(void);
int TerminalWrite(char *, int);
int TerminalRead(unsigned char *, int);
int TerminalAutoFlush(void);
int TerminalSpecialChars(int);
void TerminalFlushOutput(void);
void TerminalSaveState(void);
cc_t *tcval(int);
void TerminalDefaultChars(void);
void TerminalRestoreState(void);
void TerminalNewMode(int);
void TerminalSpeeds(long *, long *);
int TerminalWindowSize(long *, long *);
int NetClose(int);
void NetNonblockingIO(int, int);
void NetSigIO(int, int);
void NetSetPgrp(int);
void sys_telnet_init(void);
int process_rings(int , int , int , int , int , int);

/* telnet.c */
void init_telnet(void);
void send_do(int, int );
void send_dont(int, int );
void send_will(int, int );
void send_wont(int, int );
void willoption(int);
void wontoption(int);
char **mklist(char *, char *);
int is_unique(char *, char **, char **);
int setup_term(char *, int, int *);
char *gettermname(void);
void lm_will(unsigned char *, int);
void lm_wont(unsigned char *, int);
void lm_do(unsigned char *, int);
void lm_dont(unsigned char *, int);
void lm_mode(unsigned char *, int, int );
void slc_init(void);
void slcstate(void);
void slc_mode_export(int);
void slc_mode_import(int);
void slc_import(int);
void slc_export(void);
void slc(unsigned char *, int);
void slc_check(void);
void slc_start_reply(void);
void slc_add_reply(unsigned int, unsigned int, cc_t);
void slc_end_reply(void);
int slc_update(void);
void env_opt(unsigned char *, int);
void env_opt_start(void);
void env_opt_start_info(void);
void env_opt_add(unsigned char *);
int opt_welldefined(char *);
void env_opt_end(int);
int telrcv(void);
int rlogin_susp(void);
int Scheduler(int);
void telnet(const char *);
void xmitAO(void);
void xmitEL(void);
void xmitEC(void);
int dosynch(char *);
int get_status(char *);
void intp(void);
void sendbrk(void);
void sendabort(void);
void sendsusp(void);
void sendeof(void);
void sendayt(void);
void sendnaws(void);
void tel_enter_binary(int);
void tel_leave_binary(int);

/* terminal.c */
void init_terminal(void);
int ttyflush(int);
int getconnmode(void);
void setconnmode(int);
void setcommandmode(void);

/* utilities.c */
void upcase(char *);
int SetSockOpt(int, int, int, int);
void SetNetTrace(char *);
void Dump(int, unsigned char *, int);
void printoption(char *, int, int );
void optionstatus(void);
void printsub(int, unsigned char *, int);
void EmptyTerminal(void);
void SetForExit(void);
void Exit(int) __attribute__((__noreturn__));
void ExitString(char *, int) __attribute__((__noreturn__));


extern struct	termios new_tc;

# define termEofChar		new_tc.c_cc[VEOF]
# define termEraseChar		new_tc.c_cc[VERASE]
# define termIntChar		new_tc.c_cc[VINTR]
# define termKillChar		new_tc.c_cc[VKILL]
# define termQuitChar		new_tc.c_cc[VQUIT]

#  define termSuspChar		new_tc.c_cc[VSUSP]
#  define termFlushChar		new_tc.c_cc[VDISCARD]
#  define termWerasChar		new_tc.c_cc[VWERASE]
#  define termRprntChar		new_tc.c_cc[VREPRINT]
#  define termLiteralNextChar	new_tc.c_cc[VLNEXT]
#  define termStartChar		new_tc.c_cc[VSTART]
#  define termStopChar		new_tc.c_cc[VSTOP]
#  define termForw1Char		new_tc.c_cc[VEOL]
#  define termForw2Char		new_tc.c_cc[VEOL]
#  define termAytChar		new_tc.c_cc[VSTATUS]

# define termEofCharp		&termEofChar
# define termEraseCharp		&termEraseChar
# define termIntCharp		&termIntChar
# define termKillCharp		&termKillChar
# define termQuitCharp		&termQuitChar
# define termSuspCharp		&termSuspChar
# define termFlushCharp		&termFlushChar
# define termWerasCharp		&termWerasChar
# define termRprntCharp		&termRprntChar
# define termLiteralNextCharp	&termLiteralNextChar
# define termStartCharp		&termStartChar
# define termStopCharp		&termStopChar
# define termForw1Charp		&termForw1Char
# define termForw2Charp		&termForw2Char
# define termAytCharp		&termAytChar


/* Tn3270 section */
#if	defined(TN3270)

extern int
    HaveInput,		/* Whether an asynchronous I/O indication came in */
    noasynchtty,	/* Don't do signals on I/O (SIGURG, SIGIO) */
    noasynchnet,	/* Don't do signals on I/O (SIGURG, SIGIO) */
    sigiocount,		/* Count of SIGIO receptions */
    shell_active;	/* Subshell is active */

extern char
    *Ibackp,		/* Oldest byte of 3270 data */
    Ibuf[],		/* 3270 buffer */
    *Ifrontp,		/* Where next 3270 byte goes */
    tline[200],
    *transcom;		/* Transparent command */

/* tn3270.c */
void init_3270(void);
int DataToNetwork(char *, int, int);
void inputAvailable(int);
void outputPurge(void);
int DataToTerminal(char *, int);
int Push3270(void);
void Finish3270(void);
void StringToTerminal(char *);
int _putchar(int);
void SetIn3270(void);
int tn3270_ttype(void);
int settranscom(int, char *[]);
int shell_continue(void);
int DataFromTerminal(char *, int);
int DataFromNetwork(char *, int, int);
void ConnectScreen(void);
int DoTerminalOutput(void);

#endif	/* defined(TN3270) */

File Added: pkgsrc/comms/tn3270/files/telnet/Attic/general.h
/*	$NetBSD: general.h,v 1.1.1.1 2010/01/17 01:33:29 dholland Exp $	*/
/*	From NetBSD: general.h,v 1.6 2003/08/07 11:16:09 agc Exp 	*/

/*
 * 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. 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.
 *
 *	from: @(#)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)

#define	ClearElement(x)		memset((char *)&x, 0, sizeof x)
#define	ClearArray(x)		memset((char *)x, 0, sizeof x)

File Added: pkgsrc/comms/tn3270/files/telnet/Attic/main.c
/*	$NetBSD: main.c,v 1.1.1.1 2010/01/17 01:33:29 dholland Exp $	*/
/*	From NetBSD: main.c,v 1.27 2008/07/21 14:19:26 lukem Exp 	*/

/*
 * Copyright (c) 1988, 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. 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.
 */

#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1988, 1990, 1993\
 The Regents of the University of California.  All rights reserved.");
#endif /* not lint */

#ifndef lint
#if 0
static char sccsid[] = "@(#)main.c	8.3 (Berkeley) 5/30/95";
#else
__RCSID("$NetBSD: main.c,v 1.1.1.1 2010/01/17 01:33:29 dholland Exp $");
#endif
#endif /* not lint */

#include <sys/types.h>
#include <sys/socket.h>

#include <unistd.h>

#include "ring.h"
#include "externs.h"
#include "defines.h"
#ifdef AUTHENTICATION
#include <libtelnet/auth.h>
#endif
#ifdef ENCRYPTION
#include <libtelnet/encrypt.h>
#endif

/* These values need to be the same as defined in libtelnet/kerberos5.c */
/* Either define them in both places, or put in some common header file. */
#define OPTS_FORWARD_CREDS	0x00000002
#define OPTS_FORWARDABLE_CREDS	0x00000001

#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
char *ipsec_policy_in = NULL;
char *ipsec_policy_out = NULL;
#endif

int family = AF_UNSPEC;

int main(int, char *[]);

/*
 * Initialize variables.
 */
void
tninit(void)
{
    init_terminal();

    init_network();

    init_telnet();

    init_sys();

#ifdef TN3270
    init_3270();
#endif
}

	void
usage()
{
	fprintf(stderr, "usage: %s %s%s%s%s\n",
	    prompt,
#ifdef	AUTHENTICATION
	    "[-4] [-6] [-8] [-E] [-K] [-L] [-N] [-S tos] [-X atype] [-a] [-c]",
	    "\n\t[-d] [-e char] [-k realm] [-l user] [-f/-F] [-n tracefile] ",
#else
	    "[-4] [-6] [-8] [-E] [-L] [-N] [-S tos] [-a] [-c] [-d] [-e char]",
	    "\n\t[-l user] [-n tracefile] ",
#endif
#ifdef TN3270
# ifdef AUTHENTICATION
	    "[-noasynch] [-noasynctty]\n\t[-noasyncnet] [-r] [-t transcom] ",
# else
	    "[-noasynch] [-noasynctty] [-noasyncnet] [-r]\n\t[-t transcom]",
# endif
#else
	    "[-r] ",
#endif
#ifdef	ENCRYPTION
	    "[-x] "
#endif
#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
	    "\n\t[-P policy] [host-name [port]]"
#else
	    "\n\t[host-name [port]]"
#endif
	);
	exit(1);
}

/*
 * main.  Parse arguments, invoke the protocol or command parser.
 */


int
main(int argc, char *argv[])
{
	extern char *optarg;
	extern int optind;
	int ch;
	char *user;
#ifdef	FORWARD
	extern int forward_flags;
#endif	/* FORWARD */

	tninit();		/* Clear out things */

	TerminalSaveState();

	if ((prompt = strrchr(argv[0], '/')) != NULL)
		++prompt;
	else
		prompt = argv[0];

	user = NULL;

	rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
	autologin = -1;

#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
#define IPSECOPT	"P:"
#else
#define IPSECOPT
#endif
	while ((ch = getopt(argc, argv, "468EKLNS:X:acde:fFk:l:n:rt:x"
			IPSECOPT)) != -1) {
#undef IPSECOPT
		switch(ch) {
		case '4':
			family = AF_INET;
			break;
		case '6':
			family = AF_INET6;
			break;
		case '8':
			eight = 3;	/* binary output and input */
			break;
		case 'E':
			rlogin = escape = _POSIX_VDISABLE;
			break;
		case 'K':
#ifdef	AUTHENTICATION
			autologin = 0;
#endif
			break;
		case 'L':
			eight |= 2;	/* binary output only */
			break;
		case 'N':
			doaddrlookup = 0;
			break;
		case 'S':
		    {
			fprintf(stderr,
			   "%s: Warning: -S ignored, no parsetos() support.\n",
								prompt);
		    }
			break;
		case 'X':
#ifdef	AUTHENTICATION
			auth_disable_name(optarg);
#endif
			break;
		case 'a':
			autologin = 1;
			break;
		case 'c':
			skiprc = 1;
			break;
		case 'd':
			telnet_debug = 1;
			break;
		case 'e':
			set_escape_char(optarg);
			break;
		case 'f':
#if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
			if (forward_flags & OPTS_FORWARD_CREDS) {
			    fprintf(stderr,
				    "%s: Only one of -f and -F allowed.\n",
				    prompt);
			    usage();
			}
			forward_flags |= OPTS_FORWARD_CREDS;
#else
			fprintf(stderr,
			 "%s: Warning: -f ignored, no Kerberos V5 support.\n",
				prompt);
#endif
			break;
		case 'F':
#if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
			if (forward_flags & OPTS_FORWARD_CREDS) {
			    fprintf(stderr,
				    "%s: Only one of -f and -F allowed.\n",
				    prompt);
			    usage();
			}
			forward_flags |= OPTS_FORWARD_CREDS;
			forward_flags |= OPTS_FORWARDABLE_CREDS;
#else
			fprintf(stderr,
			 "%s: Warning: -F ignored, no Kerberos V5 support.\n",
				prompt);
#endif
			break;
		case 'k':
			fprintf(stderr,
			   "%s: Warning: -k ignored, no Kerberos V4 support.\n",
								prompt);
			break;
		case 'l':
			if(autologin == 0) {
				autologin = -1;
			}
			user = optarg;
			break;
		case 'n':
#ifdef TN3270
			/* distinguish between "-n oasynch" and "-noasynch" */
			if (argv[optind - 1][0] == '-' && argv[optind - 1][1]
			    == 'n' && argv[optind - 1][2] == 'o') {
				if (!strcmp(optarg, "oasynch")) {
					noasynchtty = 1;
					noasynchnet = 1;
				} else if (!strcmp(optarg, "oasynchtty"))
					noasynchtty = 1;
				else if (!strcmp(optarg, "oasynchnet"))
					noasynchnet = 1;
			} else
#endif	/* defined(TN3270) */
				SetNetTrace(optarg);
			break;
		case 'r':
			rlogin = '~';
			break;
		case 't':
#ifdef TN3270
			(void)strlcpy(tline, optarg, sizeof(tline));
			transcom = tline;
#else
			fprintf(stderr,
			   "%s: Warning: -t ignored, no TN3270 support.\n",
								prompt);
#endif
			break;
		case 'x':
#ifdef	ENCRYPTION
			encrypt_auto(1);
			decrypt_auto(1);
#else	/* ENCRYPTION */
			fprintf(stderr,
			    "%s: Warning: -x ignored, no ENCRYPT support.\n",
								prompt);
#endif	/* ENCRYPTION */
			break;
#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
		case 'P':
			if (!strncmp("in", optarg, 2))
				ipsec_policy_in = strdup(optarg);
			else if (!strncmp("out", optarg, 3)) 
				ipsec_policy_out = strdup(optarg);
			else
				usage();
			break;
#endif
		case '?':
		default:
			usage();
			/* NOTREACHED */
		}
	}

	if (autologin == -1) {		/* esc@magic.fi; force  */
#if defined(AUTHENTICATION)
		autologin = 1;
#endif
#if defined(ENCRYPTION)
		encrypt_auto(1);
		decrypt_auto(1);
#endif
	}

	if (autologin == -1)
		autologin = (rlogin == _POSIX_VDISABLE) ? 0 : 1;

	argc -= optind;
	argv += optind;

	if (argc) {
		char *args[7];
		char ** volatile argp;	/* avoid longjmp clobbering */

		argp = args;
		if (argc > 2)
			usage();
		*argp++ = prompt;
		if (user) {
			*argp++ = "-l";
			*argp++ = user;
		}
		*argp++ = argv[0];		/* host */
		if (argc > 1)
			*argp++ = argv[1];	/* port */
		*argp = 0;

		if (setjmp(toplevel) != 0)
			Exit(0);
		if (tn(argp - args, args) == 1)
			return (0);
		else
			return (1);
	}
	(void)setjmp(toplevel);
	for (;;) {
#ifdef TN3270
		if (shell_active)
			shell_continue();
		else
#endif
			command(1, 0, 0);
	}
}

File Added: pkgsrc/comms/tn3270/files/telnet/Attic/network.c
/*	$NetBSD: network.c,v 1.1.1.1 2010/01/17 01:33:29 dholland Exp $	*/
/*	From NetBSD: network.c,v 1.17 2004/03/20 23:26:05 heas Exp 	*/

/*
 * 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. 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.
 */

#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)network.c	8.2 (Berkeley) 12/15/93";
#else
__RCSID("$NetBSD: network.c,v 1.1.1.1 2010/01/17 01:33:29 dholland Exp $");
#endif
#endif /* not lint */

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>

#include <errno.h>
#include <unistd.h>
#include <poll.h>

#include <arpa/telnet.h>

#include "ring.h"
#include "defines.h"
#include "externs.h"

Ring		netoring, netiring;
unsigned char	netobuf[2*BUFSIZ], netibuf[BUFSIZ];

/*
 * Initialize internal network data structures.
 */

void
init_network(void)
{
    if (ring_init(&netoring, netobuf, sizeof netobuf) != 1) {
	exit(1);
    }
    if (ring_init(&netiring, netibuf, sizeof netibuf) != 1) {
	exit(1);
    }
    NetTrace = stdout;
}


/*
 * Check to see if any out-of-band data exists on a socket (for
 * Telnet "synch" processing).
 */

int
stilloob(void)
{
    struct pollfd set[1];
    int value;

    set[0].fd = net;
    set[0].events = POLLPRI;
    do {
	value = poll(set, 1, 0);
    } while ((value == -1) && (errno == EINTR));

    if (value < 0) {
	perror("poll");
	(void) quit(0, NULL);
	/* NOTREACHED */
    }
    if (set[0].revents & POLLPRI) {
	return 1;
    } else {
	return 0;
    }
}


/*
 *  setneturg()
 *
 *	Sets "neturg" to the current location.
 */

void
setneturg(void)
{
    ring_mark(&netoring);
}


/*
 *  netflush
 *		Send as much data as possible to the network,
 *	handling requests for urgent data.
 *
 *		The return value indicates whether we did any
 *	useful work.
 */


int
netflush(void)
{
    int n, n1;

#ifdef	ENCRYPTION
    if (encrypt_output)
	ring_encrypt(&netoring, encrypt_output);
#endif	/* ENCRYPTION */
    if ((n1 = n = ring_full_consecutive(&netoring)) > 0) {
	if (!ring_at_mark(&netoring)) {
	    n = send(net, (char *)netoring.consume, n, 0); /* normal write */
	} else {
	    /*
	     * In 4.2 (and 4.3) systems, there is some question about
	     * what byte in a sendOOB operation is the "OOB" data.
	     * To make ourselves compatible, we only send ONE byte
	     * out of band, the one WE THINK should be OOB (though
	     * we really have more the TCP philosophy of urgent data
	     * rather than the Unix philosophy of OOB data).
	     */
	    n = send(net, (char *)netoring.consume, 1, MSG_OOB);/* URGENT data */
	}
    }
    if (n < 0) {
	if (errno != ENOBUFS && errno != EWOULDBLOCK) {
	    setcommandmode();
	    perror(hostname);
	    (void)NetClose(net);
	    ring_clear_mark(&netoring);
	    ExitString("Connection closed by foreign host.\n", 1);
	    /*NOTREACHED*/
	}
	n = 0;
    }
    if (netdata && n) {
	Dump('>', netoring.consume, n);
    }
    if (n) {
	ring_consumed(&netoring, n);
	/*
	 * If we sent all, and more to send, then recurse to pick
	 * up the other half.
	 */
	if ((n1 == n) && ring_full_consecutive(&netoring)) {
	    (void) netflush();
	}
	return 1;
    } else {
	return 0;
    }
}

File Added: pkgsrc/comms/tn3270/files/telnet/Attic/ring.c
/*	$NetBSD: ring.c,v 1.1.1.1 2010/01/17 01:33:30 dholland Exp $	*/
/*	From NetBSD: ring.c,v 1.13 2003/08/07 11:16:10 agc Exp 	*/

/*
 * 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. 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.
 */

#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)ring.c	8.2 (Berkeley) 5/30/95";
#else
__RCSID("$NetBSD: ring.c,v 1.1.1.1 2010/01/17 01:33:30 dholland Exp $");
#endif
#endif /* not lint */

/*
 * This defines a structure for a ring buffer.
 *
 * The circular buffer has two parts:
 *(((
 *	full:	[consume, supply)
 *	empty:	[supply, consume)
 *]]]
 *
 */

#include	<stdio.h>
#include	<string.h>
#include	<strings.h>
#include	<errno.h>
#include	<sys/types.h>
#include	<sys/ioctl.h>
#include	<sys/socket.h>

#include	"ring.h"
#include	"general.h"

/* Internal macros */

#if	!defined(MIN)
#define	MIN(a,b)	(((a)<(b))? (a):(b))
#endif	/* !defined(MIN) */

#define	ring_subtract(d,a,b)	(((a)-(b) >= 0)? \
					(a)-(b): (((a)-(b))+(d)->size))

#define	ring_increment(d,a,c)	(((a)+(c) < (d)->top)? \
					(a)+(c) : (((a)+(c))-(d)->size))

#define	ring_decrement(d,a,c)	(((a)-(c) >= (d)->bottom)? \
					(a)-(c) : (((a)-(c))-(d)->size))


/*
 * The following is a clock, used to determine full, empty, etc.
 *
 * There is some trickiness here.  Since the ring buffers are initialized
 * to ZERO on allocation, we need to make sure, when interpreting the
 * clock, that when the times are EQUAL, then the buffer is FULL.
 */
static u_long ring_clock = 0;


#define	ring_empty(d) (((d)->consume == (d)->supply) && \
				((d)->consumetime >= (d)->supplytime))
#define	ring_full(d) (((d)->supply == (d)->consume) && \
				((d)->supplytime > (d)->consumetime))





/* Buffer state transition routines */

int
ring_init(Ring *ring, unsigned char *buffer, int count)
{
    memset((char *)ring, 0, sizeof *ring);

    ring->size = count;

    ring->supply = ring->consume = ring->bottom = buffer;

    ring->top = ring->bottom+ring->size;

#ifdef	ENCRYPTION
    ring->clearto = 0;
#endif	/* ENCRYPTION */

    return 1;
}

/* Mark routines */

/*
 * Mark the most recently supplied byte.
 */

void
ring_mark(Ring *ring)
{
    ring->mark = ring_decrement(ring, ring->supply, 1);
}

/*
 * Is the ring pointing to the mark?
 */

int
ring_at_mark(Ring *ring)
{
    if (ring->mark == ring->consume) {
	return 1;
    } else {
	return 0;
    }
}

/*
 * Clear any mark set on the ring.
 */

void
ring_clear_mark(Ring *ring)
{
    ring->mark = 0;
}

/*
 * Add characters from current segment to ring buffer.
 */
void
ring_supplied(Ring *ring, int count)
{
    ring->supply = ring_increment(ring, ring->supply, count);
    ring->supplytime = ++ring_clock;
}

/*
 * We have just consumed "c" bytes.
 */
void
ring_consumed(Ring *ring, int count)
{
    if (count == 0)	/* don't update anything */
	return;

    if (ring->mark &&
		(ring_subtract(ring, ring->mark, ring->consume) < count)) {
	ring->mark = 0;
    }
#ifdef	ENCRYPTION
    if (ring->consume < ring->clearto &&
		ring->clearto <= ring->consume + count)
	ring->clearto = 0;
    else if (ring->consume + count > ring->top &&
		ring->bottom <= ring->clearto &&
		ring->bottom + ((ring->consume + count) - ring->top))
	ring->clearto = 0;
#endif	/* ENCRYPTION */
    ring->consume = ring_increment(ring, ring->consume, count);
    ring->consumetime = ++ring_clock;
    /*
     * Try to encourage "ring_empty_consecutive()" to be large.
     */
    if (ring_empty(ring)) {
	ring->consume = ring->supply = ring->bottom;
    }
}



/* Buffer state query routines */


/* Number of bytes that may be supplied */
int
ring_empty_count(Ring *ring)
{
    if (ring_empty(ring)) {	/* if empty */
	    return ring->size;
    } else {
	return ring_subtract(ring, ring->consume, ring->supply);
    }
}

/* number of CONSECUTIVE bytes that may be supplied */
int
ring_empty_consecutive(Ring *ring)
{
    if ((ring->consume < ring->supply) || ring_empty(ring)) {
			    /*
			     * if consume is "below" supply, or empty, then
			     * return distance to the top
			     */
	return ring_subtract(ring, ring->top, ring->supply);
    } else {
				    /*
				     * else, return what we may.
				     */
	return ring_subtract(ring, ring->consume, ring->supply);
    }
}

/* Return the number of bytes that are available for consuming
 * (but don't give more than enough to get to cross over set mark)
 */

int
ring_full_count(Ring *ring)
{
    if ((ring->mark == 0) || (ring->mark == ring->consume)) {
	if (ring_full(ring)) {
	    return ring->size;	/* nothing consumed, but full */
	} else {
	    return ring_subtract(ring, ring->supply, ring->consume);
	}
    } else {
	return ring_subtract(ring, ring->mark, ring->consume);
    }
}

/*
 * Return the number of CONSECUTIVE bytes available for consuming.
 * However, don't return more than enough to cross over set mark.
 */
int
ring_full_consecutive(Ring *ring)
{
    if ((ring->mark == 0) || (ring->mark == ring->consume)) {
	if ((ring->supply < ring->consume) || ring_full(ring)) {
	    return ring_subtract(ring, ring->top, ring->consume);
	} else {
	    return ring_subtract(ring, ring->supply, ring->consume);
	}
    } else {
	if (ring->mark < ring->consume) {
	    return ring_subtract(ring, ring->top, ring->consume);
	} else {	/* Else, distance to mark */
	    return ring_subtract(ring, ring->mark, ring->consume);
	}
    }
}

/*
 * Move data into the "supply" portion of of the ring buffer.
 */
void
ring_supply_data(Ring *ring, unsigned char *buffer, int count)
{
    int i;

    while (count) {
	i = MIN(count, ring_empty_consecutive(ring));
	memmove(ring->supply, buffer, i);
	ring_supplied(ring, i);
	count -= i;
	buffer += i;
    }
}

#ifdef notdef

/*
 * Move data from the "consume" portion of the ring buffer
 */
void
ring_consume_data(Ring *ring, unsigned char *buffer, int count)
{
    int i;

    while (count) {
	i = MIN(count, ring_full_consecutive(ring));
	memmove(buffer, ring->consume, i);
	ring_consumed(ring, i);
	count -= i;
	buffer += i;
    }
}
#endif

#ifdef	ENCRYPTION
void
ring_encrypt(Ring *ring, void (*encryptor)(unsigned char *, int))
{
	unsigned char *s, *c;

	if (ring_empty(ring) || ring->clearto == ring->supply)
		return;

	if (!(c = ring->clearto))
		c = ring->consume;

	s = ring->supply;

	if (s <= c) {
		(*encryptor)(c, ring->top - c);
		(*encryptor)(ring->bottom, s - ring->bottom);
	} else
		(*encryptor)(c, s - c);

	ring->clearto = ring->supply;
}

void
ring_clearto(Ring *ring)
{

	if (!ring_empty(ring))
		ring->clearto = ring->supply;
	else
		ring->clearto = 0;
}
#endif	/* ENCRYPTION */

File Added: pkgsrc/comms/tn3270/files/telnet/Attic/ring.h
/*	$NetBSD: ring.h,v 1.1.1.1 2010/01/17 01:33:30 dholland Exp $	*/
/*	From NetBSD: ring.h,v 1.10 2003/08/07 11:16:10 agc Exp 	*/

/*
 * 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. 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.
 *
 *	from: @(#)ring.h	8.1 (Berkeley) 6/6/93
 */

#include <sys/cdefs.h>

/*
 * This defines a structure for a ring buffer.
 *
 * The circular buffer has two parts:
 *(((
 *	full:	[consume, supply)
 *	empty:	[supply, consume)
 *]]]
 *
 */
typedef struct {
    unsigned char	*consume,	/* where data comes out of */
			*supply,	/* where data comes in to */
			*bottom,	/* lowest address in buffer */
			*top,		/* highest address+1 in buffer */
			*mark;		/* marker (user defined) */
#ifdef	ENCRYPTION
    unsigned char	*clearto;	/* Data to this point is clear text */
    unsigned char	*encryyptedto;	/* Data is encrypted to here */
#endif	/* ENCRYPTION */
    int		size;		/* size in bytes of buffer */
    u_long	consumetime,	/* help us keep straight full, empty, etc. */
		supplytime;
} Ring;

/* Ring buffer structures which are shared */

extern Ring
    netoring,
    netiring,
    ttyoring,
    ttyiring;

/* Here are some functions and macros to deal with the ring buffer */

/* Initialization routine */
extern int
	ring_init(Ring *ring, unsigned char *buffer, int count);

/* Data movement routines */
extern void
	ring_supply_data(Ring *ring, unsigned char *buffer, int count);
#ifdef notdef
extern void
	ring_consume_data(Ring *ring, unsigned char *buffer, int count);
#endif

/* Buffer state transition routines */
extern void
	ring_supplied(Ring *ring, int count),
	ring_consumed(Ring *ring, int count);

/* Buffer state query routines */
extern int
	ring_empty_count(Ring *ring),
	ring_empty_consecutive(Ring *ring),
	ring_full_count(Ring *ring),
	ring_full_consecutive(Ring *ring),
	ring_at_mark(Ring *ring);

#ifdef	ENCRYPTION
extern void
	ring_encrypt(Ring *ring, void (*func)(unsigned char *, int)),
	ring_clearto(Ring *ring);
#endif	/* ENCRYPTION */

extern void
	ring_clear_mark(Ring *ring),
	ring_mark(Ring *ring);

File Added: pkgsrc/comms/tn3270/files/telnet/Attic/sys_bsd.c
/*	$NetBSD: sys_bsd.c,v 1.1.1.1 2010/01/17 01:33:30 dholland Exp $	*/
/*	From NetBSD: sys_bsd.c,v 1.32 2004/11/10 20:26:43 christos Exp 	*/

/*
 * Copyright (c) 1988, 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. 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.
 */

#include <sys/cdefs.h>
#ifndef lint
#if 0
from: static char sccsid[] = "@(#)sys_bsd.c	8.4 (Berkeley) 5/30/95";
#else
__RCSID("$NetBSD: sys_bsd.c,v 1.1.1.1 2010/01/17 01:33:30 dholland Exp $");
#endif
#endif /* not lint */

/*
 * The following routines try to encapsulate what is system dependent
 * (at least between 4.x and dos) which is used in telnet.c.
 */


#include <fcntl.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <poll.h>
#include <arpa/telnet.h>

#include "ring.h"
#include "defines.h"
#include "externs.h"
#include "types.h"

#define	SIG_FUNC_RET	void

SIG_FUNC_RET susp(int);
SIG_FUNC_RET ayt(int);

SIG_FUNC_RET intr(int);
SIG_FUNC_RET intr2(int);
SIG_FUNC_RET sendwin(int);


int
	tout,			/* Output file descriptor */
	tin,			/* Input file descriptor */
	net;

struct	termios old_tc = { 0 };
extern struct termios new_tc;

# ifndef	TCSANOW
#  ifdef TCSETS
#   define	TCSANOW		TCSETS
#   define	TCSADRAIN	TCSETSW
#   define	tcgetattr(f, t) ioctl(f, TCGETS, (char *)t)
#  else
#   ifdef TCSETA
#    define	TCSANOW		TCSETA
#    define	TCSADRAIN	TCSETAW
#    define	tcgetattr(f, t) ioctl(f, TCGETA, (char *)t)
#   else
#    define	TCSANOW		TIOCSETA
#    define	TCSADRAIN	TIOCSETAW
#    define	tcgetattr(f, t) ioctl(f, TIOCGETA, (char *)t)
#   endif
#  endif
#  define	tcsetattr(f, a, t) ioctl(f, a, (char *)t)
#  define	cfgetospeed(ptr)	((ptr)->c_cflag&CBAUD)
#  ifdef CIBAUD
#   define	cfgetispeed(ptr)	(((ptr)->c_cflag&CIBAUD) >> IBSHIFT)
#  else
#   define	cfgetispeed(ptr)	cfgetospeed(ptr)
#  endif
# endif /* TCSANOW */


void
init_sys(void)
{
    tout = fileno(stdout);
    tin = fileno(stdin);

    errno = 0;
}


int
TerminalWrite(char *buf, int  n)
{
    return write(tout, buf, n);
}

int
TerminalRead(unsigned char *buf, int  n)
{
    return read(tin, buf, n);
}

/*
 *
 */

int
TerminalAutoFlush(void)
{
    return 1;
}

#ifdef	KLUDGELINEMODE
extern int kludgelinemode;
#endif
/*
 * TerminalSpecialChars()
 *
 * Look at an input character to see if it is a special character
 * and decide what to do.
 *
 * Output:
 *
 *	0	Don't add this character.
 *	1	Do add this character
 */

int
TerminalSpecialChars(int c)
{
    if (c == termIntChar) {
	intp();
	return 0;
    } else if (c == termQuitChar) {
#ifdef	KLUDGELINEMODE
	if (kludgelinemode)
	    sendbrk();
	else
#endif
	    sendabort();
	return 0;
    } else if (c == termEofChar) {
	if (my_want_state_is_will(TELOPT_LINEMODE)) {
	    sendeof();
	    return 0;
	}
	return 1;
    } else if (c == termSuspChar) {
	sendsusp();
	return(0);
    } else if (c == termFlushChar) {
	xmitAO();		/* Transmit Abort Output */
	return 0;
    } else if (!MODE_LOCAL_CHARS(globalmode)) {
	if (c == termKillChar) {
	    xmitEL();
	    return 0;
	} else if (c == termEraseChar) {
	    xmitEC();		/* Transmit Erase Character */
	    return 0;
	}
    }
    return 1;
}


/*
 * Flush output to the terminal
 */

void
TerminalFlushOutput(void)
{
    int com = 0;
    (void) ioctl(fileno(stdout), TIOCFLUSH, &com);
}

void
TerminalSaveState(void)
{
    tcgetattr(0, &old_tc);

    new_tc = old_tc;
}

cc_t *
tcval(int func)
{
    switch(func) {
    case SLC_IP:	return(&termIntChar);
    case SLC_ABORT:	return(&termQuitChar);
    case SLC_EOF:	return(&termEofChar);
    case SLC_EC:	return(&termEraseChar);
    case SLC_EL:	return(&termKillChar);
    case SLC_XON:	return(&termStartChar);
    case SLC_XOFF:	return(&termStopChar);
    case SLC_FORW1:	return(&termForw1Char);
    case SLC_FORW2:	return(&termForw2Char);
    case SLC_AO:	return(&termFlushChar);
    case SLC_SUSP:	return(&termSuspChar);
    case SLC_EW:	return(&termWerasChar);
    case SLC_RP:	return(&termRprntChar);
    case SLC_LNEXT:	return(&termLiteralNextChar);
    case SLC_AYT:	return(&termAytChar);

    case SLC_SYNCH:
    case SLC_BRK:
    case SLC_EOR:
    default:
	return((cc_t *)0);
    }
}

void
TerminalDefaultChars(void)
{
    memmove(new_tc.c_cc, old_tc.c_cc, sizeof(old_tc.c_cc));
}

#ifdef notdef
void
TerminalRestoreState(void)
{
}
#endif

/*
 * TerminalNewMode - set up terminal to a specific mode.
 *	MODE_ECHO: do local terminal echo
 *	MODE_FLOW: do local flow control
 *	MODE_TRAPSIG: do local mapping to TELNET IAC sequences
 *	MODE_EDIT: do local line editing
 *
 *	Command mode:
 *		MODE_ECHO|MODE_EDIT|MODE_FLOW|MODE_TRAPSIG
 *		local echo
 *		local editing
 *		local xon/xoff
 *		local signal mapping
 *
 *	Linemode:
 *		local/no editing
 *	Both Linemode and Single Character mode:
 *		local/remote echo
 *		local/no xon/xoff
 *		local/no signal mapping
 */


void
TerminalNewMode(int f)
{
    static int prevmode = 0;
    struct termios tmp_tc;
    int onoff;
    int old;
    cc_t esc;

    globalmode = f&~MODE_FORCE;
    if (prevmode == f)
	return;

    /*
     * Write any outstanding data before switching modes
     * ttyflush() returns 0 only when there is no more data
     * left to write out, it returns -1 if it couldn't do
     * anything at all, otherwise it returns 1 + the number
     * of characters left to write.
#ifndef	USE_TERMIO
     * We would really like to ask the kernel to wait for the output
     * to drain, like we can do with the TCSADRAIN, but we don't have
     * that option.  The only ioctl that waits for the output to
     * drain, TIOCSETP, also flushes the input queue, which is NOT
     * what we want (TIOCSETP is like TCSADFLUSH).
#endif
     */
    old = ttyflush(SYNCHing|flushout);
    if (old < 0 || old > 1) {
	tcgetattr(tin, &tmp_tc);
	do {
	    /*
	     * Wait for data to drain, then flush again.
	     */
	    tcsetattr(tin, TCSADRAIN, &tmp_tc);
	    old = ttyflush(SYNCHing|flushout);
	} while (old < 0 || old > 1);
    }

    old = prevmode;
    prevmode = f&~MODE_FORCE;
    tmp_tc = new_tc;

    if (f&MODE_ECHO) {
	tmp_tc.c_lflag |= ECHO;
	tmp_tc.c_oflag |= ONLCR;
	if (crlf)
		tmp_tc.c_iflag |= ICRNL;
    } else {
	tmp_tc.c_lflag &= ~ECHO;
	tmp_tc.c_oflag &= ~ONLCR;
# ifdef notdef
	if (crlf)
		tmp_tc.c_iflag &= ~ICRNL;
# endif
    }

    if ((f&MODE_FLOW) == 0) {
	tmp_tc.c_iflag &= ~(IXOFF|IXON);	/* Leave the IXANY bit alone */
    } else {
	if (restartany < 0) {
		tmp_tc.c_iflag |= IXOFF|IXON;	/* Leave the IXANY bit alone */
	} else if (restartany > 0) {
		tmp_tc.c_iflag |= IXOFF|IXON|IXANY;
	} else {
		tmp_tc.c_iflag |= IXOFF|IXON;
		tmp_tc.c_iflag &= ~IXANY;
	}
    }

    if ((f&MODE_TRAPSIG) == 0) {
	tmp_tc.c_lflag &= ~ISIG;
	localchars = 0;
    } else {
	tmp_tc.c_lflag |= ISIG;
	localchars = 1;
    }

    if (f&MODE_EDIT) {
	tmp_tc.c_lflag |= ICANON;
    } else {
	tmp_tc.c_lflag &= ~ICANON;
	tmp_tc.c_iflag &= ~ICRNL;
	tmp_tc.c_cc[VMIN] = 1;
	tmp_tc.c_cc[VTIME] = 0;
    }

    if ((f&(MODE_EDIT|MODE_TRAPSIG)) == 0) {
	tmp_tc.c_lflag &= ~IEXTEN;
    }

    if (f&MODE_SOFT_TAB) {
# ifdef	OXTABS
	tmp_tc.c_oflag |= OXTABS;
# endif
# ifdef	TABDLY
	tmp_tc.c_oflag &= ~TABDLY;
	tmp_tc.c_oflag |= TAB3;
# endif
    } else {
# ifdef	OXTABS
	tmp_tc.c_oflag &= ~OXTABS;
# endif
# ifdef	TABDLY
	tmp_tc.c_oflag &= ~TABDLY;
# endif
    }

    if (f&MODE_LIT_ECHO) {
# ifdef	ECHOCTL
	tmp_tc.c_lflag &= ~ECHOCTL;
# endif
    } else {
# ifdef	ECHOCTL
	tmp_tc.c_lflag |= ECHOCTL;
# endif
    }

    if (f == -1) {
	onoff = 0;
    } else {
	if (f & MODE_INBIN)
		tmp_tc.c_iflag &= ~ISTRIP;
	else
		tmp_tc.c_iflag |= ISTRIP;
	if (f & MODE_OUTBIN) {
		tmp_tc.c_cflag &= ~(CSIZE|PARENB);
		tmp_tc.c_cflag |= CS8;
		tmp_tc.c_oflag &= ~OPOST;
	} else {
		tmp_tc.c_cflag &= ~(CSIZE|PARENB);
		tmp_tc.c_cflag |= old_tc.c_cflag & (CSIZE|PARENB);
		tmp_tc.c_oflag |= OPOST;
	}
	onoff = 1;
    }

    if (f != -1) {
	(void) signal(SIGTSTP, susp);
	(void) signal(SIGINFO, ayt);
#if	defined(USE_TERMIO) && defined(NOKERNINFO)
	tmp_tc.c_lflag |= NOKERNINFO;
#endif
	/*
	 * We don't want to process ^Y here.  It's just another
	 * character that we'll pass on to the back end.  It has
	 * to process it because it will be processed when the
	 * user attempts to read it, not when we send it.
	 */
# ifdef	VDSUSP
	tmp_tc.c_cc[VDSUSP] = (cc_t)(_POSIX_VDISABLE);
# endif
	/*
	 * If the VEOL character is already set, then use VEOL2,
	 * otherwise use VEOL.
	 */
	esc = (rlogin != _POSIX_VDISABLE) ? rlogin : escape;
	if ((tmp_tc.c_cc[VEOL] != esc)
# ifdef	VEOL2
	    && (tmp_tc.c_cc[VEOL2] != esc)
# endif
	    ) {
		if (tmp_tc.c_cc[VEOL] == (cc_t)(_POSIX_VDISABLE))
		    tmp_tc.c_cc[VEOL] = esc;
# ifdef	VEOL2
		else if (tmp_tc.c_cc[VEOL2] == (cc_t)(_POSIX_VDISABLE))
		    tmp_tc.c_cc[VEOL2] = esc;
# endif
	}
    } else {
	(void) signal(SIGINFO, (void (*)(int)) ayt_status);
	(void) signal(SIGTSTP, SIG_DFL);
	(void) sigsetmask(sigblock(0) & ~(1<<(SIGTSTP-1)));
	tmp_tc = old_tc;
    }
    if (tcsetattr(tin, TCSADRAIN, &tmp_tc) < 0)
	tcsetattr(tin, TCSANOW, &tmp_tc);

    ioctl(tin, FIONBIO, (char *)&onoff);
    ioctl(tout, FIONBIO, (char *)&onoff);
#if	defined(TN3270)
    if (noasynchtty == 0) {
	ioctl(tin, FIOASYNC, (char *)&onoff);
    }
#endif	/* defined(TN3270) */

}

void
TerminalSpeeds(long *ispeed, long *ospeed)
{
    long in, out;

    out = cfgetospeed(&old_tc);
    in = cfgetispeed(&old_tc);
    if (in == 0)
	in = out;

	*ispeed = in;
	*ospeed = out;
}

int
TerminalWindowSize(long *rows, long *cols)
{
    struct winsize ws;

    if (ioctl(fileno(stdin), TIOCGWINSZ, (char *)&ws) >= 0) {
	*rows = ws.ws_row;
	*cols = ws.ws_col;
	return 1;
    }
    return 0;
}

int
NetClose(int fd)
{
    return close(fd);
}


void
NetNonblockingIO(int fd, int onoff)
{
    ioctl(fd, FIONBIO, (char *)&onoff);
}

#ifdef TN3270
void
NetSigIO(int fd, int onoff)
{
    ioctl(fd, FIOASYNC, (char *)&onoff);	/* hear about input */
}

void
NetSetPgrp(int fd)
{
    int myPid;

    myPid = getpid();
    fcntl(fd, F_SETOWN, myPid);
}
#endif	/*defined(TN3270)*/

/*
 * Various signal handling routines.
 */

/* ARGSUSED */
SIG_FUNC_RET
intr(int sig)
{
    if (localchars) {
	intp();
	return;
    }
    setcommandmode();
    longjmp(toplevel, -1);
}

/* ARGSUSED */
SIG_FUNC_RET
intr2(int sig)
{
    if (localchars) {
#ifdef	KLUDGELINEMODE
	if (kludgelinemode)
	    sendbrk();
	else
#endif
	    sendabort();
	return;
    }
}

/* ARGSUSED */
SIG_FUNC_RET
susp(int sig)
{
    if ((rlogin != _POSIX_VDISABLE) && rlogin_susp())
	return;
    if (localchars)
	sendsusp();
}

/* ARGSUSED */
SIG_FUNC_RET
sendwin(int sig)
{
    if (connected) {
	sendnaws();
    }
}

/* ARGSUSED */
SIG_FUNC_RET
ayt(int sig)
{
    if (connected)
	sendayt();
    else
	ayt_status();
}


void
sys_telnet_init(void)
{
    (void) signal(SIGINT, intr);
    (void) signal(SIGQUIT, intr2);
    (void) signal(SIGPIPE, SIG_IGN);
    (void) signal(SIGWINCH, sendwin);
    (void) signal(SIGTSTP, susp);
    (void) signal(SIGINFO, ayt);

    setconnmode(0);

    NetNonblockingIO(net, 1);

#ifdef TN3270
    if (noasynchnet == 0) {			/* DBX can't handle! */
	NetSigIO(net, 1);
	NetSetPgrp(net);
    }
#endif	/* defined(TN3270) */

    if (SetSockOpt(net, SOL_SOCKET, SO_OOBINLINE, 1) == -1) {
	perror("SetSockOpt");
    }
}

/*
 * Process rings -
 *
 *	This routine tries to fill up/empty our various rings.
 *
 *	The parameter specifies whether this is a poll operation,
 *	or a block-until-something-happens operation.
 *
 *	The return value is 1 if something happened, 0 if not, < 0 if an
 *	error occurred.
 */

int
process_rings(int netin, int netout, int netex, int ttyin, int ttyout,
    int dopoll)		/* If 0, then block until something to do */
{
    struct pollfd set[3];
    int c;
		/* One wants to be a bit careful about setting returnValue
		 * to one, since a one implies we did some useful work,
		 * and therefore probably won't be called to block next
		 * time (TN3270 mode only).
		 */
    int returnValue = 0;

    set[0].fd = net;
    set[0].events = (netout ? POLLOUT : 0) | (netin ? POLLIN : 0) |
	(netex ? POLLPRI : 0);
    set[1].fd = tout;
    set[1].events = ttyout ? POLLOUT : 0;
    set[2].fd = tin;
    set[2].events = ttyin ? POLLIN : 0;

    if ((c = poll(set, 3, dopoll ? 0 : INFTIM)) < 0) {
	if (c == -1) {
		    /*
		     * we can get EINTR if we are in line mode,
		     * and the user does an escape (TSTP), or
		     * some other signal generator.
		     */
	    if (errno == EINTR) {
		return 0;
	    }
#ifdef TN3270
		    /*
		     * we can get EBADF if we were in transparent
		     * mode, and the transcom process died.
		    */
	    if (errno == EBADF)
		return 0;
#endif /* defined(TN3270) */
		    /* I don't like this, does it ever happen? */
	    printf("sleep(5) from telnet, after poll\r\n");
	    sleep(5);
	}
	return 0;
    }

    /*
     * Any urgent data?
     */
    if (set[0].revents & POLLPRI) {
	SYNCHing = 1;
	(void) ttyflush(1);	/* flush already enqueued data */
    }

    /*
     * Something to read from the network...
     */
    if (set[0].revents & POLLIN) {
	int canread;

	canread = ring_empty_consecutive(&netiring);
	c = recv(net, (char *)netiring.supply, canread, 0);
	if (c < 0 && errno == EWOULDBLOCK) {
	    c = 0;
	} else if (c <= 0) {
	    return -1;
	}
	if (netdata) {
	    Dump('<', netiring.supply, c);
	}
	if (c)
	    ring_supplied(&netiring, c);
	returnValue = 1;
    }

    /*
     * Something to read from the tty...
     */
    if (set[2].revents & POLLIN) {
	c = TerminalRead(ttyiring.supply, ring_empty_consecutive(&ttyiring));
	if (c < 0 && errno == EIO)
	    c = 0;
	if (c < 0 && errno == EWOULDBLOCK) {
	    c = 0;
	} else {
	    if (c < 0) {
		return -1;
	    }
	    if (c == 0) {
		/* must be an EOF... */
		if (MODE_LOCAL_CHARS(globalmode) && isatty(tin)) {
		    *ttyiring.supply = termEofChar;
		    c = 1;
		} else {
		    clienteof = 1;
		    shutdown(net, 1);
		    return 0;
		}
	    }
	    if (termdata) {
		Dump('<', ttyiring.supply, c);
	    }
	    ring_supplied(&ttyiring, c);
	}
	returnValue = 1;		/* did something useful */
    }

    if (set[0].revents & POLLOUT) {
	returnValue |= netflush();
    }

    if (set[1].revents & (POLLHUP|POLLNVAL))
	return(-1);

    if (set[1].revents & POLLOUT) {
	returnValue |= (ttyflush(SYNCHing|flushout) > 0);
    }

    return returnValue;
}

File Added: pkgsrc/comms/tn3270/files/telnet/Attic/telnet.c
/*	$NetBSD: telnet.c,v 1.1.1.1 2010/01/17 01:33:31 dholland Exp $	*/
/*	From NetBSD: telnet.c,v 1.31 2006/02/02 19:33:12 he Exp 	*/

/*
 * Copyright (c) 1988, 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. 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.
 */

#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)telnet.c	8.4 (Berkeley) 5/30/95";
#else
__RCSID("$NetBSD: telnet.c,v 1.1.1.1 2010/01/17 01:33:31 dholland Exp $");
#endif
#endif /* not lint */

#include <sys/param.h>

#include <signal.h>
#include <termcap.h>
#include <unistd.h>
/* By the way, we need to include curses.h before telnet.h since,
 * among other things, telnet.h #defines 'DO', which is a variable
 * declared in curses.h.
 */

#include <arpa/telnet.h>

#include <ctype.h>

#include "ring.h"
#include "defines.h"
#include "externs.h"
#include "types.h"
#include "general.h"

#include <libtelnet/misc.h>
#ifdef AUTHENTICATION
#include <libtelnet/auth.h>
#endif
#ifdef ENCRYPTION
#include <libtelnet/encrypt.h>
#endif


#define	strip(x) ((my_want_state_is_wont(TELOPT_BINARY)) ? ((x)&0x7f) : (x))

static unsigned char	subbuffer[SUBBUFSIZE],
			*subpointer, *subend;	 /* buffer for sub-options */
#define	SB_CLEAR()	subpointer = subbuffer;
#define	SB_TERM()	{ subend = subpointer; SB_CLEAR(); }
#define	SB_ACCUM(c)	if (subpointer < (subbuffer+sizeof subbuffer)) { \
				*subpointer++ = (c); \
			}

#define	SB_GET()	((*subpointer++)&0xff)
#define	SB_PEEK()	((*subpointer)&0xff)
#define	SB_EOF()	(subpointer >= subend)
#define	SB_LEN()	(subend - subpointer)

char	options[256];		/* The combined options */
char	do_dont_resp[256];
char	will_wont_resp[256];

int
	eight = 0,
	autologin = 0,	/* Autologin anyone? */
	skiprc = 0,
	connected,
	showoptions,
	In3270,		/* Are we in 3270 mode? */
	ISend,		/* trying to send network data in */
	telnet_debug = 0,
	crmod,
	netdata,	/* Print out network data flow */
	crlf,		/* Should '\r' be mapped to <CR><LF> (or <CR><NUL>)? */
#ifdef TN3270
	noasynchtty = 0,/* User specified "-noasynch" on command line */
	noasynchnet = 0,/* User specified "-noasynch" on command line */
	askedSGA = 0,	/* We have talked about suppress go ahead */
#endif	/* defined(TN3270) */
	telnetport,
	SYNCHing,	/* we are in TELNET SYNCH mode */
	flushout,	/* flush output */
	autoflush = 0,	/* flush output when interrupting? */
	autosynch,	/* send interrupt characters with SYNCH? */
	localflow,	/* we handle flow control locally */
	restartany,	/* if flow control enabled, restart on any character */
	localchars,	/* we recognize interrupt/quit */
	donelclchars,	/* the user has set "localchars" */
	donebinarytoggle,	/* the user has put us in binary */
	dontlecho,	/* do we suppress local echoing right now? */
	globalmode,
	doaddrlookup = 1, /* do a reverse address lookup? */
	clienteof = 0;

char *prompt = 0;

cc_t escape;
cc_t rlogin;
#ifdef	KLUDGELINEMODE
cc_t echoc;
#endif

/*
 * Telnet receiver states for fsm
 */
#define	TS_DATA		0
#define	TS_IAC		1
#define	TS_WILL		2
#define	TS_WONT		3
#define	TS_DO		4
#define	TS_DONT		5
#define	TS_CR		6
#define	TS_SB		7		/* sub-option collection */
#define	TS_SE		8		/* looking for sub-option end */

static int	telrcv_state;
#ifdef	OLD_ENVIRON
unsigned char telopt_environ = TELOPT_NEW_ENVIRON;
#else
# define telopt_environ TELOPT_NEW_ENVIRON
#endif

jmp_buf	toplevel = { 0 };

int	flushline;
int	linemode;

#ifdef	KLUDGELINEMODE
int	kludgelinemode = 1;
#endif

static void dooption(int);
static void dontoption(int);
static void suboption(void);
static int telsnd(void);
static void netclear(void);
static void doflush(void);

/*
 * The following are some clocks used to decide how to interpret
 * the relationship between various variables.
 */

Clocks clocks;

#ifdef	notdef
Modelist modelist[] = {
	{ "telnet command mode", COMMAND_LINE },
	{ "character-at-a-time mode", 0 },
	{ "character-at-a-time mode (local echo)", LOCAL_ECHO|LOCAL_CHARS },
	{ "line-by-line mode (remote echo)", LINE | LOCAL_CHARS },
	{ "line-by-line mode", LINE | LOCAL_ECHO | LOCAL_CHARS },
	{ "line-by-line mode (local echoing suppressed)", LINE | LOCAL_CHARS },
	{ "3270 mode", 0 },
};
#endif


/*
 * Initialize telnet environment.
 */

void
init_telnet(void)
{
    env_init();

    SB_CLEAR();
    ClearArray(options);

    connected = In3270 = ISend = localflow = donebinarytoggle = 0;
#if	defined(AUTHENTICATION) || defined(ENCRYPTION)
    auth_encrypt_connect(connected);
#endif	/* defined(AUTHENTICATION) || defined(ENCRYPTION) */
    restartany = -1;

    SYNCHing = 0;

    /* Don't change NetTrace */

    escape = CONTROL(']');
    rlogin = _POSIX_VDISABLE;
#ifdef	KLUDGELINEMODE
    echoc = CONTROL('E');
#endif

    flushline = 1;
    telrcv_state = TS_DATA;
}


#ifdef	notdef
#include <stdarg.h>

/*VARARGS*/
static void
printring(Ring *ring, char *format, ...)
    va_dcl
{
    va_list ap;
    char buffer[100];		/* where things go */
    char *ptr;
    char *string;
    int i;

    va_start(ap, format);

    ptr = buffer;

    while ((i = *format++) != 0) {
	if (i == '%') {
	    i = *format++;
	    switch (i) {
	    case 'c':
		*ptr++ = va_arg(ap, int);
		break;
	    case 's':
		string = va_arg(ap, char *);
		ring_supply_data(ring, buffer, ptr-buffer);
		ring_supply_data(ring, string, strlen(string));
		ptr = buffer;
		break;
	    case 0:
		ExitString("printring: trailing %%.\n", 1);
		/*NOTREACHED*/
	    default:
		ExitString("printring: unknown format character.\n", 1);
		/*NOTREACHED*/
	    }
	} else {
	    *ptr++ = i;
	}
    }
    va_end(ap);
    ring_supply_data(ring, buffer, ptr-buffer);
}
#endif

/*
 * These routines are in charge of sending option negotiations
 * to the other side.
 *
 * The basic idea is that we send the negotiation if either side
 * is in disagreement as to what the current state should be.
 */

void
send_do(int c, int init)
{
    if (init) {
	if (((do_dont_resp[c] == 0) && my_state_is_do(c)) ||
				my_want_state_is_do(c))
	    return;
	set_my_want_state_do(c);
	do_dont_resp[c]++;
    }
    NET2ADD(IAC, DO);
    NETADD(c);
    printoption("SENT", DO, c);
}

void
send_dont(int c, int init)
{
    if (init) {
	if (((do_dont_resp[c] == 0) && my_state_is_dont(c)) ||
				my_want_state_is_dont(c))
	    return;
	set_my_want_state_dont(c);
	do_dont_resp[c]++;
    }
    NET2ADD(IAC, DONT);
    NETADD(c);
    printoption("SENT", DONT, c);
}

void
send_will(int c, int init)
{
    if (init) {
	if (((will_wont_resp[c] == 0) && my_state_is_will(c)) ||
				my_want_state_is_will(c))
	    return;
	set_my_want_state_will(c);
	will_wont_resp[c]++;
    }
    NET2ADD(IAC, WILL);
    NETADD(c);
    printoption("SENT", WILL, c);
}

void
send_wont(int c, int init)
{
    if (init) {
	if (((will_wont_resp[c] == 0) && my_state_is_wont(c)) ||
				my_want_state_is_wont(c))
	    return;
	set_my_want_state_wont(c);
	will_wont_resp[c]++;
    }
    NET2ADD(IAC, WONT);
    NETADD(c);
    printoption("SENT", WONT, c);
}


void
willoption(int option)
{
	int new_state_ok = 0;

	if (do_dont_resp[option]) {
	    --do_dont_resp[option];
	    if (do_dont_resp[option] && my_state_is_do(option))
		--do_dont_resp[option];
	}

	if ((do_dont_resp[option] == 0) && my_want_state_is_dont(option)) {

	    switch (option) {

	    case TELOPT_ECHO:
#	    if defined(TN3270)
		/*
		 * The following is a pain in the rear-end.
		 * Various IBM servers (some versions of Wiscnet,
		 * possibly Fibronics/Spartacus, and who knows who
		 * else) will NOT allow us to send "DO SGA" too early
		 * in the setup proceedings.  On the other hand,
		 * 4.2 servers (telnetd) won't set SGA correctly.
		 * So, we are stuck.  Empirically (but, based on
		 * a VERY small sample), the IBM servers don't send
		 * out anything about ECHO, so we postpone our sending
		 * "DO SGA" until we see "WILL ECHO" (which 4.2 servers
		 * DO send).
		  */
		{
		    if (askedSGA == 0) {
			askedSGA = 1;
			if (my_want_state_is_dont(TELOPT_SGA))
			    send_do(TELOPT_SGA, 1);
		    }
		}
		    /* Fall through */
	    case TELOPT_EOR:
#endif	    /* defined(TN3270) */
	    case TELOPT_BINARY:
	    case TELOPT_SGA:
		settimer(modenegotiated);
		/* FALL THROUGH */
	    case TELOPT_STATUS:
#ifdef AUTHENTICATION
	    case TELOPT_AUTHENTICATION:
#ifdef	ENCRYPTION
	    case TELOPT_ENCRYPT:
#endif	/* ENCRYPTION */
#endif
		new_state_ok = 1;
		break;

	    case TELOPT_TM:
		if (flushout)
		    flushout = 0;
		/*
		 * Special case for TM.  If we get back a WILL,
		 * pretend we got back a WONT.
		 */
		set_my_want_state_dont(option);
		set_my_state_dont(option);
		return;			/* Never reply to TM will's/wont's */

	    case TELOPT_LINEMODE:
	    default:
		break;
	    }

	    if (new_state_ok) {
		set_my_want_state_do(option);
		send_do(option, 0);
		setconnmode(0);		/* possibly set new tty mode */
	    } else {
		do_dont_resp[option]++;
		send_dont(option, 0);
	    }
	}
	set_my_state_do(option);
#ifdef	ENCRYPTION
	if (option == TELOPT_ENCRYPT)
		encrypt_send_support();
#endif	/* ENCRYPTION */
}

void
wontoption(int option)
{
	if (do_dont_resp[option]) {
	    --do_dont_resp[option];
	    if (do_dont_resp[option] && my_state_is_dont(option))
		--do_dont_resp[option];
	}

	if ((do_dont_resp[option] == 0) && my_want_state_is_do(option)) {

	    switch (option) {

#ifdef	KLUDGELINEMODE
	    case TELOPT_SGA:
		if (!kludgelinemode)
		    break;
		/* FALL THROUGH */
#endif
	    case TELOPT_ECHO:
		settimer(modenegotiated);
		break;

	    case TELOPT_TM:
		if (flushout)
		    flushout = 0;
		set_my_want_state_dont(option);
		set_my_state_dont(option);
		return;		/* Never reply to TM will's/wont's */

	    default:
		break;
	    }
	    set_my_want_state_dont(option);
	    if (my_state_is_do(option))
		send_dont(option, 0);
	    setconnmode(0);			/* Set new tty mode */
	} else if (option == TELOPT_TM) {
	    /*
	     * Special case for TM.
	     */
	    if (flushout)
		flushout = 0;
	    set_my_want_state_dont(option);
	}
	set_my_state_dont(option);
}

static void
dooption(int option)
{
	int new_state_ok = 0;

	if (will_wont_resp[option]) {
	    --will_wont_resp[option];
	    if (will_wont_resp[option] && my_state_is_will(option))
		--will_wont_resp[option];
	}

	if (will_wont_resp[option] == 0) {
	  if (my_want_state_is_wont(option)) {

	    switch (option) {

	    case TELOPT_TM:
		/*
		 * Special case for TM.  We send a WILL, but pretend
		 * we sent WONT.
		 */
		send_will(option, 0);
		set_my_want_state_wont(TELOPT_TM);
		set_my_state_wont(TELOPT_TM);
		return;

#	if defined(TN3270)
	    case TELOPT_EOR:		/* end of record */
#	endif	/* defined(TN3270) */
	    case TELOPT_BINARY:		/* binary mode */
	    case TELOPT_NAWS:		/* window size */
	    case TELOPT_TSPEED:		/* terminal speed */
	    case TELOPT_LFLOW:		/* local flow control */
	    case TELOPT_TTYPE:		/* terminal type option */
	    case TELOPT_SGA:		/* no big deal */
#ifdef	ENCRYPTION
	    case TELOPT_ENCRYPT:	/* encryption variable option */
#endif	/* ENCRYPTION */
		new_state_ok = 1;
		break;

	    case TELOPT_NEW_ENVIRON:	/* New environment variable option */
#ifdef	OLD_ENVIRON
		if (my_state_is_will(TELOPT_OLD_ENVIRON))
			send_wont(TELOPT_OLD_ENVIRON, 1); /* turn off the old */
		goto env_common;
	    case TELOPT_OLD_ENVIRON:	/* Old environment variable option */
		if (my_state_is_will(TELOPT_NEW_ENVIRON))
			break;		/* Don't enable if new one is in use! */
	    env_common:
		telopt_environ = option;
#endif
		new_state_ok = 1;
		break;

#ifdef AUTHENTICATION
	    case TELOPT_AUTHENTICATION:
		if (autologin)
			new_state_ok = 1;
		break;
#endif

	    case TELOPT_XDISPLOC:	/* X Display location */
		if (env_getvalue((unsigned char *)"DISPLAY"))
		    new_state_ok = 1;
		break;

	    case TELOPT_LINEMODE:
#ifdef	KLUDGELINEMODE
		kludgelinemode = 0;
		send_do(TELOPT_SGA, 1);
#endif
		set_my_want_state_will(TELOPT_LINEMODE);
		send_will(option, 0);
		set_my_state_will(TELOPT_LINEMODE);
		slc_init();
		return;

	    case TELOPT_ECHO:		/* We're never going to echo... */
	    default:
		break;
	    }

	    if (new_state_ok) {
		set_my_want_state_will(option);
		send_will(option, 0);
		setconnmode(0);			/* Set new tty mode */
	    } else {
		will_wont_resp[option]++;
		send_wont(option, 0);
	    }
	  } else {
	    /*
	     * Handle options that need more things done after the
	     * other side has acknowledged the option.
	     */
	    switch (option) {
	    case TELOPT_LINEMODE:
#ifdef	KLUDGELINEMODE
		kludgelinemode = 0;
		send_do(TELOPT_SGA, 1);
#endif
		set_my_state_will(option);
		slc_init();
		send_do(TELOPT_SGA, 0);
		return;
	    }
	  }
	}
	set_my_state_will(option);
}

static void
dontoption(int option)
{

	if (will_wont_resp[option]) {
	    --will_wont_resp[option];
	    if (will_wont_resp[option] && my_state_is_wont(option))
		--will_wont_resp[option];
	}

	if ((will_wont_resp[option] == 0) && my_want_state_is_will(option)) {
	    switch (option) {
	    case TELOPT_LINEMODE:
		linemode = 0;	/* put us back to the default state */
		break;
#ifdef	OLD_ENVIRON
	    case TELOPT_NEW_ENVIRON:
		/*
		 * The new environ option wasn't recognized, try
		 * the old one.
		 */
		send_will(TELOPT_OLD_ENVIRON, 1);
		telopt_environ = TELOPT_OLD_ENVIRON;
		break;
#endif
	    }
	    /* we always accept a DONT */
	    set_my_want_state_wont(option);
	    if (my_state_is_will(option))
		send_wont(option, 0);
	    setconnmode(0);			/* Set new tty mode */
	}
	set_my_state_wont(option);
}

/*
 * Given a buffer returned by tgetent(), this routine will turn
 * the pipe separated list of names in the buffer into an array
 * of pointers to null terminated names.  We toss out any bad,
 * duplicate, or verbose names (names with spaces).
 */

static char *name_unknown = "UNKNOWN";
static char *unknown[] = { 0, 0 };

char **
mklist(char *buf, char *name)
{
	int n;
	char c, *cp, **argvp, *cp2, **argv, **avt;

	if (name) {
		if ((int)strlen(name) > 40) {
			name = 0;
			unknown[0] = name_unknown;
		} else {
			unknown[0] = name;
			upcase(name);
		}
	} else
		unknown[0] = name_unknown;
	/*
	 * Count up the number of names.
	 */
	for (n = 1, cp = buf; *cp && *cp != ':'; cp++) {
		if (*cp == '|')
			n++;
	}
	/*
	 * Allocate an array to put the name pointers into
	 */
	argv = (char **)malloc((n+3)*sizeof(char *));
	if (argv == 0)
		return(unknown);

	/*
	 * Fill up the array of pointers to names.
	 */
	*argv = 0;
	argvp = argv+1;
	n = 0;
	for (cp = cp2 = buf; (c = *cp);  cp++) {
		if (c == '|' || c == ':') {
			*cp++ = '\0';
			/*
			 * Skip entries that have spaces or are over 40
			 * characters long.  If this is our environment
			 * name, then put it up front.  Otherwise, as
			 * long as this is not a duplicate name (case
			 * insensitive) add it to the list.
			 */
			if (n || (cp - cp2 > 41))
				;
			else if (name && (strncasecmp(name, cp2, cp-cp2) == 0))
				*argv = cp2;
			else if (is_unique(cp2, argv+1, argvp))
				*argvp++ = cp2;
			if (c == ':')
				break;
			/*
			 * Skip multiple delimiters. Reset cp2 to
			 * the beginning of the next name. Reset n,
			 * the flag for names with spaces.
			 */
			while ((c = *cp) == '|')
				cp++;
			cp2 = cp;
			n = 0;
		}
		/*
		 * Skip entries with spaces or non-ascii values.
		 * Convert lower case letters to upper case.
		 */
		if ((c == ' ') || !isascii(c))
			n = 1;
		else if (islower((unsigned char)c))
			*cp = toupper((unsigned char)c);
	}

	/*
	 * Check for an old V6 2 character name.  If the second
	 * name points to the beginning of the buffer, and is
	 * only 2 characters long, move it to the end of the array.
	 */
	if ((argv[1] == buf) && (strlen(argv[1]) == 2)) {
		--argvp;
		for (avt = &argv[1]; avt < argvp; avt++)
			*avt = *(avt+1);
		*argvp++ = buf;
	}

	/*
	 * Duplicate last name, for TTYPE option, and null
	 * terminate the array.  If we didn't find a match on
	 * our terminal name, put that name at the beginning.
	 */
	cp = *(argvp-1);
	*argvp++ = cp;
	*argvp = 0;

	if (*argv == 0) {
		if (name)
			*argv = name;
		else {
			--argvp;
			for (avt = argv; avt < argvp; avt++)
				*avt = *(avt+1);
		}
	}
	if (*argv)
		return(argv);
	else
		return(unknown);
}

int
is_unique(char *name, char **as, char **ae)
{
	char **ap;
	int n;

	n = strlen(name) + 1;
	for (ap = as; ap < ae; ap++)
		if (strncasecmp(*ap, name, n) == 0)
			return(0);
	return (1);
}

#ifdef	TERMCAP
char *termbuf;

/*ARGSUSED*/
int
setup_term(char *tname, int fd, int *errp)
{
	char zz[1024], *zz_ptr;
	char *ext_tc, *newptr;
	
	if ((termbuf = (char *) malloc(1024)) == NULL)
		goto error;
	
	if (tgetent(termbuf, tname) == 1) {
		  /* check for ZZ capability, which indicates termcap truncated */
		zz_ptr = zz;
		if (tgetstr("ZZ", &zz_ptr) != NULL) {
			  /* it was, fish back the full termcap */
			sscanf(zz, "%p", &ext_tc);
			if ((newptr = (char *) realloc(termbuf,
						       strlen(ext_tc) + 1))
			    == NULL) {
				goto error;
			}

			strlcpy(newptr, ext_tc, strlen(ext_tc) + 1);
			termbuf = newptr;
		}

		if (errp)
			*errp = 1;
		return(0);
	}
  error:
	if (errp)
		*errp = 0;
	return(-1);
}
#else
#define	termbuf	ttytype
extern char ttytype[];
#endif

int resettermname = 1;

char *
gettermname(void)
{
	char *tname;
	static char **tnamep = 0;
	static char **next;
	int err;

	if (resettermname) {
		resettermname = 0;
		if (tnamep && tnamep != unknown)
			free(tnamep);
		if ((tname = (char *)env_getvalue((unsigned char *)"TERM")) &&
				(setup_term(tname, 1, &err) == 0)) {
			tnamep = mklist(termbuf, tname);
		} else {
			if (tname && ((int)strlen(tname) <= 40)) {
				unknown[0] = tname;
				upcase(tname);
			} else
				unknown[0] = name_unknown;
			tnamep = unknown;
		}
		next = tnamep;
	}
	if (*next == 0)
		next = tnamep;
	return(*next++);
}
/*
 * suboption()
 *
 *	Look at the sub-option buffer, and try to be helpful to the other
 * side.
 *
 *	Currently we recognize:
 *
 *		Terminal type, send request.
 *		Terminal speed (send request).
 *		Local flow control (is request).
 *		Linemode
 */

static void
suboption(void)
{
    unsigned char subchar;

    printsub('<', subbuffer, SB_LEN()+2);
    switch (subchar = SB_GET()) {
    case TELOPT_TTYPE:
	if (my_want_state_is_wont(TELOPT_TTYPE))
	    return;
	if (SB_EOF() || SB_GET() != TELQUAL_SEND) {
	    return;
	} else {
	    char *name;
	    unsigned char temp[50];
	    int len;

#ifdef TN3270
	    if (tn3270_ttype()) {
		return;
	    }
#endif	/* defined(TN3270) */
	    name = gettermname();
	    len = strlen(name) + 4 + 2;
	    if (len < NETROOM()) {
		sprintf((char *)temp, "%c%c%c%c%s%c%c", IAC, SB, TELOPT_TTYPE,
				TELQUAL_IS, name, IAC, SE);
		ring_supply_data(&netoring, temp, len);
		printsub('>', &temp[2], len-2);
	    } else {
		ExitString("No room in buffer for terminal type.\n", 1);
		/*NOTREACHED*/
	    }
	}
	break;
    case TELOPT_TSPEED:
	if (my_want_state_is_wont(TELOPT_TSPEED))
	    return;
	if (SB_EOF())
	    return;
	if (SB_GET() == TELQUAL_SEND) {
	    long ospeed, ispeed;
	    unsigned char temp[50];
	    int len;

	    TerminalSpeeds(&ispeed, &ospeed);

	    sprintf((char *)temp, "%c%c%c%c%ld,%ld%c%c", IAC, SB, TELOPT_TSPEED,
		    TELQUAL_IS, (long)ospeed, (long)ispeed, IAC, SE);
	    len = strlen((char *)temp+4) + 4;	/* temp[3] is 0 ... */

	    if (len < NETROOM()) {
		ring_supply_data(&netoring, temp, len);
		printsub('>', temp+2, len - 2);
	    }
/*@*/	    else printf("lm_will: not enough room in buffer\n");
	}
	break;
    case TELOPT_LFLOW:
	if (my_want_state_is_wont(TELOPT_LFLOW))
	    return;
	if (SB_EOF())
	    return;
	switch(SB_GET()) {
	case LFLOW_RESTART_ANY:
	    restartany = 1;
	    break;
	case LFLOW_RESTART_XON:
	    restartany = 0;
	    break;
	case LFLOW_ON:
	    localflow = 1;
	    break;
	case LFLOW_OFF:
	    localflow = 0;
	    break;
	default:
	    return;
	}
	setcommandmode();
	setconnmode(0);
	break;

    case TELOPT_LINEMODE:
	if (my_want_state_is_wont(TELOPT_LINEMODE))
	    return;
	if (SB_EOF())
	    return;
	switch (SB_GET()) {
	case WILL:
	    lm_will(subpointer, SB_LEN());
	    break;
	case WONT:
	    lm_wont(subpointer, SB_LEN());
	    break;
	case DO:
	    lm_do(subpointer, SB_LEN());
	    break;
	case DONT:
	    lm_dont(subpointer, SB_LEN());
	    break;
	case LM_SLC:
	    slc(subpointer, SB_LEN());
	    break;
	case LM_MODE:
	    lm_mode(subpointer, SB_LEN(), 0);
	    break;
	default:
	    break;
	}
	break;

#ifdef	OLD_ENVIRON
    case TELOPT_OLD_ENVIRON:
#endif
    case TELOPT_NEW_ENVIRON:
	if (SB_EOF())
	    return;
	switch(SB_PEEK()) {
	case TELQUAL_IS:
	case TELQUAL_INFO:
	    if (my_want_state_is_dont(subchar))
		return;
	    break;
	case TELQUAL_SEND:
	    if (my_want_state_is_wont(subchar)) {
		return;
	    }
	    break;
	default:
	    return;
	}
	env_opt(subpointer, SB_LEN());
	break;

    case TELOPT_XDISPLOC:
	if (my_want_state_is_wont(TELOPT_XDISPLOC))
	    return;
	if (SB_EOF())
	    return;
	if (SB_GET() == TELQUAL_SEND) {
	    unsigned char temp[50], *dp;
	    int len;

	    if ((dp = env_getvalue((unsigned char *)"DISPLAY")) == NULL) {
		/*
		 * Something happened, we no longer have a DISPLAY
		 * variable.  So, turn off the option.
		 */
		send_wont(TELOPT_XDISPLOC, 1);
		break;
	    }
	    sprintf((char *)temp, "%c%c%c%c%s%c%c", IAC, SB, TELOPT_XDISPLOC,
		    TELQUAL_IS, dp, IAC, SE);
	    len = strlen((char *)temp+4) + 4;	/* temp[3] is 0 ... */

	    if (len < NETROOM()) {
		ring_supply_data(&netoring, temp, len);
		printsub('>', temp+2, len - 2);
	    }
/*@*/	    else printf("lm_will: not enough room in buffer\n");
	}
	break;

#ifdef AUTHENTICATION
	case TELOPT_AUTHENTICATION: {
		if (!autologin)
			break;
		if (SB_EOF())
			return;
		switch(SB_GET()) {
		case TELQUAL_IS:
			if (my_want_state_is_dont(TELOPT_AUTHENTICATION))
				return;
			auth_is(subpointer, SB_LEN());
			break;
		case TELQUAL_SEND:
			if (my_want_state_is_wont(TELOPT_AUTHENTICATION))
				return;
			auth_send(subpointer, SB_LEN());
			break;
		case TELQUAL_REPLY:
			if (my_want_state_is_wont(TELOPT_AUTHENTICATION))
				return;
			auth_reply(subpointer, SB_LEN());
			break;
		case TELQUAL_NAME:
			if (my_want_state_is_dont(TELOPT_AUTHENTICATION))
				return;
			auth_name(subpointer, SB_LEN());
			break;
		}
	}
	break;
#endif
#ifdef	ENCRYPTION
    case TELOPT_ENCRYPT:
	if (SB_EOF())
		return;
	switch(SB_GET()) {
	case ENCRYPT_START:
		if (my_want_state_is_dont(TELOPT_ENCRYPT))
			return;
		encrypt_start(subpointer, SB_LEN());
		break;
	case ENCRYPT_END:
		if (my_want_state_is_dont(TELOPT_ENCRYPT))
			return;
		encrypt_end();
		break;
	case ENCRYPT_SUPPORT:
		if (my_want_state_is_wont(TELOPT_ENCRYPT))
			return;
		encrypt_support(subpointer, SB_LEN());
		break;
	case ENCRYPT_REQSTART:
		if (my_want_state_is_wont(TELOPT_ENCRYPT))
			return;
		encrypt_request_start(subpointer, SB_LEN());
		break;
	case ENCRYPT_REQEND:
		if (my_want_state_is_wont(TELOPT_ENCRYPT))
			return;
		/*
		 * We can always send an REQEND so that we cannot
		 * get stuck encrypting.  We should only get this
		 * if we have been able to get in the correct mode
		 * anyhow.
		 */
		encrypt_request_end();
		break;
	case ENCRYPT_IS:
		if (my_want_state_is_dont(TELOPT_ENCRYPT))
			return;
		encrypt_is(subpointer, SB_LEN());
		break;
	case ENCRYPT_REPLY:
		if (my_want_state_is_wont(TELOPT_ENCRYPT))
			return;
		encrypt_reply(subpointer, SB_LEN());
		break;
	case ENCRYPT_ENC_KEYID:
		if (my_want_state_is_dont(TELOPT_ENCRYPT))
			return;
		encrypt_enc_keyid(subpointer, SB_LEN());
		break;
	case ENCRYPT_DEC_KEYID:
		if (my_want_state_is_wont(TELOPT_ENCRYPT))
			return;
		encrypt_dec_keyid(subpointer, SB_LEN());
		break;
	default:
		break;
	}
	break;
#endif	/* ENCRYPTION */
    default:
	break;
    }
}

static unsigned char str_lm[] = { IAC, SB, TELOPT_LINEMODE, 0, 0, IAC, SE };

void
lm_will(unsigned char *cmd, int len)
{
    if (len < 1) {
/*@*/	printf("lm_will: no command!!!\n");	/* Should not happen... */
	return;
    }
    switch(cmd[0]) {
    case LM_FORWARDMASK:	/* We shouldn't ever get this... */
    default:
	str_lm[3] = DONT;
	str_lm[4] = cmd[0];
	if (NETROOM() > sizeof(str_lm)) {
	    ring_supply_data(&netoring, str_lm, sizeof(str_lm));
	    printsub('>', &str_lm[2], sizeof(str_lm)-2);
	}
/*@*/	else printf("lm_will: not enough room in buffer\n");
	break;
    }
}

void
lm_wont(unsigned char *cmd, int len)
{
    if (len < 1) {
/*@*/	printf("lm_wont: no command!!!\n");	/* Should not happen... */
	return;
    }
    switch(cmd[0]) {
    case LM_FORWARDMASK:	/* We shouldn't ever get this... */
    default:
	/* We are always DONT, so don't respond */
	return;
    }
}

void
lm_do(unsigned char *cmd, int len)
{
    if (len < 1) {
/*@*/	printf("lm_do: no command!!!\n");	/* Should not happen... */
	return;
    }
    switch(cmd[0]) {
    case LM_FORWARDMASK:
    default:
	str_lm[3] = WONT;
	str_lm[4] = cmd[0];
	if (NETROOM() > sizeof(str_lm)) {
	    ring_supply_data(&netoring, str_lm, sizeof(str_lm));
	    printsub('>', &str_lm[2], sizeof(str_lm)-2);
	}
/*@*/	else printf("lm_do: not enough room in buffer\n");
	break;
    }
}

void
lm_dont(unsigned char *cmd, int len)
{
    if (len < 1) {
/*@*/	printf("lm_dont: no command!!!\n");	/* Should not happen... */
	return;
    }
    switch(cmd[0]) {
    case LM_FORWARDMASK:
    default:
	/* we are always WONT, so don't respond */
	break;
    }
}

static unsigned char str_lm_mode[] = {
	IAC, SB, TELOPT_LINEMODE, LM_MODE, 0, IAC, SE
};

void
lm_mode(unsigned char *cmd, int len, int init)
{
	if (len != 1)
		return;
	if ((linemode&MODE_MASK&~MODE_ACK) == *cmd)
		return;
	if (*cmd&MODE_ACK)
		return;
	linemode = *cmd&(MODE_MASK&~MODE_ACK);
	str_lm_mode[4] = linemode;
	if (!init)
	    str_lm_mode[4] |= MODE_ACK;
	if (NETROOM() > sizeof(str_lm_mode)) {
	    ring_supply_data(&netoring, str_lm_mode, sizeof(str_lm_mode));
	    printsub('>', &str_lm_mode[2], sizeof(str_lm_mode)-2);
	}
/*@*/	else printf("lm_mode: not enough room in buffer\n");
	setconnmode(0);	/* set changed mode */
}



/*
 * slc()
 * Handle special character suboption of LINEMODE.
 */

struct spc {
	cc_t val;
	cc_t *valp;
	char flags;	/* Current flags & level */
	char mylevel;	/* Maximum level & flags */
} spc_data[NSLC+1];

#define SLC_IMPORT	0
#define	SLC_EXPORT	1
#define SLC_RVALUE	2
static int slc_mode = SLC_EXPORT;

void
slc_init(void)
{
	struct spc *spcp;

	localchars = 1;
	for (spcp = spc_data; spcp < &spc_data[NSLC+1]; spcp++) {
		spcp->val = 0;
		spcp->valp = 0;
		spcp->flags = spcp->mylevel = SLC_NOSUPPORT;
	}

#define	initfunc(func, flags) { \
					spcp = &spc_data[func]; \
					if ((spcp->valp = tcval(func)) != NULL){ \
					    spcp->val = *spcp->valp; \
					    spcp->mylevel = SLC_VARIABLE|flags; \
					} else { \
					    spcp->val = 0; \
					    spcp->mylevel = SLC_DEFAULT; \
					} \
				    }

	initfunc(SLC_SYNCH, 0);
	/* No BRK */
	initfunc(SLC_AO, 0);
	initfunc(SLC_AYT, 0);
	/* No EOR */
	initfunc(SLC_ABORT, SLC_FLUSHIN|SLC_FLUSHOUT);
	initfunc(SLC_EOF, 0);
	initfunc(SLC_SUSP, SLC_FLUSHIN);
	initfunc(SLC_EC, 0);
	initfunc(SLC_EL, 0);
	initfunc(SLC_EW, 0);
	initfunc(SLC_RP, 0);
	initfunc(SLC_LNEXT, 0);
	initfunc(SLC_XON, 0);
	initfunc(SLC_XOFF, 0);
	initfunc(SLC_FORW1, 0);
	initfunc(SLC_FORW2, 0);
	/* No FORW2 */

	initfunc(SLC_IP, SLC_FLUSHIN|SLC_FLUSHOUT);
#undef	initfunc

	if (slc_mode == SLC_EXPORT)
		slc_export();
	else
		slc_import(1);

}

void
slcstate(void)
{
    printf("Special characters are %s values\n",
		slc_mode == SLC_IMPORT ? "remote default" :
		slc_mode == SLC_EXPORT ? "local" :
					 "remote");
}

void
slc_mode_export(int n)
{
    slc_mode = SLC_EXPORT;
    if (my_state_is_will(TELOPT_LINEMODE))
	slc_export();
}

void
slc_mode_import(int def)
{
    slc_mode = def ? SLC_IMPORT : SLC_RVALUE;
    if (my_state_is_will(TELOPT_LINEMODE))
	slc_import(def);
}

unsigned char slc_import_val[] = {
	IAC, SB, TELOPT_LINEMODE, LM_SLC, 0, SLC_VARIABLE, 0, IAC, SE
};
unsigned char slc_import_def[] = {
	IAC, SB, TELOPT_LINEMODE, LM_SLC, 0, SLC_DEFAULT, 0, IAC, SE
};

void
slc_import(int def)
{
    if (NETROOM() > sizeof(slc_import_val)) {
	if (def) {
	    ring_supply_data(&netoring, slc_import_def, sizeof(slc_import_def));
	    printsub('>', &slc_import_def[2], sizeof(slc_import_def)-2);
	} else {
	    ring_supply_data(&netoring, slc_import_val, sizeof(slc_import_val));
	    printsub('>', &slc_import_val[2], sizeof(slc_import_val)-2);
	}
    }
/*@*/ else printf("slc_import: not enough room\n");
}

void
slc_export(void)
{
    struct spc *spcp;

    TerminalDefaultChars();

    slc_start_reply();
    for (spcp = &spc_data[1]; spcp < &spc_data[NSLC+1]; spcp++) {
	if (spcp->mylevel != SLC_NOSUPPORT) {
	    if (spcp->val == (cc_t)(_POSIX_VDISABLE))
		spcp->flags = SLC_NOSUPPORT;
	    else
		spcp->flags = spcp->mylevel;
	    if (spcp->valp)
		spcp->val = *spcp->valp;
	    slc_add_reply(spcp - spc_data, spcp->flags, spcp->val);
	}
    }
    slc_end_reply();
    (void)slc_update();
    setconnmode(1);	/* Make sure the character values are set */
}

void
slc(unsigned char *cp, int len)
{
	struct spc *spcp;
	int func,level;

	slc_start_reply();

	for (; len >= 3; len -=3, cp +=3) {

		func = cp[SLC_FUNC];

		if (func == 0) {
			/*
			 * Client side: always ignore 0 function.
			 */
			continue;
		}
		if (func > NSLC) {
			if ((cp[SLC_FLAGS] & SLC_LEVELBITS) != SLC_NOSUPPORT)
				slc_add_reply(func, SLC_NOSUPPORT, 0);
			continue;
		}

		spcp = &spc_data[func];

		level = cp[SLC_FLAGS]&(SLC_LEVELBITS|SLC_ACK);

		if ((cp[SLC_VALUE] == (unsigned char)spcp->val) &&
		    ((level&SLC_LEVELBITS) == (spcp->flags&SLC_LEVELBITS))) {
			continue;
		}

		if (level == (SLC_DEFAULT|SLC_ACK)) {
			/*
			 * This is an error condition, the SLC_ACK
			 * bit should never be set for the SLC_DEFAULT
			 * level.  Our best guess to recover is to
			 * ignore the SLC_ACK bit.
			 */
			cp[SLC_FLAGS] &= ~SLC_ACK;
		}

		if (level == ((spcp->flags&SLC_LEVELBITS)|SLC_ACK)) {
			spcp->val = (cc_t)cp[SLC_VALUE];
			spcp->flags = cp[SLC_FLAGS];	/* include SLC_ACK */
			continue;
		}

		level &= ~SLC_ACK;

		if (level <= (spcp->mylevel&SLC_LEVELBITS)) {
			spcp->flags = cp[SLC_FLAGS]|SLC_ACK;
			spcp->val = (cc_t)cp[SLC_VALUE];
		}
		if (level == SLC_DEFAULT) {
			if ((spcp->mylevel&SLC_LEVELBITS) != SLC_DEFAULT)
				spcp->flags = spcp->mylevel;
			else
				spcp->flags = SLC_NOSUPPORT;
		}
		slc_add_reply(func, spcp->flags, spcp->val);
	}
	slc_end_reply();
	if (slc_update())
		setconnmode(1);	/* set the  new character values */
}

void
slc_check(void)
{
    struct spc *spcp;

    slc_start_reply();
    for (spcp = &spc_data[1]; spcp < &spc_data[NSLC+1]; spcp++) {
	if (spcp->valp && spcp->val != *spcp->valp) {
	    spcp->val = *spcp->valp;
	    if (spcp->val == (cc_t)(_POSIX_VDISABLE))
		spcp->flags = SLC_NOSUPPORT;
	    else
		spcp->flags = spcp->mylevel;
	    slc_add_reply(spcp - spc_data, spcp->flags, spcp->val);
	}
    }
    slc_end_reply();
    setconnmode(1);
}


unsigned char slc_reply[128];
unsigned char *slc_replyp;

void
slc_start_reply(void)
{
	slc_replyp = slc_reply;
	*slc_replyp++ = IAC;
	*slc_replyp++ = SB;
	*slc_replyp++ = TELOPT_LINEMODE;
	*slc_replyp++ = LM_SLC;
}

void
slc_add_reply(unsigned int func, unsigned int flags, cc_t value)
{
	if ((slc_replyp - slc_reply) + 6 > sizeof(slc_reply))
		return;
	if ((*slc_replyp++ = func) == IAC)
		*slc_replyp++ = IAC;
	if ((*slc_replyp++ = flags) == IAC)
		*slc_replyp++ = IAC;
	if ((*slc_replyp++ = (unsigned char)value) == IAC)
		*slc_replyp++ = IAC;
}

void
slc_end_reply(void)
{
    int len;

    len = slc_replyp - slc_reply;
    if (len <= 4 || (len + 2 > sizeof(slc_reply)))
	return;
    *slc_replyp++ = IAC;
    *slc_replyp++ = SE;
    len += 2;
    if (NETROOM() > len) {
	ring_supply_data(&netoring, slc_reply, slc_replyp - slc_reply);
	printsub('>', &slc_reply[2], slc_replyp - slc_reply - 2);
    }
/*@*/else printf("slc_end_reply: not enough room\n");
}

int
slc_update(void)
{
	struct spc *spcp;
	int need_update = 0;

	for (spcp = &spc_data[1]; spcp < &spc_data[NSLC+1]; spcp++) {
		if (!(spcp->flags&SLC_ACK))
			continue;
		spcp->flags &= ~SLC_ACK;
		if (spcp->valp && (*spcp->valp != spcp->val)) {
			*spcp->valp = spcp->val;
			need_update = 1;
		}
	}
	return(need_update);
}

#ifdef	OLD_ENVIRON
# ifdef	ENV_HACK
/*
 * Earlier version of telnet/telnetd from the BSD code had
 * the definitions of VALUE and VAR reversed.  To ensure
 * maximum interoperability, we assume that the server is
 * an older BSD server, until proven otherwise.  The newer
 * BSD servers should be able to handle either definition,
 * so it is better to use the wrong values if we don't
 * know what type of server it is.
 */
int env_auto = 1;
int old_env_var = OLD_ENV_VAR;
int old_env_value = OLD_ENV_VALUE;
# else
#  define old_env_var OLD_ENV_VAR
#  define old_env_value OLD_ENV_VALUE
# endif
#endif

void
env_opt(unsigned char *buf, int len)
{
	unsigned char *ep = 0, *epc = 0;
	int i;

	switch(buf[0]&0xff) {
	case TELQUAL_SEND:
		env_opt_start();
		if (len == 1) {
			env_opt_add(NULL);
		} else for (i = 1; i < len; i++) {
			switch (buf[i]&0xff) {
#ifdef	OLD_ENVIRON
			case OLD_ENV_VAR:
# ifdef	ENV_HACK
				if (telopt_environ == TELOPT_OLD_ENVIRON
				    && env_auto) {
					/* Server has the same definitions */
					old_env_var = OLD_ENV_VAR;
					old_env_value = OLD_ENV_VALUE;
				}
				/* FALL THROUGH */
# endif
			case OLD_ENV_VALUE:
				/*
				 * Although OLD_ENV_VALUE is not legal, we will
				 * still recognize it, just in case it is an
				 * old server that has VAR & VALUE mixed up...
				 */
				/* FALL THROUGH */
#else
			case NEW_ENV_VAR:
#endif
			case ENV_USERVAR:
				if (ep) {
					*epc = 0;
					env_opt_add(ep);
				}
				ep = epc = &buf[i+1];
				break;
			case ENV_ESC:
				i++;
				/*FALL THROUGH*/
			default:
				if (epc)
					*epc++ = buf[i];
				break;
			}
		}
		if (ep) {
			*epc = 0;
			env_opt_add(ep);
		}
		env_opt_end(1);
		break;

	case TELQUAL_IS:
	case TELQUAL_INFO:
		/* Ignore for now.  We shouldn't get it anyway. */
		break;

	default:
		break;
	}
}

#define	OPT_REPLY_SIZE	256
unsigned char *opt_reply;
unsigned char *opt_replyp;
unsigned char *opt_replyend;

void
env_opt_start(void)
{
	unsigned char *p;

	if (opt_reply) {
		p = (unsigned char *)realloc(opt_reply, OPT_REPLY_SIZE);
		if (p == NULL)
			free(opt_reply);
	} else
		p = (unsigned char *)malloc(OPT_REPLY_SIZE);
	opt_reply = p;
	if (opt_reply == NULL) {
/*@*/		printf("env_opt_start: malloc()/realloc() failed!!!\n");
		opt_reply = opt_replyp = opt_replyend = NULL;
		return;
	}
	opt_replyp = opt_reply;
	opt_replyend = opt_reply + OPT_REPLY_SIZE;
	*opt_replyp++ = IAC;
	*opt_replyp++ = SB;
	*opt_replyp++ = telopt_environ;
	*opt_replyp++ = TELQUAL_IS;
}

void
env_opt_start_info(void)
{
	env_opt_start();
	if (opt_replyp)
	    opt_replyp[-1] = TELQUAL_INFO;
}

void
env_opt_add(unsigned char *ep)
{
	unsigned char *vp, c;
	unsigned int len, olen, elen;

	if (opt_reply == NULL)		/*XXX*/
		return;			/*XXX*/

	if (ep == NULL || *ep == '\0') {
		/* Send user defined variables first. */
		env_default(1, 0);
		while ((ep = env_default(0, 0)) != NULL)
			env_opt_add(ep);

		/* Now add the list of well know variables.  */
		env_default(1, 1);
		while ((ep = env_default(0, 1)) != NULL)
			env_opt_add(ep);
		return;
	}
	vp = env_getvalue(ep);
	elen = 2 * (vp ? strlen((char *)vp) : 0) +
		2 * strlen((char *)ep) + 6;
	if ((opt_replyend - opt_replyp) < elen)
	{
		unsigned char *p;
		len = opt_replyend - opt_reply + elen;
		olen = opt_replyp - opt_reply;
		p = (unsigned char *)realloc(opt_reply, len);
		if (p == NULL)
			free(opt_reply);
		opt_reply = p;
		if (opt_reply == NULL) {
/*@*/			printf("env_opt_add: realloc() failed!!!\n");
			opt_reply = opt_replyp = opt_replyend = NULL;
			return;
		}
		opt_replyp = opt_reply + olen;
		opt_replyend = opt_reply + len;
	}
	if (opt_welldefined(ep))
#ifdef	OLD_ENVIRON
		if (telopt_environ == TELOPT_OLD_ENVIRON)
			*opt_replyp++ = old_env_var;
		else
#endif
			*opt_replyp++ = NEW_ENV_VAR;
	else
		*opt_replyp++ = ENV_USERVAR;
	for (;;) {
		while ((c = *ep++) != '\0') {
			switch(c&0xff) {
			case IAC:
				*opt_replyp++ = IAC;
				break;
			case NEW_ENV_VAR:
			case NEW_ENV_VALUE:
			case ENV_ESC:
			case ENV_USERVAR:
				*opt_replyp++ = ENV_ESC;
				break;
			}
			*opt_replyp++ = c;
		}
		if ((ep = vp) != NULL) {
#ifdef	OLD_ENVIRON
			if (telopt_environ == TELOPT_OLD_ENVIRON)
				*opt_replyp++ = old_env_value;
			else
#endif
				*opt_replyp++ = NEW_ENV_VALUE;
			vp = NULL;
		} else
			break;
	}
}

int
opt_welldefined(char *ep)
{
	if ((strcmp(ep, "USER") == 0) ||
	    (strcmp(ep, "DISPLAY") == 0) ||
	    (strcmp(ep, "PRINTER") == 0) ||
	    (strcmp(ep, "SYSTEMTYPE") == 0) ||
	    (strcmp(ep, "JOB") == 0) ||
	    (strcmp(ep, "ACCT") == 0))
		return(1);
	return(0);
}
void
env_opt_end(int emptyok)
{
	int len;

	len = opt_replyp - opt_reply + 2;
	if (emptyok || len > 6) {
		*opt_replyp++ = IAC;
		*opt_replyp++ = SE;
		if (NETROOM() > len) {
			ring_supply_data(&netoring, opt_reply, len);
			printsub('>', &opt_reply[2], len - 2);
		}
/*@*/		else printf("slc_end_reply: not enough room\n");
	}
	if (opt_reply) {
		free(opt_reply);
		opt_reply = opt_replyp = opt_replyend = NULL;
	}
}



int
telrcv(void)
{
    int c;
    int scc;
    unsigned char *sbp = NULL;
    int count;
    int returnValue = 0;

    scc = 0;
    count = 0;
    while (TTYROOM() > 2) {
	if (scc == 0) {
	    if (count) {
		ring_consumed(&netiring, count);
		returnValue = 1;
		count = 0;
	    }
	    sbp = netiring.consume;
	    scc = ring_full_consecutive(&netiring);
	    if (scc == 0) {
		/* No more data coming in */
		break;
	    }
	}

	c = *sbp++ & 0xff, scc--; count++;
#ifdef	ENCRYPTION
	if (decrypt_input)
		c = (*decrypt_input)(c);
#endif	/* ENCRYPTION */

	switch (telrcv_state) {

	case TS_CR:
	    telrcv_state = TS_DATA;
	    if (c == '\0') {
		break;	/* Ignore \0 after CR */
	    }
	    else if ((c == '\n') && my_want_state_is_dont(TELOPT_ECHO) && !crmod) {
		TTYADD(c);
		break;
	    }
	    /* Else, fall through */

	case TS_DATA:
	    if (c == IAC) {
		telrcv_state = TS_IAC;
		break;
	    }
#	    if defined(TN3270)
	    if (In3270) {
		*Ifrontp++ = c;
		while (scc > 0) {
		    c = *sbp++ & 0377, scc--; count++;
#ifdef	ENCRYPTION
		    if (decrypt_input)
			c = (*decrypt_input)(c);
#endif	/* ENCRYPTION */
		    if (c == IAC) {
			telrcv_state = TS_IAC;
			break;
		    }
		    *Ifrontp++ = c;
		}
	    } else
#	    endif /* defined(TN3270) */
		    /*
		     * The 'crmod' hack (see following) is needed
		     * since we can't * set CRMOD on output only.
		     * Machines like MULTICS like to send \r without
		     * \n; since we must turn off CRMOD to get proper
		     * input, the mapping is done here (sigh).
		     */
	    if ((c == '\r') && my_want_state_is_dont(TELOPT_BINARY)) {
		if (scc > 0) {
		    c = *sbp&0xff;
#ifdef	ENCRYPTION
		    if (decrypt_input)
			c = (*decrypt_input)(c);
#endif	/* ENCRYPTION */
		    if (c == 0) {
			sbp++, scc--; count++;
			/* a "true" CR */
			TTYADD('\r');
		    } else if (my_want_state_is_dont(TELOPT_ECHO) &&
					(c == '\n')) {
			sbp++, scc--; count++;
			TTYADD('\n');
		    } else {
#ifdef	ENCRYPTION
			if (decrypt_input)
			    (*decrypt_input)(-1);
#endif	/* ENCRYPTION */

			TTYADD('\r');
			if (crmod) {
				TTYADD('\n');
			}
		    }
		} else {
		    telrcv_state = TS_CR;
		    TTYADD('\r');
		    if (crmod) {
			    TTYADD('\n');
		    }
		}
	    } else {
		TTYADD(c);
	    }
	    continue;

	case TS_IAC:
process_iac:
	    switch (c) {

	    case WILL:
		telrcv_state = TS_WILL;
		continue;

	    case WONT:
		telrcv_state = TS_WONT;
		continue;

	    case DO:
		telrcv_state = TS_DO;
		continue;

	    case DONT:
		telrcv_state = TS_DONT;
		continue;

	    case DM:
		    /*
		     * We may have missed an urgent notification,
		     * so make sure we flush whatever is in the
		     * buffer currently.
		     */
		printoption("RCVD", IAC, DM);
		SYNCHing = 1;
		(void) ttyflush(1);
		SYNCHing = stilloob();
		settimer(gotDM);
		break;

	    case SB:
		SB_CLEAR();
		telrcv_state = TS_SB;
		continue;

#	    if defined(TN3270)
	    case EOR:
		if (In3270) {
		    if (Ibackp == Ifrontp) {
			Ibackp = Ifrontp = Ibuf;
			ISend = 0;	/* should have been! */
		    } else {
			Ibackp += DataFromNetwork(Ibackp, Ifrontp-Ibackp, 1);
			ISend = 1;
		    }
		}
		printoption("RCVD", IAC, EOR);
		break;
#	    endif /* defined(TN3270) */

	    case IAC:
#	    if !defined(TN3270)
		TTYADD(IAC);
#	    else /* !defined(TN3270) */
		if (In3270) {
		    *Ifrontp++ = IAC;
		} else {
		    TTYADD(IAC);
		}
#	    endif /* !defined(TN3270) */
		break;

	    case NOP:
	    case GA:
	    default:
		printoption("RCVD", IAC, c);
		break;
	    }
	    telrcv_state = TS_DATA;
	    continue;

	case TS_WILL:
	    printoption("RCVD", WILL, c);
	    willoption(c);
	    SetIn3270();
	    telrcv_state = TS_DATA;
	    continue;

	case TS_WONT:
	    printoption("RCVD", WONT, c);
	    wontoption(c);
	    SetIn3270();
	    telrcv_state = TS_DATA;
	    continue;

	case TS_DO:
	    printoption("RCVD", DO, c);
	    dooption(c);
	    SetIn3270();
	    if (c == TELOPT_NAWS) {
		sendnaws();
	    } else if (c == TELOPT_LFLOW) {
		localflow = 1;
		setcommandmode();
		setconnmode(0);
	    }
	    telrcv_state = TS_DATA;
	    continue;

	case TS_DONT:
	    printoption("RCVD", DONT, c);
	    dontoption(c);
	    flushline = 1;
	    setconnmode(0);	/* set new tty mode (maybe) */
	    SetIn3270();
	    telrcv_state = TS_DATA;
	    continue;

	case TS_SB:
	    if (c == IAC) {
		telrcv_state = TS_SE;
	    } else {
		SB_ACCUM(c);
	    }
	    continue;

	case TS_SE:
	    if (c != SE) {
		if (c != IAC) {
		    /*
		     * This is an error.  We only expect to get
		     * "IAC IAC" or "IAC SE".  Several things may
		     * have happened.  An IAC was not doubled, the
		     * IAC SE was left off, or another option got
		     * inserted into the suboption are all possibilities.
		     * If we assume that the IAC was not doubled,
		     * and really the IAC SE was left off, we could
		     * get into an infinite loop here.  So, instead,
		     * we terminate the suboption, and process the
		     * partial suboption if we can.
		     */
		    SB_ACCUM(IAC);
		    SB_ACCUM(c);
		    subpointer -= 2;
		    SB_TERM();

		    printoption("In SUBOPTION processing, RCVD", IAC, c);
		    suboption();	/* handle sub-option */
		    SetIn3270();
		    telrcv_state = TS_IAC;
		    goto process_iac;
		}
		SB_ACCUM(c);
		telrcv_state = TS_SB;
	    } else {
		SB_ACCUM(IAC);
		SB_ACCUM(SE);
		subpointer -= 2;
		SB_TERM();
		suboption();	/* handle sub-option */
		SetIn3270();
		telrcv_state = TS_DATA;
	    }
	}
    }
    if (count)
	ring_consumed(&netiring, count);
    return returnValue||count;
}

static int bol = 1, local = 0;

int
rlogin_susp(void)
{
    if (local) {
	local = 0;
	bol = 1;
	command(0, "z\n", 2);
	return(1);
    }
    return(0);
}

static int
telsnd(void)
{
    int tcc;
    int count;
    int returnValue = 0;
    unsigned char *tbp = NULL;

    tcc = 0;
    count = 0;
    while (NETROOM() > 2) {
	int sc;
	int c;

	if (tcc == 0) {
	    if (count) {
		ring_consumed(&ttyiring, count);
		returnValue = 1;
		count = 0;
	    }
	    tbp = ttyiring.consume;
	    tcc = ring_full_consecutive(&ttyiring);
	    if (tcc == 0) {
		break;
	    }
	}
	c = *tbp++ & 0xff, sc = strip(c), tcc--; count++;
	if (rlogin != _POSIX_VDISABLE) {
		if (bol) {
			bol = 0;
			if (sc == rlogin) {
				local = 1;
				continue;
			}
		} else if (local) {
			local = 0;
			if (sc == '.' || c == termEofChar) {
				bol = 1;
				command(0, "close\n", 6);
				continue;
			}
			if (sc == termSuspChar) {
				bol = 1;
				command(0, "z\n", 2);
				continue;
			}
			if (sc == escape) {
				command(0, (char *)tbp, tcc);
				bol = 1;
				count += tcc;
				tcc = 0;
				flushline = 1;
				break;
			}
			if (sc != rlogin) {
				++tcc;
				--tbp;
				--count;
				c = sc = rlogin;
			}
		}
		if ((sc == '\n') || (sc == '\r'))
			bol = 1;
	} else if (sc == escape && escape != _POSIX_VDISABLE) {
	    /*
	     * Double escape is a pass through of a single escape character.
	     */
	    if (tcc && strip(*tbp) == escape) {
		tbp++;
		tcc--;
		count++;
		bol = 0;
	    } else {
		command(0, (char *)tbp, tcc);
		bol = 1;
		count += tcc;
		tcc = 0;
		flushline = 1;
		break;
	    }
	} else
	    bol = 0;
#ifdef	KLUDGELINEMODE
	if (kludgelinemode && (globalmode&MODE_EDIT) && (sc == echoc)) {
	    if (tcc > 0 && strip(*tbp) == echoc) {
		tcc--; tbp++; count++;
	    } else {
		dontlecho = !dontlecho;
		settimer(echotoggle);
		setconnmode(0);
		flushline = 1;
		break;
	    }
	}
#endif
	if (sc != _POSIX_VDISABLE && MODE_LOCAL_CHARS(globalmode)) {
	    if (TerminalSpecialChars(sc) == 0) {
		bol = 1;
		break;
	    }
	}
	if (my_want_state_is_wont(TELOPT_BINARY)) {
	    switch (c) {
	    case '\n':
		    /*
		     * If we are in CRMOD mode (\r ==> \n)
		     * on our local machine, then probably
		     * a newline (unix) is CRLF (TELNET).
		     */
		if (MODE_LOCAL_CHARS(globalmode)) {
		    NETADD('\r');
		}
		NETADD('\n');
		bol = flushline = 1;
		break;
	    case '\r':
		if (!crlf) {
		    NET2ADD('\r', '\0');
		} else {
		    NET2ADD('\r', '\n');
		}
		bol = flushline = 1;
		break;
	    case IAC:
		NET2ADD(IAC, IAC);
		break;
	    default:
		NETADD(c);
		break;
	    }
	} else if (c == IAC) {
	    NET2ADD(IAC, IAC);
	} else {
	    NETADD(c);
	}
    }
    if (count)
	ring_consumed(&ttyiring, count);
    return returnValue||count;		/* Non-zero if we did anything */
}

/*
 * Scheduler()
 *
 * Try to do something.
 *
 * If we do something useful, return 1; else return 0.
 *
 */


int
Scheduler(int block)			/* should we block in the select ? */
{
		/* One wants to be a bit careful about setting returnValue
		 * to one, since a one implies we did some useful work,
		 * and therefore probably won't be called to block next
		 * time (TN3270 mode only).
		 */
    int returnValue;
    int netin, netout, netex, ttyin, ttyout;

    /* Decide which rings should be processed */

    netout = ring_full_count(&netoring) &&
	    (flushline ||
		(my_want_state_is_wont(TELOPT_LINEMODE)
#ifdef	KLUDGELINEMODE
			&& (!kludgelinemode || my_want_state_is_do(TELOPT_SGA))
#endif
		) ||
			my_want_state_is_will(TELOPT_BINARY));
    ttyout = ring_full_count(&ttyoring);

#ifdef TN3270
    ttyin = ring_empty_count(&ttyiring) && (clienteof == 0) && (shell_active == 0);
#else	/* defined(TN3270) */
    ttyin = ring_empty_count(&ttyiring) && (clienteof == 0);
#endif	/* defined(TN3270) */

#ifdef TN3270
    netin = ring_empty_count(&netiring);
#   else /* !defined(TN3270) */
    netin = !ISend && ring_empty_count(&netiring);
#   endif /* !defined(TN3270) */

    netex = !SYNCHing;

    /* If we have seen a signal recently, reset things */
#   ifdef TN3270
    if (HaveInput) {
	HaveInput = 0;
	(void) signal(SIGIO, inputAvailable);
    }
#endif	/* defined(TN3270) */

    /* Call to system code to process rings */

    returnValue = process_rings(netin, netout, netex, ttyin, ttyout, !block);

    /* Now, look at the input rings, looking for work to do. */

    if (ring_full_count(&ttyiring)) {
#   if defined(TN3270)
	if (In3270) {
	    int c;

	    c = DataFromTerminal(ttyiring.consume,
					ring_full_consecutive(&ttyiring));
	    if (c) {
		returnValue = 1;
		ring_consumed(&ttyiring, c);
	    }
	} else {
#   endif /* defined(TN3270) */
	    returnValue |= telsnd();
#   if defined(TN3270)
	}
#   endif /* defined(TN3270) */
    }

    if (ring_full_count(&netiring)) {
#	if !defined(TN3270)
	returnValue |= telrcv();
#	else /* !defined(TN3270) */
	returnValue = Push3270();
#	endif /* !defined(TN3270) */
    }
    return returnValue;
}

/*
 * Select from tty and network...
 */
void
telnet(const char *user)
{
    sys_telnet_init();

#if	defined(AUTHENTICATION) || defined(ENCRYPTION)
    {
	static char local_host[MAXHOSTNAMELEN + 1] = { 0 };

	if (!local_host[0]) {
		gethostname(local_host, sizeof(local_host));
		local_host[sizeof(local_host)-1] = 0;
	}
	auth_encrypt_init(local_host, hostname, "TELNET", 0);
	auth_encrypt_user(user);
    }
#endif	/* defined(AUTHENTICATION) || defined(ENCRYPTION) */
#   if !defined(TN3270)
    if (telnetport) {
#ifdef AUTHENTICATION
	if (autologin)
		send_will(TELOPT_AUTHENTICATION, 1);
#endif
#ifdef	ENCRYPTION
	send_do(TELOPT_ENCRYPT, 1);
	send_will(TELOPT_ENCRYPT, 1);
#endif	/* ENCRYPTION */
	send_do(TELOPT_SGA, 1);
	send_will(TELOPT_TTYPE, 1);
	send_will(TELOPT_NAWS, 1);
	send_will(TELOPT_TSPEED, 1);
	send_will(TELOPT_LFLOW, 1);
	send_will(TELOPT_LINEMODE, 1);
	send_will(TELOPT_NEW_ENVIRON, 1);
	send_do(TELOPT_STATUS, 1);
	if (env_getvalue((unsigned char *)"DISPLAY"))
	    send_will(TELOPT_XDISPLOC, 1);
	if (eight)
	    tel_enter_binary(eight);
    }
#   endif /* !defined(TN3270) */

#   if !defined(TN3270)
    for (;;) {
	int schedValue;

	while ((schedValue = Scheduler(0)) != 0) {
	    if (schedValue == -1) {
		setcommandmode();
		return;
	    }
	}

	if (Scheduler(1) == -1) {
	    setcommandmode();
	    return;
	}
    }
#   else /* !defined(TN3270) */
    for (;;) {
	int schedValue;

	while (!In3270 && !shell_active) {
	    if (Scheduler(1) == -1) {
		setcommandmode();
		return;
	    }
	}

	while ((schedValue = Scheduler(0)) != 0) {
	    if (schedValue == -1) {
		setcommandmode();
		return;
	    }
	}
		/* If there is data waiting to go out to terminal, don't
		 * schedule any more data for the terminal.
		 */
	if (ring_full_count(&ttyoring)) {
	    schedValue = 1;
	} else {
	    if (shell_active) {
		if (shell_continue() == 0) {
		    ConnectScreen();
		}
	    } else if (In3270) {
		schedValue = DoTerminalOutput();
	    }
	}
	if (schedValue && (shell_active == 0)) {
	    if (Scheduler(1) == -1) {
		setcommandmode();
		return;
	    }
	}
    }
#   endif /* !defined(TN3270) */
}

#if	0	/* XXX - this not being in is a bug */
/*
 * nextitem()
 *
 *	Return the address of the next "item" in the TELNET data
 * stream.  This will be the address of the next character if
 * the current address is a user data character, or it will
 * be the address of the character following the TELNET command
 * if the current address is a TELNET IAC ("I Am a Command")
 * character.
 */

static char *
nextitem(char *current)
{
    if ((*current&0xff) != IAC) {
	return current+1;
    }
    switch (*(current+1)&0xff) {
    case DO:
    case DONT:
    case WILL:
    case WONT:
	return current+3;
    case SB:		/* loop forever looking for the SE */
	{
	    char *look = current+2;

	    for (;;) {
		if ((*look++&0xff) == IAC) {
		    if ((*look++&0xff) == SE) {
			return look;
		    }
		}
	    }
	}
    default:
	return current+2;
    }
}
#endif	/* 0 */

/*
 * netclear()
 *
 *	We are about to do a TELNET SYNCH operation.  Clear
 * the path to the network.
 *
 *	Things are a bit tricky since we may have sent the first
 * byte or so of a previous TELNET command into the network.
 * So, we have to scan the network buffer from the beginning
 * until we are up to where we want to be.
 *
 *	A side effect of what we do, just to keep things
 * simple, is to clear the urgent data pointer.  The principal
 * caller should be setting the urgent data pointer AFTER calling
 * us in any case.
 */

static void
netclear(void)
{
#if	0	/* XXX */
    char *thisitem, *next;
    char *good;
#define	wewant(p)	((nfrontp > p) && ((*p&0xff) == IAC) && \
				((*(p+1)&0xff) != EC) && ((*(p+1)&0xff) != EL))

    thisitem = netobuf;

    while ((next = nextitem(thisitem)) <= netobuf.send) {
	thisitem = next;
    }

    /* Now, thisitem is first before/at boundary. */

    good = netobuf;	/* where the good bytes go */

    while (netoring.add > thisitem) {
	if (wewant(thisitem)) {
	    int length;

	    next = thisitem;
	    do {
		next = nextitem(next);
	    } while (wewant(next) && (nfrontp > next));
	    length = next-thisitem;
	    memmove(good, thisitem, length);
	    good += length;
	    thisitem = next;
	} else {
	    thisitem = nextitem(thisitem);
	}
    }

#endif	/* 0 */
}

/*
 * These routines add various telnet commands to the data stream.
 */

static void
doflush(void)
{
    NET2ADD(IAC, DO);
    NETADD(TELOPT_TM);
    flushline = 1;
    flushout = 1;
    (void) ttyflush(1);			/* Flush/drop output */
    /* do printoption AFTER flush, otherwise the output gets tossed... */
    printoption("SENT", DO, TELOPT_TM);
}

void
xmitAO(void)
{
    NET2ADD(IAC, AO);
    printoption("SENT", IAC, AO);
    if (autoflush) {
	doflush();
    }
}


void
xmitEL(void)
{
    NET2ADD(IAC, EL);
    printoption("SENT", IAC, EL);
}

void
xmitEC(void)
{
    NET2ADD(IAC, EC);
    printoption("SENT", IAC, EC);
}


int
dosynch(char *s)
{
    netclear();			/* clear the path to the network */
    NETADD(IAC);
    setneturg();
    NETADD(DM);
    printoption("SENT", IAC, DM);
    return 1;
}

int want_status_response = 0;

int
get_status(char *s)
{
    unsigned char tmp[16];
    unsigned char *cp;

    if (my_want_state_is_dont(TELOPT_STATUS)) {
	printf("Remote side does not support STATUS option\n");
	return 0;
    }
    cp = tmp;

    *cp++ = IAC;
    *cp++ = SB;
    *cp++ = TELOPT_STATUS;
    *cp++ = TELQUAL_SEND;
    *cp++ = IAC;
    *cp++ = SE;
    if (NETROOM() >= cp - tmp) {
	ring_supply_data(&netoring, tmp, cp-tmp);
	printsub('>', tmp+2, cp - tmp - 2);
    }
    ++want_status_response;
    return 1;
}

void
intp(void)
{
    NET2ADD(IAC, IP);
    printoption("SENT", IAC, IP);
    flushline = 1;
    if (autoflush) {
	doflush();
    }
    if (autosynch) {
	dosynch(NULL);
    }
}

void
sendbrk(void)
{
    NET2ADD(IAC, BREAK);
    printoption("SENT", IAC, BREAK);
    flushline = 1;
    if (autoflush) {
	doflush();
    }
    if (autosynch) {
	dosynch(NULL);
    }
}

void
sendabort(void)
{
    NET2ADD(IAC, ABORT);
    printoption("SENT", IAC, ABORT);
    flushline = 1;
    if (autoflush) {
	doflush();
    }
    if (autosynch) {
	dosynch(NULL);
    }
}

void
sendsusp(void)
{
    NET2ADD(IAC, SUSP);
    printoption("SENT", IAC, SUSP);
    flushline = 1;
    if (autoflush) {
	doflush();
    }
    if (autosynch) {
	dosynch(NULL);
    }
}

void
sendeof(void)
{
    NET2ADD(IAC, xEOF);
    printoption("SENT", IAC, xEOF);
}

void
sendayt(void)
{
    NET2ADD(IAC, AYT);
    printoption("SENT", IAC, AYT);
}

/*
 * Send a window size update to the remote system.
 */

void
sendnaws(void)
{
    long rows, cols;
    unsigned char tmp[16];
    unsigned char *cp;

    if (my_state_is_wont(TELOPT_NAWS))
	return;

#define	PUTSHORT(cp, x) { if ((*cp++ = ((x)>>8)&0xff) == IAC) *cp++ = IAC; \
			    if ((*cp++ = ((x))&0xff) == IAC) *cp++ = IAC; }

    if (TerminalWindowSize(&rows, &cols) == 0) {	/* Failed */
	return;
    }

    cp = tmp;

    *cp++ = IAC;
    *cp++ = SB;
    *cp++ = TELOPT_NAWS;
    PUTSHORT(cp, cols);
    PUTSHORT(cp, rows);
    *cp++ = IAC;
    *cp++ = SE;
    if (NETROOM() >= cp - tmp) {
	ring_supply_data(&netoring, tmp, cp-tmp);
	printsub('>', tmp+2, cp - tmp - 2);
    }
}

void
tel_enter_binary(int rw)
{
    if (rw&1)
	send_do(TELOPT_BINARY, 1);
    if (rw&2)
	send_will(TELOPT_BINARY, 1);
}

void
tel_leave_binary(int rw)
{
    if (rw&1)
	send_dont(TELOPT_BINARY, 1);
    if (rw&2)
	send_wont(TELOPT_BINARY, 1);
}

File Added: pkgsrc/comms/tn3270/files/telnet/Attic/terminal.c
/*	$NetBSD: terminal.c,v 1.1.1.1 2010/01/17 01:33:32 dholland Exp $	*/
/*	From NetBSD: terminal.c,v 1.15 2005/02/19 23:28:41 christos Exp 	*/

/*
 * Copyright (c) 1988, 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. 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.
 */

#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)terminal.c	8.2 (Berkeley) 2/16/95";
#else
__RCSID("$NetBSD: terminal.c,v 1.1.1.1 2010/01/17 01:33:32 dholland Exp $");
#endif
#endif /* not lint */

#include <arpa/telnet.h>
#include <sys/types.h>

#include "ring.h"

#include "externs.h"
#include "types.h"

#ifdef ENCRYPTION
#include <libtelnet/encrypt.h>
#endif

Ring		ttyoring, ttyiring;
unsigned char	ttyobuf[2*BUFSIZ], ttyibuf[BUFSIZ];
char line[] = { '\0' };

int termdata;			/* Debugging flag */

/*
 * initialize the terminal data structures.
 */

void
init_terminal(void)
{
    if (ring_init(&ttyoring, ttyobuf, sizeof ttyobuf) != 1) {
	exit(1);
    }
    if (ring_init(&ttyiring, ttyibuf, sizeof ttyibuf) != 1) {
	exit(1);
    }
    autoflush = TerminalAutoFlush();
}


/*
 *		Send as much data as possible to the terminal, else exits if
 *		it encounters a permanent failure when writing to the tty.
 *
 *		Return value:
 *			-1: No useful work done, data waiting to go out.
 *			 0: No data was waiting, so nothing was done.
 *			 1: All waiting data was written out.
 *			 n: All data - n was written out.
 */


int
ttyflush(int drop)
{
    int n, n0, n1;

    n0 = ring_full_count(&ttyoring);
    if ((n1 = n = ring_full_consecutive(&ttyoring)) > 0) {
	if (drop) {
	    TerminalFlushOutput();
	    /* we leave 'n' alone! */
	} else {
	    n = TerminalWrite(ttyoring.consume, n);
	}
    }
    if (n > 0) {
	if (termdata && n) {
	    Dump('>', ttyoring.consume, n);
	}
	/*
	 * If we wrote everything, and the full count is
	 * larger than what we wrote, then write the
	 * rest of the buffer.
	 */
	if (n1 == n && n0 > n) {
		n1 = n0 - n;
		if (!drop)
			n1 = TerminalWrite(ttyoring.bottom, n1);
		if (n1 > 0)
			n += n1;
	}
	ring_consumed(&ttyoring, n);
    }
    if (n < 0) {
	if (errno == EAGAIN || errno == EINTR) {
	    return -1;
	} else {
	    ring_consumed(&ttyoring, ring_full_count(&ttyoring));
	    setconnmode(0);
	    setcommandmode();
	    NetClose(net);
	    fprintf(stderr, "Connection closed by foreign host.\n");
	    exit(1);
	}
    }
    if (n == n0) {
	if (n0)
	    return -1;
	return 0;
    }
    return n0 - n + 1;
}


/*
 * These routines decides on what the mode should be (based on the values
 * of various global variables).
 */


int
getconnmode(void)
{
    extern int linemode;
    int mode = 0;
#ifdef	KLUDGELINEMODE
    extern int kludgelinemode;
#endif

    if (In3270)
	return(MODE_FLOW);

    if (my_want_state_is_dont(TELOPT_ECHO))
	mode |= MODE_ECHO;

    if (localflow)
	mode |= MODE_FLOW;

    if (my_want_state_is_will(TELOPT_BINARY))
	mode |= MODE_INBIN;

    if (his_want_state_is_will(TELOPT_BINARY))
	mode |= MODE_OUTBIN;

#ifdef	KLUDGELINEMODE
    if (kludgelinemode) {
	if (my_want_state_is_dont(TELOPT_SGA)) {
	    mode |= (MODE_TRAPSIG|MODE_EDIT);
	    if (dontlecho && (clocks.echotoggle > clocks.modenegotiated)) {
		mode &= ~MODE_ECHO;
	    }
	}
	return(mode);
    }
#endif
    if (my_want_state_is_will(TELOPT_LINEMODE))
	mode |= linemode;
    return(mode);
}

void
setconnmode(int force)
{
#ifdef	ENCRYPTION
    static int enc_passwd = 0;
#endif
    int newmode;

    newmode = getconnmode()|(force?MODE_FORCE:0);

    TerminalNewMode(newmode);

#ifdef	ENCRYPTION
    if ((newmode & (MODE_ECHO|MODE_EDIT)) == MODE_EDIT) {
	if (my_want_state_is_will(TELOPT_ENCRYPT)
				&& (enc_passwd == 0) && !encrypt_output) {
	    encrypt_request_start(0, 0);
	    enc_passwd = 1;
	}
    } else {
	if (enc_passwd) {
	    encrypt_request_end();
	    enc_passwd = 0;
	}
    }
#endif	/* ENCRYPTION */
}


void
setcommandmode(void)
{
    TerminalNewMode(-1);
}

File Added: pkgsrc/comms/tn3270/files/telnet/Attic/tn3270.c
/*	$NetBSD: tn3270.c,v 1.1.1.1 2010/01/17 01:33:32 dholland Exp $	*/
/*	From NetBSD: tn3270.c,v 1.22 2006/10/07 17:27:57 elad Exp 	*/

/*
 * 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. 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.
 */

#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)tn3270.c	8.2 (Berkeley) 5/30/95";
#else
__RCSID("$NetBSD: tn3270.c,v 1.1.1.1 2010/01/17 01:33:32 dholland Exp $");
#endif
#endif /* not lint */

#include <sys/types.h>
#include <sys/time.h>
#include <arpa/telnet.h>
#include <unistd.h>
#include <poll.h>

#include "general.h"
#include "defines.h"
#include "ring.h"
#include "externs.h"

#ifdef TN3270

#include "../ctlr/screen.h"
#include "../ctlr/declare.h"

#include "../ascii/state.h"

#include "../general/globals.h"

#include "../sys_curses/telextrn.h"

int
	HaveInput,		/* There is input available to scan */
	cursesdata,		/* Do we dump curses data? */
	sigiocount;		/* Number of times we got a SIGIO */

char	tline[200];
char	*transcom = 0;	/* transparent mode command (default: none) */

char	Ibuf[8*BUFSIZ], *Ifrontp, *Ibackp;

static char	sb_terminal[] = { IAC, SB,
			TELOPT_TTYPE, TELQUAL_IS,
			'I', 'B', 'M', '-', '3', '2', '7', '8', '-', '2',
			IAC, SE };
#define	SBTERMMODEL	13

static int
	Sent3270TerminalType;	/* Have we said we are a 3270? */

#endif	/* defined(TN3270) */


#ifdef TN3270
void
init_3270(void)
{
    HaveInput = 0;
    sigiocount = 0;
    Sent3270TerminalType = 0;
    Ifrontp = Ibackp = Ibuf;
    init_ctlr();		/* Initialize some things */
    init_keyboard();
    init_screen();
    init_system();
}
#endif	/* defined(TN3270) */


#ifdef TN3270

/*
 * DataToNetwork - queue up some data to go to network.  If "done" is set,
 * then when last byte is queued, we add on an IAC EOR sequence (so,
 * don't call us with "done" until you want that done...)
 *
 * We actually do send all the data to the network buffer, since our
 * only client needs for us to do that.
 */

int
DataToNetwork(char *buffer,	/* where the data is */
    int  count,	/* how much to send */
    int		  done)		/* is this the last of a logical block */
{
    int loop, c;
    int origCount;

    origCount = count;

    while (count) {
	/* If not enough room for EORs, IACs, etc., wait */
	if (NETROOM() < 6) {
	    struct pollfd set[1];

	    set[0].fd = net;
	    set[0].events = POLLOUT;
	    netflush();
	    while (NETROOM() < 6) {
		(void) poll(set, 1, INFTIM);
		netflush();
	    }
	}
	c = ring_empty_count(&netoring);
	if (c > count) {
	    c = count;
	}
	loop = c;
	while (loop) {
	    if (((unsigned char)*buffer) == IAC) {
		break;
	    }
	    buffer++;
	    loop--;
	}
	if ((c = c-loop)) {
	    ring_supply_data(&netoring, buffer-c, c);
	    count -= c;
	}
	if (loop) {
	    NET2ADD(IAC, IAC);
	    count--;
	    buffer++;
	}
    }

    if (done) {
	NET2ADD(IAC, EOR);
	netflush();		/* try to move along as quickly as ... */
    }
    return(origCount - count);
}


void
inputAvailable(int signo)
{
    HaveInput = 1;
    sigiocount++;
}

void
outputPurge(void)
{
    (void) ttyflush(1);
}


/*
 * The following routines are places where the various tn3270
 * routines make calls into telnet.c.
 */

/*
 * DataToTerminal - queue up some data to go to terminal.
 *
 * Note: there are people who call us and depend on our processing
 * *all* the data at one time (thus the poll).
 */

int
DataToTerminal(
    char	*buffer,		/* where the data is */
    int	count)			/* how much to send */
{
    int c;
    int origCount;

    origCount = count;

    while (count) {
	if (TTYROOM() == 0) {
	    struct pollfd set[1];

	    set[0].fd = tout;
	    set[0].events = POLLOUT;
	    (void) ttyflush(0);
	    while (TTYROOM() == 0) {
		(void) poll(set, 1, INFTIM);
		(void) ttyflush(0);
	    }
	}
	c = TTYROOM();
	if (c > count) {
	    c = count;
	}
	ring_supply_data(&ttyoring, buffer, c);
	count -= c;
	buffer += c;
    }
    return(origCount);
}


/*
 * Push3270 - Try to send data along the 3270 output (to screen) direction.
 */

int
Push3270(void)
{
    int save = ring_full_count(&netiring);

    if (save) {
	if (Ifrontp+save > Ibuf+sizeof Ibuf) {
	    if (Ibackp != Ibuf) {
		memmove(Ibuf, Ibackp, Ifrontp-Ibackp);
		Ifrontp -= (Ibackp-Ibuf);
		Ibackp = Ibuf;
	    }
	}
	if (Ifrontp+save < Ibuf+sizeof Ibuf) {
	    (void)telrcv();
	}
    }
    return save != ring_full_count(&netiring);
}


/*
 * Finish3270 - get the last dregs of 3270 data out to the terminal
 *		before quitting.
 */

void
Finish3270(void)
{
    while (Push3270() || !DoTerminalOutput()) {
	HaveInput = 0;
	;
    }
}


/* StringToTerminal - output a null terminated string to the terminal */

void
StringToTerminal(char *s)
{
    int count;

    count = strlen(s);
    if (count) {
	(void) DataToTerminal(s, count);	/* we know it always goes... */
    }
}


/* _putchar - output a single character to the terminal.  This name is so that
 *	curses(3x) can call us to send out data.
 */

int
_putchar(int cc)
{
    char c = (char)cc;
    if (cursesdata) {
	Dump('>', &c, 1);
    }
    if (!TTYROOM()) {
	(void) DataToTerminal(&c, 1);
    } else {
	TTYADD(c);
    }

    return (0);
}

void
SetIn3270(void)
{
    if (Sent3270TerminalType && my_want_state_is_will(TELOPT_BINARY)
		&& my_want_state_is_do(TELOPT_BINARY) && !donebinarytoggle) {
	if (!In3270) {
	    In3270 = 1;
	    Init3270();		/* Initialize 3270 functions */
	    /* initialize terminal key mapping */
	    InitTerminal();	/* Start terminal going */
	    setconnmode(0);
	}
    } else {
	if (In3270) {
	    StopScreen(1);
	    In3270 = 0;
	    Stop3270();		/* Tell 3270 we aren't here anymore */
	    setconnmode(0);
	}
    }
}

/*
 * tn3270_ttype()
 *
 *	Send a response to a terminal type negotiation.
 *
 *	Return '0' if no more responses to send; '1' if a response sent.
 */

int
tn3270_ttype(void)
{
    /*
     * Try to send a 3270 type terminal name.  Decide which one based
     * on the format of our screen, and (in the future) color
     * capaiblities.
     */
    InitTerminal();		/* Sets MaxNumberColumns, MaxNumberLines */
    if ((MaxNumberLines >= 24) && (MaxNumberColumns >= 80)) {
	Sent3270TerminalType = 1;
	if ((MaxNumberLines >= 27) && (MaxNumberColumns >= 132)) {
	    MaxNumberLines = 27;
	    MaxNumberColumns = 132;
	    sb_terminal[SBTERMMODEL] = '5';
	} else if (MaxNumberLines >= 43) {
	    MaxNumberLines = 43;
	    MaxNumberColumns = 80;
	    sb_terminal[SBTERMMODEL] = '4';
	} else if (MaxNumberLines >= 32) {
	    MaxNumberLines = 32;
	    MaxNumberColumns = 80;
	    sb_terminal[SBTERMMODEL] = '3';
	} else {
	    MaxNumberLines = 24;
	    MaxNumberColumns = 80;
	    sb_terminal[SBTERMMODEL] = '2';
	}
	NumberLines = 24;		/* before we start out... */
	NumberColumns = 80;
	ScreenSize = NumberLines*NumberColumns;
	if ((MaxNumberLines*MaxNumberColumns) > MAXSCREENSIZE) {
	    ExitString("Programming error:  MAXSCREENSIZE too small.\n",
								1);
	    /*NOTREACHED*/
	}
	printsub('>', sb_terminal+2, sizeof sb_terminal-2);
	ring_supply_data(&netoring, sb_terminal, sizeof sb_terminal);
	return 1;
    } else {
	return 0;
    }
}

int
settranscom(int argc, char *argv[])
{
	int i;

	if (argc == 1 && transcom) {
	   transcom = 0;
	}
	if (argc == 1) {
	   return 1;
	}
	transcom = tline;
	(void) strlcpy(tline, argv[1], sizeof(tline));
	for (i = 2; i < argc; ++i) {
	    (void) strlcat(tline, " ", sizeof(tline));
	    (void) strlcat(tline, argv[i], sizeof(tline));
	}
	return 1;
}

#endif	/* defined(TN3270) */

File Added: pkgsrc/comms/tn3270/files/telnet/Attic/types.h
/*	$NetBSD: types.h,v 1.1.1.1 2010/01/17 01:33:32 dholland Exp $	*/
/*	From NetBSD: types.h,v 1.6 2003/08/07 11:16:12 agc Exp 	*/

/*
 * 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. 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.
 *
 *	from: @(#)types.h	8.1 (Berkeley) 6/6/93
 */

typedef struct {
    char *modedescriptions;
    char modetype;
} Modelist;

extern Modelist modelist[];

typedef struct {
    int
	system,			/* what the current time is */
	echotoggle,		/* last time user entered echo character */
	modenegotiated,		/* last time operating mode negotiated */
	didnetreceive,		/* last time we read data from network */
	gotDM;			/* when did we last see a data mark */
} Clocks;

extern Clocks clocks;

File Added: pkgsrc/comms/tn3270/files/telnet/Attic/utilities.c
/*	$NetBSD: utilities.c,v 1.1.1.1 2010/01/17 01:33:33 dholland Exp $	*/
/*	From NetBSD: utilities.c,v 1.22 2006/10/07 17:27:57 elad Exp 	*/

/*
 * 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. 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.
 */

#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)utilities.c	8.3 (Berkeley) 5/30/95";
#else
__RCSID("$NetBSD: utilities.c,v 1.1.1.1 2010/01/17 01:33:33 dholland Exp $");
#endif
#endif /* not lint */

#define	TELOPTS
#define	TELCMDS
#define	SLC_NAMES
#include <arpa/telnet.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <unistd.h>
#include <poll.h>

#include <ctype.h>

#include "general.h"
#include "ring.h"
#include "defines.h"
#include "externs.h"

#ifdef TN3270
#include "../sys_curses/telextrn.h"
#endif

#ifdef AUTHENTICATION
#include <libtelnet/auth.h>
#endif
#ifdef ENCRYPTION
#include <libtelnet/encrypt.h>
#endif

FILE	*NetTrace = 0;		/* Not in bss, since needs to stay */
int	prettydump;

/*
 * upcase()
 *
 *	Upcase (in place) the argument.
 */

void
upcase(char *argument)
{
    int c;

    while ((c = *argument) != 0) {
	if (islower(c)) {
	    *argument = toupper(c);
	}
	argument++;
    }
}

/*
 * SetSockOpt()
 *
 * Compensate for differences in 4.2 and 4.3 systems.
 */

int
SetSockOpt(int fd, int level, int option, int yesno)
{
    return setsockopt(fd, level, option, (char *)&yesno, sizeof yesno);
}

/*
 * The following are routines used to print out debugging information.
 */

char NetTraceFile[256] = "(standard output)";

void
SetNetTrace(char *file)
{
    if (NetTrace && NetTrace != stdout)
	fclose(NetTrace);
    if (file  && (strcmp(file, "-") != 0)) {
	NetTrace = fopen(file, "w");
	if (NetTrace) {
	    strlcpy(NetTraceFile, file, sizeof(NetTraceFile));
	    return;
	}
	fprintf(stderr, "Cannot open %s.\n", file);
    }
    NetTrace = stdout;
    strlcpy(NetTraceFile, "(standard output)", sizeof(NetTraceFile));
}

void
Dump(int direction, unsigned char *buffer, int length)
{
#   define BYTES_PER_LINE	32
#   define min(x,y)	((x<y)? x:y)
    unsigned char *pThis;
    int offset;

    offset = 0;

    while (length) {
	/* print one line */
	fprintf(NetTrace, "%c 0x%x\t", direction, offset);
	pThis = buffer;
	if (prettydump) {
	    buffer = buffer + min(length, BYTES_PER_LINE/2);
	    while (pThis < buffer) {
		fprintf(NetTrace, "%c%.2x",
		    (((*pThis)&0xff) == 0xff) ? '*' : ' ',
		    (*pThis)&0xff);
		pThis++;
	    }
	    length -= BYTES_PER_LINE/2;
	    offset += BYTES_PER_LINE/2;
	} else {
	    buffer = buffer + min(length, BYTES_PER_LINE);
	    while (pThis < buffer) {
		fprintf(NetTrace, "%.2x", (*pThis)&0xff);
		pThis++;
	    }
	    length -= BYTES_PER_LINE;
	    offset += BYTES_PER_LINE;
	}
	if (NetTrace == stdout) {
	    fprintf(NetTrace, "\r\n");
	} else {
	    fprintf(NetTrace, "\n");
	}
	if (length < 0) {
	    fflush(NetTrace);
	    return;
	}
	/* find next unique line */
    }
    fflush(NetTrace);
}


void
printoption(char *direction, int cmd, int option)
{
	if (!showoptions)
		return;
	if (cmd == IAC) {
		if (TELCMD_OK(option))
		    fprintf(NetTrace, "%s IAC %s", direction, TELCMD(option));
		else
		    fprintf(NetTrace, "%s IAC %d", direction, option);
	} else {
		char *fmt;
		fmt = (cmd == WILL) ? "WILL" : (cmd == WONT) ? "WONT" :
			(cmd == DO) ? "DO" : (cmd == DONT) ? "DONT" : 0;
		if (fmt) {
		    fprintf(NetTrace, "%s %s ", direction, fmt);
		    if (TELOPT_OK(option))
			fprintf(NetTrace, "%s", TELOPT(option));
		    else if (option == TELOPT_EXOPL)
			fprintf(NetTrace, "EXOPL");
		    else
			fprintf(NetTrace, "%d", option);
		} else
		    fprintf(NetTrace, "%s %d %d", direction, cmd, option);
	}
	if (NetTrace == stdout) {
	    fprintf(NetTrace, "\r\n");
	    fflush(NetTrace);
	} else {
	    fprintf(NetTrace, "\n");
	}
	return;
}

void
optionstatus(void)
{
    int i;
    extern char will_wont_resp[], do_dont_resp[];

    for (i = 0; i < 256; i++) {
	if (do_dont_resp[i]) {
	    if (TELOPT_OK(i))
		printf("resp DO_DONT %s: %d\n", TELOPT(i), do_dont_resp[i]);
	    else if (TELCMD_OK(i))
		printf("resp DO_DONT %s: %d\n", TELCMD(i), do_dont_resp[i]);
	    else
		printf("resp DO_DONT %d: %d\n", i,
				do_dont_resp[i]);
	    if (my_want_state_is_do(i)) {
		if (TELOPT_OK(i))
		    printf("want DO   %s\n", TELOPT(i));
		else if (TELCMD_OK(i))
		    printf("want DO   %s\n", TELCMD(i));
		else
		    printf("want DO   %d\n", i);
	    } else {
		if (TELOPT_OK(i))
		    printf("want DONT %s\n", TELOPT(i));
		else if (TELCMD_OK(i))
		    printf("want DONT %s\n", TELCMD(i));
		else
		    printf("want DONT %d\n", i);
	    }
	} else {
	    if (my_state_is_do(i)) {
		if (TELOPT_OK(i))
		    printf("     DO   %s\n", TELOPT(i));
		else if (TELCMD_OK(i))
		    printf("     DO   %s\n", TELCMD(i));
		else
		    printf("     DO   %d\n", i);
	    }
	}
	if (will_wont_resp[i]) {
	    if (TELOPT_OK(i))
		printf("resp WILL_WONT %s: %d\n", TELOPT(i), will_wont_resp[i]);
	    else if (TELCMD_OK(i))
		printf("resp WILL_WONT %s: %d\n", TELCMD(i), will_wont_resp[i]);
	    else
		printf("resp WILL_WONT %d: %d\n",
				i, will_wont_resp[i]);
	    if (my_want_state_is_will(i)) {
		if (TELOPT_OK(i))
		    printf("want WILL %s\n", TELOPT(i));
		else if (TELCMD_OK(i))
		    printf("want WILL %s\n", TELCMD(i));
		else
		    printf("want WILL %d\n", i);
	    } else {
		if (TELOPT_OK(i))
		    printf("want WONT %s\n", TELOPT(i));
		else if (TELCMD_OK(i))
		    printf("want WONT %s\n", TELCMD(i));
		else
		    printf("want WONT %d\n", i);
	    }
	} else {
	    if (my_state_is_will(i)) {
		if (TELOPT_OK(i))
		    printf("     WILL %s\n", TELOPT(i));
		else if (TELCMD_OK(i))
		    printf("     WILL %s\n", TELCMD(i));
		else
		    printf("     WILL %d\n", i);
	    }
	}
    }

}

void
printsub(
    int direction,	/* '<' or '>' */
    unsigned char *pointer,	/* where suboption data sits */
    int		  length)	/* length of suboption data */
{
    int i;
#ifdef	ENCRYPTION
    char buf[512];
#endif	/* ENCRYPTION */
    extern int want_status_response;

    if (showoptions || direction == 0 ||
	(want_status_response && (pointer[0] == TELOPT_STATUS))) {
	if (direction) {
	    fprintf(NetTrace, "%s IAC SB ",
				(direction == '<')? "RCVD":"SENT");
	    if (length >= 3) {
		int j;

		i = pointer[length-2];
		j = pointer[length-1];

		if (i != IAC || j != SE) {
		    fprintf(NetTrace, "(terminated by ");
		    if (TELOPT_OK(i))
			fprintf(NetTrace, "%s ", TELOPT(i));
		    else if (TELCMD_OK(i))
			fprintf(NetTrace, "%s ", TELCMD(i));
		    else
			fprintf(NetTrace, "%d ", i);
		    if (TELOPT_OK(j))
			fprintf(NetTrace, "%s", TELOPT(j));
		    else if (TELCMD_OK(j))
			fprintf(NetTrace, "%s", TELCMD(j));
		    else
			fprintf(NetTrace, "%d", j);
		    fprintf(NetTrace, ", not IAC SE!) ");
		}
	    }
	    length -= 2;
	}
	if (length < 1) {
	    fprintf(NetTrace, "(Empty suboption??\?)");
	    if (NetTrace == stdout)
		fflush(NetTrace);
	    return;
	}
	switch (pointer[0]) {
	case TELOPT_TTYPE:
	    fprintf(NetTrace, "TERMINAL-TYPE ");
	    switch (pointer[1]) {
	    case TELQUAL_IS:
		fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2);
		break;
	    case TELQUAL_SEND:
		fprintf(NetTrace, "SEND");
		break;
	    default:
		fprintf(NetTrace,
				"- unknown qualifier %d (0x%x).",
				pointer[1], pointer[1]);
	    }
	    break;
	case TELOPT_TSPEED:
	    fprintf(NetTrace, "TERMINAL-SPEED");
	    if (length < 2) {
		fprintf(NetTrace, " (empty suboption??\?)");
		break;
	    }
	    switch (pointer[1]) {
	    case TELQUAL_IS:
		fprintf(NetTrace, " IS ");
		fprintf(NetTrace, "%.*s", length-2, (char *)pointer+2);
		break;
	    default:
		if (pointer[1] == 1)
		    fprintf(NetTrace, " SEND");
		else
		    fprintf(NetTrace, " %d (unknown)", pointer[1]);
		for (i = 2; i < length; i++)
		    fprintf(NetTrace, " ?%d?", pointer[i]);
		break;
	    }
	    break;

	case TELOPT_LFLOW:
	    fprintf(NetTrace, "TOGGLE-FLOW-CONTROL");
	    if (length < 2) {
		fprintf(NetTrace, " (empty suboption??\?)");
		break;
	    }
	    switch (pointer[1]) {
	    case LFLOW_OFF:
		fprintf(NetTrace, " OFF"); break;
	    case LFLOW_ON:
		fprintf(NetTrace, " ON"); break;
	    case LFLOW_RESTART_ANY:
		fprintf(NetTrace, " RESTART-ANY"); break;
	    case LFLOW_RESTART_XON:
		fprintf(NetTrace, " RESTART-XON"); break;
	    default:
		fprintf(NetTrace, " %d (unknown)", pointer[1]);
	    }
	    for (i = 2; i < length; i++)
		fprintf(NetTrace, " ?%d?", pointer[i]);
	    break;

	case TELOPT_NAWS:
	    fprintf(NetTrace, "NAWS");
	    if (length < 2) {
		fprintf(NetTrace, " (empty suboption??\?)");
		break;
	    }
	    if (length == 2) {
		fprintf(NetTrace, " ?%d?", pointer[1]);
		break;
	    }
	    fprintf(NetTrace, " %d %d (%d)",
		pointer[1], pointer[2],
		(int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2])));
	    if (length == 4) {
		fprintf(NetTrace, " ?%d?", pointer[3]);
		break;
	    }
	    fprintf(NetTrace, " %d %d (%d)",
		pointer[3], pointer[4],
		(int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4])));
	    for (i = 5; i < length; i++)
		fprintf(NetTrace, " ?%d?", pointer[i]);
	    break;

#ifdef AUTHENTICATION
	case TELOPT_AUTHENTICATION:
	    fprintf(NetTrace, "AUTHENTICATION");
	    if (length < 2) {
		fprintf(NetTrace, " (empty suboption??\?)");
		break;
	    }
	    switch (pointer[1]) {
	    case TELQUAL_REPLY:
	    case TELQUAL_IS:
		fprintf(NetTrace, " %s ", (pointer[1] == TELQUAL_IS) ?
							"IS" : "REPLY");
		if (AUTHTYPE_NAME_OK(pointer[2]))
		    fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[2]));
		else
		    fprintf(NetTrace, "%d ", pointer[2]);
		if (length < 3) {
		    fprintf(NetTrace, "(partial suboption??\?)");
		    break;
		}
		fprintf(NetTrace, "%s|%s",
			((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ?
			"CLIENT" : "SERVER",
			((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ?
			"MUTUAL" : "ONE-WAY");

		auth_printsub(&pointer[1], length - 1, buf, sizeof(buf));
		fprintf(NetTrace, "%s", buf);
		break;

	    case TELQUAL_SEND:
		i = 2;
		fprintf(NetTrace, " SEND ");
		while (i < length) {
		    if (AUTHTYPE_NAME_OK(pointer[i]))
			fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[i]));
		    else
			fprintf(NetTrace, "%d ", pointer[i]);
		    if (++i >= length) {
			fprintf(NetTrace, "(partial suboption??\?)");
			break;
		    }
		    fprintf(NetTrace, "%s|%s ",
			((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ?
							"CLIENT" : "SERVER",
			((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ?
							"MUTUAL" : "ONE-WAY");
		    ++i;
		}
		break;

	    case TELQUAL_NAME:
		i = 2;
		fprintf(NetTrace, " NAME \"");
		while (i < length)
		    putc(pointer[i++], NetTrace);
		putc('"', NetTrace);
		break;

	    default:
		    for (i = 2; i < length; i++)
			fprintf(NetTrace, " ?%d?", pointer[i]);
		    break;
	    }
	    break;
#endif

#ifdef	ENCRYPTION
	case TELOPT_ENCRYPT:
		fprintf(NetTrace, "ENCRYPT");
		if (length < 2) {
			fprintf(NetTrace, " (empty suboption??\?)");
			break;
		}
		switch (pointer[1]) {
		case ENCRYPT_START:
			fprintf(NetTrace, " START");
			break;

		case ENCRYPT_END:
			fprintf(NetTrace, " END");
			break;

		case ENCRYPT_REQSTART:
			fprintf(NetTrace, " REQUEST-START");
			break;

		case ENCRYPT_REQEND:
			fprintf(NetTrace, " REQUEST-END");
			break;

		case ENCRYPT_IS:
		case ENCRYPT_REPLY:
			fprintf(NetTrace, " %s ", (pointer[1] == ENCRYPT_IS) ?
			    "IS" : "REPLY");
			if (length < 3) {
				fprintf(NetTrace, " (partial suboption??\?)");
				break;
			}
			if (ENCTYPE_NAME_OK(pointer[2]))
				fprintf(NetTrace, "%s ",
				    ENCTYPE_NAME(pointer[2]));
			else
				fprintf(NetTrace, " %d (unknown)", pointer[2]);

			encrypt_printsub(&pointer[1], length - 1, buf,
			    sizeof(buf));
			fprintf(NetTrace, "%s", buf);
			break;

		case ENCRYPT_SUPPORT:
			i = 2;
			fprintf(NetTrace, " SUPPORT ");
			while (i < length) {
				if (ENCTYPE_NAME_OK(pointer[i]))
					fprintf(NetTrace, "%s ",
					    ENCTYPE_NAME(pointer[i]));
				else
					fprintf(NetTrace, "%d ", pointer[i]);
				i++;
			}
			break;

		case ENCRYPT_ENC_KEYID:
			fprintf(NetTrace, " ENC_KEYID ");
			goto encommon;

		case ENCRYPT_DEC_KEYID:
			fprintf(NetTrace, " DEC_KEYID ");
			goto encommon;

		default:
			fprintf(NetTrace, " %d (unknown)", pointer[1]);
		encommon:
			for (i = 2; i < length; i++)
				fprintf(NetTrace, " %d", pointer[i]);
			break;
		}
		break;
#endif	/* ENCRYPTION */

	case TELOPT_LINEMODE:
	    fprintf(NetTrace, "LINEMODE ");
	    if (length < 2) {
		fprintf(NetTrace, " (empty suboption??\?)");
		break;
	    }
	    switch (pointer[1]) {
	    case WILL:
		fprintf(NetTrace, "WILL ");
		goto common;
	    case WONT:
		fprintf(NetTrace, "WONT ");
		goto common;
	    case DO:
		fprintf(NetTrace, "DO ");
		goto common;
	    case DONT:
		fprintf(NetTrace, "DONT ");
	    common:
		if (length < 3) {
		    fprintf(NetTrace, "(no option??\?)");
		    break;
		}
		switch (pointer[2]) {
		case LM_FORWARDMASK:
		    fprintf(NetTrace, "Forward Mask");
		    for (i = 3; i < length; i++)
			fprintf(NetTrace, " %x", pointer[i]);
		    break;
		default:
		    fprintf(NetTrace, "%d (unknown)", pointer[2]);
		    for (i = 3; i < length; i++)
			fprintf(NetTrace, " %d", pointer[i]);
		    break;
		}
		break;

	    case LM_SLC:
		fprintf(NetTrace, "SLC");
		for (i = 2; i < length - 2; i += 3) {
		    if (SLC_NAME_OK(pointer[i+SLC_FUNC]))
			fprintf(NetTrace, " %s", SLC_NAME(pointer[i+SLC_FUNC]));
		    else
			fprintf(NetTrace, " %d", pointer[i+SLC_FUNC]);
		    switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) {
		    case SLC_NOSUPPORT:
			fprintf(NetTrace, " NOSUPPORT"); break;
		    case SLC_CANTCHANGE:
			fprintf(NetTrace, " CANTCHANGE"); break;
		    case SLC_VARIABLE:
			fprintf(NetTrace, " VARIABLE"); break;
		    case SLC_DEFAULT:
			fprintf(NetTrace, " DEFAULT"); break;
		    }
		    fprintf(NetTrace, "%s%s%s",
			pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "",
			pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "",
			pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : "");
		    if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN|
						SLC_FLUSHOUT| SLC_LEVELBITS))
			fprintf(NetTrace, "(0x%x)", pointer[i+SLC_FLAGS]);
		    fprintf(NetTrace, " %d;", pointer[i+SLC_VALUE]);
		    if ((pointer[i+SLC_VALUE] == IAC) &&
			(pointer[i+SLC_VALUE+1] == IAC))
				i++;
		}
		for (; i < length; i++)
		    fprintf(NetTrace, " ?%d?", pointer[i]);
		break;

	    case LM_MODE:
		fprintf(NetTrace, "MODE ");
		if (length < 3) {
		    fprintf(NetTrace, "(no mode??\?)");
		    break;
		}
		{
		    char tbuf[64];
		    sprintf(tbuf, "%s%s%s%s%s",
			pointer[2]&MODE_EDIT ? "|EDIT" : "",
			pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "",
			pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "",
			pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "",
			pointer[2]&MODE_ACK ? "|ACK" : "");
		    fprintf(NetTrace, "%s", tbuf[1] ? &tbuf[1] : "0");
		}
		if (pointer[2]&~(MODE_MASK))
		    fprintf(NetTrace, " (0x%x)", pointer[2]);
		for (i = 3; i < length; i++)
		    fprintf(NetTrace, " ?0x%x?", pointer[i]);
		break;
	    default:
		fprintf(NetTrace, "%d (unknown)", pointer[1]);
		for (i = 2; i < length; i++)
		    fprintf(NetTrace, " %d", pointer[i]);
	    }
	    break;

	case TELOPT_STATUS: {
	    char *cp;
	    int j, k;

	    fprintf(NetTrace, "STATUS");

	    switch (pointer[1]) {
	    default:
		if (pointer[1] == TELQUAL_SEND)
		    fprintf(NetTrace, " SEND");
		else
		    fprintf(NetTrace, " %d (unknown)", pointer[1]);
		for (i = 2; i < length; i++)
		    fprintf(NetTrace, " ?%d?", pointer[i]);
		break;
	    case TELQUAL_IS:
		if (--want_status_response < 0)
		    want_status_response = 0;
		if (NetTrace == stdout)
		    fprintf(NetTrace, " IS\r\n");
		else
		    fprintf(NetTrace, " IS\n");

		for (i = 2; i < length; i++) {
		    switch(pointer[i]) {
		    case DO:	cp = "DO"; goto common2;
		    case DONT:	cp = "DONT"; goto common2;
		    case WILL:	cp = "WILL"; goto common2;
		    case WONT:	cp = "WONT"; goto common2;
		    common2:
			i++;
			if (TELOPT_OK((int)pointer[i]))
			    fprintf(NetTrace, " %s %s", cp, TELOPT(pointer[i]));
			else
			    fprintf(NetTrace, " %s %d", cp, pointer[i]);

			if (NetTrace == stdout)
			    fprintf(NetTrace, "\r\n");
			else
			    fprintf(NetTrace, "\n");
			break;

		    case SB:
			fprintf(NetTrace, " SB ");
			i++;
			j = k = i;
			while (j < length) {
			    if (pointer[j] == SE) {
				if (j+1 == length)
				    break;
				if (pointer[j+1] == SE)
				    j++;
				else
				    break;
			    }
			    pointer[k++] = pointer[j++];
			}
			printsub(0, &pointer[i], k - i);
			if (i < length) {
			    fprintf(NetTrace, " SE");
			    i = j;
			} else
			    i = j - 1;

			if (NetTrace == stdout)
			    fprintf(NetTrace, "\r\n");
			else
			    fprintf(NetTrace, "\n");

			break;

		    default:
			fprintf(NetTrace, " %d", pointer[i]);
			break;
		    }
		}
		break;
	    }
	    break;
	  }

	case TELOPT_XDISPLOC:
	    fprintf(NetTrace, "X-DISPLAY-LOCATION ");
	    switch (pointer[1]) {
	    case TELQUAL_IS:
		fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2);
		break;
	    case TELQUAL_SEND:
		fprintf(NetTrace, "SEND");
		break;
	    default:
		fprintf(NetTrace, "- unknown qualifier %d (0x%x).",
				pointer[1], pointer[1]);
	    }
	    break;

	case TELOPT_NEW_ENVIRON:
	    fprintf(NetTrace, "NEW-ENVIRON ");
#ifdef	OLD_ENVIRON
	    goto env_common1;
	case TELOPT_OLD_ENVIRON:
	    fprintf(NetTrace, "OLD-ENVIRON");
	env_common1:
#endif
	    switch (pointer[1]) {
	    case TELQUAL_IS:
		fprintf(NetTrace, "IS ");
		goto env_common;
	    case TELQUAL_SEND:
		fprintf(NetTrace, "SEND ");
		goto env_common;
	    case TELQUAL_INFO:
		fprintf(NetTrace, "INFO ");
	    env_common:
		{
		    int noquote = 2;
#if defined(ENV_HACK) && defined(OLD_ENVIRON)
		    extern int old_env_var, old_env_value;
#endif
		    for (i = 2; i < length; i++ ) {
			switch (pointer[i]) {
			case NEW_ENV_VALUE:
#ifdef OLD_ENVIRON
		     /*	case NEW_ENV_OVAR: */
			    if (pointer[0] == TELOPT_OLD_ENVIRON) {
# ifdef	ENV_HACK
				if (old_env_var == OLD_ENV_VALUE)
				    fprintf(NetTrace, "\" (VALUE) " + noquote);
				else
# endif
				    fprintf(NetTrace, "\" VAR " + noquote);
			    } else
#endif /* OLD_ENVIRON */
				fprintf(NetTrace, "\" VALUE " + noquote);
			    noquote = 2;
			    break;

			case NEW_ENV_VAR:
#ifdef OLD_ENVIRON
		     /* case OLD_ENV_VALUE: */
			    if (pointer[0] == TELOPT_OLD_ENVIRON) {
# ifdef	ENV_HACK
				if (old_env_value == OLD_ENV_VAR)
				    fprintf(NetTrace, "\" (VAR) " + noquote);
				else
# endif
				    fprintf(NetTrace, "\" VALUE " + noquote);
			    } else
#endif /* OLD_ENVIRON */
				fprintf(NetTrace, "\" VAR " + noquote);
			    noquote = 2;
			    break;

			case ENV_ESC:
			    fprintf(NetTrace, "\" ESC " + noquote);
			    noquote = 2;
			    break;

			case ENV_USERVAR:
			    fprintf(NetTrace, "\" USERVAR " + noquote);
			    noquote = 2;
			    break;

			default:
			    if (isprint(pointer[i]) && pointer[i] != '"') {
				if (noquote) {
				    putc('"', NetTrace);
				    noquote = 0;
				}
				putc(pointer[i], NetTrace);
			    } else {
				fprintf(NetTrace, "\" %03o " + noquote,
							pointer[i]);
				noquote = 2;
			    }
			    break;
			}
		    }
		    if (!noquote)
			putc('"', NetTrace);
		    break;
		}
	    }
	    break;

	default:
	    if (TELOPT_OK(pointer[0]))
		fprintf(NetTrace, "%s (unknown)", TELOPT(pointer[0]));
	    else
		fprintf(NetTrace, "%d (unknown)", pointer[0]);
	    for (i = 1; i < length; i++)
		fprintf(NetTrace, " %d", pointer[i]);
	    break;
	}
	if (direction) {
	    if (NetTrace == stdout)
		fprintf(NetTrace, "\r\n");
	    else
		fprintf(NetTrace, "\n");
	}
	if (NetTrace == stdout)
	    fflush(NetTrace);
    }
}

/* EmptyTerminal - called to make sure that the terminal buffer is empty.
 *			Note that we consider the buffer to run all the
 *			way to the kernel (thus the poll).
 */

void
EmptyTerminal(void)
{
    struct pollfd set[1];

    set[0].fd = tout;
    set[0].events = POLLOUT;

    if (TTYBYTES() == 0) {
	(void) poll(set, 1, INFTIM);
    } else {
	while (TTYBYTES()) {
	    (void) ttyflush(0);
	    (void) poll(set, 1, INFTIM);
	}
    }
}

void
SetForExit(void)
{
    setconnmode(0);
#ifdef TN3270
    if (In3270) {
	Finish3270();
    }
#else	/* defined(TN3270) */
    do {
	(void)telrcv();			/* Process any incoming data */
	EmptyTerminal();
    } while (ring_full_count(&netiring));	/* While there is any */
#endif	/* defined(TN3270) */
    setcommandmode();
    fflush(stdout);
    fflush(stderr);
#ifdef TN3270
    if (In3270) {
	StopScreen(1);
    }
#endif	/* defined(TN3270) */
    setconnmode(0);
    EmptyTerminal();			/* Flush the path to the tty */
    setcommandmode();
}

void
Exit(int returnCode)
{
    SetForExit();
    exit(returnCode);
}

void
ExitString(char *string, int returnCode)
{
    SetForExit();
    fwrite(string, 1, strlen(string), stderr);
    exit(returnCode);
}

File Added: pkgsrc/comms/tn3270/files/telnet/libtelnet/Attic/genget.c
/*	$NetBSD: genget.c,v 1.1.1.1 2010/01/17 01:33:33 dholland Exp $	*/
/*	From NetBSD: genget.c,v 1.11 2004/10/28 21:14:52 dsl Exp 	*/

/*-
 * Copyright (c) 1991, 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. 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.
 */

#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)genget.c	8.2 (Berkeley) 5/30/95";
#else
__RCSID("$NetBSD: genget.c,v 1.1.1.1 2010/01/17 01:33:33 dholland Exp $");
#endif
#endif /* not lint */


#include <ctype.h>
#include "misc.h"

#define	LOWER(x) (isupper((unsigned char)x) ? tolower((unsigned char)x) : (x))
/*
 * The prefix function returns 0 if *s1 is not a prefix
 * of *s2.  If *s1 exactly matches *s2, the negative of
 * the length is returned.  If *s1 is a prefix of *s2,
 * the length of *s1 is returned.
 */
	int
isprefix(s1, s2)
	register char *s1, *s2;
{
	char *os1;
	register char c1, c2;

	if (*s1 == '\0')
		return(-1);
	os1 = s1;
	c1 = *s1;
	c2 = *s2;
	while (LOWER(c1) == LOWER(c2)) {
		if (c1 == '\0')
			break;
		c1 = *++s1;
		c2 = *++s2;
	}
	return(*s1 ? 0 : (*s2 ? (s1 - os1) : (os1 - s1)));
}

static char *ambiguous;		/* special return value for command routines */

	char **
genget(name, table, stlen)
	char	*name;		/* name to match */
	char	**table;	/* name entry in table */
	int	stlen;
{
	register char **c, **found;
	register int n;

	if (name == 0)
	    return 0;

	found = 0;
	for (c = table; *c != 0; c = (char **)((char *)c + stlen)) {
		if ((n = isprefix(name, *c)) == 0)
			continue;
		if (n < 0)		/* exact match */
			return(c);
		if (found)
			return(&ambiguous);
		found = c;
	}
	return(found);
}

/*
 * Function call version of Ambiguous()
 */
	int
Ambiguous(s)
	void *s;
{
	return(s == &ambiguous);
}

File Added: pkgsrc/comms/tn3270/files/telnet/libtelnet/Attic/misc-proto.h
/*	$NetBSD: misc-proto.h,v 1.1.1.1 2010/01/17 01:33:33 dholland Exp $	*/
/*	From NetBSD: misc-proto.h,v 1.10 2005/02/06 05:53:07 perry Exp 	*/

/*-
 * Copyright (c) 1991, 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. 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.
 *
 *	from: @(#)misc-proto.h	8.1 (Berkeley) 6/4/93
 */

/*
 * Copyright (C) 1990 by the Massachusetts Institute of Technology
 *
 * Export of this software from the United States of America is assumed
 * to require a specific license from the United States Government.
 * It is the responsibility of any person or organization contemplating
 * export to obtain such a license before exporting.
 *
 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
 * distribute this software and its documentation for any purpose and
 * without fee is hereby granted, provided that the above copyright
 * notice appear in all copies and that both that copyright notice and
 * this permission notice appear in supporting documentation, and that
 * the name of M.I.T. not be used in advertising or publicity pertaining
 * to distribution of the software without specific, written prior
 * permission.  M.I.T. makes no representations about the suitability of
 * this software for any purpose.  It is provided "as is" without express
 * or implied warranty.
 */

#ifndef	__MISC_PROTO__
#define	__MISC_PROTO__

#include <sys/cdefs.h>

void auth_encrypt_init(const char *, const char *, const char *, int);
void auth_encrypt_user(const char *);
void auth_encrypt_connect(int);
void printd(const unsigned char *, int);

/*
 * These functions are imported from the application
 */
int telnet_net_write(unsigned char *, int);
void net_encrypt(void);
int telnet_spin(void);
char *telnet_getenv(char *);
char *telnet_gets(char *, char *, int, int);
#endif

File Added: pkgsrc/comms/tn3270/files/telnet/libtelnet/Attic/misc.h
/*	$NetBSD: misc.h,v 1.1.1.1 2010/01/17 01:33:33 dholland Exp $	*/
/*	From NetBSD: misc.h,v 1.8 2005/02/06 05:53:07 perry Exp 	*/

/*-
 * Copyright (c) 1991, 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. 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.
 *
 *	from: @(#)misc.h	8.1 (Berkeley) 6/4/93
 */

__BEGIN_DECLS
extern char *UserNameRequested;
extern const char *LocalHostName;
extern const char *RemoteHostName;
extern int ConnectedCount;
extern int ReservedPort;

int isprefix(char *, char *);
char **genget(char *, char **, int);
int Ambiguous(void *);
__END_DECLS

#include "misc-proto.h"