|
|
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.