diff options
Diffstat (limited to 'usr.bin/tn3270/tools/prt3270.c')
-rw-r--r-- | usr.bin/tn3270/tools/prt3270.c | 620 |
1 files changed, 620 insertions, 0 deletions
diff --git a/usr.bin/tn3270/tools/prt3270.c b/usr.bin/tn3270/tools/prt3270.c new file mode 100644 index 0000000..55d72d5 --- /dev/null +++ b/usr.bin/tn3270/tools/prt3270.c @@ -0,0 +1,620 @@ +/*- + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1988, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)prt3270.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#if defined(unix) +#endif +#include <stdio.h> +#include <ctype.h> + +#include "../general/general.h" + +#include "../api/asc_ebc.h" +#include "../ctlr/hostctlr.h" +#include "../ctlr/screen.h" +#include "../ctlr/function.h" +#include "../api/astosc.h" +#include "../general/globals.h" + +#include "../ctlr/kbd.out" + + +int NumberColumns = 80; + +int direction; + +int column = 1; +int indenting = 0; +int direction = '?'; + +unsigned char printBuffer[200], *print = printBuffer; + +#define ColsLeft() (79-column) /* A little room for error */ + + +void +putSpace() +{ + extern void Column1(); + unsigned char *ourPrint = print; + + print = printBuffer; /* For mutual calls */ + *ourPrint = 0; + if (ColsLeft() < 0) { + Column1(); + } + if (column != (indenting*8+1)) { + putchar(' '); + } else { + int i; + + putchar(direction); + putchar(' '); + for (i = 0; i < indenting; i++) { + putchar('\t'); + } + } + printf("%s", printBuffer); + column += strlen(printBuffer); +} + +void +Column1() +{ + if (print != printBuffer) { + putSpace(); + } + if (column != (indenting*8+1)) { + putchar('\n'); + column = indenting*8+1; + } +} + +void +Indent() +{ + if ((column != (indenting*8+1)) || (print != printBuffer)) { + Column1(); + } + indenting++; + column = indenting*8+1; +} + +void +Undent() +{ + if ((column != (indenting*8+1)) || (print != printBuffer)) { + Column1(); + } + indenting--; + if (indenting < 0) { + fflush(stdout); + fprintf(stderr, "INTERNAL ERROR: indenting < 0.\n"); + fflush(stderr); + } else { + column = indenting*8+1; + } +} + +void +putChar(character) +int character; +{ + *print++ = character; + column++; +} + +void +putstr(s) +char *s; +{ + while (*s) { + putChar(*s++); + } +} + +void +put2hex(i) +int i; +{ + char place[40]; + + sprintf(place, "%02x", i); + putstr(place); +} + + +void +putdecimal(i) +int i; +{ + char place[40]; + + sprintf(place, "%d", i); + putstr(place); +} + +void +puthex(i) +int i; +{ + char place[40]; + + sprintf(place, "%x", i); + putstr(place); +} + +void +putEChar(character) +int character; +{ + putChar(ebc_asc[character]); + if (ColsLeft() < 10) { + Column1(); + } +} + +void +PrintAid(i) +int i; +{ + struct astosc *this; + + for (this = &astosc[0]; this <= &astosc[highestof(astosc)]; this++) { + if (this->function == FCN_AID) { + int j; + + switch (this->shiftstate) { + case 0: + j = 0; + break; + case SHIFT_UPSHIFT: + j = 1; + break; + case SHIFT_ALT: + j = 2; + break; + case (SHIFT_UPSHIFT|SHIFT_ALT): + j = 3; + break; + default: + fprintf(stderr, "Bad shiftstate 0x%x.\n", this->shiftstate); + exit(1); + } + if (hits[this->scancode].hit[j].code == i) { + putstr(this->name); + return; + } + } + } + + putstr("Unknown AID 0x"); + put2hex(i); +} + +void +PrintAddr(i) +int i; +{ + if (ColsLeft() < 9) { + Column1(); + } + putChar('('); + putdecimal(ScreenLine(i)); + putChar(','); + putdecimal(ScreenLineOffset(i)); + putChar(')'); +} + + +/* returns the number of characters consumed */ +int +DataFromNetwork(buffer, count, control) +register unsigned char *buffer; /* what the data is */ +register int count; /* and how much there is */ +int control; /* this buffer ended block? */ +{ + int origCount; + register int c; + register int i; + static int Command; + static int Wcc; + static int LastWasTerminated = 1; /* was "control" = 1 last time? */ + + if (count == 0) { + Column1(); + return 0; + } + + origCount = count; + + if (LastWasTerminated) { + + if (count < 2) { + if (count == 0) { + fflush(stdout); + fprintf(stderr, "Short count received from host!\n"); + fflush(stderr); + return(count); + } + Command = buffer[0]; + switch (Command) { /* This had better be a read command */ + case CMD_READ_MODIFIED: + putstr("read_modified command\n"); + break; + case CMD_SNA_READ_MODIFIED: + putstr("sna_read_modified command\n"); + break; + case CMD_SNA_READ_MODIFIED_ALL: + putstr("sna_read_modified_all command\n"); + break; + case CMD_READ_BUFFER: + putstr("read_buffer command\n"); + break; + case CMD_SNA_READ_BUFFER: + putstr("sna_read_buffer command\n"); + break; + default: + break; + } + return(1); /* We consumed everything */ + } + Command = buffer[0]; + Wcc = buffer[1]; + switch (Command) { + case CMD_ERASE_WRITE: + putstr("erase write command "); + break; + case CMD_ERASE_WRITE_ALTERNATE: + putstr("erase write alternate command "); + break; + case CMD_SNA_ERASE_WRITE: + putstr("sna erase write command "); + break; + case CMD_SNA_ERASE_WRITE_ALTERNATE: + putstr("erase write alternate command "); + break; + case CMD_ERASE_ALL_UNPROTECTED: + putstr("erase all unprotected command "); + break; + case CMD_SNA_ERASE_ALL_UNPROTECTED: + putstr("sna erase write command "); + break; + case CMD_WRITE: + putstr("write command "); + break; + case CMD_SNA_WRITE: + putstr("sna write command "); + break; + default: + putstr("Unexpected command code 0x"); + puthex(Command); + putstr(" received."); + Column1(); + break; + } + putstr("WCC is 0x"); + puthex(Wcc); + Column1(); + + count -= 2; /* strip off command and wcc */ + buffer += 2; + + } + LastWasTerminated = 0; /* then, reset at end... */ + + while (count) { + count--; + c = *buffer++; + if (IsOrder(c)) { + /* handle an order */ + switch (c) { +# define Ensure(x) if (count < x) { \ + if (!control) { \ + return(origCount-(count+1)); \ + } else { \ + /* XXX - should not occur */ \ + count = 0; \ + break; \ + } \ + } + case ORDER_SF: + Ensure(1); + c = *buffer++; + count--; + putstr("SF (0x"); + put2hex(c); + putstr(") "); + break; + case ORDER_SBA: + Ensure(2); + i = buffer[0]; + c = buffer[1]; + buffer += 2; + count -= 2; + putstr("SBA to "); + PrintAddr(Addr3270(i,c)); + putSpace(); + break; + case ORDER_IC: + putstr("IC"); + putSpace(); + break; + case ORDER_PT: + putstr("PT"); + putSpace(); + break; + case ORDER_RA: + Ensure(3); + i = Addr3270(buffer[0], buffer[1]); + c = buffer[2]; + buffer += 3; + count -= 3; + putstr("RA to "); + PrintAddr(i); + putstr(" of 0x"); + put2hex(c); + putSpace(); + break; + case ORDER_EUA: /* (from [here,there), ie: half open interval] */ + Ensure(2); + putstr("EUA to "); + PrintAddr(Addr3270(buffer[0], buffer[1])); + putSpace(); + buffer += 2; + count -= 2; + break; + case ORDER_YALE: /* special YALE defined order */ + Ensure(2); /* need at least two characters */ + putstr("YALE order"); + putSpace(); + break; + default: + putstr("UNKNOWN ORDER: 0x"); + put2hex(c); + putSpace(); + break; + } + if (count < 0) { + count = 0; + } + } else { + /* Data comes in large clumps - take it all */ + putstr("DATA:"); + Indent(); + putEChar(c); + c = *buffer; + while (count && !IsOrder(c)) { + putEChar(c); + count--; + buffer++; + c = *buffer; + } + Undent(); + } + } + LastWasTerminated = control; + return origCount - count; +} + +int +DataToNetwork(buffer, count, control) +unsigned char *buffer; +int count; +int control; +{ +#define NEED_AID 0 +#define JUST_GOT_AID 1 +#define DATA 2 +#define DATA_CONTINUE 3 + static int state = NEED_AID; + static int aid; + int origCount = count; + + if (count == 0) { + if (control) { + state = NEED_AID; + } + Column1(); + return 0; + } + + switch (state) { + case NEED_AID: + aid = buffer[0]; + buffer++; + count--; + PrintAid(aid); + putSpace(); + if (aid == AID_TREQ) { + state = DATA; + } else { + state = JUST_GOT_AID; + } + return origCount - count + DataToNetwork(buffer, count, control); + case JUST_GOT_AID: + Ensure(2); + PrintAddr(Addr3270(buffer[0], buffer[1])); + putSpace(); + buffer += 2; + count -= 2; + state = DATA; + return origCount - count + DataToNetwork(buffer, count, control); + case DATA: + case DATA_CONTINUE: + while (count) { + if (*buffer == ORDER_SBA) { + if (state == DATA_CONTINUE) { + Undent(); + state = DATA; + } + putstr("SBA "); + PrintAddr(Addr3270(buffer[1], buffer[2])); + putSpace(); + buffer += 3; + count -= 3; + } else { + if (state == DATA) { + putstr("DATA:"); + Indent(); + state = DATA_CONTINUE; + } + putEChar(*buffer); + buffer++; + count--; + } + } + if (control) { + if (state == DATA_CONTINUE) { + Undent(); + } + state = NEED_AID; + } + return origCount-count; + } +} + +int +GetXValue(c) +int c; +{ + if (!isascii(c)) { + fflush(stdout); + fprintf(stderr, "Non-hex digit 0x%x.\n"); + fflush(stderr); + return 0; + } else { + if (islower(c)) { + return (c-'a')+10; + } else if (isupper(c)) { + return (c-'A')+10; + } else { + return c-'0'; + } + } +} + +unsigned char outbound[8192], inbound[8192], + *outnext = outbound, *innext = inbound, *p = 0; + +void +termblock(old, new, control) +int old, + new; /* old and new directions */ +{ + int count; + + if (p) { + if (old == '<') { + outnext = p; + count = DataFromNetwork(outbound, outnext-outbound, control); + if (outbound+count == outnext) { + outnext = outbound; + } else { + memcpy(outbound, outbound+count, outnext-(outbound+count)); + outnext = outbound+count; + } + } else { + innext = p; + count = DataToNetwork(inbound, innext-inbound, control); + if (inbound+count == innext) { + innext = inbound; + } else { + memcpy(inbound, inbound+count, innext-(inbound+count)); + innext = inbound+count; + } + } + } + if (new == '<') { + p = outnext; + } else if (new == '>') { + p = innext; + } else { + fprintf(stderr, "Bad direction character '%c'.\n", new); + exit(1); + } +} + +main() +{ + int location; + char new; + int c, c1; + + memset(Orders, 0, sizeof Orders); + Orders[ORDER_SF] = Orders[ORDER_SBA] = Orders[ORDER_IC] + = Orders[ORDER_PT] = Orders[ORDER_RA] = Orders[ORDER_EUA] + = Orders[ORDER_YALE] = 1; + + while (scanf("%c 0x%x\t", &new, &location) != EOF) { + if (new != direction) { + termblock(direction, new, 0); + direction = new; + } + while (((c = getchar()) != EOF) && (c != '\n') && (isxdigit(c))) { +#define NORMAL 0 +#define GOT0XFF 0xff + static int state = NORMAL; + + c1 = getchar(); + c = (GetXValue(c) << 4) + GetXValue(c1); + switch (state) { + case NORMAL: + if (c == 0xff) { + state = GOT0XFF; + } else { + *p++ = c; + } + break; + case GOT0XFF: + if (c == 0xef) { + termblock(direction, direction, 1); + } else { + *p++ = 0xff; + *p++ = c; + } + state = NORMAL; + } + } + } + return 0; +} |