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