+ register int ch;
+ extern char *optarg;
+ extern int optind;
+#if defined(IPPROTO_IP) && defined(IP_TOS)
+ int tos = -1;
+#endif
+
+ pfrontp = pbackp = ptyobuf;
+ netip = netibuf;
+ nfrontp = nbackp = netobuf;
+#if defined(ENCRYPTION)
+ nclearto = 0;
+#endif
+
+ progname = *argv;
+
+#ifdef CRAY
+ /*
+ * Get number of pty's before trying to process options,
+ * which may include changing pty range.
+ */
+ highpty = getnpty();
+#endif /* CRAY */
+
+ while ((ch = getopt(argc, argv, "d:a:e:klhnr:u:UI:D:B:sS:a:X:")) != EOF) {
+ switch(ch) {
+
+#ifdef AUTHENTICATION
+ case 'a':
+ /*
+ * Check for required authentication level
+ */
+ if (strcmp(optarg, "debug") == 0) {
+ extern int auth_debug_mode;
+ auth_debug_mode = 1;
+ } else if (strcasecmp(optarg, "none") == 0) {
+ auth_level = 0;
+ } else if (strcasecmp(optarg, "other") == 0) {
+ auth_level = AUTH_OTHER;
+ } else if (strcasecmp(optarg, "user") == 0) {
+ auth_level = AUTH_USER;
+ } else if (strcasecmp(optarg, "valid") == 0) {
+ auth_level = AUTH_VALID;
+ } else if (strcasecmp(optarg, "off") == 0) {
+ /*
+ * This hack turns off authentication
+ */
+ auth_level = -1;
+ } else {
+ fprintf(stderr,
+ "telnetd: unknown authorization level for -a\n");
+ }
+ break;
+#endif /* AUTHENTICATION */
+
+#ifdef BFTPDAEMON
+ case 'B':
+ bftpd++;
+ break;
+#endif /* BFTPDAEMON */
+
+ case 'd':
+ if (strcmp(optarg, "ebug") == 0) {
+ debug++;
+ break;
+ }
+ usage();
+ /* NOTREACHED */
+ break;
+
+#ifdef DIAGNOSTICS
+ case 'D':
+ /*
+ * Check for desired diagnostics capabilities.
+ */
+ if (!strcmp(optarg, "report")) {
+ diagnostic |= TD_REPORT|TD_OPTIONS;
+ } else if (!strcmp(optarg, "exercise")) {
+ diagnostic |= TD_EXERCISE;
+ } else if (!strcmp(optarg, "netdata")) {
+ diagnostic |= TD_NETDATA;
+ } else if (!strcmp(optarg, "ptydata")) {
+ diagnostic |= TD_PTYDATA;
+ } else if (!strcmp(optarg, "options")) {
+ diagnostic |= TD_OPTIONS;
+ } else {
+ usage();
+ /* NOT REACHED */
+ }
+ break;
+#endif /* DIAGNOSTICS */
+
+#ifdef ENCRYPTION
+ case 'e':
+ if (strcmp(optarg, "debug") == 0) {
+ extern int encrypt_debug_mode;
+ encrypt_debug_mode = 1;
+ break;
+ }
+ usage();
+ /* NOTREACHED */
+ break;
+#endif /* ENCRYPTION */
+
+ case 'h':
+ hostinfo = 0;
+ break;
+
+#if defined(CRAY) && defined(NEWINIT)
+ case 'I':
+ {
+ extern char *gen_id;
+ gen_id = optarg;
+ break;
+ }
+#endif /* defined(CRAY) && defined(NEWINIT) */
+
+#ifdef LINEMODE
+ case 'l':
+ alwayslinemode = 1;
+ break;
+#endif /* LINEMODE */
+
+ case 'k':
+#if defined(LINEMODE) && defined(KLUDGELINEMODE)
+ lmodetype = NO_AUTOKLUDGE;
+#else
+ /* ignore -k option if built without kludge linemode */
+#endif /* defined(LINEMODE) && defined(KLUDGELINEMODE) */
+ break;
+
+ case 'n':
+ keepalive = 0;
+ break;
+
+#ifdef CRAY
+ case 'r':
+ {
+ char *strchr();
+ char *c;
+
+ /*
+ * Allow the specification of alterations
+ * to the pty search range. It is legal to
+ * specify only one, and not change the
+ * other from its default.
+ */
+ c = strchr(optarg, '-');
+ if (c) {
+ *c++ = '\0';
+ highpty = atoi(c);
+ }
+ if (*optarg != '\0')
+ lowpty = atoi(optarg);
+ if ((lowpty > highpty) || (lowpty < 0) ||
+ (highpty > 32767)) {
+ usage();
+ /* NOT REACHED */
+ }
+ break;
+ }
+#endif /* CRAY */
+
+#ifdef SecurID
+ case 's':
+ /* SecurID required */
+ require_SecurID = 1;
+ break;
+#endif /* SecurID */
+ case 'S':
+#ifdef HAS_GETTOS
+ if ((tos = parsetos(optarg, "tcp")) < 0)
+ fprintf(stderr, "%s%s%s\n",
+ "telnetd: Bad TOS argument '", optarg,
+ "'; will try to use default TOS");
+#else
+ fprintf(stderr, "%s%s\n", "TOS option unavailable; ",
+ "-S flag not supported\n");
+#endif
+ break;
+
+ case 'u':
+ utmp_len = atoi(optarg);
+ break;
+
+ case 'U':
+ registerd_host_only = 1;
+ break;
+
+#ifdef AUTHENTICATION
+ case 'X':
+ /*
+ * Check for invalid authentication types
+ */
+ auth_disable_name(optarg);
+ break;
+#endif /* AUTHENTICATION */
+
+ default:
+ fprintf(stderr, "telnetd: %s: unknown option\n", ch);
+ /* FALLTHROUGH */
+ case '?':
+ usage();
+ /* NOTREACHED */
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (debug) {
+ int s, ns, foo;
+ struct servent *sp;
+ static struct sockaddr_in sin = { AF_INET };
+
+ if (argc > 1) {
+ usage();
+ /* NOT REACHED */
+ } else if (argc == 1) {
+ if (sp = getservbyname(*argv, "tcp")) {
+ sin.sin_port = sp->s_port;
+ } else {
+ sin.sin_port = atoi(*argv);
+ if ((int)sin.sin_port <= 0) {
+ fprintf(stderr, "telnetd: %s: bad port #\n", *argv);
+ usage();
+ /* NOT REACHED */
+ }
+ sin.sin_port = htons((u_short)sin.sin_port);
+ }
+ } else {
+ sp = getservbyname("telnet", "tcp");
+ if (sp == 0) {
+ fprintf(stderr, "telnetd: tcp/telnet: unknown service\n");
+ exit(1);
+ }
+ sin.sin_port = sp->s_port;
+ }
+
+ s = socket(AF_INET, SOCK_STREAM, 0);
+ if (s < 0) {
+ perror("telnetd: socket");;
+ exit(1);
+ }
+ (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
+ (char *)&on, sizeof(on));
+ if (bind(s, (struct sockaddr *)&sin, sizeof sin) < 0) {
+ perror("bind");
+ exit(1);
+ }
+ if (listen(s, 1) < 0) {
+ perror("listen");
+ exit(1);
+ }
+ foo = sizeof sin;
+ ns = accept(s, (struct sockaddr *)&sin, &foo);
+ if (ns < 0) {
+ perror("accept");
+ exit(1);
+ }
+ (void) dup2(ns, 0);
+ (void) close(ns);
+ (void) close(s);
+#ifdef convex
+ } else if (argc == 1) {
+ ; /* VOID*/ /* Just ignore the host/port name */
+#endif
+ } else if (argc > 0) {
+ usage();
+ /* NOT REACHED */
+ }
+
+#if defined(_SC_CRAY_SECURE_SYS)
+ secflag = sysconf(_SC_CRAY_SECURE_SYS);
+
+ /*
+ * Get socket's security label
+ */
+ if (secflag) {
+ int sz = sizeof(ss);
+
+ bzero((char *)&dv, sizeof(dv));
+
+ if (getsysv(&sysv, sizeof(struct sysv)) != 0) {
+ perror("getsysv");
+ exit(1);
+ }
+
+ /*
+ * Get socket security label and set device values
+ * {security label to be set on ttyp device}
+ */
+ if (getsockopt(0, SOL_SOCKET, SO_SECURITY,
+ (char *)&ss, &sz) >= 0) {
+
+ dv.dv_actlvl = ss.ss_slevel;
+ dv.dv_actcmp = ss.ss_compart;
+ dv.dv_minlvl = ss.ss_minlvl;
+ dv.dv_maxlvl = ss.ss_maxlvl;
+ dv.dv_valcmp = ss.ss_maxcmp;
+ }
+ }
+#endif /* _SC_CRAY_SECURE_SYS */