summaryrefslogtreecommitdiffstats
path: root/usr.bin/tn3270/distribution/utilities/tnrecv.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/tn3270/distribution/utilities/tnrecv.c')
-rw-r--r--usr.bin/tn3270/distribution/utilities/tnrecv.c674
1 files changed, 674 insertions, 0 deletions
diff --git a/usr.bin/tn3270/distribution/utilities/tnrecv.c b/usr.bin/tn3270/distribution/utilities/tnrecv.c
new file mode 100644
index 0000000..4474691
--- /dev/null
+++ b/usr.bin/tn3270/distribution/utilities/tnrecv.c
@@ -0,0 +1,674 @@
+/*-
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1988, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)tnrecv.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include <stdio.h>
+
+#include <api/apilib.h>
+
+#include "tncomp.h"
+
+
+#include "../ctlr/api.h"
+#include "../ctlr/function.h"
+#include "../ctlr/hostctlr.h"
+#include "../ctlr/oia.h"
+#include "../ctlr/screen.h"
+
+#include "../api/disp_asc.h"
+#include "../api/astosc.h"
+
+#include "../general/general.h"
+
+ScreenImage Host[MAXSCREENSIZE];
+
+static char
+ a_send_sequence[SEND_SEQUENCE_LENGTH+1],
+ a_ack_sequence[ACK_SEQUENCE_LENGTH+1],
+ a_checksum[CHECKSUM_LENGTH+1],
+ data_array[DATA_LENGTH+1];
+
+static int
+ verbose,
+ blocks,
+ enter_index,
+ clear_index,
+ ScreenSize,
+ session_id;
+
+static unsigned int
+ send_sequence,
+ ack_sequence = -1,
+ checksum;
+
+api_perror(string)
+char *string;
+{
+ fprintf(stderr, "Error: [0x%x/0x%x:0x%x/0x%x] from %s.\n",
+ api_sup_fcn_id, api_sup_errno,
+ api_fcn_fcn_id, api_fcn_errno, string);
+}
+
+
+char *
+session_type(type)
+int type;
+{
+ switch (type) {
+ case TYPE_WSCTL:
+ return "work station control";
+ case TYPE_DFT:
+ return "distributed function terminal";
+ case TYPE_CUT:
+ return "control unit terminal";
+ case TYPE_NOTEPAD:
+ return "notepad";
+ case TYPE_PC:
+ return "personal computer";
+ default:
+ return "(UNKNOWN)";
+ }
+}
+
+static int
+wait_for_ps_or_oia()
+{
+#if defined(unix)
+ return api_ps_or_oia_modified();
+#endif /* defined(unix) */
+}
+
+
+static int
+wait_for_unlock()
+{
+ OIA oia;
+ ReadOiaGroupParms re;
+ static char zeroes[sizeof oia.input_inhibited] = { 0 };
+
+ do {
+ re.rc = re.function_id = 0;
+ re.session_id = session_id;
+ re.oia_buffer = (char far *) &oia;
+ re.oia_group_number = API_OIA_ALL_GROUPS;
+ if (api_read_oia_group(&re) == -1) {
+ api_perror("api_read_oia_group");
+ return -1;
+ } else if (verbose) {
+ if (IsOiaReady3274(&oia)) {
+ printf("3274 ready, ");
+ }
+ if (IsOiaMyJob(&oia)) {
+ printf("my job, ");
+ }
+ if (IsOiaInsert(&oia)) {
+ printf("insert mode, ");
+ }
+ if (IsOiaSystemLocked(&oia)) {
+ printf("system locked, ");
+ }
+ if (IsOiaTWait(&oia)) {
+ printf("terminal wait, ");
+ }
+ printf("are some bits from the OIA.\n");
+ }
+ /* We turned this on, so turn it off now */
+ ResetOiaApiInhibit(&oia);
+ if (memcmp(zeroes, oia.input_inhibited, sizeof oia.input_inhibited)) {
+ if (wait_for_ps_or_oia() == -1) {
+ return -1;
+ }
+ }
+ } while (memcmp(zeroes, oia.input_inhibited, sizeof oia.input_inhibited));
+ return 0;
+}
+
+static int
+initialize()
+{
+ QuerySessionIdParms id;
+ QuerySessionParametersParms pa;
+ QuerySessionCursorParms cu;
+ ConnectToKeyboardParms conn;
+ DisableInputParms disable;
+ NameArray namearray;
+
+ if (api_init() == 0) {
+ fprintf(stderr, "API function not available.\n");
+ return -1;
+ }
+
+ id.rc = 0;
+ id.function_id = 0;
+ id.option_code = ID_OPTION_BY_NAME;
+ id.data_code = 'E';
+ id.name_array = &namearray;
+ namearray.length = sizeof namearray;
+ if (api_query_session_id(&id)) {
+ api_perror("api_query_session_id");
+ } else if (namearray.number_matching_session == 0) {
+ fprintf(stderr, "query_session_id: No matching sessions!\n");
+ return -1;
+ } else if (verbose) {
+ printf("Session short name 0x%x, type is ",
+ namearray.name_array_element.short_name);
+ printf("%s", session_type(namearray.name_array_element.type));
+ printf(", session ID is: 0x%x\n",
+ namearray.name_array_element.session_id);
+ }
+ session_id = namearray.name_array_element.session_id;
+
+ pa.rc = pa.function_id = 0;
+ pa.session_id = session_id;
+ if (api_query_session_parameters(&pa) == -1) {
+ api_perror("api_query_session_parameters");
+ return -1;
+ } else if (verbose) {
+ printf("Session type %s, ", session_type(pa.session_type));
+ if (pa.session_characteristics&CHARACTERISTIC_EAB) {
+ printf(" has EAB, ");
+ }
+ if (pa.session_characteristics&CHARACTERISTIC_PSS) {
+ printf(" has PSS, ");
+ }
+ printf("%d rows, %d columns ", pa.rows, pa.columns);
+ if (pa.presentation_space) {
+ printf("presentation space at 0x%x:0x%x.\n",
+ FP_SEG(pa.presentation_space), FP_OFF(pa.presentation_space));
+ } else {
+ printf("(no direct presentation space access).\n");
+ }
+ }
+ ScreenSize = pa.rows*pa.columns;
+ if (pa.session_characteristics&CHARACTERISTIC_EAB) {
+ fprintf(stderr,
+ "tncomp utilities not designed to work with extended attribute buffers.\n");
+ return -1;
+ }
+
+ if (verbose) {
+ cu.rc = cu.function_id = 0;
+ cu.session_id = session_id;
+ if (api_query_session_cursor(&cu) == -1) {
+ api_perror("api_query_session_cursor");
+ } else {
+ printf("cursor");
+ if (cu.cursor_type&CURSOR_INHIBITED_AUTOSCROLL) {
+ printf(" inhibited autoscroll");
+ }
+ if (cu.cursor_type&CURSOR_INHIBITED) {
+ printf(" inhibited");
+ }
+ if (cu.cursor_type&CURSOR_BLINKING) {
+ printf(" blinking");
+ } else {
+ printf(" not blinking");
+ }
+ if (cu.cursor_type&CURSOR_BOX) {
+ printf(" box ");
+ } else {
+ printf(" not box ");
+ }
+ printf("at row %d, column %d.\n",
+ cu.row_address, cu.column_address);
+ }
+ }
+
+ conn.rc = conn.function_id = 0;
+ conn.session_id = session_id;
+ conn.event_queue_id = conn.input_queue_id = 0;
+ conn.intercept_options = 0;
+ if (api_connect_to_keyboard(&conn) == -1) {
+ api_perror("api_connect_to_keyboard");
+ } else if (verbose) {
+ if (conn.first_connection_identifier) {
+ printf("First keyboard connection.\n");
+ } else {
+ printf("Not first keyboard connection.\n");
+ }
+ }
+
+ disable.rc = disable.function_id = 0;
+ disable.session_id = session_id;
+ disable.connectors_task_id = 0;
+ if (api_disable_input(&disable) == -1) {
+ api_perror("api_disable_input");
+ return -1;
+ } else if (verbose) {
+ printf("Disabled.\n");
+ }
+
+ if ((enter_index = ascii_to_index("ENTER")) == -1) {
+ return -1;
+ }
+ if ((clear_index = ascii_to_index("CLEAR")) == -1) {
+ return -1;
+ }
+
+ return 0; /* all ok */
+}
+
+static int
+send_key(index)
+int index;
+{
+ WriteKeystrokeParms wr;
+ extern struct astosc astosc[];
+
+ wait_for_unlock();
+
+ wr.rc = wr.function_id = 0;
+ wr.session_id = session_id;
+ wr.connectors_task_id = 0;
+ wr.options = OPTION_SINGLE_KEYSTROKE;
+ wr.number_of_keys_sent = 0;
+ wr.keystroke_specifier.keystroke_entry.scancode = astosc[index].scancode;
+ wr.keystroke_specifier.keystroke_entry.shift_state
+ = astosc[index].shiftstate;
+ if (api_write_keystroke(&wr) == -1) {
+ api_perror("api_write_keystroke");
+ return -1;
+ } else if (wr.number_of_keys_sent != 1) {
+ fprintf(stderr, "write_keystroke claims to have sent %d keystrokes.\n",
+ wr.number_of_keys_sent);
+ return -1;
+ } else if (verbose) {
+ printf("Keystroke sent.\n");
+ }
+ if (wait_for_ps_or_oia() == -1) {
+ return -1;
+ }
+ return 0;
+}
+
+static int
+terminate()
+{
+ EnableInputParms enable;
+ DisconnectFromKeyboardParms disc;
+
+ enable.rc = enable.function_id = 0;
+ enable.session_id = session_id;
+ enable.connectors_task_id = 0;
+ if (api_enable_input(&enable) == -1) {
+ api_perror("api_enable");
+ return -1;
+ } else if (verbose) {
+ printf("Enabled.\n");
+ }
+
+ disc.rc = disc.function_id = 0;
+ disc.session_id = session_id;
+ disc.connectors_task_id = 0;
+ if (api_disconnect_from_keyboard(&disc) == -1) {
+ api_perror("api_disconnect_from_keyboard");
+ return -1;
+ } else if (verbose) {
+ printf("Disconnected from keyboard.\n");
+ }
+
+ (void) api_finish();
+
+ return 0;
+}
+
+
+static int
+get_screen()
+{
+ CopyStringParms copy;
+ /* Time copy services */
+
+ wait_for_unlock();
+
+ copy.copy_mode = 0;
+ copy.rc = copy.function_id = 0;
+ copy.source.session_id = session_id;
+ copy.source.buffer = 0;
+ copy.source.characteristics = 0;
+ copy.source.session_type = TYPE_DFT;
+ copy.source.begin = 0;
+
+ copy.source_end = ScreenSize;
+
+ copy.target.session_id = 0;
+ copy.target.buffer = (char *) &Host[0];
+ copy.target.characteristics = 0;
+ copy.target.session_type = TYPE_DFT;
+
+ if (api_copy_string(&copy) == -1) {
+ api_perror("api_copy_string");
+ return -1;
+ }
+ return 0;
+}
+
+
+put_at(offset, from, length, attribute)
+int offset;
+char *from;
+int length;
+{
+ CopyStringParms copy;
+
+ wait_for_unlock();
+
+ copy.copy_mode = 0;
+ copy.rc = copy.function_id = 0;
+ copy.source.session_id = 0;
+ copy.source.buffer = from;
+ copy.source.characteristics = 0;
+ copy.source.session_type = TYPE_DFT;
+ copy.source.begin = 0;
+
+ copy.source_end = length-1;
+
+ copy.target.session_id = session_id;
+ copy.target.buffer = 0;
+ copy.target.characteristics = 0;
+ copy.target.session_type = TYPE_DFT;
+ copy.target.begin = offset;
+
+ if (api_copy_string(&copy) == -1) {
+ api_perror("api_copy_string");
+ return -1;
+ }
+ return 0;
+}
+
+static void
+translate(input, output, table, length)
+char *input, *output, table[];
+int length;
+{
+ unsigned char *indices = (unsigned char *) input;
+
+ while (length--) {
+ *output++ = table[*indices++];
+ }
+}
+
+static int
+find_input_area(from)
+int from;
+{
+#define FieldDec(p) (0) /* We don't really use this */
+ register int i, attr;
+
+ for (i = from; i < MAXSCREENSIZE; ) {
+ if (IsStartField(i)) {
+ attr = FieldAttributes(i);
+ i++;
+ if (!IsProtectedAttr(i, attr)) {
+ return i;
+ }
+ } else {
+ i++;
+ }
+ }
+ return -1;
+}
+
+
+static void
+getascii(offset, to, length)
+int offset; /* Where in screen */
+char *to; /* Where it goes to */
+int length; /* Where to put it */
+{
+ translate(Host+offset, to, disp_asc, length);
+}
+
+static int
+putascii(offset, from, length, before)
+int offset; /* Where in screen */
+char *from; /* Where it comes from */
+int length; /* Where to put it */
+int before; /* How much else should go */
+{
+ translate(from, Host+offset, asc_disp, length);
+ if (put_at(offset-before,
+ (char *) Host+offset-before, length+before) == -1) {
+ return -1;
+ }
+ return 0;
+}
+
+static int
+ack()
+{
+ static char ack_blanks[sizeof a_ack_sequence] = {0};
+
+ if (ack_blanks[0] == 0) {
+ int i;
+
+ for (i = 0; i < sizeof ack_blanks; i++) {
+ ack_blanks[i] = ' ';
+ }
+ }
+
+ memcpy(a_ack_sequence, ack_blanks, sizeof a_ack_sequence);
+ sprintf(a_ack_sequence, "%d", ack_sequence);
+ a_ack_sequence[strlen(a_ack_sequence)] = ' ';
+ if (putascii(ACK_SEQUENCE, a_ack_sequence, ACK_SEQUENCE_LENGTH, 0) == -1) {
+ return -1;
+ }
+ return 0;
+}
+
+static int
+formatted_correct()
+{
+ if ((find_input_area(SEND_SEQUENCE-1) != SEND_SEQUENCE) ||
+ (find_input_area(SEND_SEQUENCE) != ACK_SEQUENCE) ||
+ (find_input_area(ACK_SEQUENCE) != CHECKSUM) ||
+ (find_input_area(CHECKSUM) != DATA)) {
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ register int i;
+ int data_length, input_length;
+ char ascii[8]; /* Lots of room */
+ FILE *outfile;
+ char *data;
+ char *argv0 = argv[0];
+
+ argc--;
+ argv++;
+ /* Process any flags */
+ while (argc && (argv[0][0] == '-')) {
+ switch (argv[0][1]) {
+ case 'v':
+ verbose = 1;
+ break;
+ case 'b':
+ blocks = 1;
+ break;
+ }
+ argc--;
+ argv++;
+ }
+
+ if ((argc) < 2) {
+ fprintf(stderr,
+ "usage: %s [-b] [-v] local.file remote.file [remote.options]\n",
+ argv0);
+ exit(1);
+ }
+
+ /* Open the local file */
+ if ((outfile = fopen(argv[0], "w")) == NULL) {
+ perror("fopen");
+ exit(2);
+ }
+ argc--;
+ argv++;
+
+ if (initialize() == -1) {
+ return -1;
+ }
+
+ /* build the command line */
+ data = data_array;
+ strcpy(data, "TNCOMP SEND");
+ data += strlen(data);
+ while (argc--) {
+ *data++ = ' ';
+ strcpy(data, argv[0]);
+ data += strlen(argv[0]);
+ argv++;
+ }
+ if (verbose) {
+ printf("%s\n", data_array);
+ }
+ if (get_screen() == -1) {
+ return -1;
+ }
+ data_length = strlen(data_array);
+ if ((i = find_input_area(0)) == -1) { /* Get an input area */
+ if (send_key(clear_index) == -1) {
+ return -1;
+ }
+ if ((i = find_input_area(0)) == -1) { /* Try again */
+ fprintf(stderr, "Unable to enter command line.\n");
+ return -1;
+ }
+ }
+ if (putascii(i, data_array, data_length, 0) == -1) {
+ return -1;
+ }
+ if (send_key(enter_index) == -1) {
+ return -1;
+ }
+ do {
+ if (get_screen() == -1) {
+ return -1;
+ }
+ } while (formatted_correct() == -1);
+
+ do {
+ if (get_screen() == -1) {
+ return -1;
+ }
+ /* For each screen */
+ if (formatted_correct() == -1) {
+ fprintf(stderr, "Bad screen written by host.\n");
+ return -1;
+ }
+ /* If MDT isn't reset in the sequence number, go around again */
+ if (Host[ACK_SEQUENCE-1]&ATTR_MDT) {
+ if (wait_for_ps_or_oia() == -1) {
+ return -1;
+ }
+ continue;
+ }
+ getascii(SEND_SEQUENCE, a_send_sequence, SEND_SEQUENCE_LENGTH);
+ send_sequence = atoi(a_send_sequence);
+ getascii(CHECKSUM, a_checksum, CHECKSUM_LENGTH);
+ checksum = atoi(a_checksum);
+ getascii(DATA, data_array, DATA_LENGTH);
+ data = data_array;
+ if (send_sequence != (ack_sequence+1)) {
+ if (ack() == -1) {
+ return -1;
+ }
+ data = "1234"; /* Keep loop from failing */
+ if (send_key(enter_index) == -1) {
+ return -1;
+ }
+ if (get_screen() == -1) {
+ return -1;
+ }
+ continue;
+ }
+
+ data_length = DATA_LENGTH;
+ while (data_length && memcmp(data, " EOF", 4)
+ && memcmp(data, " ", 4)) {
+ memcpy(ascii, data, 4);
+ data += 4;
+ data_length -= 4;
+ ascii[4] = 0;
+ input_length = atoi(ascii);
+ /* CMS can't live with zero length records */
+ if ((input_length > 1) ||
+ ((input_length == 1) && (data[0] != ' '))) {
+ if (fwrite(data, sizeof (char),
+ input_length, outfile) == 0) {
+ perror("fwrite");
+ exit(9);
+ }
+ }
+ fprintf(outfile, "\n");
+ data += input_length;
+ data_length -= input_length;
+ }
+
+ ack_sequence = send_sequence;
+ if (blocks) {
+ printf("#");
+ fflush(stdout);
+ }
+ if (ack() == -1) {
+ return -1;
+ }
+ if (send_key(enter_index) == -1) {
+ return -1;
+ }
+ } while (memcmp(data, " EOF", 4));
+
+ if (blocks) {
+ printf("\n");
+ }
+ if (terminate() == -1) {
+ return -1;
+ }
+ return 0;
+}
OpenPOWER on IntegriCloud