xref: /freebsd/contrib/telnet/telnet/main.c (revision a3c858005cae175e277f6f6735ca9eaea7eaf3c3)
181cb6ddcSMark Murray /*
281cb6ddcSMark Murray  * Copyright (c) 1988, 1990, 1993
381cb6ddcSMark Murray  *	The Regents of the University of California.  All rights reserved.
481cb6ddcSMark Murray  *
581cb6ddcSMark Murray  * Redistribution and use in source and binary forms, with or without
681cb6ddcSMark Murray  * modification, are permitted provided that the following conditions
781cb6ddcSMark Murray  * are met:
881cb6ddcSMark Murray  * 1. Redistributions of source code must retain the above copyright
981cb6ddcSMark Murray  *    notice, this list of conditions and the following disclaimer.
1081cb6ddcSMark Murray  * 2. Redistributions in binary form must reproduce the above copyright
1181cb6ddcSMark Murray  *    notice, this list of conditions and the following disclaimer in the
1281cb6ddcSMark Murray  *    documentation and/or other materials provided with the distribution.
1383129c0bSEd Maste  * 3. Neither the name of the University nor the names of its contributors
1481cb6ddcSMark Murray  *    may be used to endorse or promote products derived from this software
1581cb6ddcSMark Murray  *    without specific prior written permission.
1681cb6ddcSMark Murray  *
1781cb6ddcSMark Murray  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1881cb6ddcSMark Murray  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1981cb6ddcSMark Murray  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2081cb6ddcSMark Murray  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2181cb6ddcSMark Murray  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2281cb6ddcSMark Murray  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2381cb6ddcSMark Murray  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2481cb6ddcSMark Murray  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2581cb6ddcSMark Murray  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2681cb6ddcSMark Murray  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2781cb6ddcSMark Murray  * SUCH DAMAGE.
2881cb6ddcSMark Murray  */
2981cb6ddcSMark Murray 
3077b7cdf1SDavid E. O'Brien #if 0
3181cb6ddcSMark Murray #ifndef lint
3204c426ccSMark Murray static const char sccsid[] = "@(#)main.c	8.3 (Berkeley) 5/30/95";
338fa113e5SMark Murray #endif
3477b7cdf1SDavid E. O'Brien #endif
3581cb6ddcSMark Murray 
36de93353dSMaxim Konovalov #include <sys/param.h>
374dd8b5abSYoshinobu Inoue #include <sys/socket.h>
3804c426ccSMark Murray #include <stdlib.h>
3921f083c0SMark Murray #include <string.h>
4021f083c0SMark Murray #include <unistd.h>
4181cb6ddcSMark Murray 
4281cb6ddcSMark Murray #include "ring.h"
4381cb6ddcSMark Murray #include "externs.h"
4481cb6ddcSMark Murray #include "defines.h"
4581cb6ddcSMark Murray 
468fa113e5SMark Murray #ifdef	AUTHENTICATION
4704c426ccSMark Murray #include <libtelnet/auth.h>
4804c426ccSMark Murray #endif
498fa113e5SMark Murray #ifdef	ENCRYPTION
5004c426ccSMark Murray #include <libtelnet/encrypt.h>
5104c426ccSMark Murray #endif
5204c426ccSMark Murray 
5381cb6ddcSMark Murray /* These values need to be the same as defined in libtelnet/kerberos5.c */
5481cb6ddcSMark Murray /* Either define them in both places, or put in some common header file. */
5581cb6ddcSMark Murray #define OPTS_FORWARD_CREDS	0x00000002
5681cb6ddcSMark Murray #define OPTS_FORWARDABLE_CREDS	0x00000001
5781cb6ddcSMark Murray 
584dd8b5abSYoshinobu Inoue #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
594dd8b5abSYoshinobu Inoue char *ipsec_policy_in = NULL;
604dd8b5abSYoshinobu Inoue char *ipsec_policy_out = NULL;
614dd8b5abSYoshinobu Inoue #endif
624dd8b5abSYoshinobu Inoue 
63de93353dSMaxim Konovalov extern int tos;
64*224c772cSEdward Tomasz Napierala extern int quiet_mode;
65de93353dSMaxim Konovalov 
664dd8b5abSYoshinobu Inoue int family = AF_UNSPEC;
674dd8b5abSYoshinobu Inoue 
6881cb6ddcSMark Murray /*
6981cb6ddcSMark Murray  * Initialize variables.
7081cb6ddcSMark Murray  */
7181cb6ddcSMark Murray void
tninit(void)728fa113e5SMark Murray tninit(void)
7381cb6ddcSMark Murray {
7481cb6ddcSMark Murray     init_terminal();
7581cb6ddcSMark Murray 
7681cb6ddcSMark Murray     init_network();
7781cb6ddcSMark Murray 
7881cb6ddcSMark Murray     init_telnet();
7981cb6ddcSMark Murray 
8081cb6ddcSMark Murray     init_sys();
8181cb6ddcSMark Murray }
8281cb6ddcSMark Murray 
838fa113e5SMark Murray static void
usage(void)848fa113e5SMark Murray usage(void)
8581cb6ddcSMark Murray {
8686953b02SMark Murray 	fprintf(stderr, "usage: %s %s%s%s%s\n",
8781cb6ddcSMark Murray 	    prompt,
8881cb6ddcSMark Murray #ifdef	AUTHENTICATION
89ad11def5SEnji Cooper 	    "[-4] [-6] [-8] [-B baudrate] [-E] [-K] [-L] [-N] [-S tos] [-X atype]",
90ad11def5SEnji Cooper 	    "\n\t[-c] [-d] [-e char] [-k realm] [-l user] [-f/-F] [-n tracefile] ",
9181cb6ddcSMark Murray #else
92ad11def5SEnji Cooper 	    "[-4] [-6] [-8] [-B baudrate] [-E] [-L] [-N] [-S tos] [-c] [-d]",
93a5493c1bSRuslan Ermilov 	    "\n\t[-e char] [-l user] [-n tracefile] ",
9481cb6ddcSMark Murray #endif
95a5493c1bSRuslan Ermilov 	    "[-r] [-s src_addr] [-u] ",
964dd8b5abSYoshinobu Inoue #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
974dd8b5abSYoshinobu Inoue 	    "[-P policy] "
984dd8b5abSYoshinobu Inoue #endif
9981cb6ddcSMark Murray #ifdef	ENCRYPTION
10003679084SNick Sayer 	    "[-y] [host-name [port]]"
10181cb6ddcSMark Murray #else	/* ENCRYPTION */
10281cb6ddcSMark Murray 	    "[host-name [port]]"
10381cb6ddcSMark Murray #endif	/* ENCRYPTION */
10481cb6ddcSMark Murray 	);
10581cb6ddcSMark Murray 	exit(1);
10681cb6ddcSMark Murray }
10781cb6ddcSMark Murray 
10881cb6ddcSMark Murray /*
10981cb6ddcSMark Murray  * main.  Parse arguments, invoke the protocol or command parser.
11081cb6ddcSMark Murray  */
11181cb6ddcSMark Murray 
11204c426ccSMark Murray int
main(int argc,char * argv[])1138fa113e5SMark Murray main(int argc, char *argv[])
11481cb6ddcSMark Murray {
115de93353dSMaxim Konovalov 	u_long ultmp;
11681cb6ddcSMark Murray 	int ch;
117de93353dSMaxim Konovalov 	char *ep, *user;
11842cf8219SRuslan Ermilov 	char *src_addr = NULL;
11981cb6ddcSMark Murray #ifdef	FORWARD
12081cb6ddcSMark Murray 	extern int forward_flags;
12181cb6ddcSMark Murray #endif	/* FORWARD */
12281cb6ddcSMark Murray 
1233db1b221SPoul-Henning Kamp 	setbuf(stdout, NULL);
1243db1b221SPoul-Henning Kamp 	setbuf(stderr, NULL);
12581cb6ddcSMark Murray 	tninit();		/* Clear out things */
12681cb6ddcSMark Murray 
12781cb6ddcSMark Murray 	TerminalSaveState();
12881cb6ddcSMark Murray 
12904c426ccSMark Murray 	if ((prompt = strrchr(argv[0], '/')))
13081cb6ddcSMark Murray 		++prompt;
13181cb6ddcSMark Murray 	else
13281cb6ddcSMark Murray 		prompt = argv[0];
13381cb6ddcSMark Murray 
13481cb6ddcSMark Murray 	user = NULL;
13581cb6ddcSMark Murray 
13681cb6ddcSMark Murray 	rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
13721f083c0SMark Murray #ifdef AUTHENTICATION
13803679084SNick Sayer 	autologin = 1;
13921f083c0SMark Murray #else
14021f083c0SMark Murray 	autologin = -1;
14121f083c0SMark Murray #endif
14203679084SNick Sayer 
1438fa113e5SMark Murray #ifdef	ENCRYPTION
14403679084SNick Sayer 	encrypt_auto(1);
14503679084SNick Sayer 	decrypt_auto(1);
14603679084SNick Sayer #endif
14781cb6ddcSMark Murray 
1484dd8b5abSYoshinobu Inoue #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
1494dd8b5abSYoshinobu Inoue #define IPSECOPT	"P:"
1504dd8b5abSYoshinobu Inoue #else
1514dd8b5abSYoshinobu Inoue #define IPSECOPT
1524dd8b5abSYoshinobu Inoue #endif
1534dd8b5abSYoshinobu Inoue 	while ((ch = getopt(argc, argv,
154*224c772cSEdward Tomasz Napierala 			    "468B:EKLNQS:X:acde:fFk:l:n:rs:uxy" IPSECOPT)) != -1)
1554dd8b5abSYoshinobu Inoue #undef IPSECOPT
1564dd8b5abSYoshinobu Inoue 	{
15781cb6ddcSMark Murray 		switch(ch) {
1584dd8b5abSYoshinobu Inoue 		case '4':
1594dd8b5abSYoshinobu Inoue 			family = AF_INET;
1604dd8b5abSYoshinobu Inoue 			break;
1614dd8b5abSYoshinobu Inoue #ifdef INET6
1624dd8b5abSYoshinobu Inoue 		case '6':
1634dd8b5abSYoshinobu Inoue 			family = AF_INET6;
1644dd8b5abSYoshinobu Inoue 			break;
1654dd8b5abSYoshinobu Inoue #endif
16681cb6ddcSMark Murray 		case '8':
16781cb6ddcSMark Murray 			eight = 3;	/* binary output and input */
16881cb6ddcSMark Murray 			break;
169ad11def5SEnji Cooper 		case 'B':
170ad11def5SEnji Cooper 			DoBaudRate(optarg);
171ad11def5SEnji Cooper 			break;
17281cb6ddcSMark Murray 		case 'E':
17381cb6ddcSMark Murray 			rlogin = escape = _POSIX_VDISABLE;
17481cb6ddcSMark Murray 			break;
17581cb6ddcSMark Murray 		case 'K':
17681cb6ddcSMark Murray #ifdef	AUTHENTICATION
17781cb6ddcSMark Murray 			autologin = 0;
17881cb6ddcSMark Murray #endif
17981cb6ddcSMark Murray 			break;
18081cb6ddcSMark Murray 		case 'L':
18181cb6ddcSMark Murray 			eight |= 2;	/* binary output only */
18281cb6ddcSMark Murray 			break;
18342cf8219SRuslan Ermilov 		case 'N':
18442cf8219SRuslan Ermilov 			doaddrlookup = 0;
18542cf8219SRuslan Ermilov 			break;
186*224c772cSEdward Tomasz Napierala 		case 'Q':
187*224c772cSEdward Tomasz Napierala 			quiet_mode = 1;
188*224c772cSEdward Tomasz Napierala 			break;
18981cb6ddcSMark Murray 		case 'S':
19081cb6ddcSMark Murray #ifdef	HAS_GETTOS
19181cb6ddcSMark Murray 
19281cb6ddcSMark Murray 			if ((tos = parsetos(optarg, "tcp")) < 0)
19381cb6ddcSMark Murray 				fprintf(stderr, "%s%s%s%s\n",
19481cb6ddcSMark Murray 					prompt, ": Bad TOS argument '",
19581cb6ddcSMark Murray 					optarg,
19681cb6ddcSMark Murray 					"; will try to use default TOS");
19781cb6ddcSMark Murray #else
198de93353dSMaxim Konovalov #define	MAXTOS	255
199de93353dSMaxim Konovalov 			ultmp = strtoul(optarg, &ep, 0);
200de93353dSMaxim Konovalov 			if (*ep || ep == optarg || ultmp > MAXTOS)
201de93353dSMaxim Konovalov 				fprintf(stderr, "%s%s%s%s\n",
202de93353dSMaxim Konovalov 					prompt, ": Bad TOS argument '",
203de93353dSMaxim Konovalov 					optarg,
204de93353dSMaxim Konovalov 					"; will try to use default TOS");
205de93353dSMaxim Konovalov 			else
206de93353dSMaxim Konovalov 				tos = ultmp;
20781cb6ddcSMark Murray #endif
20881cb6ddcSMark Murray 			break;
20981cb6ddcSMark Murray 		case 'X':
21081cb6ddcSMark Murray #ifdef	AUTHENTICATION
21181cb6ddcSMark Murray 			auth_disable_name(optarg);
21281cb6ddcSMark Murray #endif
21381cb6ddcSMark Murray 			break;
21481cb6ddcSMark Murray 		case 'a':
21521f083c0SMark Murray #ifdef	AUTHENTICATION
21603679084SNick Sayer 			/* It's the default now, so ignore */
21721f083c0SMark Murray #else
21821f083c0SMark Murray 			autologin = 1;
21921f083c0SMark Murray #endif
22081cb6ddcSMark Murray 			break;
22181cb6ddcSMark Murray 		case 'c':
22281cb6ddcSMark Murray 			skiprc = 1;
22381cb6ddcSMark Murray 			break;
22481cb6ddcSMark Murray 		case 'd':
225074e8e8eSMark Murray 			telnet_debug = 1;
22681cb6ddcSMark Murray 			break;
22781cb6ddcSMark Murray 		case 'e':
22881cb6ddcSMark Murray 			set_escape_char(optarg);
22981cb6ddcSMark Murray 			break;
23081cb6ddcSMark Murray 		case 'f':
2318fa113e5SMark Murray #ifdef	AUTHENTICATION
2328fa113e5SMark Murray #if defined(KRB5) && defined(FORWARD)
23381cb6ddcSMark Murray 			if (forward_flags & OPTS_FORWARD_CREDS) {
23481cb6ddcSMark Murray 			    fprintf(stderr,
23581cb6ddcSMark Murray 				    "%s: Only one of -f and -F allowed.\n",
23681cb6ddcSMark Murray 				    prompt);
23781cb6ddcSMark Murray 			    usage();
23881cb6ddcSMark Murray 			}
23981cb6ddcSMark Murray 			forward_flags |= OPTS_FORWARD_CREDS;
24081cb6ddcSMark Murray #else
24181cb6ddcSMark Murray 			fprintf(stderr,
24281cb6ddcSMark Murray 			 "%s: Warning: -f ignored, no Kerberos V5 support.\n",
24381cb6ddcSMark Murray 				prompt);
24481cb6ddcSMark Murray #endif
2458fa113e5SMark Murray #else
2468fa113e5SMark Murray 			fprintf(stderr,
2478fa113e5SMark Murray 			 "%s: Warning: -f ignored, no Kerberos V5 support.\n",
2488fa113e5SMark Murray 				prompt);
2498fa113e5SMark Murray #endif
25081cb6ddcSMark Murray 			break;
25181cb6ddcSMark Murray 		case 'F':
2528fa113e5SMark Murray #ifdef	AUTHENTICATION
2538fa113e5SMark Murray #if defined(KRB5) && defined(FORWARD)
25481cb6ddcSMark Murray 			if (forward_flags & OPTS_FORWARD_CREDS) {
25581cb6ddcSMark Murray 			    fprintf(stderr,
25681cb6ddcSMark Murray 				    "%s: Only one of -f and -F allowed.\n",
25781cb6ddcSMark Murray 				    prompt);
25881cb6ddcSMark Murray 			    usage();
25981cb6ddcSMark Murray 			}
26081cb6ddcSMark Murray 			forward_flags |= OPTS_FORWARD_CREDS;
26181cb6ddcSMark Murray 			forward_flags |= OPTS_FORWARDABLE_CREDS;
26281cb6ddcSMark Murray #else
26381cb6ddcSMark Murray 			fprintf(stderr,
26481cb6ddcSMark Murray 			 "%s: Warning: -F ignored, no Kerberos V5 support.\n",
26581cb6ddcSMark Murray 				prompt);
26681cb6ddcSMark Murray #endif
2678fa113e5SMark Murray #else
2688fa113e5SMark Murray 			fprintf(stderr,
2698fa113e5SMark Murray 			 "%s: Warning: -F ignored, no Kerberos V5 support.\n",
2708fa113e5SMark Murray 				prompt);
2718fa113e5SMark Murray #endif
27281cb6ddcSMark Murray 			break;
27381cb6ddcSMark Murray 		case 'k':
2748fa113e5SMark Murray #ifdef	AUTHENTICATION
2758fa113e5SMark Murray #if defined(KRB4)
27681cb6ddcSMark Murray 		    {
27781cb6ddcSMark Murray 			extern char *dest_realm, dst_realm_buf[], dst_realm_sz;
27881cb6ddcSMark Murray 			dest_realm = dst_realm_buf;
27981cb6ddcSMark Murray 			(void)strncpy(dest_realm, optarg, dst_realm_sz);
28081cb6ddcSMark Murray 		    }
28181cb6ddcSMark Murray #else
28281cb6ddcSMark Murray 			fprintf(stderr,
28381cb6ddcSMark Murray 			   "%s: Warning: -k ignored, no Kerberos V4 support.\n",
28481cb6ddcSMark Murray 								prompt);
28581cb6ddcSMark Murray #endif
2868fa113e5SMark Murray #else
2878fa113e5SMark Murray 			fprintf(stderr,
2888fa113e5SMark Murray 			   "%s: Warning: -k ignored, no Kerberos V4 support.\n",
2898fa113e5SMark Murray 								prompt);
2908fa113e5SMark Murray #endif
29181cb6ddcSMark Murray 			break;
29281cb6ddcSMark Murray 		case 'l':
29321f083c0SMark Murray #ifdef	AUTHENTICATION
29421f083c0SMark Murray 			/* This is the default now, so ignore it */
29521f083c0SMark Murray #else
29621f083c0SMark Murray 			autologin = 1;
29721f083c0SMark Murray #endif
29881cb6ddcSMark Murray 			user = optarg;
29981cb6ddcSMark Murray 			break;
30081cb6ddcSMark Murray 		case 'n':
30181cb6ddcSMark Murray 				SetNetTrace(optarg);
30281cb6ddcSMark Murray 			break;
30381cb6ddcSMark Murray 		case 'r':
30481cb6ddcSMark Murray 			rlogin = '~';
30581cb6ddcSMark Murray 			break;
30642cf8219SRuslan Ermilov 		case 's':
30742cf8219SRuslan Ermilov 			src_addr = optarg;
30842cf8219SRuslan Ermilov 			break;
309a5493c1bSRuslan Ermilov 		case 'u':
310a5493c1bSRuslan Ermilov 			family = AF_UNIX;
311a5493c1bSRuslan Ermilov 			break;
31281cb6ddcSMark Murray 		case 'x':
3138fa113e5SMark Murray #ifndef	ENCRYPTION
31421f083c0SMark Murray 			fprintf(stderr,
31521f083c0SMark Murray 			    "%s: Warning: -x ignored, no ENCRYPT support.\n",
31621f083c0SMark Murray 								prompt);
31721f083c0SMark Murray #endif	/* ENCRYPTION */
31803679084SNick Sayer 			break;
31903679084SNick Sayer 		case 'y':
32081cb6ddcSMark Murray #ifdef	ENCRYPTION
32103679084SNick Sayer 			encrypt_auto(0);
32203679084SNick Sayer 			decrypt_auto(0);
32321f083c0SMark Murray #else
32421f083c0SMark Murray 			fprintf(stderr,
32521f083c0SMark Murray 			    "%s: Warning: -y ignored, no ENCRYPT support.\n",
32621f083c0SMark Murray 								prompt);
32781cb6ddcSMark Murray #endif	/* ENCRYPTION */
32881cb6ddcSMark Murray 			break;
3294dd8b5abSYoshinobu Inoue #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
3304dd8b5abSYoshinobu Inoue 		case 'P':
3314dd8b5abSYoshinobu Inoue 			if (!strncmp("in", optarg, 2))
3324dd8b5abSYoshinobu Inoue 				ipsec_policy_in = strdup(optarg);
3334dd8b5abSYoshinobu Inoue 			else if (!strncmp("out", optarg, 3))
3344dd8b5abSYoshinobu Inoue 				ipsec_policy_out = strdup(optarg);
3354dd8b5abSYoshinobu Inoue 			else
3364dd8b5abSYoshinobu Inoue 				usage();
3374dd8b5abSYoshinobu Inoue 			break;
3384dd8b5abSYoshinobu Inoue #endif
33981cb6ddcSMark Murray 		case '?':
34081cb6ddcSMark Murray 		default:
34181cb6ddcSMark Murray 			usage();
34281cb6ddcSMark Murray 			/* NOTREACHED */
34381cb6ddcSMark Murray 		}
34481cb6ddcSMark Murray 	}
34521f083c0SMark Murray 	if (autologin == -1)
34621f083c0SMark Murray 		autologin = (rlogin == _POSIX_VDISABLE) ? 0 : 1;
347bb330cd0SAssar Westerlund 
34881cb6ddcSMark Murray 	argc -= optind;
34981cb6ddcSMark Murray 	argv += optind;
35081cb6ddcSMark Murray 
35181cb6ddcSMark Murray 	if (argc) {
35242cf8219SRuslan Ermilov 		char *args[9], **argp = args;
35381cb6ddcSMark Murray 
35481cb6ddcSMark Murray 		if (argc > 2)
35581cb6ddcSMark Murray 			usage();
35681cb6ddcSMark Murray 		*argp++ = prompt;
35781cb6ddcSMark Murray 		if (user) {
3588fa113e5SMark Murray 			*argp++ = strdup("-l");
35981cb6ddcSMark Murray 			*argp++ = user;
36081cb6ddcSMark Murray 		}
36142cf8219SRuslan Ermilov 		if (src_addr) {
3628fa113e5SMark Murray 			*argp++ = strdup("-s");
36342cf8219SRuslan Ermilov 			*argp++ = src_addr;
36442cf8219SRuslan Ermilov 		}
36581cb6ddcSMark Murray 		*argp++ = argv[0];		/* host */
36681cb6ddcSMark Murray 		if (argc > 1)
36781cb6ddcSMark Murray 			*argp++ = argv[1];	/* port */
36881cb6ddcSMark Murray 		*argp = 0;
36981cb6ddcSMark Murray 
37081cb6ddcSMark Murray 		if (setjmp(toplevel) != 0)
37181cb6ddcSMark Murray 			Exit(0);
37281cb6ddcSMark Murray 		if (tn(argp - args, args) == 1)
37381cb6ddcSMark Murray 			return (0);
37481cb6ddcSMark Murray 		else
37581cb6ddcSMark Murray 			return (1);
37681cb6ddcSMark Murray 	}
37781cb6ddcSMark Murray 	(void)setjmp(toplevel);
37881cb6ddcSMark Murray 	for (;;) {
37981cb6ddcSMark Murray 			command(1, 0, 0);
38081cb6ddcSMark Murray 	}
38104c426ccSMark Murray 	return 0;
38281cb6ddcSMark Murray }
383