|
|
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[] = "@(#)tnrecv.c 3.2 (Berkeley) 3/28/88";
21: #endif /* not lint */
22:
23: #include <stdio.h>
24:
25: #include <api/apilib.h>
26:
27: #include "tncomp.h"
28:
29:
30: #include "../ctlr/api.h"
31: #include "../ctlr/function.h"
32: #include "../ctlr/hostctlr.h"
33: #include "../ctlr/oia.h"
34: #include "../ctlr/screen.h"
35:
36: #include "../api/disp_asc.h"
37: #include "../api/astosc.h"
38:
39: #include "../general/general.h"
40:
41: ScreenImage Host[MAXSCREENSIZE];
42:
43: static char
44: a_send_sequence[SEND_SEQUENCE_LENGTH+1],
45: a_ack_sequence[ACK_SEQUENCE_LENGTH+1],
46: a_checksum[CHECKSUM_LENGTH+1],
47: data_array[DATA_LENGTH+1];
48:
49: static int
50: verbose,
51: blocks,
52: enter_index,
53: clear_index,
54: ScreenSize,
55: session_id;
56:
57: static unsigned int
58: send_sequence,
59: ack_sequence = -1,
60: checksum;
61:
62: api_perror(string)
63: char *string;
64: {
65: fprintf(stderr, "Error: [0x%x/0x%x:0x%x/0x%x] from %s.\n",
66: api_sup_fcn_id, api_sup_errno,
67: api_fcn_fcn_id, api_fcn_errno, string);
68: }
69:
70:
71: char *
72: session_type(type)
73: int type;
74: {
75: switch (type) {
76: case TYPE_WSCTL:
77: return "work station control";
78: case TYPE_DFT:
79: return "distributed function terminal";
80: case TYPE_CUT:
81: return "control unit terminal";
82: case TYPE_NOTEPAD:
83: return "notepad";
84: case TYPE_PC:
85: return "personal computer";
86: default:
87: return "(UNKNOWN)";
88: }
89: }
90:
91: static int
92: wait_for_ps_or_oia()
93: {
94: #if defined(unix)
95: return api_ps_or_oia_modified();
96: #endif /* defined(unix) */
97: }
98:
99:
100: static int
101: wait_for_unlock()
102: {
103: OIA oia;
104: ReadOiaGroupParms re;
105: static char zeroes[sizeof oia.input_inhibited] = { 0 };
106:
107: do {
108: re.rc = re.function_id = 0;
109: re.session_id = session_id;
110: re.oia_buffer = (char far *) &oia;
111: re.oia_group_number = API_OIA_ALL_GROUPS;
112: if (api_read_oia_group(&re) == -1) {
113: api_perror("api_read_oia_group");
114: return -1;
115: } else if (verbose) {
116: if (IsOiaReady3274(&oia)) {
117: printf("3274 ready, ");
118: }
119: if (IsOiaMyJob(&oia)) {
120: printf("my job, ");
121: }
122: if (IsOiaInsert(&oia)) {
123: printf("insert mode, ");
124: }
125: if (IsOiaSystemLocked(&oia)) {
126: printf("system locked, ");
127: }
128: if (IsOiaTWait(&oia)) {
129: printf("terminal wait, ");
130: }
131: printf("are some bits from the OIA.\n");
132: }
133: /* We turned this on, so turn it off now */
134: ResetOiaApiInhibit(&oia);
135: if (memcmp(zeroes, oia.input_inhibited, sizeof oia.input_inhibited)) {
136: if (wait_for_ps_or_oia() == -1) {
137: return -1;
138: }
139: }
140: } while (memcmp(zeroes, oia.input_inhibited, sizeof oia.input_inhibited));
141: return 0;
142: }
143:
144: static int
145: initialize()
146: {
147: QuerySessionIdParms id;
148: QuerySessionParametersParms pa;
149: QuerySessionCursorParms cu;
150: ConnectToKeyboardParms conn;
151: DisableInputParms disable;
152: NameArray namearray;
153:
154: if (api_init() == 0) {
155: fprintf(stderr, "API function not available.\n");
156: return -1;
157: }
158:
159: id.rc = 0;
160: id.function_id = 0;
161: id.option_code = ID_OPTION_BY_NAME;
162: id.data_code = 'E';
163: id.name_array = &namearray;
164: namearray.length = sizeof namearray;
165: if (api_query_session_id(&id)) {
166: api_perror("api_query_session_id");
167: } else if (namearray.number_matching_session == 0) {
168: fprintf(stderr, "query_session_id: No matching sessions!\n");
169: return -1;
170: } else if (verbose) {
171: printf("Session short name 0x%x, type is ",
172: namearray.name_array_element.short_name);
173: printf("%s", session_type(namearray.name_array_element.type));
174: printf(", session ID is: 0x%x\n",
175: namearray.name_array_element.session_id);
176: }
177: session_id = namearray.name_array_element.session_id;
178:
179: pa.rc = pa.function_id = 0;
180: pa.session_id = session_id;
181: if (api_query_session_parameters(&pa) == -1) {
182: api_perror("api_query_session_parameters");
183: return -1;
184: } else if (verbose) {
185: printf("Session type %s, ", session_type(pa.session_type));
186: if (pa.session_characteristics&CHARACTERISTIC_EAB) {
187: printf(" has EAB, ");
188: }
189: if (pa.session_characteristics&CHARACTERISTIC_PSS) {
190: printf(" has PSS, ");
191: }
192: printf("%d rows, %d columns ", pa.rows, pa.columns);
193: if (pa.presentation_space) {
194: printf("presentation space at 0x%x:0x%x.\n",
195: FP_SEG(pa.presentation_space), FP_OFF(pa.presentation_space));
196: } else {
197: printf("(no direct presentation space access).\n");
198: }
199: }
200: ScreenSize = pa.rows*pa.columns;
201: if (pa.session_characteristics&CHARACTERISTIC_EAB) {
202: fprintf(stderr,
203: "tncomp utilities not designed to work with extended attribute buffers.\n");
204: return -1;
205: }
206:
207: if (verbose) {
208: cu.rc = cu.function_id = 0;
209: cu.session_id = session_id;
210: if (api_query_session_cursor(&cu) == -1) {
211: api_perror("api_query_session_cursor");
212: } else {
213: printf("cursor");
214: if (cu.cursor_type&CURSOR_INHIBITED_AUTOSCROLL) {
215: printf(" inhibited autoscroll");
216: }
217: if (cu.cursor_type&CURSOR_INHIBITED) {
218: printf(" inhibited");
219: }
220: if (cu.cursor_type&CURSOR_BLINKING) {
221: printf(" blinking");
222: } else {
223: printf(" not blinking");
224: }
225: if (cu.cursor_type&CURSOR_BOX) {
226: printf(" box ");
227: } else {
228: printf(" not box ");
229: }
230: printf("at row %d, column %d.\n",
231: cu.row_address, cu.column_address);
232: }
233: }
234:
235: conn.rc = conn.function_id = 0;
236: conn.session_id = session_id;
237: conn.event_queue_id = conn.input_queue_id = 0;
238: conn.intercept_options = 0;
239: if (api_connect_to_keyboard(&conn) == -1) {
240: api_perror("api_connect_to_keyboard");
241: } else if (verbose) {
242: if (conn.first_connection_identifier) {
243: printf("First keyboard connection.\n");
244: } else {
245: printf("Not first keyboard connection.\n");
246: }
247: }
248:
249: disable.rc = disable.function_id = 0;
250: disable.session_id = session_id;
251: disable.connectors_task_id = 0;
252: if (api_disable_input(&disable) == -1) {
253: api_perror("api_disable_input");
254: return -1;
255: } else if (verbose) {
256: printf("Disabled.\n");
257: }
258:
259: if ((enter_index = ascii_to_index("ENTER")) == -1) {
260: return -1;
261: }
262: if ((clear_index = ascii_to_index("CLEAR")) == -1) {
263: return -1;
264: }
265:
266: return 0; /* all ok */
267: }
268:
269: static int
270: send_key(index)
271: int index;
272: {
273: WriteKeystrokeParms wr;
274: extern struct astosc astosc[];
275:
276: wait_for_unlock();
277:
278: wr.rc = wr.function_id = 0;
279: wr.session_id = session_id;
280: wr.connectors_task_id = 0;
281: wr.options = OPTION_SINGLE_KEYSTROKE;
282: wr.number_of_keys_sent = 0;
283: wr.keystroke_specifier.keystroke_entry.scancode = astosc[index].scancode;
284: wr.keystroke_specifier.keystroke_entry.shift_state
285: = astosc[index].shiftstate;
286: if (api_write_keystroke(&wr) == -1) {
287: api_perror("api_write_keystroke");
288: return -1;
289: } else if (wr.number_of_keys_sent != 1) {
290: fprintf(stderr, "write_keystroke claims to have sent %d keystrokes.\n",
291: wr.number_of_keys_sent);
292: return -1;
293: } else if (verbose) {
294: printf("Keystroke sent.\n");
295: }
296: if (wait_for_ps_or_oia() == -1) {
297: return -1;
298: }
299: return 0;
300: }
301:
302: static int
303: terminate()
304: {
305: EnableInputParms enable;
306: DisconnectFromKeyboardParms disc;
307:
308: enable.rc = enable.function_id = 0;
309: enable.session_id = session_id;
310: enable.connectors_task_id = 0;
311: if (api_enable_input(&enable) == -1) {
312: api_perror("api_enable");
313: return -1;
314: } else if (verbose) {
315: printf("Enabled.\n");
316: }
317:
318: disc.rc = disc.function_id = 0;
319: disc.session_id = session_id;
320: disc.connectors_task_id = 0;
321: if (api_disconnect_from_keyboard(&disc) == -1) {
322: api_perror("api_disconnect_from_keyboard");
323: return -1;
324: } else if (verbose) {
325: printf("Disconnected from keyboard.\n");
326: }
327:
328: (void) api_finish();
329:
330: return 0;
331: }
332:
333:
334: static int
335: get_screen()
336: {
337: CopyStringParms copy;
338: /* Time copy services */
339:
340: wait_for_unlock();
341:
342: copy.copy_mode = 0;
343: copy.rc = copy.function_id = 0;
344: copy.source.session_id = session_id;
345: copy.source.buffer = 0;
346: copy.source.characteristics = 0;
347: copy.source.session_type = TYPE_DFT;
348: copy.source.begin = 0;
349:
350: copy.source_end = ScreenSize;
351:
352: copy.target.session_id = 0;
353: copy.target.buffer = (char *) &Host[0];
354: copy.target.characteristics = 0;
355: copy.target.session_type = TYPE_DFT;
356:
357: if (api_copy_string(©) == -1) {
358: api_perror("api_copy_string");
359: return -1;
360: }
361: return 0;
362: }
363:
364:
365: put_at(offset, from, length, attribute)
366: int offset;
367: char *from;
368: int length;
369: {
370: CopyStringParms copy;
371:
372: wait_for_unlock();
373:
374: copy.copy_mode = 0;
375: copy.rc = copy.function_id = 0;
376: copy.source.session_id = 0;
377: copy.source.buffer = from;
378: copy.source.characteristics = 0;
379: copy.source.session_type = TYPE_DFT;
380: copy.source.begin = 0;
381:
382: copy.source_end = length-1;
383:
384: copy.target.session_id = session_id;
385: copy.target.buffer = 0;
386: copy.target.characteristics = 0;
387: copy.target.session_type = TYPE_DFT;
388: copy.target.begin = offset;
389:
390: if (api_copy_string(©) == -1) {
391: api_perror("api_copy_string");
392: return -1;
393: }
394: return 0;
395: }
396:
397: static void
398: translate(input, output, table, length)
399: char *input, *output, table[];
400: int length;
401: {
402: unsigned char *indices = (unsigned char *) input;
403:
404: while (length--) {
405: *output++ = table[*indices++];
406: }
407: }
408:
409: static int
410: find_input_area(from)
411: int from;
412: {
413: #define FieldDec(p) (0) /* We don't really use this */
414: register int i, attr;
415:
416: for (i = from; i < MAXSCREENSIZE; ) {
417: if (IsStartField(i)) {
418: attr = FieldAttributes(i);
419: i++;
420: if (!IsProtectedAttr(i, attr)) {
421: return i;
422: }
423: } else {
424: i++;
425: }
426: }
427: return -1;
428: }
429:
430:
431: static void
432: getascii(offset, to, length)
433: int offset; /* Where in screen */
434: char *to; /* Where it goes to */
435: int length; /* Where to put it */
436: {
437: translate(Host+offset, to, disp_asc, length);
438: }
439:
440: static int
441: putascii(offset, from, length, before)
442: int offset; /* Where in screen */
443: char *from; /* Where it comes from */
444: int length; /* Where to put it */
445: int before; /* How much else should go */
446: {
447: translate(from, Host+offset, asc_disp, length);
448: if (put_at(offset-before,
449: (char *) Host+offset-before, length+before) == -1) {
450: return -1;
451: }
452: return 0;
453: }
454:
455: static int
456: ack()
457: {
458: static char ack_blanks[sizeof a_ack_sequence] = {0};
459:
460: if (ack_blanks[0] == 0) {
461: int i;
462:
463: for (i = 0; i < sizeof ack_blanks; i++) {
464: ack_blanks[i] = ' ';
465: }
466: }
467:
468: memcpy(a_ack_sequence, ack_blanks, sizeof a_ack_sequence);
469: sprintf(a_ack_sequence, "%d", ack_sequence);
470: a_ack_sequence[strlen(a_ack_sequence)] = ' ';
471: Host[ACK_SEQUENCE-1] |= ATTR_MDT;
472: if (putascii(ACK_SEQUENCE, a_ack_sequence, ACK_SEQUENCE_LENGTH, 1) == -1) {
473: return -1;
474: }
475: return 0;
476: }
477:
478: static int
479: formatted_correct()
480: {
481: if ((find_input_area(SEND_SEQUENCE-1) != SEND_SEQUENCE) ||
482: (find_input_area(SEND_SEQUENCE) != ACK_SEQUENCE) ||
483: (find_input_area(ACK_SEQUENCE) != CHECKSUM) ||
484: (find_input_area(CHECKSUM) != DATA)) {
485: return -1;
486: } else {
487: return 0;
488: }
489: }
490:
491:
492: main(argc, argv)
493: int argc;
494: char *argv[];
495: {
496: register int i;
497: int data_length, input_length;
498: char ascii[8]; /* Lots of room */
499: FILE *outfile;
500: char *data;
501: char *argv0 = argv[0];
502:
503: argc--;
504: argv++;
505: /* Process any flags */
506: while (argc && (argv[0][0] == '-')) {
507: switch (argv[0][1]) {
508: case 'v':
509: verbose = 1;
510: break;
511: case 'b':
512: blocks = 1;
513: break;
514: }
515: argc--;
516: argv++;
517: }
518:
519: if ((argc) < 2) {
520: fprintf(stderr,
521: "usage: %s [-b] [-v] local.file remote.file [remote.options]\n",
522: argv0);
523: exit(1);
524: }
525:
526: /* Open the local file */
527: if ((outfile = fopen(argv[0], "w")) == NULL) {
528: perror("fopen");
529: exit(2);
530: }
531: argc--;
532: argv++;
533:
534: if (initialize() == -1) {
535: return -1;
536: }
537:
538: /* build the command line */
539: data = data_array;
540: strcpy(data, "TNCOMP SEND");
541: data += strlen(data);
542: while (argc--) {
543: *data++ = ' ';
544: strcpy(data, argv[0]);
545: data += strlen(argv[0]);
546: argv++;
547: }
548: if (verbose) {
549: printf("%s\n", data_array);
550: }
551: if (get_screen() == -1) {
552: return -1;
553: }
554: data_length = strlen(data_array);
555: if ((i = find_input_area(0)) == -1) { /* Get an input area */
556: if (send_key(clear_index) == -1) {
557: return -1;
558: }
559: if ((i = find_input_area(0)) == -1) { /* Try again */
560: fprintf(stderr, "Unable to enter command line.\n");
561: return -1;
562: }
563: }
564: if (i == 0) {
565: Host[ScreenSize-1] |= ATTR_MDT;
566: } else {
567: Host[i-1] |= ATTR_MDT;
568: }
569: if (putascii(i, data_array, data_length, 1) == -1) {
570: return -1;
571: }
572: if (send_key(enter_index) == -1) {
573: return -1;
574: }
575: do {
576: if (get_screen() == -1) {
577: return -1;
578: }
579: } while (formatted_correct() == -1);
580:
581: do {
582: if (get_screen() == -1) {
583: return -1;
584: }
585: /* For each screen */
586: if (formatted_correct() == -1) {
587: fprintf(stderr, "Bad screen written by host.\n");
588: return -1;
589: }
590: /* If MDT isn't reset in the sequence number, go around again */
591: if (Host[ACK_SEQUENCE-1]&ATTR_MDT) {
592: if (wait_for_ps_or_oia() == -1) {
593: return -1;
594: }
595: continue;
596: }
597: getascii(SEND_SEQUENCE, a_send_sequence, SEND_SEQUENCE_LENGTH);
598: send_sequence = atoi(a_send_sequence);
599: getascii(CHECKSUM, a_checksum, CHECKSUM_LENGTH);
600: checksum = atoi(a_checksum);
601: getascii(DATA, data_array, DATA_LENGTH);
602: data = data_array;
603: if (send_sequence != (ack_sequence+1)) {
604: if (ack() == -1) {
605: return -1;
606: }
607: data = "1234"; /* Keep loop from failing */
608: if (send_key(enter_index) == -1) {
609: return -1;
610: }
611: if (get_screen() == -1) {
612: return -1;
613: }
614: continue;
615: }
616:
617: data_length = DATA_LENGTH;
618: while (data_length && memcmp(data, " EOF", 4)
619: && memcmp(data, " ", 4)) {
620: memcpy(ascii, data, 4);
621: data += 4;
622: data_length -= 4;
623: ascii[4] = 0;
624: input_length = atoi(ascii);
625: /* CMS can't live with zero length records */
626: if ((input_length > 1) ||
627: ((input_length == 1) && (data[0] != ' '))) {
628: if (fwrite(data, sizeof (char),
629: input_length, outfile) == 0) {
630: perror("fwrite");
631: exit(9);
632: }
633: }
634: fprintf(outfile, "\n");
635: data += input_length;
636: data_length -= input_length;
637: }
638:
639: ack_sequence = send_sequence;
640: if (blocks) {
641: printf("#");
642: fflush(stdout);
643: }
644: if (ack() == -1) {
645: return -1;
646: }
647: if (send_key(enter_index) == -1) {
648: return -1;
649: }
650: } while (memcmp(data, " EOF", 4));
651:
652: if (blocks) {
653: printf("\n");
654: }
655: if (terminate() == -1) {
656: return -1;
657: }
658: return 0;
659: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.