|
|
Power 6/32 Unix version 1.21
/* D.L.Buck and Associates, Inc. - @(#)em3277.c 1.18 REL
*
* COPYRIGHT NOTICE:
* Copyright c 1984 - An unpublished work by
* D.L.Buck and Associates, Inc.
*
* PROPRIETARY RIGHTS NOTICE:
* All rights reserved. This document and program contains
* proprietary information of D.L.Buck and Associates,Inc.
* of San Jose, California, U.S.A., embodying confidential
* information, ideas, and expressions, no part of which
* may be reproduced, or transmitted in any form or by any
* means, electronic, mechanical, or otherwise, without
* the written permission of D.L.Buck and Associates, Inc.
* NAME
* em3277 - IBM 3277 terminal emulator
*
* SYNOPSIS
* em3277 [-Ttermtype] [<hostname>]
*
* DESCRIPTION
* em3277 is the controlling utility of the IBM 3277 synchronous
* terminal emulation routines, emsetup() and emulate().
*
* ALGORITHM
* I. Initialization
* A. Process control parameters
* 1. -Ttermtype
* 2. hostname - specifies control unit interface to
* emulate
* 3. If no termtype specified, take through the
* environment (TERM=termtype)
*
* B. Get host configuration parameters
* C. Call connect installation exit
* D. Open the comm device
* E. Set device parameters
*
* II. Emulate 3277 terminal
* A. Call emsetup() routine
* 1. sets up the terminal characteristics for emulation,
* does the termcap keyboard mapping, and initializes
* the virtual screen used by the curses package to
* manipulate the cursor and the screen image.
* B. Call emulate()
* 1. the actual emulating utility
*
* III. Disconnect
* A. Call disconnect installation exit
* B. Close the comm device
* C. Call the cleanup routine
*/
#include "local.h"
#include <bsc/bscio.h>
#include <em.h>
#include <sys/time.h>
#include <errno.h>
extern char *sys_errlist[];
extern int errno;
#define libpath "/usr/lib/bscbatch/"
#define spoolpath "/usr/spool/bscbatch/"
#define YES 1
#define NO 0
static char sccsid[] = "@(#)em3277.c 1.18 REL";
/* statistics-keeping variables */
int tb_ctr = 0; /* transmitted blocks counter */
int rb_ctr = 0; /* received blocks counter */
struct tbuffer {
long utime;
long stime;
long cutime;
long cstime;
} rspbuf;
/* initial status messages */
char astsptpt[] = {'%','R',0x02,'2',' '}; /* ascii, point-to-point */
char estsptpt[] = {0x6c,0xd9,0x02,0xc2,0x40}; /*ebcdic, point-to-point */
char astsmpt[] = {'%','R',0x02,0,0,'T',' '}; /* ascii, multipoint */
char estsmpt[] = {0x6c,0xd9,0x02,0,0,0x4a,0x40};/*ebcdic, multipoint */
char adnavail[] = {'%','R',0x02,0,0,' ','&'}; /* ascii, dev. not available */
char ednavail[] = {0x6c,0xd9,0x02,0,0,0x40,0x50};/*ebcdic, dev. not available */
char hostname[20] = "3270"; /* contains host name */
char user[20]; /* user name */
char pr_dest[20] = "/usr/ucb/lpr"; /* default print job destination */
char ptype = 'p'; /* default print job destination type
(pipe) */
char audname[80]; /* temp audit file pathname goes here */
char new_audnm[80]; /* real audit pathname goes here */
char auditlock[80]; /* audit lockfile pathname goes here */
char *strcpy(); /* function copies one string to another */
char *strcat(); /* function appends one string to another */
char *getenv(); /* find string in environment */
int chk_hostid;
int chk_termid;
int primary = BSCPRIM;
int rviab;
int pt_to_pt;
int ascii; /* ascii or ebcdic data? */
int devfd; /* bsc device file descriptor */
int initflag = 0;
long atol(); /* converts ascii to long */
char devname[20];
char *termtype; /* terminal type */
char ttype[20]; /* terminal type + .3277 (for special 3277 terminal
entries) */
int stationid; /* subdevice id, translated appropriately */
char termid; /* cluster address (poll) */
FILE *fopen(); /* function opens files */
FILE *popen(); /* initiate I/O to form a process */
FILE *aud; /* host AUDIT file pointer */
struct bscio gp; /* get current bsc driver parameters in here */
struct bscio sp; /* use this to set parameters */
main(argc,argv)
int argc; char *argv[];
{
int more; /* g/p var */
char tbuf[2048]; /* buffer area for tgetent */
char filename[50]; /* file name temp area */
char note[100]; /* msg to write to AUDIT file and mail */
switch (--argc) { /* process parameters */
case 2: /* -Ttermtype hostname */
++argv; /* skip first dummy param */
if (strlen(argv[0]) < 3 ||
argv[0][0] != '-' || argv[0][1] != 'T') {
fprintf(stderr,"em3277: unrecognized parameter <%s>\n",
argv[0]);
exit(1);
}
termtype = &argv[0][2]; /* save terminal type */
case 1: /* hostname */
++argv;
strcpy(hostname,argv[0]); /* take given host name */
break;
case 0: /* take defaults */
break;
default:
fprintf(stderr,"em3277: too many parameters\n");
exit(1);
}
if (termtype == (char *)0)
termtype = getenv("TERM");
sprintf(ttype,"3270%s",termtype);
if (tgetent(tbuf,ttype) != 1) {
if (tgetent(tbuf,termtype) != 1) {
if (termtype == (char *)0)
sprintf(note,
"Terminal type unknown or not set\n");
else
sprintf(note,
"em3277: terminal type %s unknown\n",
termtype);
fprintf(stderr,note);
write_aud("E",note);
exit(0);
}
strcpy(ttype,termtype);
}
else
termtype = ttype;
/* get host configuration parameters */
sprintf(filename,"%s%s",libpath,hostname);
if (get_cnfig(filename)) exit (1);
/* construct temp AUDIT pathname, open AUDIT file */
sprintf(audname,"%s%s/%s",spoolpath,hostname,"AUDIT");
/* construct default real AUDIT pathname */
sprintf(new_audnm,"%s%s/%s",spoolpath,hostname,"AUDIT");
if (access(audname,0) == 0) {
sprintf(auditlock,"%s%s/%s",spoolpath,hostname,"auditlock");
if (creat(auditlock,0) < 0)
em_audnm();
else
aud = fopen(audname,"a");
}
#ifndef DEBUG
do {
/* write "ready for connect" msg to AUDIT */
sprintf (note,"Ready for connect via <%s>",
devname);
write_aud("C",note);
/* call connect installation exit */
if ((more = connect(hostname,devname)) != 0) {
/* skip this host if there were problems */
sprintf(note,
"Connection failed, <connect routine error code %d>",more);
write_aud("C",note);
/* tell user about it */
fputs(note,stderr);
cleanup();
exit(more);
}
/* open bsc device */
if ((devfd = open(devname,2)) == -1) {
if (errno == EBUSY) {
sprintf(note,
"Open failed, device <%s> busy.",devname);
write_aud("C", note);
fprintf(stderr, "em3277 <%s>: %s\n",
hostname, note);
continue;
}
/* update AUDIT file with the news */
sprintf(note,
"Connection failed, <%s> couldn't be opened: %s\n",
devname,sys_errlist[errno]);
fprintf(stderr,"em3277 <%s>: %s\n",hostname,note);
write_aud("C",note);
continue;
}
/* set no-delay for reads on bsc device */
ioctl(devfd,BSCNDLY,0);
/* set fast-ack */
ioctl(devfd,BSCFACK,0);
/* write "connected" message to AUDIT file */
sprintf(note,"Connected to <%s>",devname);
write_aud("C",note);
/* set device parameters */
ioctl(devfd,BSCSET,&sp);
/* get our station id if multipoint */
if (pt_to_pt == BSCMPT) {
ioctl (devfd, BSCID, &stationid);
/* Send status message: SOH % R STX ..... ETX */
ioctl(devfd,BSCSOH,0); /* set SOH mode */
ioctl(devfd,BSCLAST,0); /* set LAST message flag */
if (ascii) {
astsmpt[3] = termid; /* poll addr */
astsmpt[4] = stationid; /* stn addr */
if (write(devfd, astsmpt, sizeof astsmpt) < 0)
ioctl(devfd,BSCGET,&gp);
} else {
estsmpt[3] = termid; /* poll addr */
estsmpt[4] = stationid; /* stn addr */
if (write (devfd, estsmpt, sizeof estsmpt) < 0)
ioctl(devfd,BSCGET,&gp);
}
if (gp.b_flags == BSCNDSR ||
gp.b_flags == BSCTXTO ||
gp.b_flags == BSCNBID)
exit(1);
ioctl(devfd,BSCNSOH,0); /* end SOH mode */
++tb_ctr; /* increment tx block counter for
stats */
}
#endif
/* EMULATE 3277 TERMINAL */
do_screen = 1; /* cause display to be kept up to date */
if (emsetup(termtype)) {
cleanup();
exit(1);
}
emulate();
Disconnect:
sprintf(note,"Disconnected <%s>",devname);
write_aud ("D", note);
disconnect(hostname,devname);
close(devfd); /* close bsc device */
break;
} while (getnextopen() != -1);
/* end off curses routines, close audit file, unlink auditlock, exit */
cleanup();
write (1,"\n",1); /* make screen look pretty */
}
dev_navail()
{
/* Send status msg : dev. not available */
ioctl (devfd, BSCID, &stationid);
ioctl(devfd,BSCSOH,0); /* set SOH mode */
ioctl(devfd,BSCLAST,0); /* set LAST message flag */
if (ascii) {
adnavail[3] = termid; /* poll addr */
adnavail[4] = stationid; /* stn addr */
write(devfd, adnavail, sizeof adnavail);
} else {
ednavail[3] = termid; /* poll addr */
ednavail[4] = stationid; /* stn addr */
write (devfd, ednavail, sizeof ednavail);
}
ioctl(devfd,BSCNSOH,0); /* end SOH mode */
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.