131887Sminshall /*
233812Sbostic  * Copyright (c) 1988 Regents of the University of California.
333812Sbostic  * All rights reserved.
431887Sminshall  *
533812Sbostic  * Redistribution and use in source and binary forms are permitted
6*34897Sbostic  * provided that the above copyright notice and this paragraph are
7*34897Sbostic  * duplicated in all such forms and that any documentation,
8*34897Sbostic  * advertising materials, and other materials related to such
9*34897Sbostic  * distribution and use acknowledge that the software was developed
10*34897Sbostic  * by the University of California, Berkeley.  The name of the
11*34897Sbostic  * University may not be used to endorse or promote products derived
12*34897Sbostic  * from this software without specific prior written permission.
13*34897Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*34897Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*34897Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1631887Sminshall  */
1731887Sminshall 
1831887Sminshall #ifndef lint
1933812Sbostic char copyright[] =
2033812Sbostic "@(#) Copyright (c) 1988 Regents of the University of California.\n\
2133812Sbostic  All rights reserved.\n";
2233812Sbostic #endif /* not lint */
2331887Sminshall 
2433812Sbostic #ifndef lint
25*34897Sbostic static char sccsid[] = "@(#)tnrecv.c	3.3 (Berkeley) 06/29/88";
2633812Sbostic #endif /* not lint */
2733812Sbostic 
2831506Sminshall #include <stdio.h>
2931454Sminshall 
3031876Sminshall #include <api/apilib.h>
3131615Sminshall 
3231506Sminshall #include "tncomp.h"
3331506Sminshall 
3431506Sminshall 
3531876Sminshall #include "../ctlr/api.h"
3631506Sminshall #include "../ctlr/function.h"
3731506Sminshall #include "../ctlr/hostctlr.h"
3831506Sminshall #include "../ctlr/oia.h"
3931506Sminshall #include "../ctlr/screen.h"
4031506Sminshall 
4131876Sminshall #include "../api/disp_asc.h"
4231876Sminshall #include "../api/astosc.h"
4331506Sminshall 
4431506Sminshall #include "../general/general.h"
4531506Sminshall 
4631506Sminshall ScreenImage Host[MAXSCREENSIZE];
4731506Sminshall 
4831506Sminshall static char
4931514Sminshall     a_send_sequence[SEND_SEQUENCE_LENGTH+1],
5031514Sminshall     a_ack_sequence[ACK_SEQUENCE_LENGTH+1],
5131514Sminshall     a_checksum[CHECKSUM_LENGTH+1],
5231514Sminshall     data_array[DATA_LENGTH+1];
5331506Sminshall 
5431506Sminshall static int
5531506Sminshall     verbose,
5631514Sminshall     blocks,
5731506Sminshall     enter_index,
5831506Sminshall     clear_index,
5931506Sminshall     ScreenSize,
6031506Sminshall     session_id;
6131506Sminshall 
6231506Sminshall static unsigned int
6331506Sminshall     send_sequence,
6431514Sminshall     ack_sequence = -1,
6531506Sminshall     checksum;
6631506Sminshall 
6731506Sminshall api_perror(string)
6831506Sminshall char *string;
6931454Sminshall {
7031506Sminshall     fprintf(stderr, "Error: [0x%x/0x%x:0x%x/0x%x] from %s.\n",
7131506Sminshall 	api_sup_fcn_id, api_sup_errno,
7231506Sminshall 	api_fcn_fcn_id, api_fcn_errno, string);
7331506Sminshall }
7431454Sminshall 
7531506Sminshall 
7631506Sminshall char *
7731506Sminshall session_type(type)
7831506Sminshall int	type;
7931506Sminshall {
8031506Sminshall     switch (type) {
8131506Sminshall     case TYPE_WSCTL:
8231506Sminshall 	return "work station control";
8331506Sminshall     case TYPE_DFT:
8431506Sminshall 	return "distributed function terminal";
8531506Sminshall     case TYPE_CUT:
8631506Sminshall 	return "control unit terminal";
8731506Sminshall     case TYPE_NOTEPAD:
8831506Sminshall 	return "notepad";
8931506Sminshall     case TYPE_PC:
9031506Sminshall 	return "personal computer";
9131506Sminshall     default:
9231506Sminshall 	return "(UNKNOWN)";
9331506Sminshall     }
9431506Sminshall }
9531506Sminshall 
9631506Sminshall static int
9731514Sminshall wait_for_ps_or_oia()
9831514Sminshall {
9931514Sminshall #if	defined(unix)
10031514Sminshall     return api_ps_or_oia_modified();
10131514Sminshall #endif	/* defined(unix) */
10231514Sminshall }
10331514Sminshall 
10431514Sminshall 
10531514Sminshall static int
10631506Sminshall wait_for_unlock()
10731506Sminshall {
10831506Sminshall     OIA oia;
10931506Sminshall     ReadOiaGroupParms re;
11031514Sminshall     static char zeroes[sizeof oia.input_inhibited] = { 0 };
11131506Sminshall 
11231506Sminshall     do {
11331506Sminshall 	re.rc = re.function_id = 0;
11431506Sminshall 	re.session_id = session_id;
11531506Sminshall 	re.oia_buffer = (char far *) &oia;
11631506Sminshall 	re.oia_group_number = API_OIA_ALL_GROUPS;
11731506Sminshall 	if (api_read_oia_group(&re) == -1) {
11831506Sminshall 	    api_perror("api_read_oia_group");
11931506Sminshall 	    return -1;
12031506Sminshall 	} else if (verbose) {
12131506Sminshall 	    if (IsOiaReady3274(&oia)) {
12231506Sminshall 		printf("3274 ready, ");
12331506Sminshall 	    }
12431506Sminshall 	    if (IsOiaMyJob(&oia)) {
12531506Sminshall 		printf("my job, ");
12631506Sminshall 	    }
12731506Sminshall 	    if (IsOiaInsert(&oia)) {
12831506Sminshall 		printf("insert mode, ");
12931506Sminshall 	    }
13031506Sminshall 	    if (IsOiaSystemLocked(&oia)) {
13131506Sminshall 		printf("system locked, ");
13231506Sminshall 	    }
13331506Sminshall 	    if (IsOiaTWait(&oia)) {
13431506Sminshall 		printf("terminal wait, ");
13531506Sminshall 	    }
13631506Sminshall 	    printf("are some bits from the OIA.\n");
13731454Sminshall 	}
13831514Sminshall 	/* We turned this on, so turn it off now */
13931514Sminshall 	ResetOiaApiInhibit(&oia);
14031514Sminshall 	if (memcmp(zeroes, oia.input_inhibited, sizeof oia.input_inhibited)) {
14131514Sminshall 	    if (wait_for_ps_or_oia() == -1) {
14231514Sminshall 		return -1;
14331514Sminshall 	    }
14431514Sminshall 	}
14531514Sminshall     } while (memcmp(zeroes, oia.input_inhibited, sizeof oia.input_inhibited));
14631506Sminshall     return 0;
14731506Sminshall }
14831506Sminshall 
14931506Sminshall static int
15031506Sminshall initialize()
15131506Sminshall {
15231506Sminshall     QuerySessionIdParms id;
15331506Sminshall     QuerySessionParametersParms pa;
15431506Sminshall     QuerySessionCursorParms cu;
15531506Sminshall     ConnectToKeyboardParms conn;
15631506Sminshall     DisableInputParms disable;
15731506Sminshall     NameArray namearray;
15831506Sminshall 
15931506Sminshall     if (api_init() == 0) {
16031506Sminshall 	fprintf(stderr, "API function not available.\n");
16131506Sminshall 	return -1;
16231454Sminshall     }
16331506Sminshall 
16431506Sminshall     id.rc = 0;
16531506Sminshall     id.function_id = 0;
16631506Sminshall     id.option_code = ID_OPTION_BY_NAME;
16731506Sminshall     id.data_code = 'E';
16831506Sminshall     id.name_array = &namearray;
16931506Sminshall     namearray.length = sizeof namearray;
17031506Sminshall     if (api_query_session_id(&id)) {
17131506Sminshall 	api_perror("api_query_session_id");
17231506Sminshall     } else if (namearray.number_matching_session == 0) {
17331506Sminshall 	fprintf(stderr, "query_session_id:  No matching sessions!\n");
17431506Sminshall 	return -1;
17531506Sminshall     } else if (verbose) {
17631506Sminshall 	printf("Session short name 0x%x, type is ",
17731506Sminshall 				namearray.name_array_element.short_name);
17831506Sminshall 	printf("%s", session_type(namearray.name_array_element.type));
17931506Sminshall 	printf(", session ID is: 0x%x\n",
18031506Sminshall 				namearray.name_array_element.session_id);
18131506Sminshall     }
18231506Sminshall     session_id = namearray.name_array_element.session_id;
18331506Sminshall 
18431506Sminshall     pa.rc = pa.function_id = 0;
18531506Sminshall     pa.session_id = session_id;
18631506Sminshall     if (api_query_session_parameters(&pa) == -1) {
18731506Sminshall 	api_perror("api_query_session_parameters");
18831506Sminshall 	return -1;
18931506Sminshall     } else if (verbose) {
19031506Sminshall 	printf("Session type %s, ", session_type(pa.session_type));
19131506Sminshall 	if (pa.session_characteristics&CHARACTERISTIC_EAB) {
19231506Sminshall 	    printf(" has EAB, ");
19331506Sminshall 	}
19431506Sminshall 	if (pa.session_characteristics&CHARACTERISTIC_PSS) {
19531506Sminshall 	    printf(" has PSS, ");
19631506Sminshall 	}
19731506Sminshall 	printf("%d rows, %d columns ", pa.rows, pa.columns);
19831506Sminshall 	if (pa.presentation_space) {
19931506Sminshall 	    printf("presentation space at 0x%x:0x%x.\n",
20031506Sminshall 		FP_SEG(pa.presentation_space), FP_OFF(pa.presentation_space));
20131506Sminshall 	} else {
20231506Sminshall 	    printf("(no direct presentation space access).\n");
20331506Sminshall 	}
20431506Sminshall     }
20531506Sminshall     ScreenSize = pa.rows*pa.columns;
20631506Sminshall     if (pa.session_characteristics&CHARACTERISTIC_EAB) {
20731506Sminshall 	fprintf(stderr,
20831506Sminshall     "tncomp utilities not designed to work with extended attribute buffers.\n");
20931506Sminshall 	return -1;
21031506Sminshall     }
21131506Sminshall 
21231506Sminshall     if (verbose) {
21331506Sminshall 	cu.rc = cu.function_id = 0;
21431506Sminshall 	cu.session_id = session_id;
21531506Sminshall 	if (api_query_session_cursor(&cu) == -1) {
21631506Sminshall 	    api_perror("api_query_session_cursor");
21731506Sminshall 	} else {
21831506Sminshall 	    printf("cursor");
21931506Sminshall 	    if (cu.cursor_type&CURSOR_INHIBITED_AUTOSCROLL) {
22031506Sminshall 		printf(" inhibited autoscroll");
22131506Sminshall 	    }
22231506Sminshall 	    if (cu.cursor_type&CURSOR_INHIBITED) {
22331506Sminshall 		printf(" inhibited");
22431506Sminshall 	    }
22531506Sminshall 	    if (cu.cursor_type&CURSOR_BLINKING) {
22631506Sminshall 		printf(" blinking");
22731506Sminshall 	    } else {
22831506Sminshall 		printf(" not blinking");
22931506Sminshall 	    }
23031506Sminshall 	    if (cu.cursor_type&CURSOR_BOX) {
23131506Sminshall 		printf(" box ");
23231506Sminshall 	    } else {
23331506Sminshall 		printf(" not box ");
23431506Sminshall 	    }
23531506Sminshall 	    printf("at row %d, column %d.\n",
23631506Sminshall 				cu.row_address, cu.column_address);
23731506Sminshall 	}
23831506Sminshall     }
23931506Sminshall 
24031506Sminshall     conn.rc = conn.function_id = 0;
24131506Sminshall     conn.session_id = session_id;
24231506Sminshall     conn.event_queue_id = conn.input_queue_id = 0;
24331506Sminshall     conn.intercept_options = 0;
24431506Sminshall     if (api_connect_to_keyboard(&conn) == -1) {
24531506Sminshall 	api_perror("api_connect_to_keyboard");
24631506Sminshall     } else if (verbose) {
24731506Sminshall 	if (conn.first_connection_identifier) {
24831506Sminshall 	    printf("First keyboard connection.\n");
24931506Sminshall 	} else {
25031506Sminshall 	    printf("Not first keyboard connection.\n");
25131506Sminshall 	}
25231506Sminshall     }
25331506Sminshall 
25431506Sminshall     disable.rc = disable.function_id = 0;
25531506Sminshall     disable.session_id = session_id;
25631506Sminshall     disable.connectors_task_id = 0;
25731506Sminshall     if (api_disable_input(&disable) == -1) {
25831506Sminshall 	api_perror("api_disable_input");
25931506Sminshall 	return -1;
26031506Sminshall     } else if (verbose) {
26131506Sminshall 	printf("Disabled.\n");
26231506Sminshall     }
26331506Sminshall 
26431506Sminshall     if ((enter_index = ascii_to_index("ENTER")) == -1) {
26531506Sminshall 	return -1;
26631506Sminshall     }
26731506Sminshall     if ((clear_index = ascii_to_index("CLEAR")) == -1) {
26831506Sminshall 	return -1;
26931506Sminshall     }
27031506Sminshall 
27131506Sminshall     return 0;				/* all ok */
27231454Sminshall }
27331454Sminshall 
27431506Sminshall static int
27531506Sminshall send_key(index)
27631506Sminshall int	index;
27731506Sminshall {
27831506Sminshall     WriteKeystrokeParms wr;
27931506Sminshall     extern struct astosc astosc[];
28031454Sminshall 
28131506Sminshall     wait_for_unlock();
28231506Sminshall 
28331506Sminshall     wr.rc = wr.function_id = 0;
28431506Sminshall     wr.session_id = session_id;
28531506Sminshall     wr.connectors_task_id = 0;
28631506Sminshall     wr.options = OPTION_SINGLE_KEYSTROKE;
28731506Sminshall     wr.number_of_keys_sent = 0;
28831506Sminshall     wr.keystroke_specifier.keystroke_entry.scancode = astosc[index].scancode;
28931506Sminshall     wr.keystroke_specifier.keystroke_entry.shift_state
29031506Sminshall 						= astosc[index].shiftstate;
29131506Sminshall     if (api_write_keystroke(&wr) == -1) {
29231506Sminshall 	api_perror("api_write_keystroke");
29331506Sminshall 	return -1;
29431506Sminshall     } else if (wr.number_of_keys_sent != 1) {
29531506Sminshall 	fprintf(stderr, "write_keystroke claims to have sent %d keystrokes.\n",
29631506Sminshall 		    wr.number_of_keys_sent);
29731506Sminshall 	return -1;
29831506Sminshall     } else if (verbose) {
29931506Sminshall 	printf("Keystroke sent.\n");
30031506Sminshall     }
30131514Sminshall     if (wait_for_ps_or_oia() == -1) {
30231514Sminshall 	return -1;
30331514Sminshall     }
30431506Sminshall     return 0;
30531506Sminshall }
30631506Sminshall 
30731506Sminshall static int
30831506Sminshall terminate()
30931506Sminshall {
31031506Sminshall     EnableInputParms enable;
31131506Sminshall     DisconnectFromKeyboardParms disc;
31231506Sminshall 
31331506Sminshall     enable.rc = enable.function_id = 0;
31431506Sminshall     enable.session_id = session_id;
31531506Sminshall     enable.connectors_task_id = 0;
31631506Sminshall     if (api_enable_input(&enable) == -1) {
31731506Sminshall 	api_perror("api_enable");
31831506Sminshall 	return -1;
31931506Sminshall     } else if (verbose) {
32031506Sminshall 	printf("Enabled.\n");
32131506Sminshall     }
32231506Sminshall 
32331506Sminshall     disc.rc = disc.function_id = 0;
32431506Sminshall     disc.session_id = session_id;
32531506Sminshall     disc.connectors_task_id = 0;
32631506Sminshall     if (api_disconnect_from_keyboard(&disc) == -1) {
32731506Sminshall 	api_perror("api_disconnect_from_keyboard");
32831506Sminshall 	return -1;
32931506Sminshall     } else if (verbose) {
33031506Sminshall 	printf("Disconnected from keyboard.\n");
33131506Sminshall     }
33231506Sminshall 
33331506Sminshall     (void) api_finish();
33431506Sminshall 
33531506Sminshall     return 0;
33631506Sminshall }
33731506Sminshall 
33831506Sminshall 
33931506Sminshall static int
34031506Sminshall get_screen()
34131506Sminshall {
34231506Sminshall     CopyStringParms copy;
34331506Sminshall     /* Time copy services */
34431506Sminshall 
34531506Sminshall     wait_for_unlock();
34631506Sminshall 
34731506Sminshall     copy.copy_mode = 0;
34831506Sminshall     copy.rc = copy.function_id = 0;
34931506Sminshall     copy.source.session_id = session_id;
35031506Sminshall     copy.source.buffer = 0;
35131506Sminshall     copy.source.characteristics = 0;
35231506Sminshall     copy.source.session_type = TYPE_DFT;
35331506Sminshall     copy.source.begin = 0;
35431506Sminshall 
35531506Sminshall     copy.source_end = ScreenSize;
35631506Sminshall 
35731506Sminshall     copy.target.session_id = 0;
35831506Sminshall     copy.target.buffer = (char *) &Host[0];
35931506Sminshall     copy.target.characteristics = 0;
36031506Sminshall     copy.target.session_type = TYPE_DFT;
36131506Sminshall 
36231506Sminshall     if (api_copy_string(&copy) == -1) {
36331506Sminshall 	api_perror("api_copy_string");
36431506Sminshall 	return -1;
36531506Sminshall     }
36631506Sminshall     return 0;
36731506Sminshall }
36831514Sminshall 
36931514Sminshall 
37031514Sminshall put_at(offset, from, length, attribute)
37131506Sminshall int	offset;
37231506Sminshall char	*from;
37331506Sminshall int	length;
37431506Sminshall {
37531506Sminshall     CopyStringParms copy;
37631506Sminshall 
37731506Sminshall     wait_for_unlock();
37831506Sminshall 
37931506Sminshall     copy.copy_mode = 0;
38031506Sminshall     copy.rc = copy.function_id = 0;
38131506Sminshall     copy.source.session_id = 0;
38231506Sminshall     copy.source.buffer = from;
38331506Sminshall     copy.source.characteristics = 0;
38431506Sminshall     copy.source.session_type = TYPE_DFT;
38531506Sminshall     copy.source.begin = 0;
38631506Sminshall 
38731506Sminshall     copy.source_end = length-1;
38831506Sminshall 
38931506Sminshall     copy.target.session_id = session_id;
39031506Sminshall     copy.target.buffer = 0;
39131506Sminshall     copy.target.characteristics = 0;
39231506Sminshall     copy.target.session_type = TYPE_DFT;
39331506Sminshall     copy.target.begin = offset;
39431506Sminshall 
39531506Sminshall     if (api_copy_string(&copy) == -1) {
39631506Sminshall 	api_perror("api_copy_string");
39731506Sminshall 	return -1;
39831506Sminshall     }
39931506Sminshall     return 0;
40031506Sminshall }
40131506Sminshall 
40231506Sminshall static void
40331506Sminshall translate(input, output, table, length)
40431506Sminshall char *input, *output, table[];
40531506Sminshall int length;
40631506Sminshall {
40731506Sminshall     unsigned char *indices = (unsigned char *) input;
40831506Sminshall 
40931506Sminshall     while (length--) {
41031506Sminshall 	*output++ = table[*indices++];
41131506Sminshall     }
41231506Sminshall }
41331506Sminshall 
41431506Sminshall static int
41531514Sminshall find_input_area(from)
41631514Sminshall int	from;
41731506Sminshall {
41831776Sminshall #define	FieldDec(p)	(0)		/* We don't really use this */
41931506Sminshall     register int i, attr;
42031506Sminshall 
42131514Sminshall     for (i = from; i < MAXSCREENSIZE; ) {
42231506Sminshall 	if (IsStartField(i)) {
42331506Sminshall 	    attr = FieldAttributes(i);
42431506Sminshall 	    i++;
42531506Sminshall 	    if (!IsProtectedAttr(i, attr)) {
42631506Sminshall 		return i;
42731506Sminshall 	    }
42831506Sminshall 	} else {
42931506Sminshall 	    i++;
43031506Sminshall 	}
43131506Sminshall     }
43231506Sminshall     return -1;
43331506Sminshall }
43431506Sminshall 
43531506Sminshall 
43631506Sminshall static void
43731506Sminshall getascii(offset, to, length)
43831506Sminshall int	offset;				/* Where in screen */
43931506Sminshall char	*to;				/* Where it goes to */
44031506Sminshall int	length;				/* Where to put it */
44131506Sminshall {
44231506Sminshall     translate(Host+offset, to, disp_asc, length);
44331506Sminshall }
44431506Sminshall 
44531506Sminshall static int
44631514Sminshall putascii(offset, from, length, before)
44731506Sminshall int	offset;				/* Where in screen */
44831506Sminshall char	*from;				/* Where it comes from */
44931506Sminshall int	length;				/* Where to put it */
45031514Sminshall int	before;				/* How much else should go */
45131506Sminshall {
45231506Sminshall     translate(from, Host+offset, asc_disp, length);
45331514Sminshall     if (put_at(offset-before,
45431514Sminshall 			(char *) Host+offset-before, length+before) == -1) {
45531506Sminshall 	return -1;
45631506Sminshall     }
45731506Sminshall     return 0;
45831506Sminshall }
45931506Sminshall 
46031506Sminshall static int
46131506Sminshall ack()
46231506Sminshall {
46331514Sminshall     static char ack_blanks[sizeof a_ack_sequence] = {0};
46431514Sminshall 
46531514Sminshall     if (ack_blanks[0] == 0) {
46631514Sminshall 	int i;
46731514Sminshall 
46831514Sminshall 	for (i = 0; i < sizeof ack_blanks; i++) {
46931514Sminshall 	    ack_blanks[i] = ' ';
47031514Sminshall 	}
47131514Sminshall     }
47231514Sminshall 
47331514Sminshall     memcpy(a_ack_sequence, ack_blanks, sizeof a_ack_sequence);
47431506Sminshall     sprintf(a_ack_sequence, "%d", ack_sequence);
47531506Sminshall     a_ack_sequence[strlen(a_ack_sequence)] = ' ';
47631514Sminshall     Host[ACK_SEQUENCE-1] |= ATTR_MDT;
47731514Sminshall     if (putascii(ACK_SEQUENCE, a_ack_sequence, ACK_SEQUENCE_LENGTH, 1) == -1) {
47831506Sminshall 	return -1;
47931506Sminshall     }
48031506Sminshall     return 0;
48131506Sminshall }
48231514Sminshall 
48331514Sminshall static int
48431514Sminshall formatted_correct()
48531514Sminshall {
48631514Sminshall     if ((find_input_area(SEND_SEQUENCE-1) != SEND_SEQUENCE) ||
48731514Sminshall 	    (find_input_area(SEND_SEQUENCE) != ACK_SEQUENCE) ||
48831514Sminshall 	    (find_input_area(ACK_SEQUENCE) != CHECKSUM) ||
48931514Sminshall 	    (find_input_area(CHECKSUM) != DATA)) {
49031514Sminshall 	return -1;
49131514Sminshall     } else {
49231514Sminshall 	return 0;
49331514Sminshall     }
49431514Sminshall }
49531514Sminshall 
49631514Sminshall 
49731454Sminshall main(argc, argv)
49831454Sminshall int	argc;
49931454Sminshall char	*argv[];
50031454Sminshall {
50131506Sminshall     register int i;
50231454Sminshall     int data_length, input_length;
50331454Sminshall     char ascii[8];			/* Lots of room */
50431454Sminshall     FILE *outfile;
50531506Sminshall     char *data;
50631804Sminshall     char *argv0 = argv[0];
50731454Sminshall 
50831777Sminshall     argc--;
50931777Sminshall     argv++;
51031506Sminshall     /* Process any flags */
51131804Sminshall     while (argc && (argv[0][0] == '-')) {
51231777Sminshall 	switch (argv[0][1]) {
51331506Sminshall 	case 'v':
51431506Sminshall 	    verbose = 1;
51531514Sminshall 	    break;
51631514Sminshall 	case 'b':
51731514Sminshall 	    blocks = 1;
51831514Sminshall 	    break;
51931506Sminshall 	}
52031777Sminshall 	argc--;
52131777Sminshall 	argv++;
52231506Sminshall     }
52331506Sminshall 
52431777Sminshall     if ((argc) < 2) {
52531804Sminshall 	fprintf(stderr,
52631804Sminshall 		"usage: %s [-b] [-v] local.file remote.file [remote.options]\n",
52731804Sminshall 			argv0);
52831454Sminshall 	exit(1);
52931454Sminshall     }
53031454Sminshall 
53131454Sminshall     /* Open the local file */
53231777Sminshall     if ((outfile = fopen(argv[0], "w")) == NULL) {
53331454Sminshall 	perror("fopen");
53431454Sminshall 	exit(2);
53531454Sminshall     }
53631777Sminshall     argc--;
53731777Sminshall     argv++;
53831454Sminshall 
53931506Sminshall     if (initialize() == -1) {
54031506Sminshall 	return -1;
54131506Sminshall     }
54231506Sminshall 
54331454Sminshall     /* build the command line */
54431454Sminshall     data = data_array;
54531506Sminshall     strcpy(data, "TNCOMP SEND");
54631454Sminshall     data += strlen(data);
54731777Sminshall     while (argc--) {
54831454Sminshall 	*data++ = ' ';
54931777Sminshall 	strcpy(data, argv[0]);
55031777Sminshall 	data += strlen(argv[0]);
55131777Sminshall 	argv++;
55231454Sminshall     }
55331506Sminshall     if (verbose) {
55431506Sminshall 	printf("%s\n", data_array);
55531506Sminshall     }
55631506Sminshall     if (get_screen() == -1) {
55731506Sminshall 	return -1;
55831506Sminshall     }
55931506Sminshall     data_length = strlen(data_array);
56031877Sminshall     if ((i = find_input_area(0)) == -1) {		/* Get an input area */
56131506Sminshall 	if (send_key(clear_index) == -1) {
56231506Sminshall 	    return -1;
56331506Sminshall 	}
56431514Sminshall 	if ((i = find_input_area(0)) == -1) {		/* Try again */
56531506Sminshall 	    fprintf(stderr, "Unable to enter command line.\n");
56631506Sminshall 	    return -1;
56731506Sminshall 	}
56831506Sminshall     }
56931514Sminshall     if (i == 0) {
57031514Sminshall 	Host[ScreenSize-1] |= ATTR_MDT;
57131514Sminshall     } else {
57231514Sminshall 	Host[i-1] |= ATTR_MDT;
57331514Sminshall     }
57431514Sminshall     if (putascii(i, data_array, data_length, 1) == -1) {
57531506Sminshall 	return -1;
57631506Sminshall     }
57731506Sminshall     if (send_key(enter_index) == -1) {
57831506Sminshall 	return -1;
57931506Sminshall     }
58031506Sminshall     do {
58131506Sminshall 	if (get_screen() == -1) {
58231506Sminshall 	    return -1;
58331506Sminshall 	}
58431514Sminshall     } while (formatted_correct() == -1);
58531454Sminshall 
58631506Sminshall     do {
58731514Sminshall 	if (get_screen() == -1) {
58831514Sminshall 	    return -1;
58931514Sminshall 	}
59031506Sminshall 	/* For each screen */
59131514Sminshall 	if (formatted_correct() == -1) {
59231514Sminshall 	    fprintf(stderr, "Bad screen written by host.\n");
59331514Sminshall 	    return -1;
59431514Sminshall 	}
59531514Sminshall 	/* If MDT isn't reset in the sequence number, go around again */
59631514Sminshall 	if (Host[ACK_SEQUENCE-1]&ATTR_MDT) {
59731514Sminshall 	    if (wait_for_ps_or_oia() == -1) {
59831514Sminshall 		return -1;
59931514Sminshall 	    }
60031514Sminshall 	    continue;
60131514Sminshall 	}
60231514Sminshall 	getascii(SEND_SEQUENCE, a_send_sequence, SEND_SEQUENCE_LENGTH);
60331506Sminshall 	send_sequence = atoi(a_send_sequence);
60431514Sminshall 	getascii(CHECKSUM, a_checksum, CHECKSUM_LENGTH);
60531506Sminshall 	checksum = atoi(a_checksum);
60631514Sminshall 	getascii(DATA, data_array, DATA_LENGTH);
60731506Sminshall 	data = data_array;
60831506Sminshall 	if (send_sequence != (ack_sequence+1)) {
60931514Sminshall 	    if (ack() == -1) {
61031514Sminshall 		return -1;
61131514Sminshall 	    }
61231506Sminshall 	    data = "1234";		/* Keep loop from failing */
61331506Sminshall 	    if (send_key(enter_index) == -1) {
61431506Sminshall 		return -1;
61531506Sminshall 	    }
61631506Sminshall 	    if (get_screen() == -1) {
61731506Sminshall 		return -1;
61831506Sminshall 	    }
61931506Sminshall 	    continue;
62031506Sminshall 	}
62131454Sminshall 
62231514Sminshall 	data_length = DATA_LENGTH;
62331514Sminshall 	while (data_length && memcmp(data, " EOF", 4)
62431514Sminshall 						&& memcmp(data, "    ", 4)) {
62531506Sminshall 	    memcpy(ascii, data, 4);
62631514Sminshall 	    data += 4;
62731514Sminshall 	    data_length -= 4;
62831506Sminshall 	    ascii[4] = 0;
62931506Sminshall 	    input_length = atoi(ascii);
63031514Sminshall 	    /* CMS can't live with zero length records */
63131514Sminshall 	    if ((input_length > 1) ||
63231514Sminshall 			((input_length == 1) && (data[0] != ' '))) {
63331506Sminshall 		if (fwrite(data, sizeof (char),
63431514Sminshall 					input_length, outfile) == 0) {
63531506Sminshall 		    perror("fwrite");
63631506Sminshall 		    exit(9);
63731506Sminshall 		}
63831454Sminshall 	    }
63931506Sminshall 	    fprintf(outfile, "\n");
64031506Sminshall 	    data += input_length;
64131506Sminshall 	    data_length -= input_length;
64231454Sminshall 	}
64331514Sminshall 
64431514Sminshall 	ack_sequence = send_sequence;
64531514Sminshall 	if (blocks) {
64631514Sminshall 	    printf("#");
64731514Sminshall 	    fflush(stdout);
64831514Sminshall 	}
64931514Sminshall 	if (ack() == -1) {
65031506Sminshall 	    return -1;
65131506Sminshall 	}
65231514Sminshall 	if (send_key(enter_index) == -1) {
65331506Sminshall 	    return -1;
65431506Sminshall 	}
65531514Sminshall     } while (memcmp(data, " EOF", 4));
65631506Sminshall 
65731514Sminshall     if (blocks) {
65831514Sminshall 	printf("\n");
65931514Sminshall     }
66031506Sminshall     if (terminate() == -1) {
66131506Sminshall 	return -1;
66231454Sminshall     }
66331506Sminshall     return 0;
66431454Sminshall }
665