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