|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1988 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that this notice is preserved and that due credit is given ! 7: * to the University of California at Berkeley. The name of the University ! 8: * may not be used to endorse or promote products derived from this ! 9: * software without specific prior written permission. This software ! 10: * is provided ``as is'' without express or implied warranty. ! 11: */ ! 12: ! 13: #ifndef lint ! 14: char copyright[] = ! 15: "@(#) Copyright (c) 1988 Regents of the University of California.\n\ ! 16: All rights reserved.\n"; ! 17: #endif /* not lint */ ! 18: ! 19: #ifndef lint ! 20: static char sccsid[] = "@(#)prt3270.c 3.3 (Berkeley) 3/28/88"; ! 21: #endif /* not lint */ ! 22: ! 23: #if defined(unix) ! 24: #endif ! 25: #include <stdio.h> ! 26: #include <ctype.h> ! 27: ! 28: #include "../general/general.h" ! 29: ! 30: #include "../api/asc_ebc.h" ! 31: #include "../ctlr/hostctlr.h" ! 32: #include "../ctlr/screen.h" ! 33: #include "../ctlr/function.h" ! 34: #include "../api/astosc.h" ! 35: #include "../general/globals.h" ! 36: ! 37: #include "../ctlr/kbd.out" ! 38: ! 39: ! 40: int NumberColumns = 80; ! 41: ! 42: int direction; ! 43: ! 44: int column = 1; ! 45: int indenting = 0; ! 46: int direction = '?'; ! 47: ! 48: unsigned char printBuffer[200], *print = printBuffer; ! 49: ! 50: #define ColsLeft() (79-column) /* A little room for error */ ! 51: ! 52: ! 53: void ! 54: putSpace() ! 55: { ! 56: extern void Column1(); ! 57: unsigned char *ourPrint = print; ! 58: ! 59: print = printBuffer; /* For mutual calls */ ! 60: *ourPrint = 0; ! 61: if (ColsLeft() < 0) { ! 62: Column1(); ! 63: } ! 64: if (column != (indenting*8+1)) { ! 65: putchar(' '); ! 66: } else { ! 67: int i; ! 68: ! 69: putchar(direction); ! 70: putchar(' '); ! 71: for (i = 0; i < indenting; i++) { ! 72: putchar('\t'); ! 73: } ! 74: } ! 75: printf("%s", printBuffer); ! 76: column += strlen(printBuffer); ! 77: } ! 78: ! 79: void ! 80: Column1() ! 81: { ! 82: if (print != printBuffer) { ! 83: putSpace(); ! 84: } ! 85: if (column != (indenting*8+1)) { ! 86: putchar('\n'); ! 87: column = indenting*8+1; ! 88: } ! 89: } ! 90: ! 91: void ! 92: Indent() ! 93: { ! 94: if ((column != (indenting*8+1)) || (print != printBuffer)) { ! 95: Column1(); ! 96: } ! 97: indenting++; ! 98: column = indenting*8+1; ! 99: } ! 100: ! 101: void ! 102: Undent() ! 103: { ! 104: if ((column != (indenting*8+1)) || (print != printBuffer)) { ! 105: Column1(); ! 106: } ! 107: indenting--; ! 108: if (indenting < 0) { ! 109: fflush(stdout); ! 110: fprintf(stderr, "INTERNAL ERROR: indenting < 0.\n"); ! 111: fflush(stderr); ! 112: } else { ! 113: column = indenting*8+1; ! 114: } ! 115: } ! 116: ! 117: void ! 118: putChar(character) ! 119: int character; ! 120: { ! 121: *print++ = character; ! 122: column++; ! 123: } ! 124: ! 125: void ! 126: putstr(s) ! 127: char *s; ! 128: { ! 129: while (*s) { ! 130: putChar(*s++); ! 131: } ! 132: } ! 133: ! 134: void ! 135: put2hex(i) ! 136: int i; ! 137: { ! 138: char place[40]; ! 139: ! 140: sprintf(place, "%02x", i); ! 141: putstr(place); ! 142: } ! 143: ! 144: ! 145: void ! 146: putdecimal(i) ! 147: int i; ! 148: { ! 149: char place[40]; ! 150: ! 151: sprintf(place, "%d", i); ! 152: putstr(place); ! 153: } ! 154: ! 155: void ! 156: puthex(i) ! 157: int i; ! 158: { ! 159: char place[40]; ! 160: ! 161: sprintf(place, "%x", i); ! 162: putstr(place); ! 163: } ! 164: ! 165: void ! 166: putEChar(character) ! 167: int character; ! 168: { ! 169: putChar(ebc_asc[character]); ! 170: if (ColsLeft() < 10) { ! 171: Column1(); ! 172: } ! 173: } ! 174: ! 175: void ! 176: PrintAid(i) ! 177: int i; ! 178: { ! 179: struct astosc *this; ! 180: ! 181: for (this = &astosc[0]; this <= &astosc[highestof(astosc)]; this++) { ! 182: if (this->function == FCN_AID) { ! 183: int j; ! 184: ! 185: switch (this->shiftstate) { ! 186: case 0: ! 187: j = 0; ! 188: break; ! 189: case SHIFT_UPSHIFT: ! 190: j = 1; ! 191: break; ! 192: case SHIFT_ALT: ! 193: j = 2; ! 194: break; ! 195: case (SHIFT_UPSHIFT|SHIFT_ALT): ! 196: j = 3; ! 197: break; ! 198: default: ! 199: fprintf(stderr, "Bad shiftstate 0x%x.\n", this->shiftstate); ! 200: exit(1); ! 201: } ! 202: if (hits[this->scancode].hit[j].code == i) { ! 203: putstr(this->name); ! 204: return; ! 205: } ! 206: } ! 207: } ! 208: ! 209: putstr("Unknown AID 0x"); ! 210: put2hex(i); ! 211: } ! 212: ! 213: void ! 214: PrintAddr(i) ! 215: int i; ! 216: { ! 217: if (ColsLeft() < 9) { ! 218: Column1(); ! 219: } ! 220: putChar('('); ! 221: putdecimal(ScreenLine(i)); ! 222: putChar(','); ! 223: putdecimal(ScreenLineOffset(i)); ! 224: putChar(')'); ! 225: } ! 226: ! 227: ! 228: /* returns the number of characters consumed */ ! 229: int ! 230: DataFromNetwork(buffer, count, control) ! 231: register unsigned char *buffer; /* what the data is */ ! 232: register int count; /* and how much there is */ ! 233: int control; /* this buffer ended block? */ ! 234: { ! 235: int origCount; ! 236: register int c; ! 237: register int i; ! 238: static int Command; ! 239: static int Wcc; ! 240: static int LastWasTerminated = 1; /* was "control" = 1 last time? */ ! 241: ! 242: if (count == 0) { ! 243: Column1(); ! 244: return 0; ! 245: } ! 246: ! 247: origCount = count; ! 248: ! 249: if (LastWasTerminated) { ! 250: ! 251: if (count < 2) { ! 252: if (count == 0) { ! 253: fflush(stdout); ! 254: fprintf(stderr, "Short count received from host!\n"); ! 255: fflush(stderr); ! 256: return(count); ! 257: } ! 258: Command = buffer[0]; ! 259: switch (Command) { /* This had better be a read command */ ! 260: case CMD_READ_MODIFIED: ! 261: putstr("read_modified command\n"); ! 262: break; ! 263: case CMD_SNA_READ_MODIFIED: ! 264: putstr("sna_read_modified command\n"); ! 265: break; ! 266: case CMD_SNA_READ_MODIFIED_ALL: ! 267: putstr("sna_read_modified_all command\n"); ! 268: break; ! 269: case CMD_READ_BUFFER: ! 270: putstr("read_buffer command\n"); ! 271: break; ! 272: case CMD_SNA_READ_BUFFER: ! 273: putstr("sna_read_buffer command\n"); ! 274: break; ! 275: default: ! 276: break; ! 277: } ! 278: return(1); /* We consumed everything */ ! 279: } ! 280: Command = buffer[0]; ! 281: Wcc = buffer[1]; ! 282: switch (Command) { ! 283: case CMD_ERASE_WRITE: ! 284: putstr("erase write command "); ! 285: break; ! 286: case CMD_ERASE_WRITE_ALTERNATE: ! 287: putstr("erase write alternate command "); ! 288: break; ! 289: case CMD_SNA_ERASE_WRITE: ! 290: putstr("sna erase write command "); ! 291: break; ! 292: case CMD_SNA_ERASE_WRITE_ALTERNATE: ! 293: putstr("erase write alternate command "); ! 294: break; ! 295: case CMD_ERASE_ALL_UNPROTECTED: ! 296: putstr("erase all unprotected command "); ! 297: break; ! 298: case CMD_SNA_ERASE_ALL_UNPROTECTED: ! 299: putstr("sna erase write command "); ! 300: break; ! 301: case CMD_WRITE: ! 302: putstr("write command "); ! 303: break; ! 304: case CMD_SNA_WRITE: ! 305: putstr("sna write command "); ! 306: break; ! 307: default: ! 308: putstr("Unexpected command code 0x"); ! 309: puthex(Command); ! 310: putstr(" received."); ! 311: Column1(); ! 312: break; ! 313: } ! 314: putstr("WCC is 0x"); ! 315: puthex(Wcc); ! 316: Column1(); ! 317: ! 318: count -= 2; /* strip off command and wcc */ ! 319: buffer += 2; ! 320: ! 321: } ! 322: LastWasTerminated = 0; /* then, reset at end... */ ! 323: ! 324: while (count) { ! 325: count--; ! 326: c = *buffer++; ! 327: if (IsOrder(c)) { ! 328: /* handle an order */ ! 329: switch (c) { ! 330: # define Ensure(x) if (count < x) { \ ! 331: if (!control) { \ ! 332: return(origCount-(count+1)); \ ! 333: } else { \ ! 334: /* XXX - should not occur */ \ ! 335: count = 0; \ ! 336: break; \ ! 337: } \ ! 338: } ! 339: case ORDER_SF: ! 340: Ensure(1); ! 341: c = *buffer++; ! 342: count--; ! 343: putstr("SF (0x"); ! 344: put2hex(c); ! 345: putstr(") "); ! 346: break; ! 347: case ORDER_SBA: ! 348: Ensure(2); ! 349: i = buffer[0]; ! 350: c = buffer[1]; ! 351: buffer += 2; ! 352: count -= 2; ! 353: putstr("SBA to "); ! 354: PrintAddr(Addr3270(i,c)); ! 355: putSpace(); ! 356: break; ! 357: case ORDER_IC: ! 358: putstr("IC"); ! 359: putSpace(); ! 360: break; ! 361: case ORDER_PT: ! 362: putstr("PT"); ! 363: putSpace(); ! 364: break; ! 365: case ORDER_RA: ! 366: Ensure(3); ! 367: i = Addr3270(buffer[0], buffer[1]); ! 368: c = buffer[2]; ! 369: buffer += 3; ! 370: count -= 3; ! 371: putstr("RA to "); ! 372: PrintAddr(i); ! 373: putstr(" of 0x"); ! 374: put2hex(c); ! 375: putSpace(); ! 376: break; ! 377: case ORDER_EUA: /* (from [here,there), ie: half open interval] */ ! 378: Ensure(2); ! 379: putstr("EUA to "); ! 380: PrintAddr(Addr3270(buffer[0], buffer[1])); ! 381: putSpace(); ! 382: buffer += 2; ! 383: count -= 2; ! 384: break; ! 385: case ORDER_YALE: /* special YALE defined order */ ! 386: Ensure(2); /* need at least two characters */ ! 387: putstr("YALE order"); ! 388: putSpace(); ! 389: break; ! 390: default: ! 391: putstr("UNKNOWN ORDER: 0x"); ! 392: put2hex(c); ! 393: putSpace(); ! 394: break; ! 395: } ! 396: if (count < 0) { ! 397: count = 0; ! 398: } ! 399: } else { ! 400: /* Data comes in large clumps - take it all */ ! 401: putstr("DATA:"); ! 402: Indent(); ! 403: putEChar(c); ! 404: c = *buffer; ! 405: while (count && !IsOrder(c)) { ! 406: putEChar(c); ! 407: count--; ! 408: buffer++; ! 409: c = *buffer; ! 410: } ! 411: Undent(); ! 412: } ! 413: } ! 414: LastWasTerminated = control; ! 415: return origCount - count; ! 416: } ! 417: ! 418: int ! 419: DataToNetwork(buffer, count, control) ! 420: unsigned char *buffer; ! 421: int count; ! 422: int control; ! 423: { ! 424: #define NEED_AID 0 ! 425: #define JUST_GOT_AID 1 ! 426: #define DATA 2 ! 427: #define DATA_CONTINUE 3 ! 428: static int state = NEED_AID; ! 429: static int aid; ! 430: int origCount = count; ! 431: ! 432: if (count == 0) { ! 433: if (control) { ! 434: state = NEED_AID; ! 435: } ! 436: Column1(); ! 437: return 0; ! 438: } ! 439: ! 440: switch (state) { ! 441: case NEED_AID: ! 442: aid = buffer[0]; ! 443: buffer++; ! 444: count--; ! 445: PrintAid(aid); ! 446: putSpace(); ! 447: if (aid == AID_TREQ) { ! 448: state = DATA; ! 449: } else { ! 450: state = JUST_GOT_AID; ! 451: } ! 452: return origCount - count + DataToNetwork(buffer, count, control); ! 453: case JUST_GOT_AID: ! 454: Ensure(2); ! 455: PrintAddr(Addr3270(buffer[0], buffer[1])); ! 456: putSpace(); ! 457: buffer += 2; ! 458: count -= 2; ! 459: state = DATA; ! 460: return origCount - count + DataToNetwork(buffer, count, control); ! 461: case DATA: ! 462: case DATA_CONTINUE: ! 463: while (count) { ! 464: if (*buffer == ORDER_SBA) { ! 465: if (state == DATA_CONTINUE) { ! 466: Undent(); ! 467: state = DATA; ! 468: } ! 469: putstr("SBA "); ! 470: PrintAddr(Addr3270(buffer[1], buffer[2])); ! 471: putSpace(); ! 472: buffer += 3; ! 473: count -= 3; ! 474: } else { ! 475: if (state == DATA) { ! 476: putstr("DATA:"); ! 477: Indent(); ! 478: state = DATA_CONTINUE; ! 479: } ! 480: putEChar(*buffer); ! 481: buffer++; ! 482: count--; ! 483: } ! 484: } ! 485: if (control) { ! 486: if (state == DATA_CONTINUE) { ! 487: Undent(); ! 488: } ! 489: state = NEED_AID; ! 490: } ! 491: return origCount-count; ! 492: } ! 493: } ! 494: ! 495: int ! 496: GetXValue(c) ! 497: int c; ! 498: { ! 499: if (!isascii(c)) { ! 500: fflush(stdout); ! 501: fprintf(stderr, "Non-hex digit 0x%x.\n"); ! 502: fflush(stderr); ! 503: return 0; ! 504: } else { ! 505: if (islower(c)) { ! 506: return (c-'a')+10; ! 507: } else if (isupper(c)) { ! 508: return (c-'A')+10; ! 509: } else { ! 510: return c-'0'; ! 511: } ! 512: } ! 513: } ! 514: ! 515: unsigned char outbound[8192], inbound[8192], ! 516: *outnext = outbound, *innext = inbound, *p = 0; ! 517: ! 518: void ! 519: termblock(old, new, control) ! 520: int old, ! 521: new; /* old and new directions */ ! 522: { ! 523: int count; ! 524: ! 525: if (p) { ! 526: if (old == '<') { ! 527: outnext = p; ! 528: count = DataFromNetwork(outbound, outnext-outbound, control); ! 529: if (outbound+count == outnext) { ! 530: outnext = outbound; ! 531: } else { ! 532: memcpy(outbound, outbound+count, outnext-(outbound+count)); ! 533: outnext = outbound+count; ! 534: } ! 535: } else { ! 536: innext = p; ! 537: count = DataToNetwork(inbound, innext-inbound, control); ! 538: if (inbound+count == innext) { ! 539: innext = inbound; ! 540: } else { ! 541: memcpy(inbound, inbound+count, innext-(inbound+count)); ! 542: innext = inbound+count; ! 543: } ! 544: } ! 545: } ! 546: if (new == '<') { ! 547: p = outnext; ! 548: } else if (new == '>') { ! 549: p = innext; ! 550: } else { ! 551: fprintf(stderr, "Bad direction character '%c'.\n", new); ! 552: exit(1); ! 553: } ! 554: } ! 555: ! 556: main() ! 557: { ! 558: int location; ! 559: char new; ! 560: int c, c1; ! 561: ! 562: memset(Orders, 0, sizeof Orders); ! 563: Orders[ORDER_SF] = Orders[ORDER_SBA] = Orders[ORDER_IC] ! 564: = Orders[ORDER_PT] = Orders[ORDER_RA] = Orders[ORDER_EUA] ! 565: = Orders[ORDER_YALE] = 1; ! 566: ! 567: while (scanf("%c 0x%x\t", &new, &location) != EOF) { ! 568: if (new != direction) { ! 569: termblock(direction, new, 0); ! 570: direction = new; ! 571: } ! 572: while (((c = getchar()) != EOF) && (c != '\n') && (isxdigit(c))) { ! 573: #define NORMAL 0 ! 574: #define GOT0XFF 0xff ! 575: static int state = NORMAL; ! 576: ! 577: c1 = getchar(); ! 578: c = (GetXValue(c) << 4) + GetXValue(c1); ! 579: switch (state) { ! 580: case NORMAL: ! 581: if (c == 0xff) { ! 582: state = GOT0XFF; ! 583: } else { ! 584: *p++ = c; ! 585: } ! 586: break; ! 587: case GOT0XFF: ! 588: if (c == 0xef) { ! 589: termblock(direction, direction, 1); ! 590: } else { ! 591: *p++ = 0xff; ! 592: *p++ = c; ! 593: } ! 594: state = NORMAL; ! 595: } ! 596: } ! 597: } ! 598: return 0; ! 599: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.