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