|
|
1.1 root 1: /* D.L.Buck and Associates, Inc. - @(#)em3277.c 1.18 REL
2: *
3: * COPYRIGHT NOTICE:
4: * Copyright c 1984 - An unpublished work by
5: * D.L.Buck and Associates, Inc.
6: *
7: * PROPRIETARY RIGHTS NOTICE:
8: * All rights reserved. This document and program contains
9: * proprietary information of D.L.Buck and Associates,Inc.
10: * of San Jose, California, U.S.A., embodying confidential
11: * information, ideas, and expressions, no part of which
12: * may be reproduced, or transmitted in any form or by any
13: * means, electronic, mechanical, or otherwise, without
14: * the written permission of D.L.Buck and Associates, Inc.
15: * NAME
16: * em3277 - IBM 3277 terminal emulator
17: *
18: * SYNOPSIS
19: * em3277 [-Ttermtype] [<hostname>]
20: *
21: * DESCRIPTION
22: * em3277 is the controlling utility of the IBM 3277 synchronous
23: * terminal emulation routines, emsetup() and emulate().
24: *
25: * ALGORITHM
26: * I. Initialization
27: * A. Process control parameters
28: * 1. -Ttermtype
29: * 2. hostname - specifies control unit interface to
30: * emulate
31: * 3. If no termtype specified, take through the
32: * environment (TERM=termtype)
33: *
34: * B. Get host configuration parameters
35: * C. Call connect installation exit
36: * D. Open the comm device
37: * E. Set device parameters
38: *
39: * II. Emulate 3277 terminal
40: * A. Call emsetup() routine
41: * 1. sets up the terminal characteristics for emulation,
42: * does the termcap keyboard mapping, and initializes
43: * the virtual screen used by the curses package to
44: * manipulate the cursor and the screen image.
45: * B. Call emulate()
46: * 1. the actual emulating utility
47: *
48: * III. Disconnect
49: * A. Call disconnect installation exit
50: * B. Close the comm device
51: * C. Call the cleanup routine
52: */
53:
54: #include "local.h"
55: #include <bsc/bscio.h>
56: #include <em.h>
57: #include <sys/time.h>
58: #include <errno.h>
59: extern char *sys_errlist[];
60: extern int errno;
61:
62: #define libpath "/usr/lib/bscbatch/"
63: #define spoolpath "/usr/spool/bscbatch/"
64: #define YES 1
65: #define NO 0
66:
67: static char sccsid[] = "@(#)em3277.c 1.18 REL";
68:
69: /* statistics-keeping variables */
70: int tb_ctr = 0; /* transmitted blocks counter */
71: int rb_ctr = 0; /* received blocks counter */
72: struct tbuffer {
73: long utime;
74: long stime;
75: long cutime;
76: long cstime;
77: } rspbuf;
78:
79: /* initial status messages */
80: char astsptpt[] = {'%','R',0x02,'2',' '}; /* ascii, point-to-point */
81: char estsptpt[] = {0x6c,0xd9,0x02,0xc2,0x40}; /*ebcdic, point-to-point */
82: char astsmpt[] = {'%','R',0x02,0,0,'T',' '}; /* ascii, multipoint */
83: char estsmpt[] = {0x6c,0xd9,0x02,0,0,0x4a,0x40};/*ebcdic, multipoint */
84:
85: char adnavail[] = {'%','R',0x02,0,0,' ','&'}; /* ascii, dev. not available */
86: char ednavail[] = {0x6c,0xd9,0x02,0,0,0x40,0x50};/*ebcdic, dev. not available */
87:
88: char hostname[20] = "3270"; /* contains host name */
89: char user[20]; /* user name */
90: char pr_dest[20] = "/usr/ucb/lpr"; /* default print job destination */
91: char ptype = 'p'; /* default print job destination type
92: (pipe) */
93: char audname[80]; /* temp audit file pathname goes here */
94: char new_audnm[80]; /* real audit pathname goes here */
95: char auditlock[80]; /* audit lockfile pathname goes here */
96:
97: char *strcpy(); /* function copies one string to another */
98: char *strcat(); /* function appends one string to another */
99: char *getenv(); /* find string in environment */
100:
101: int chk_hostid;
102: int chk_termid;
103: int primary = BSCPRIM;
104: int rviab;
105: int pt_to_pt;
106: int ascii; /* ascii or ebcdic data? */
107: int devfd; /* bsc device file descriptor */
108: int initflag = 0;
109: long atol(); /* converts ascii to long */
110: char devname[20];
111: char *termtype; /* terminal type */
112: char ttype[20]; /* terminal type + .3277 (for special 3277 terminal
113: entries) */
114: int stationid; /* subdevice id, translated appropriately */
115: char termid; /* cluster address (poll) */
116:
117: FILE *fopen(); /* function opens files */
118: FILE *popen(); /* initiate I/O to form a process */
119: FILE *aud; /* host AUDIT file pointer */
120:
121: struct bscio gp; /* get current bsc driver parameters in here */
122: struct bscio sp; /* use this to set parameters */
123:
124: main(argc,argv)
125: int argc; char *argv[];
126: {
127: int more; /* g/p var */
128:
129: char tbuf[2048]; /* buffer area for tgetent */
130:
131: char filename[50]; /* file name temp area */
132: char note[100]; /* msg to write to AUDIT file and mail */
133:
134: switch (--argc) { /* process parameters */
135: case 2: /* -Ttermtype hostname */
136: ++argv; /* skip first dummy param */
137: if (strlen(argv[0]) < 3 ||
138: argv[0][0] != '-' || argv[0][1] != 'T') {
139: fprintf(stderr,"em3277: unrecognized parameter <%s>\n",
140: argv[0]);
141: exit(1);
142: }
143: termtype = &argv[0][2]; /* save terminal type */
144:
145: case 1: /* hostname */
146: ++argv;
147: strcpy(hostname,argv[0]); /* take given host name */
148: break;
149:
150: case 0: /* take defaults */
151: break;
152:
153: default:
154: fprintf(stderr,"em3277: too many parameters\n");
155: exit(1);
156: }
157:
158: if (termtype == (char *)0)
159: termtype = getenv("TERM");
160:
161: sprintf(ttype,"3270%s",termtype);
162: if (tgetent(tbuf,ttype) != 1) {
163: if (tgetent(tbuf,termtype) != 1) {
164: if (termtype == (char *)0)
165: sprintf(note,
166: "Terminal type unknown or not set\n");
167: else
168: sprintf(note,
169: "em3277: terminal type %s unknown\n",
170: termtype);
171: fprintf(stderr,note);
172: write_aud("E",note);
173: exit(0);
174: }
175: strcpy(ttype,termtype);
176: }
177: else
178: termtype = ttype;
179:
180: /* get host configuration parameters */
181: sprintf(filename,"%s%s",libpath,hostname);
182: if (get_cnfig(filename)) exit (1);
183:
184: /* construct temp AUDIT pathname, open AUDIT file */
185: sprintf(audname,"%s%s/%s",spoolpath,hostname,"AUDIT");
186: /* construct default real AUDIT pathname */
187: sprintf(new_audnm,"%s%s/%s",spoolpath,hostname,"AUDIT");
188: if (access(audname,0) == 0) {
189: sprintf(auditlock,"%s%s/%s",spoolpath,hostname,"auditlock");
190: if (creat(auditlock,0) < 0)
191: em_audnm();
192: else
193: aud = fopen(audname,"a");
194: }
195:
196: #ifndef DEBUG
197: do {
198: /* write "ready for connect" msg to AUDIT */
199: sprintf (note,"Ready for connect via <%s>",
200: devname);
201: write_aud("C",note);
202:
203: /* call connect installation exit */
204: if ((more = connect(hostname,devname)) != 0) {
205: /* skip this host if there were problems */
206: sprintf(note,
207: "Connection failed, <connect routine error code %d>",more);
208: write_aud("C",note);
209:
210: /* tell user about it */
211: fputs(note,stderr);
212: cleanup();
213: exit(more);
214: }
215:
216: /* open bsc device */
217: if ((devfd = open(devname,2)) == -1) {
218: if (errno == EBUSY) {
219: sprintf(note,
220: "Open failed, device <%s> busy.",devname);
221: write_aud("C", note);
222: fprintf(stderr, "em3277 <%s>: %s\n",
223: hostname, note);
224: continue;
225: }
226: /* update AUDIT file with the news */
227: sprintf(note,
228: "Connection failed, <%s> couldn't be opened: %s\n",
229: devname,sys_errlist[errno]);
230: fprintf(stderr,"em3277 <%s>: %s\n",hostname,note);
231: write_aud("C",note);
232: continue;
233: }
234:
235: /* set no-delay for reads on bsc device */
236: ioctl(devfd,BSCNDLY,0);
237:
238: /* set fast-ack */
239: ioctl(devfd,BSCFACK,0);
240:
241: /* write "connected" message to AUDIT file */
242: sprintf(note,"Connected to <%s>",devname);
243: write_aud("C",note);
244:
245: /* set device parameters */
246: ioctl(devfd,BSCSET,&sp);
247: /* get our station id if multipoint */
248: if (pt_to_pt == BSCMPT) {
249: ioctl (devfd, BSCID, &stationid);
250: /* Send status message: SOH % R STX ..... ETX */
251: ioctl(devfd,BSCSOH,0); /* set SOH mode */
252: ioctl(devfd,BSCLAST,0); /* set LAST message flag */
253: if (ascii) {
254: astsmpt[3] = termid; /* poll addr */
255: astsmpt[4] = stationid; /* stn addr */
256: if (write(devfd, astsmpt, sizeof astsmpt) < 0)
257: ioctl(devfd,BSCGET,&gp);
258: } else {
259: estsmpt[3] = termid; /* poll addr */
260: estsmpt[4] = stationid; /* stn addr */
261: if (write (devfd, estsmpt, sizeof estsmpt) < 0)
262: ioctl(devfd,BSCGET,&gp);
263: }
264: if (gp.b_flags == BSCNDSR ||
265: gp.b_flags == BSCTXTO ||
266: gp.b_flags == BSCNBID)
267: exit(1);
268: ioctl(devfd,BSCNSOH,0); /* end SOH mode */
269: ++tb_ctr; /* increment tx block counter for
270: stats */
271: }
272: #endif
273: /* EMULATE 3277 TERMINAL */
274: do_screen = 1; /* cause display to be kept up to date */
275: if (emsetup(termtype)) {
276: cleanup();
277: exit(1);
278: }
279: emulate();
280: Disconnect:
281: sprintf(note,"Disconnected <%s>",devname);
282: write_aud ("D", note);
283: disconnect(hostname,devname);
284:
285: close(devfd); /* close bsc device */
286: break;
287: } while (getnextopen() != -1);
288:
289: /* end off curses routines, close audit file, unlink auditlock, exit */
290: cleanup();
291: write (1,"\n",1); /* make screen look pretty */
292: }
293:
294: dev_navail()
295: {
296: /* Send status msg : dev. not available */
297: ioctl (devfd, BSCID, &stationid);
298: ioctl(devfd,BSCSOH,0); /* set SOH mode */
299: ioctl(devfd,BSCLAST,0); /* set LAST message flag */
300: if (ascii) {
301: adnavail[3] = termid; /* poll addr */
302: adnavail[4] = stationid; /* stn addr */
303: write(devfd, adnavail, sizeof adnavail);
304: } else {
305: ednavail[3] = termid; /* poll addr */
306: ednavail[4] = stationid; /* stn addr */
307: write (devfd, ednavail, sizeof ednavail);
308: }
309: ioctl(devfd,BSCNSOH,0); /* end SOH mode */
310: }
311:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.