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