xref: /csrg-svn/usr.bin/tn3270/tools/prt3270.c (revision 30732)
130051Sminshall #ifndef	lint
230051Sminshall static	char	sccsid[] = "@(#)prt3270.c	3.1  10/29/86";
330051Sminshall #endif	/* ndef lint */
430051Sminshall 
530051Sminshall 
630051Sminshall #if defined(unix)
730051Sminshall #endif
830051Sminshall #include <stdio.h>
930051Sminshall #include <curses.h>
1030051Sminshall #include <ctype.h>
1130051Sminshall 
1230051Sminshall #include "../ascii/ascebc.h"
1330051Sminshall #include "../ctlr/hostctlr.h"
1430051Sminshall #include "../ctlr/screen.h"
1530051Sminshall #define	DEFINEAIDS
1630051Sminshall #define	LETS_SEE_ASCII
1730051Sminshall #include "../keyboard/m4.out"
1830051Sminshall #include "../system/globals.h"
1930051Sminshall 
2030051Sminshall 
2130051Sminshall int NumberColumns = 80;
2230051Sminshall 
2330051Sminshall int direction;
2430051Sminshall 
2530051Sminshall int column = 1;
2630051Sminshall int indenting = 0;
2730051Sminshall int direction = '?';
2830051Sminshall 
2930051Sminshall unsigned char printBuffer[200], *print = printBuffer;
3030051Sminshall 
3130051Sminshall #define	ColsLeft()	(79-column)	/* A little room for error */
3230051Sminshall 
3330051Sminshall 
3430051Sminshall void
3530051Sminshall putSpace()
3630051Sminshall {
3730051Sminshall     extern void Column1();
3830051Sminshall     unsigned char *ourPrint = print;
3930051Sminshall 
4030051Sminshall     print = printBuffer;		/* For mutual calls */
4130051Sminshall     *ourPrint = 0;
4230051Sminshall     if (ColsLeft() < 0) {
4330051Sminshall 	Column1();
4430051Sminshall     }
4530051Sminshall     if (column != (indenting*8+1)) {
4630051Sminshall 	putchar(' ');
4730051Sminshall     } else {
4830051Sminshall 	int i;
4930051Sminshall 
5030051Sminshall 	putchar(direction);
5130051Sminshall 	putchar(' ');
5230051Sminshall 	for (i = 0; i < indenting; i++) {
5330051Sminshall 	    putchar('\t');
5430051Sminshall 	}
5530051Sminshall     }
5630051Sminshall     printf("%s", printBuffer);
5730051Sminshall     column += strlen(printBuffer);
5830051Sminshall }
5930051Sminshall 
6030051Sminshall void
6130051Sminshall Column1()
6230051Sminshall {
6330051Sminshall     if (print != printBuffer) {
6430051Sminshall 	putSpace();
6530051Sminshall     }
6630051Sminshall     if (column != (indenting*8+1)) {
6730051Sminshall 	putchar('\n');
6830051Sminshall 	column = indenting*8+1;
6930051Sminshall     }
7030051Sminshall }
7130051Sminshall 
7230051Sminshall void
7330051Sminshall Indent()
7430051Sminshall {
7530051Sminshall     if ((column != (indenting*8+1)) || (print != printBuffer)) {
7630051Sminshall 	Column1();
7730051Sminshall     }
7830051Sminshall     indenting++;
7930051Sminshall     column = indenting*8+1;
8030051Sminshall }
8130051Sminshall 
8230051Sminshall void
8330051Sminshall Undent()
8430051Sminshall {
8530051Sminshall     if ((column != (indenting*8+1)) || (print != printBuffer)) {
8630051Sminshall 	Column1();
8730051Sminshall     }
8830051Sminshall     indenting--;
8930051Sminshall     if (indenting < 0) {
9030051Sminshall 	fflush(stdout);
9130051Sminshall 	fprintf(stderr, "INTERNAL ERROR: indenting < 0.\n");
9230051Sminshall 	fflush(stderr);
9330051Sminshall     } else {
9430051Sminshall 	column = indenting*8+1;
9530051Sminshall     }
9630051Sminshall }
9730051Sminshall 
9830051Sminshall void
9930051Sminshall putChar(character)
10030051Sminshall int	character;
10130051Sminshall {
10230051Sminshall     *print++ = character;
103*30732Sminshall     column++;
10430051Sminshall }
10530051Sminshall 
10630051Sminshall void
10730051Sminshall putstr(s)
10830051Sminshall char *s;
10930051Sminshall {
11030051Sminshall     while (*s) {
11130051Sminshall 	putChar(*s++);
11230051Sminshall     }
11330051Sminshall }
11430051Sminshall 
11530051Sminshall void
11630051Sminshall put2hex(i)
11730051Sminshall int i;
11830051Sminshall {
11930051Sminshall     char place[40];
12030051Sminshall 
12130051Sminshall     sprintf(place, "%02x", i);
12230051Sminshall     putstr(place);
12330051Sminshall }
12430051Sminshall 
12530051Sminshall 
12630051Sminshall void
12730051Sminshall putdecimal(i)
12830051Sminshall int i;
12930051Sminshall {
13030051Sminshall     char place[40];
13130051Sminshall 
13230051Sminshall     sprintf(place, "%d", i);
13330051Sminshall     putstr(place);
13430051Sminshall }
13530051Sminshall 
13630051Sminshall void
13730051Sminshall puthex(i)
13830051Sminshall int i;
13930051Sminshall {
14030051Sminshall     char place[40];
14130051Sminshall 
14230051Sminshall     sprintf(place, "%x", i);
14330051Sminshall     putstr(place);
14430051Sminshall }
14530051Sminshall 
14630051Sminshall void
14730051Sminshall putEChar(character)
14830051Sminshall int character;
14930051Sminshall {
15030051Sminshall     putChar(ebcasc[0][character]);
15130051Sminshall     if (ColsLeft() < 10) {
15230051Sminshall 	Column1();
15330051Sminshall     }
15430051Sminshall }
15530051Sminshall 
15630051Sminshall void
15730051Sminshall PrintAid(i)
15830051Sminshall int	i;
15930051Sminshall {
16030051Sminshall     TC_AsciiAids_t *TC;
16130051Sminshall 
16230051Sminshall     for (TC = &TC_AsciiAids[TC_LOWEST_AID-TC_LOWEST];
16330051Sminshall 		TC <= &TC_AsciiAids[TC_HIGHEST_AID-TC_LOWEST]; TC++) {
16430051Sminshall 	if ((TC->tc_aid&0xff) == i) {
16530051Sminshall 	    putstr(TC->tc_name);
16630051Sminshall 	    return;
16730051Sminshall 	}
16830051Sminshall     }
16930051Sminshall 
17030051Sminshall     putstr("Unknown AID 0x");
17130051Sminshall     put2hex(i);
17230051Sminshall }
17330051Sminshall 
17430051Sminshall void
17530051Sminshall PrintAddr(i)
17630051Sminshall int	i;
17730051Sminshall {
17830051Sminshall     if (ColsLeft() < 9) {
17930051Sminshall 	Column1();
18030051Sminshall     }
18130051Sminshall     putChar('(');
18230051Sminshall     putdecimal(ScreenLine(i));
18330051Sminshall     putChar(',');
18430051Sminshall     putdecimal(ScreenLineOffset(i));
18530051Sminshall     putChar(')');
18630051Sminshall }
18730051Sminshall 
18830051Sminshall 
18930051Sminshall /* returns the number of characters consumed */
19030051Sminshall int
19130051Sminshall DataFromNetwork(buffer, count, control)
19230051Sminshall register unsigned char	*buffer;		/* what the data is */
19330051Sminshall register int	count;				/* and how much there is */
19430051Sminshall int	control;				/* this buffer ended block? */
19530051Sminshall {
19630051Sminshall     int origCount;
19730051Sminshall     register int c;
19830051Sminshall     register int i;
19930051Sminshall     static int Command;
20030051Sminshall     static int Wcc;
20130051Sminshall     static int	LastWasTerminated = 1;	/* was "control" = 1 last time? */
20230051Sminshall 
20330051Sminshall     if (count == 0) {
20430051Sminshall 	Column1();
20530051Sminshall 	return 0;
20630051Sminshall     }
20730051Sminshall 
20830051Sminshall     origCount = count;
20930051Sminshall 
21030051Sminshall     if (LastWasTerminated) {
21130051Sminshall 
21230051Sminshall 	if (count < 2) {
21330051Sminshall 	    if (count == 0) {
21430051Sminshall 		fflush(stdout);
21530051Sminshall 		fprintf(stderr, "Short count received from host!\n");
21630051Sminshall 		fflush(stderr);
21730051Sminshall 		return(count);
21830051Sminshall 	    }
21930051Sminshall 	    Command = buffer[0];
22030051Sminshall 	    switch (Command) {		/* This had better be a read command */
22130051Sminshall 	    case CMD_READ_MODIFIED:
22230051Sminshall 		putstr("read_modified command\n");
22330051Sminshall 		break;
22430051Sminshall 	    case CMD_SNA_READ_MODIFIED:
22530051Sminshall 		putstr("read_modified command\n");
22630051Sminshall 		break;
22730051Sminshall 	    case CMD_SNA_READ_MODIFIED_ALL:
22830051Sminshall 		putstr("read_modified command\n");
22930051Sminshall 		break;
23030051Sminshall 	    case CMD_READ_BUFFER:
23130051Sminshall 		putstr("read_modified command\n");
23230051Sminshall 		break;
23330051Sminshall 	    case CMD_SNA_READ_BUFFER:
23430051Sminshall 		putstr("read_modified command\n");
23530051Sminshall 		break;
23630051Sminshall 	    default:
23730051Sminshall 		break;
23830051Sminshall 	    }
23930051Sminshall 	    return(1);			/* We consumed everything */
24030051Sminshall 	}
24130051Sminshall 	Command = buffer[0];
24230051Sminshall 	Wcc = buffer[1];
24330051Sminshall 	switch (Command) {
24430051Sminshall 	case CMD_ERASE_WRITE:
24530051Sminshall 	    putstr("erase write command ");
24630051Sminshall 	    break;
24730051Sminshall 	case CMD_ERASE_WRITE_ALTERNATE:
24830051Sminshall 	    putstr("erase write alternate command ");
24930051Sminshall 	    break;
25030051Sminshall 	case CMD_SNA_ERASE_WRITE:
25130051Sminshall 	    putstr("sna erase write command ");
25230051Sminshall 	    break;
25330051Sminshall 	case CMD_SNA_ERASE_WRITE_ALTERNATE:
25430051Sminshall 	    putstr("erase write alternate command ");
25530051Sminshall 	    break;
25630051Sminshall 	case CMD_ERASE_ALL_UNPROTECTED:
25730051Sminshall 	    putstr("erase all unprotected command ");
25830051Sminshall 	    break;
25930051Sminshall 	case CMD_SNA_ERASE_ALL_UNPROTECTED:
26030051Sminshall 	    putstr("sna erase write command ");
26130051Sminshall 	    break;
26230051Sminshall 	case CMD_WRITE:
26330051Sminshall 	    putstr("write command ");
26430051Sminshall 	    break;
26530051Sminshall 	case CMD_SNA_WRITE:
26630051Sminshall 	    putstr("sna write command ");
26730051Sminshall 	    break;
26830051Sminshall 	default:
26930051Sminshall 	    putstr("Unexpected command code 0x");
27030051Sminshall 	    puthex(Command);
27130051Sminshall 	    putstr(" received.");
27230051Sminshall 	    Column1();
27330051Sminshall 	    break;
27430051Sminshall 	}
27530051Sminshall 	putstr("WCC is 0x");
27630051Sminshall 	puthex(Wcc);
27730051Sminshall 	Column1();
27830051Sminshall 
27930051Sminshall 	count -= 2;			/* strip off command and wcc */
28030051Sminshall 	buffer += 2;
28130051Sminshall 
28230051Sminshall     }
28330051Sminshall     LastWasTerminated = 0;		/* then, reset at end... */
28430051Sminshall 
28530051Sminshall     while (count) {
28630051Sminshall 	count--;
28730051Sminshall 	c = *buffer++;
28830051Sminshall 	if (IsOrder(c)) {
28930051Sminshall 	    /* handle an order */
29030051Sminshall 	    switch (c) {
29130051Sminshall #		define Ensure(x)	if (count < x) { \
29230051Sminshall 					    if (!control) { \
29330051Sminshall 						return(origCount-(count+1)); \
29430051Sminshall 					    } else { \
29530051Sminshall 						/* XXX - should not occur */ \
29630051Sminshall 						count = 0; \
29730051Sminshall 						break; \
29830051Sminshall 					    } \
29930051Sminshall 					}
30030051Sminshall 	    case ORDER_SF:
30130051Sminshall 		Ensure(1);
30230051Sminshall 		c = *buffer++;
30330051Sminshall 		count--;
30430051Sminshall 		putstr("SF (0x");
30530051Sminshall 		put2hex(c);
30630051Sminshall 		putstr(") ");
30730051Sminshall 		break;
30830051Sminshall 	    case ORDER_SBA:
30930051Sminshall 		Ensure(2);
31030051Sminshall 		i = buffer[0];
31130051Sminshall 		c = buffer[1];
31230051Sminshall 		buffer += 2;
31330051Sminshall 		count -= 2;
31430051Sminshall 		putstr("SBA to ");
31530051Sminshall 		PrintAddr(Addr3270(i,c));
31630051Sminshall 		putSpace();
31730051Sminshall 		break;
31830051Sminshall 	    case ORDER_IC:
31930051Sminshall 		putstr("IC");
32030051Sminshall 		putSpace();
32130051Sminshall 		break;
32230051Sminshall 	    case ORDER_PT:
32330051Sminshall 		putstr("PT");
32430051Sminshall 		putSpace();
32530051Sminshall 		break;
32630051Sminshall 	    case ORDER_RA:
32730051Sminshall 		Ensure(3);
32830051Sminshall 		i = Addr3270(buffer[0], buffer[1]);
32930051Sminshall 		c = buffer[2];
33030051Sminshall 		buffer += 3;
33130051Sminshall 		count -= 3;
33230051Sminshall 		putstr("RA to ");
33330051Sminshall 		PrintAddr(i);
33430051Sminshall 		putstr(" of 0x");
33530051Sminshall 		put2hex(c);
33630051Sminshall 		putSpace();
33730051Sminshall 		break;
33830051Sminshall 	    case ORDER_EUA:    /* (from [here,there), ie: half open interval] */
33930051Sminshall 		Ensure(2);
34030051Sminshall 		putstr("EUA to ");
34130051Sminshall 		PrintAddr(Addr3270(buffer[0], buffer[1]));
34230051Sminshall 		putSpace();
34330051Sminshall 		buffer += 2;
34430051Sminshall 		count -= 2;
34530051Sminshall 		break;
34630051Sminshall 	    case ORDER_YALE:		/* special YALE defined order */
34730051Sminshall 		Ensure(2);	/* need at least two characters */
34830051Sminshall 		putstr("YALE order");
34930051Sminshall 		putSpace();
35030051Sminshall 		break;
35130051Sminshall 	    default:
35230051Sminshall 		putstr("UNKNOWN ORDER: 0x");
35330051Sminshall 		put2hex(c);
35430051Sminshall 		putSpace();
35530051Sminshall 		break;
35630051Sminshall 	    }
35730051Sminshall 	    if (count < 0) {
35830051Sminshall 		count = 0;
35930051Sminshall 	    }
36030051Sminshall 	} else {
36130051Sminshall 	    /* Data comes in large clumps - take it all */
36230051Sminshall 	    putstr("DATA:");
36330051Sminshall 	    Indent();
36430051Sminshall 	    putEChar(c);
36530051Sminshall 	    c = *buffer;
36630051Sminshall 	    while (count && !IsOrder(c)) {
36730051Sminshall 		putEChar(c);
36830051Sminshall 		count--;
36930051Sminshall 		buffer++;
37030051Sminshall 		c = *buffer;
37130051Sminshall 	    }
37230051Sminshall 	    Undent();
37330051Sminshall 	}
37430051Sminshall     }
37530051Sminshall     LastWasTerminated = control;
37630051Sminshall     return origCount - count;
37730051Sminshall }
37830051Sminshall 
37930051Sminshall int
38030051Sminshall DataToNetwork(buffer, count, control)
38130051Sminshall unsigned char *buffer;
38230051Sminshall int count;
38330051Sminshall int control;
38430051Sminshall {
38530051Sminshall #define	NEED_AID	0
38630051Sminshall #define	JUST_GOT_AID	1
38730051Sminshall #define	DATA		2
38830051Sminshall #define	DATA_CONTINUE	3
38930051Sminshall     static int state = NEED_AID;
39030051Sminshall     static int aid;
39130051Sminshall     int origCount = count;
39230051Sminshall 
39330051Sminshall     if (count == 0) {
39430051Sminshall 	if (control) {
39530051Sminshall 	    state = NEED_AID;
39630051Sminshall 	}
39730051Sminshall 	Column1();
39830051Sminshall 	return 0;
39930051Sminshall     }
40030051Sminshall 
40130051Sminshall     switch (state) {
40230051Sminshall     case NEED_AID:
40330051Sminshall 	aid = buffer[0];
40430051Sminshall 	buffer++;
40530051Sminshall 	count--;
40630051Sminshall 	PrintAid(aid);
40730051Sminshall 	putSpace();
40830051Sminshall 	if (aid == TCtoAid(TC_TREQ)) {
40930051Sminshall 	    state = DATA;
41030051Sminshall 	} else {
41130051Sminshall 	    state = JUST_GOT_AID;
41230051Sminshall 	}
41330051Sminshall 	return origCount - count + DataToNetwork(buffer, count, control);
41430051Sminshall     case JUST_GOT_AID:
41530051Sminshall 	Ensure(2);
41630051Sminshall 	PrintAddr(Addr3270(buffer[0], buffer[1]));
41730051Sminshall 	putSpace();
41830051Sminshall 	buffer += 2;
41930051Sminshall 	count -= 2;
42030051Sminshall 	state = DATA;
42130051Sminshall 	return origCount - count + DataToNetwork(buffer, count, control);
42230051Sminshall     case DATA:
42330051Sminshall     case DATA_CONTINUE:
42430051Sminshall 	while (count) {
42530051Sminshall 	    if (*buffer == ORDER_SBA) {
42630051Sminshall 		if (state == DATA_CONTINUE) {
42730051Sminshall 		    Undent();
42830051Sminshall 		    state = DATA;
42930051Sminshall 		}
43030051Sminshall 		putstr("SBA ");
43130051Sminshall 		PrintAddr(Addr3270(buffer[1], buffer[2]));
43230051Sminshall 		putSpace();
43330051Sminshall 		buffer += 3;
43430051Sminshall 		count -= 3;
43530051Sminshall 	    } else {
43630051Sminshall 		if (state == DATA) {
43730051Sminshall 		    putstr("DATA:");
43830051Sminshall 		    Indent();
43930051Sminshall 		    state = DATA_CONTINUE;
44030051Sminshall 		}
44130051Sminshall 		putEChar(*buffer);
44230051Sminshall 		buffer++;
44330051Sminshall 		count--;
44430051Sminshall 	    }
44530051Sminshall 	}
44630051Sminshall 	if (control) {
44730051Sminshall 	    if (state == DATA_CONTINUE) {
44830051Sminshall 		Undent();
44930051Sminshall 	    }
45030051Sminshall 	    state = NEED_AID;
45130051Sminshall 	}
45230051Sminshall 	return origCount-count;
45330051Sminshall     }
45430051Sminshall }
45530051Sminshall 
45630051Sminshall int
45730051Sminshall GetXValue(c)
45830051Sminshall int	c;
45930051Sminshall {
46030051Sminshall     if (!isascii(c)) {
46130051Sminshall 	fflush(stdout);
46230051Sminshall 	fprintf(stderr, "Non-hex digit 0x%x.\n");
46330051Sminshall 	fflush(stderr);
46430051Sminshall 	return 0;
46530051Sminshall     } else {
46630051Sminshall 	if (islower(c)) {
46730051Sminshall 	    return (c-'a')+10;
46830051Sminshall 	} else if (isupper(c)) {
46930051Sminshall 	    return (c-'A')+10;
47030051Sminshall 	} else {
47130051Sminshall 	    return c-'0';
47230051Sminshall 	}
47330051Sminshall     }
47430051Sminshall }
47530051Sminshall 
47630051Sminshall unsigned char outbound[8192], inbound[8192],
47730051Sminshall 	*outnext = outbound, *innext = inbound, *p = 0;
47830051Sminshall 
47930051Sminshall void
48030051Sminshall termblock(old, new, control)
48130051Sminshall int old,
48230051Sminshall 	new;		/* old and new directions */
48330051Sminshall {
48430051Sminshall     int count;
48530051Sminshall 
48630051Sminshall     if (p) {
48730051Sminshall 	if (old == '<') {
48830051Sminshall 	    outnext = p;
48930051Sminshall 	    count = DataFromNetwork(outbound, outnext-outbound, control);
49030051Sminshall 	    if (outbound+count == outnext) {
49130051Sminshall 		outnext = outbound;
49230051Sminshall 	    } else {
49330051Sminshall 		bcopy(outbound+count, outbound, outnext-(outbound+count));
49430051Sminshall 		outnext = outbound+count;
49530051Sminshall 	    }
49630051Sminshall 	} else {
49730051Sminshall 	    innext = p;
49830051Sminshall 	    count = DataToNetwork(inbound, innext-inbound, control);
49930051Sminshall 	    if (inbound+count == innext) {
50030051Sminshall 		innext = inbound;
50130051Sminshall 	    } else {
50230051Sminshall 		bcopy(inbound+count, inbound, innext-(inbound+count));
50330051Sminshall 		innext = inbound+count;
50430051Sminshall 	    }
50530051Sminshall 	}
50630051Sminshall     }
50730051Sminshall     if (new == '<') {
50830051Sminshall 	p = outnext;
50930051Sminshall     } else if (new == '>') {
51030051Sminshall 	p = innext;
51130051Sminshall     } else {
51230051Sminshall 	fprintf(stderr, "Bad direction character '%c'.\n", new);
51330051Sminshall 	exit(1);
51430051Sminshall     }
51530051Sminshall }
51630051Sminshall 
51730051Sminshall main()
51830051Sminshall {
51930051Sminshall     int location;
52030051Sminshall     int new;
52130051Sminshall     int c, c1;
52230051Sminshall 
52330051Sminshall     bzero(Orders, sizeof Orders);
52430051Sminshall     Orders[ORDER_SF] = Orders[ORDER_SBA] = Orders[ORDER_IC]
52530051Sminshall 	    = Orders[ORDER_PT] = Orders[ORDER_RA] = Orders[ORDER_EUA]
52630051Sminshall 	    = Orders[ORDER_YALE] = 1;
52730051Sminshall 
52830051Sminshall     while (scanf("%c 0x%x\t", &new, &location) != EOF) {
52930051Sminshall 	if (new != direction) {
53030051Sminshall 	    termblock(direction, new, 0);
53130051Sminshall 	    direction = new;
53230051Sminshall 	}
53330051Sminshall 	while (((c = getchar()) != EOF) && (c != '\n') && (isxdigit(c))) {
53430051Sminshall #define	NORMAL	0
53530051Sminshall #define	GOT0XFF	0xff
53630051Sminshall 	    static int state = NORMAL;
53730051Sminshall 
53830051Sminshall 	    c1 = getchar();
53930051Sminshall 	    c = (GetXValue(c) << 4) + GetXValue(c1);
54030051Sminshall 	    switch (state) {
54130051Sminshall 	    case NORMAL:
54230051Sminshall 		if (c == 0xff) {
54330051Sminshall 		    state = GOT0XFF;
54430051Sminshall 		} else {
54530051Sminshall 		    *p++ = c;
54630051Sminshall 		}
54730051Sminshall 		break;
54830051Sminshall 	    case GOT0XFF:
54930051Sminshall 		if (c == 0xef) {
55030051Sminshall 		    termblock(direction, direction, 1);
55130051Sminshall 		} else {
55230051Sminshall 		    *p++ = 0xff;
55330051Sminshall 		    *p++ = c;
55430051Sminshall 		}
55530051Sminshall 		state = NORMAL;
55630051Sminshall 	    }
55730051Sminshall 	}
55830051Sminshall     }
55930051Sminshall     return 0;
56030051Sminshall }
561