131896Sminshall /* 2*33811Sbostic * Copyright (c) 1988 Regents of the University of California. 3*33811Sbostic * All rights reserved. 431896Sminshall * 5*33811Sbostic * Redistribution and use in source and binary forms are permitted 6*33811Sbostic * provided that this notice is preserved and that due credit is given 7*33811Sbostic * to the University of California at Berkeley. The name of the University 8*33811Sbostic * may not be used to endorse or promote products derived from this 9*33811Sbostic * software without specific prior written permission. This software 10*33811Sbostic * is provided ``as is'' without express or implied warranty. 1131896Sminshall */ 1230051Sminshall 1331896Sminshall #ifndef lint 14*33811Sbostic char copyright[] = 15*33811Sbostic "@(#) Copyright (c) 1988 Regents of the University of California.\n\ 16*33811Sbostic All rights reserved.\n"; 17*33811Sbostic #endif /* not lint */ 1830051Sminshall 19*33811Sbostic #ifndef lint 20*33811Sbostic static char sccsid[] = "@(#)prt3270.c 3.3 (Berkeley) 03/28/88"; 21*33811Sbostic #endif /* not lint */ 22*33811Sbostic 2330051Sminshall #if defined(unix) 2430051Sminshall #endif 2530051Sminshall #include <stdio.h> 2630051Sminshall #include <ctype.h> 2730051Sminshall 2831175Sminshall #include "../general/general.h" 2931102Sminshall 3031875Sminshall #include "../api/asc_ebc.h" 3130051Sminshall #include "../ctlr/hostctlr.h" 3230051Sminshall #include "../ctlr/screen.h" 3331444Sminshall #include "../ctlr/function.h" 3431875Sminshall #include "../api/astosc.h" 3531175Sminshall #include "../general/globals.h" 3630051Sminshall 3731444Sminshall #include "../ctlr/kbd.out" 3830051Sminshall 3931444Sminshall 4030051Sminshall int NumberColumns = 80; 4130051Sminshall 4230051Sminshall int direction; 4330051Sminshall 4430051Sminshall int column = 1; 4530051Sminshall int indenting = 0; 4630051Sminshall int direction = '?'; 4730051Sminshall 4830051Sminshall unsigned char printBuffer[200], *print = printBuffer; 4930051Sminshall 5030051Sminshall #define ColsLeft() (79-column) /* A little room for error */ 5130051Sminshall 5230051Sminshall 5330051Sminshall void 5430051Sminshall putSpace() 5530051Sminshall { 5630051Sminshall extern void Column1(); 5730051Sminshall unsigned char *ourPrint = print; 5830051Sminshall 5930051Sminshall print = printBuffer; /* For mutual calls */ 6030051Sminshall *ourPrint = 0; 6130051Sminshall if (ColsLeft() < 0) { 6230051Sminshall Column1(); 6330051Sminshall } 6430051Sminshall if (column != (indenting*8+1)) { 6530051Sminshall putchar(' '); 6630051Sminshall } else { 6730051Sminshall int i; 6830051Sminshall 6930051Sminshall putchar(direction); 7030051Sminshall putchar(' '); 7130051Sminshall for (i = 0; i < indenting; i++) { 7230051Sminshall putchar('\t'); 7330051Sminshall } 7430051Sminshall } 7530051Sminshall printf("%s", printBuffer); 7630051Sminshall column += strlen(printBuffer); 7730051Sminshall } 7830051Sminshall 7930051Sminshall void 8030051Sminshall Column1() 8130051Sminshall { 8230051Sminshall if (print != printBuffer) { 8330051Sminshall putSpace(); 8430051Sminshall } 8530051Sminshall if (column != (indenting*8+1)) { 8630051Sminshall putchar('\n'); 8730051Sminshall column = indenting*8+1; 8830051Sminshall } 8930051Sminshall } 9030051Sminshall 9130051Sminshall void 9230051Sminshall Indent() 9330051Sminshall { 9430051Sminshall if ((column != (indenting*8+1)) || (print != printBuffer)) { 9530051Sminshall Column1(); 9630051Sminshall } 9730051Sminshall indenting++; 9830051Sminshall column = indenting*8+1; 9930051Sminshall } 10030051Sminshall 10130051Sminshall void 10230051Sminshall Undent() 10330051Sminshall { 10430051Sminshall if ((column != (indenting*8+1)) || (print != printBuffer)) { 10530051Sminshall Column1(); 10630051Sminshall } 10730051Sminshall indenting--; 10830051Sminshall if (indenting < 0) { 10930051Sminshall fflush(stdout); 11030051Sminshall fprintf(stderr, "INTERNAL ERROR: indenting < 0.\n"); 11130051Sminshall fflush(stderr); 11230051Sminshall } else { 11330051Sminshall column = indenting*8+1; 11430051Sminshall } 11530051Sminshall } 11630051Sminshall 11730051Sminshall void 11830051Sminshall putChar(character) 11930051Sminshall int character; 12030051Sminshall { 12130051Sminshall *print++ = character; 12230732Sminshall column++; 12330051Sminshall } 12430051Sminshall 12530051Sminshall void 12630051Sminshall putstr(s) 12730051Sminshall char *s; 12830051Sminshall { 12930051Sminshall while (*s) { 13030051Sminshall putChar(*s++); 13130051Sminshall } 13230051Sminshall } 13330051Sminshall 13430051Sminshall void 13530051Sminshall put2hex(i) 13630051Sminshall int i; 13730051Sminshall { 13830051Sminshall char place[40]; 13930051Sminshall 14030051Sminshall sprintf(place, "%02x", i); 14130051Sminshall putstr(place); 14230051Sminshall } 14330051Sminshall 14430051Sminshall 14530051Sminshall void 14630051Sminshall putdecimal(i) 14730051Sminshall int i; 14830051Sminshall { 14930051Sminshall char place[40]; 15030051Sminshall 15130051Sminshall sprintf(place, "%d", i); 15230051Sminshall putstr(place); 15330051Sminshall } 15430051Sminshall 15530051Sminshall void 15630051Sminshall puthex(i) 15730051Sminshall int i; 15830051Sminshall { 15930051Sminshall char place[40]; 16030051Sminshall 16130051Sminshall sprintf(place, "%x", i); 16230051Sminshall putstr(place); 16330051Sminshall } 16430051Sminshall 16530051Sminshall void 16630051Sminshall putEChar(character) 16730051Sminshall int character; 16830051Sminshall { 16931614Sminshall putChar(ebc_asc[character]); 17030051Sminshall if (ColsLeft() < 10) { 17130051Sminshall Column1(); 17230051Sminshall } 17330051Sminshall } 17430051Sminshall 17530051Sminshall void 17630051Sminshall PrintAid(i) 17730051Sminshall int i; 17830051Sminshall { 17931444Sminshall struct astosc *this; 18030051Sminshall 18131444Sminshall for (this = &astosc[0]; this <= &astosc[highestof(astosc)]; this++) { 18231444Sminshall if (this->function == FCN_AID) { 18331444Sminshall int j; 18431444Sminshall 18531444Sminshall switch (this->shiftstate) { 18631444Sminshall case 0: 18731444Sminshall j = 0; 18831444Sminshall break; 18931444Sminshall case SHIFT_UPSHIFT: 19031444Sminshall j = 1; 19131444Sminshall break; 19231444Sminshall case SHIFT_ALT: 19331444Sminshall j = 2; 19431444Sminshall break; 19531444Sminshall case (SHIFT_UPSHIFT|SHIFT_ALT): 19631444Sminshall j = 3; 19731444Sminshall break; 19831444Sminshall default: 19931444Sminshall fprintf(stderr, "Bad shiftstate 0x%x.\n", this->shiftstate); 20031444Sminshall exit(1); 20131444Sminshall } 20231444Sminshall if (hits[this->scancode].hit[j].code == i) { 20331444Sminshall putstr(this->name); 20431444Sminshall return; 20531444Sminshall } 20630051Sminshall } 20730051Sminshall } 20830051Sminshall 20930051Sminshall putstr("Unknown AID 0x"); 21030051Sminshall put2hex(i); 21130051Sminshall } 21230051Sminshall 21330051Sminshall void 21430051Sminshall PrintAddr(i) 21530051Sminshall int i; 21630051Sminshall { 21730051Sminshall if (ColsLeft() < 9) { 21830051Sminshall Column1(); 21930051Sminshall } 22030051Sminshall putChar('('); 22130051Sminshall putdecimal(ScreenLine(i)); 22230051Sminshall putChar(','); 22330051Sminshall putdecimal(ScreenLineOffset(i)); 22430051Sminshall putChar(')'); 22530051Sminshall } 22630051Sminshall 22730051Sminshall 22830051Sminshall /* returns the number of characters consumed */ 22930051Sminshall int 23030051Sminshall DataFromNetwork(buffer, count, control) 23130051Sminshall register unsigned char *buffer; /* what the data is */ 23230051Sminshall register int count; /* and how much there is */ 23330051Sminshall int control; /* this buffer ended block? */ 23430051Sminshall { 23530051Sminshall int origCount; 23630051Sminshall register int c; 23730051Sminshall register int i; 23830051Sminshall static int Command; 23930051Sminshall static int Wcc; 24030051Sminshall static int LastWasTerminated = 1; /* was "control" = 1 last time? */ 24130051Sminshall 24230051Sminshall if (count == 0) { 24330051Sminshall Column1(); 24430051Sminshall return 0; 24530051Sminshall } 24630051Sminshall 24730051Sminshall origCount = count; 24830051Sminshall 24930051Sminshall if (LastWasTerminated) { 25030051Sminshall 25130051Sminshall if (count < 2) { 25230051Sminshall if (count == 0) { 25330051Sminshall fflush(stdout); 25430051Sminshall fprintf(stderr, "Short count received from host!\n"); 25530051Sminshall fflush(stderr); 25630051Sminshall return(count); 25730051Sminshall } 25830051Sminshall Command = buffer[0]; 25930051Sminshall switch (Command) { /* This had better be a read command */ 26030051Sminshall case CMD_READ_MODIFIED: 26130051Sminshall putstr("read_modified command\n"); 26230051Sminshall break; 26330051Sminshall case CMD_SNA_READ_MODIFIED: 26432090Sminshall putstr("sna_read_modified command\n"); 26530051Sminshall break; 26630051Sminshall case CMD_SNA_READ_MODIFIED_ALL: 26732090Sminshall putstr("sna_read_modified_all command\n"); 26830051Sminshall break; 26930051Sminshall case CMD_READ_BUFFER: 27032090Sminshall putstr("read_buffer command\n"); 27130051Sminshall break; 27230051Sminshall case CMD_SNA_READ_BUFFER: 27332090Sminshall putstr("sna_read_buffer command\n"); 27430051Sminshall break; 27530051Sminshall default: 27630051Sminshall break; 27730051Sminshall } 27830051Sminshall return(1); /* We consumed everything */ 27930051Sminshall } 28030051Sminshall Command = buffer[0]; 28130051Sminshall Wcc = buffer[1]; 28230051Sminshall switch (Command) { 28330051Sminshall case CMD_ERASE_WRITE: 28430051Sminshall putstr("erase write command "); 28530051Sminshall break; 28630051Sminshall case CMD_ERASE_WRITE_ALTERNATE: 28730051Sminshall putstr("erase write alternate command "); 28830051Sminshall break; 28930051Sminshall case CMD_SNA_ERASE_WRITE: 29030051Sminshall putstr("sna erase write command "); 29130051Sminshall break; 29230051Sminshall case CMD_SNA_ERASE_WRITE_ALTERNATE: 29330051Sminshall putstr("erase write alternate command "); 29430051Sminshall break; 29530051Sminshall case CMD_ERASE_ALL_UNPROTECTED: 29630051Sminshall putstr("erase all unprotected command "); 29730051Sminshall break; 29830051Sminshall case CMD_SNA_ERASE_ALL_UNPROTECTED: 29930051Sminshall putstr("sna erase write command "); 30030051Sminshall break; 30130051Sminshall case CMD_WRITE: 30230051Sminshall putstr("write command "); 30330051Sminshall break; 30430051Sminshall case CMD_SNA_WRITE: 30530051Sminshall putstr("sna write command "); 30630051Sminshall break; 30730051Sminshall default: 30830051Sminshall putstr("Unexpected command code 0x"); 30930051Sminshall puthex(Command); 31030051Sminshall putstr(" received."); 31130051Sminshall Column1(); 31230051Sminshall break; 31330051Sminshall } 31430051Sminshall putstr("WCC is 0x"); 31530051Sminshall puthex(Wcc); 31630051Sminshall Column1(); 31730051Sminshall 31830051Sminshall count -= 2; /* strip off command and wcc */ 31930051Sminshall buffer += 2; 32030051Sminshall 32130051Sminshall } 32230051Sminshall LastWasTerminated = 0; /* then, reset at end... */ 32330051Sminshall 32430051Sminshall while (count) { 32530051Sminshall count--; 32630051Sminshall c = *buffer++; 32730051Sminshall if (IsOrder(c)) { 32830051Sminshall /* handle an order */ 32930051Sminshall switch (c) { 33030051Sminshall # define Ensure(x) if (count < x) { \ 33130051Sminshall if (!control) { \ 33230051Sminshall return(origCount-(count+1)); \ 33330051Sminshall } else { \ 33430051Sminshall /* XXX - should not occur */ \ 33530051Sminshall count = 0; \ 33630051Sminshall break; \ 33730051Sminshall } \ 33830051Sminshall } 33930051Sminshall case ORDER_SF: 34030051Sminshall Ensure(1); 34130051Sminshall c = *buffer++; 34230051Sminshall count--; 34330051Sminshall putstr("SF (0x"); 34430051Sminshall put2hex(c); 34530051Sminshall putstr(") "); 34630051Sminshall break; 34730051Sminshall case ORDER_SBA: 34830051Sminshall Ensure(2); 34930051Sminshall i = buffer[0]; 35030051Sminshall c = buffer[1]; 35130051Sminshall buffer += 2; 35230051Sminshall count -= 2; 35330051Sminshall putstr("SBA to "); 35430051Sminshall PrintAddr(Addr3270(i,c)); 35530051Sminshall putSpace(); 35630051Sminshall break; 35730051Sminshall case ORDER_IC: 35830051Sminshall putstr("IC"); 35930051Sminshall putSpace(); 36030051Sminshall break; 36130051Sminshall case ORDER_PT: 36230051Sminshall putstr("PT"); 36330051Sminshall putSpace(); 36430051Sminshall break; 36530051Sminshall case ORDER_RA: 36630051Sminshall Ensure(3); 36730051Sminshall i = Addr3270(buffer[0], buffer[1]); 36830051Sminshall c = buffer[2]; 36930051Sminshall buffer += 3; 37030051Sminshall count -= 3; 37130051Sminshall putstr("RA to "); 37230051Sminshall PrintAddr(i); 37330051Sminshall putstr(" of 0x"); 37430051Sminshall put2hex(c); 37530051Sminshall putSpace(); 37630051Sminshall break; 37730051Sminshall case ORDER_EUA: /* (from [here,there), ie: half open interval] */ 37830051Sminshall Ensure(2); 37930051Sminshall putstr("EUA to "); 38030051Sminshall PrintAddr(Addr3270(buffer[0], buffer[1])); 38130051Sminshall putSpace(); 38230051Sminshall buffer += 2; 38330051Sminshall count -= 2; 38430051Sminshall break; 38530051Sminshall case ORDER_YALE: /* special YALE defined order */ 38630051Sminshall Ensure(2); /* need at least two characters */ 38730051Sminshall putstr("YALE order"); 38830051Sminshall putSpace(); 38930051Sminshall break; 39030051Sminshall default: 39130051Sminshall putstr("UNKNOWN ORDER: 0x"); 39230051Sminshall put2hex(c); 39330051Sminshall putSpace(); 39430051Sminshall break; 39530051Sminshall } 39630051Sminshall if (count < 0) { 39730051Sminshall count = 0; 39830051Sminshall } 39930051Sminshall } else { 40030051Sminshall /* Data comes in large clumps - take it all */ 40130051Sminshall putstr("DATA:"); 40230051Sminshall Indent(); 40330051Sminshall putEChar(c); 40430051Sminshall c = *buffer; 40530051Sminshall while (count && !IsOrder(c)) { 40630051Sminshall putEChar(c); 40730051Sminshall count--; 40830051Sminshall buffer++; 40930051Sminshall c = *buffer; 41030051Sminshall } 41130051Sminshall Undent(); 41230051Sminshall } 41330051Sminshall } 41430051Sminshall LastWasTerminated = control; 41530051Sminshall return origCount - count; 41630051Sminshall } 41730051Sminshall 41830051Sminshall int 41930051Sminshall DataToNetwork(buffer, count, control) 42030051Sminshall unsigned char *buffer; 42130051Sminshall int count; 42230051Sminshall int control; 42330051Sminshall { 42430051Sminshall #define NEED_AID 0 42530051Sminshall #define JUST_GOT_AID 1 42630051Sminshall #define DATA 2 42730051Sminshall #define DATA_CONTINUE 3 42830051Sminshall static int state = NEED_AID; 42930051Sminshall static int aid; 43030051Sminshall int origCount = count; 43130051Sminshall 43230051Sminshall if (count == 0) { 43330051Sminshall if (control) { 43430051Sminshall state = NEED_AID; 43530051Sminshall } 43630051Sminshall Column1(); 43730051Sminshall return 0; 43830051Sminshall } 43930051Sminshall 44030051Sminshall switch (state) { 44130051Sminshall case NEED_AID: 44230051Sminshall aid = buffer[0]; 44330051Sminshall buffer++; 44430051Sminshall count--; 44530051Sminshall PrintAid(aid); 44630051Sminshall putSpace(); 44731444Sminshall if (aid == AID_TREQ) { 44830051Sminshall state = DATA; 44930051Sminshall } else { 45030051Sminshall state = JUST_GOT_AID; 45130051Sminshall } 45230051Sminshall return origCount - count + DataToNetwork(buffer, count, control); 45330051Sminshall case JUST_GOT_AID: 45430051Sminshall Ensure(2); 45530051Sminshall PrintAddr(Addr3270(buffer[0], buffer[1])); 45630051Sminshall putSpace(); 45730051Sminshall buffer += 2; 45830051Sminshall count -= 2; 45930051Sminshall state = DATA; 46030051Sminshall return origCount - count + DataToNetwork(buffer, count, control); 46130051Sminshall case DATA: 46230051Sminshall case DATA_CONTINUE: 46330051Sminshall while (count) { 46430051Sminshall if (*buffer == ORDER_SBA) { 46530051Sminshall if (state == DATA_CONTINUE) { 46630051Sminshall Undent(); 46730051Sminshall state = DATA; 46830051Sminshall } 46930051Sminshall putstr("SBA "); 47030051Sminshall PrintAddr(Addr3270(buffer[1], buffer[2])); 47130051Sminshall putSpace(); 47230051Sminshall buffer += 3; 47330051Sminshall count -= 3; 47430051Sminshall } else { 47530051Sminshall if (state == DATA) { 47630051Sminshall putstr("DATA:"); 47730051Sminshall Indent(); 47830051Sminshall state = DATA_CONTINUE; 47930051Sminshall } 48030051Sminshall putEChar(*buffer); 48130051Sminshall buffer++; 48230051Sminshall count--; 48330051Sminshall } 48430051Sminshall } 48530051Sminshall if (control) { 48630051Sminshall if (state == DATA_CONTINUE) { 48730051Sminshall Undent(); 48830051Sminshall } 48930051Sminshall state = NEED_AID; 49030051Sminshall } 49130051Sminshall return origCount-count; 49230051Sminshall } 49330051Sminshall } 49430051Sminshall 49530051Sminshall int 49630051Sminshall GetXValue(c) 49730051Sminshall int c; 49830051Sminshall { 49930051Sminshall if (!isascii(c)) { 50030051Sminshall fflush(stdout); 50130051Sminshall fprintf(stderr, "Non-hex digit 0x%x.\n"); 50230051Sminshall fflush(stderr); 50330051Sminshall return 0; 50430051Sminshall } else { 50530051Sminshall if (islower(c)) { 50630051Sminshall return (c-'a')+10; 50730051Sminshall } else if (isupper(c)) { 50830051Sminshall return (c-'A')+10; 50930051Sminshall } else { 51030051Sminshall return c-'0'; 51130051Sminshall } 51230051Sminshall } 51330051Sminshall } 51430051Sminshall 51530051Sminshall unsigned char outbound[8192], inbound[8192], 51630051Sminshall *outnext = outbound, *innext = inbound, *p = 0; 51730051Sminshall 51830051Sminshall void 51930051Sminshall termblock(old, new, control) 52030051Sminshall int old, 52130051Sminshall new; /* old and new directions */ 52230051Sminshall { 52330051Sminshall int count; 52430051Sminshall 52530051Sminshall if (p) { 52630051Sminshall if (old == '<') { 52730051Sminshall outnext = p; 52830051Sminshall count = DataFromNetwork(outbound, outnext-outbound, control); 52930051Sminshall if (outbound+count == outnext) { 53030051Sminshall outnext = outbound; 53130051Sminshall } else { 53231102Sminshall memcpy(outbound, outbound+count, outnext-(outbound+count)); 53330051Sminshall outnext = outbound+count; 53430051Sminshall } 53530051Sminshall } else { 53630051Sminshall innext = p; 53730051Sminshall count = DataToNetwork(inbound, innext-inbound, control); 53830051Sminshall if (inbound+count == innext) { 53930051Sminshall innext = inbound; 54030051Sminshall } else { 54131102Sminshall memcpy(inbound, inbound+count, innext-(inbound+count)); 54230051Sminshall innext = inbound+count; 54330051Sminshall } 54430051Sminshall } 54530051Sminshall } 54630051Sminshall if (new == '<') { 54730051Sminshall p = outnext; 54830051Sminshall } else if (new == '>') { 54930051Sminshall p = innext; 55030051Sminshall } else { 55130051Sminshall fprintf(stderr, "Bad direction character '%c'.\n", new); 55230051Sminshall exit(1); 55330051Sminshall } 55430051Sminshall } 55530051Sminshall 55630051Sminshall main() 55730051Sminshall { 55830051Sminshall int location; 55932090Sminshall char new; 56030051Sminshall int c, c1; 56130051Sminshall 56231102Sminshall memset(Orders, 0, sizeof Orders); 56330051Sminshall Orders[ORDER_SF] = Orders[ORDER_SBA] = Orders[ORDER_IC] 56430051Sminshall = Orders[ORDER_PT] = Orders[ORDER_RA] = Orders[ORDER_EUA] 56530051Sminshall = Orders[ORDER_YALE] = 1; 56630051Sminshall 56730051Sminshall while (scanf("%c 0x%x\t", &new, &location) != EOF) { 56830051Sminshall if (new != direction) { 56930051Sminshall termblock(direction, new, 0); 57030051Sminshall direction = new; 57130051Sminshall } 57230051Sminshall while (((c = getchar()) != EOF) && (c != '\n') && (isxdigit(c))) { 57330051Sminshall #define NORMAL 0 57430051Sminshall #define GOT0XFF 0xff 57530051Sminshall static int state = NORMAL; 57630051Sminshall 57730051Sminshall c1 = getchar(); 57830051Sminshall c = (GetXValue(c) << 4) + GetXValue(c1); 57930051Sminshall switch (state) { 58030051Sminshall case NORMAL: 58130051Sminshall if (c == 0xff) { 58230051Sminshall state = GOT0XFF; 58330051Sminshall } else { 58430051Sminshall *p++ = c; 58530051Sminshall } 58630051Sminshall break; 58730051Sminshall case GOT0XFF: 58830051Sminshall if (c == 0xef) { 58930051Sminshall termblock(direction, direction, 1); 59030051Sminshall } else { 59130051Sminshall *p++ = 0xff; 59230051Sminshall *p++ = c; 59330051Sminshall } 59430051Sminshall state = NORMAL; 59530051Sminshall } 59630051Sminshall } 59730051Sminshall } 59830051Sminshall return 0; 59930051Sminshall } 600