xref: /netbsd-src/usr.bin/telnet/main.c (revision 8e6ab8837d8d6b9198e67c1c445300b483e2f304)
1 /*	$NetBSD: main.c,v 1.20 2003/07/14 15:56:29 itojun Exp $	*/
2 
3 /*
4  * Copyright (c) 1988, 1990, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by the University of
18  *	California, Berkeley and its contributors.
19  * 4. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35 
36 #include <sys/cdefs.h>
37 #ifndef lint
38 __COPYRIGHT("@(#) Copyright (c) 1988, 1990, 1993\n\
39 	The Regents of the University of California.  All rights reserved.\n");
40 #endif /* not lint */
41 
42 #ifndef lint
43 #if 0
44 static char sccsid[] = "@(#)main.c	8.3 (Berkeley) 5/30/95";
45 #else
46 __RCSID("$NetBSD: main.c,v 1.20 2003/07/14 15:56:29 itojun Exp $");
47 #endif
48 #endif /* not lint */
49 
50 #include <sys/types.h>
51 #include <sys/socket.h>
52 
53 #include <unistd.h>
54 
55 #include "ring.h"
56 #include "externs.h"
57 #include "defines.h"
58 #ifdef AUTHENTICATION
59 #include <libtelnet/auth.h>
60 #endif
61 #ifdef ENCRYPTION
62 #include <libtelnet/encrypt.h>
63 #endif
64 
65 /* These values need to be the same as defined in libtelnet/kerberos5.c */
66 /* Either define them in both places, or put in some common header file. */
67 #define OPTS_FORWARD_CREDS	0x00000002
68 #define OPTS_FORWARDABLE_CREDS	0x00000001
69 
70 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
71 char *ipsec_policy_in = NULL;
72 char *ipsec_policy_out = NULL;
73 #endif
74 
75 int family = AF_UNSPEC;
76 
77 int main(int, char *[]);
78 
79 /*
80  * Initialize variables.
81  */
82 void
83 tninit(void)
84 {
85     init_terminal();
86 
87     init_network();
88 
89     init_telnet();
90 
91     init_sys();
92 
93 #ifdef TN3270
94     init_3270();
95 #endif
96 }
97 
98 	void
99 usage()
100 {
101 	fprintf(stderr, "Usage: %s %s%s%s%s\n",
102 	    prompt,
103 #ifdef	AUTHENTICATION
104 	    "[-4] [-6] [-8] [-E] [-K] [-L] [-N] [-S tos] [-X atype] [-a] [-c] [-d]",
105 	    "\n\t[-e char] [-k realm] [-l user] [-f/-F] [-n tracefile] ",
106 #else
107 	    "[-4] [-6] [-8] [-E] [-L] [-N] [-S tos] [-a] [-c] [-d] [-e char] [-l user]",
108 	    "\n\t[-n tracefile]",
109 #endif
110 #ifdef TN3270
111 # ifdef AUTHENTICATION
112 	    "[-noasynch] [-noasynctty]\n\t[-noasyncnet] [-r] [-t transcom] ",
113 # else
114 	    "[-noasynch] [-noasynctty] [-noasyncnet] [-r]\n\t[-t transcom]",
115 # endif
116 #else
117 	    "[-r] ",
118 #endif
119 #ifdef	ENCRYPTION
120 	    "[-x] "
121 #endif
122 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
123 	    "[-P policy] [host-name [port]]"
124 #else
125 	    "[host-name [port]]"
126 #endif
127 	);
128 	exit(1);
129 }
130 
131 /*
132  * main.  Parse arguments, invoke the protocol or command parser.
133  */
134 
135 
136 int
137 main(int argc, char *argv[])
138 {
139 	extern char *optarg;
140 	extern int optind;
141 	int ch;
142 	char *user;
143 #ifdef	FORWARD
144 	extern int forward_flags;
145 #endif	/* FORWARD */
146 
147 	tninit();		/* Clear out things */
148 
149 	TerminalSaveState();
150 
151 	if ((prompt = strrchr(argv[0], '/')) != NULL)
152 		++prompt;
153 	else
154 		prompt = argv[0];
155 
156 	user = NULL;
157 
158 	rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
159 	autologin = -1;
160 
161 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
162 #define IPSECOPT	"P:"
163 #else
164 #define IPSECOPT
165 #endif
166 	while ((ch = getopt(argc, argv, "468EKLNS:X:acde:fFk:l:n:rt:x"
167 			IPSECOPT)) != -1) {
168 #undef IPSECOPT
169 		switch(ch) {
170 		case '4':
171 			family = AF_INET;
172 			break;
173 		case '6':
174 			family = AF_INET6;
175 			break;
176 		case '8':
177 			eight = 3;	/* binary output and input */
178 			break;
179 		case 'E':
180 			rlogin = escape = _POSIX_VDISABLE;
181 			break;
182 		case 'K':
183 #ifdef	AUTHENTICATION
184 			autologin = 0;
185 #endif
186 			break;
187 		case 'L':
188 			eight |= 2;	/* binary output only */
189 			break;
190 		case 'N':
191 			doaddrlookup = 0;
192 			break;
193 		case 'S':
194 		    {
195 			fprintf(stderr,
196 			   "%s: Warning: -S ignored, no parsetos() support.\n",
197 								prompt);
198 		    }
199 			break;
200 		case 'X':
201 #ifdef	AUTHENTICATION
202 			auth_disable_name(optarg);
203 #endif
204 			break;
205 		case 'a':
206 			autologin = 1;
207 			break;
208 		case 'c':
209 			skiprc = 1;
210 			break;
211 		case 'd':
212 			debug = 1;
213 			break;
214 		case 'e':
215 			set_escape_char(optarg);
216 			break;
217 		case 'f':
218 #if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
219 			if (forward_flags & OPTS_FORWARD_CREDS) {
220 			    fprintf(stderr,
221 				    "%s: Only one of -f and -F allowed.\n",
222 				    prompt);
223 			    usage();
224 			}
225 			forward_flags |= OPTS_FORWARD_CREDS;
226 #else
227 			fprintf(stderr,
228 			 "%s: Warning: -f ignored, no Kerberos V5 support.\n",
229 				prompt);
230 #endif
231 			break;
232 		case 'F':
233 #if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
234 			if (forward_flags & OPTS_FORWARD_CREDS) {
235 			    fprintf(stderr,
236 				    "%s: Only one of -f and -F allowed.\n",
237 				    prompt);
238 			    usage();
239 			}
240 			forward_flags |= OPTS_FORWARD_CREDS;
241 			forward_flags |= OPTS_FORWARDABLE_CREDS;
242 #else
243 			fprintf(stderr,
244 			 "%s: Warning: -F ignored, no Kerberos V5 support.\n",
245 				prompt);
246 #endif
247 			break;
248 		case 'k':
249 #if defined(AUTHENTICATION) && defined(KRB4)
250 		    {
251 			extern char *dest_realm, dst_realm_buf[], dst_realm_sz;
252 			dest_realm = dst_realm_buf;
253 			(void)strlcpy(dest_realm, optarg, dst_realm_sz);
254 		    }
255 #else
256 			fprintf(stderr,
257 			   "%s: Warning: -k ignored, no Kerberos V4 support.\n",
258 								prompt);
259 #endif
260 			break;
261 		case 'l':
262 			if(autologin == 0) {
263 				autologin = -1;
264 			}
265 			user = optarg;
266 			break;
267 		case 'n':
268 #ifdef TN3270
269 			/* distinguish between "-n oasynch" and "-noasynch" */
270 			if (argv[optind - 1][0] == '-' && argv[optind - 1][1]
271 			    == 'n' && argv[optind - 1][2] == 'o') {
272 				if (!strcmp(optarg, "oasynch")) {
273 					noasynchtty = 1;
274 					noasynchnet = 1;
275 				} else if (!strcmp(optarg, "oasynchtty"))
276 					noasynchtty = 1;
277 				else if (!strcmp(optarg, "oasynchnet"))
278 					noasynchnet = 1;
279 			} else
280 #endif	/* defined(TN3270) */
281 				SetNetTrace(optarg);
282 			break;
283 		case 'r':
284 			rlogin = '~';
285 			break;
286 		case 't':
287 #ifdef TN3270
288 			(void)strlcpy(tline, optarg, sizeof(tline));
289 			transcom = tline;
290 #else
291 			fprintf(stderr,
292 			   "%s: Warning: -t ignored, no TN3270 support.\n",
293 								prompt);
294 #endif
295 			break;
296 		case 'x':
297 #ifdef	ENCRYPTION
298 			encrypt_auto(1);
299 			decrypt_auto(1);
300 #else	/* ENCRYPTION */
301 			fprintf(stderr,
302 			    "%s: Warning: -x ignored, no ENCRYPT support.\n",
303 								prompt);
304 #endif	/* ENCRYPTION */
305 			break;
306 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
307 		case 'P':
308 			if (!strncmp("in", optarg, 2))
309 				ipsec_policy_in = strdup(optarg);
310 			else if (!strncmp("out", optarg, 3))
311 				ipsec_policy_out = strdup(optarg);
312 			else
313 				usage();
314 			break;
315 #endif
316 		case '?':
317 		default:
318 			usage();
319 			/* NOTREACHED */
320 		}
321 	}
322 
323 	if (autologin == -1) {		/* esc@magic.fi; force  */
324 #if defined(AUTHENTICATION)
325 		autologin = 1;
326 #endif
327 #if defined(ENCRYPTION)
328 		encrypt_auto(1);
329 		decrypt_auto(1);
330 #endif
331 	}
332 
333 	if (autologin == -1)
334 		autologin = (rlogin == _POSIX_VDISABLE) ? 0 : 1;
335 
336 	argc -= optind;
337 	argv += optind;
338 
339 	if (argc) {
340 		char *args[7], **argp = args;
341 #ifdef __GNUC__
342 		(void) &argp;	/* avoid longjmp clobbering */
343 #endif
344 
345 		if (argc > 2)
346 			usage();
347 		*argp++ = prompt;
348 		if (user) {
349 			*argp++ = "-l";
350 			*argp++ = user;
351 		}
352 		*argp++ = argv[0];		/* host */
353 		if (argc > 1)
354 			*argp++ = argv[1];	/* port */
355 		*argp = 0;
356 
357 		if (setjmp(toplevel) != 0)
358 			Exit(0);
359 		if (tn(argp - args, args) == 1)
360 			return (0);
361 		else
362 			return (1);
363 	}
364 	(void)setjmp(toplevel);
365 	for (;;) {
366 #ifdef TN3270
367 		if (shell_active)
368 			shell_continue();
369 		else
370 #endif
371 			command(1, 0, 0);
372 	}
373 }
374