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