-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
- * Reserved. This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.0 (the 'License'). You may not use this file
- * except in compliance with the License. Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
- *
- * @APPLE_LICENSE_HEADER_END@
- */
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*/
#ifndef lint
-static char copyright[] =
+static const char copyright[] =
"@(#) Copyright (c) 1989, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)telnetd.c 8.4 (Berkeley) 5/30/95";
+#if 0
+static char sccsid[] = "@(#)telnetd.c 8.2 (Berkeley) 12/15/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD: src/libexec/telnetd/telnetd.c,v 1.28 2001/07/20 15:14:03 ru Exp $";
#endif /* not lint */
#include "telnetd.h"
# undef _SC_CRAY_SECURE_SYS
#endif
+#include <err.h>
+#include <arpa/inet.h>
+#include <util.h>
+#include <sys/mman.h>
+#include <paths.h>
+#include <utmp.h>
+#include <sys/types.h>
+
#if defined(_SC_CRAY_SECURE_SYS)
#include <sys/sysv.h>
#include <sys/secdev.h>
#include <sys/secparm.h>
#include <sys/usrv.h>
# endif /* SO_SEC_MULTI */
+
+/* wrapper for KAME-special getnameinfo() */
+#ifndef NI_WITHSCOPEID
+#define NI_WITHSCOPEID 0
+#endif
+
int secflag;
char tty_dev[16];
struct secdev dv;
int require_SecurID = 0;
#endif
-extern int utmp_len;
+char remote_hostname[MAXHOSTNAMELEN];
+int utmp_len = sizeof(remote_hostname) - 1;
int registerd_host_only = 0;
#ifdef STREAMSPTY
/*
* Because of the way ptyibuf is used with streams messages, we need
- * ptyibuf+1 to be on a full-word boundary. The following wierdness
+ * ptyibuf+1 to be on a full-word boundary. The following weirdness
* is simply to make that happen.
*/
long ptyibufbuf[BUFSIZ/sizeof(long)+1];
int debug = 0;
int keepalive = 1;
-char *progname;
+char *altlogin;
+void doit __P((struct sockaddr *));
+int terminaltypeok __P((char *));
+void startslave __P((char *, int, char *));
extern void usage P((void));
-void doit(struct sockaddr_in *);
-int terminaltypeok(char *);
-void startslave(char *, int, char *);
-
/*
* The string to pass to getopt(). We do it this way so
* passed off to getopt().
*/
char valid_opts[] = {
- 'd', ':', 'h', 'k', 'n', 'S', ':', 'u', ':', 'U',
+ 'd', ':', 'h', 'k', 'n', 'p', ':', 'S', ':', 'u', ':', 'U',
+ '4', '6',
#ifdef AUTHENTICATION
'a', ':', 'X', ':',
#endif
#ifdef DIAGNOSTICS
'D', ':',
#endif
-#ifdef ENCRYPTION
- 'e', ':',
-#endif
#if defined(CRAY) && defined(NEWINIT)
'I', ':',
#endif
'\0'
};
+int family = AF_INET;
+
int
main(argc, argv)
char *argv[];
{
- struct sockaddr_in from;
+ struct sockaddr_storage from;
int on = 1, fromlen;
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;
-#ifdef ENCRYPTION
- nclearto = 0;
-#endif /* ENCRYPTION */
- progname = *argv;
+ /*
+ * This initialization causes linemode to default to a configuration
+ * that works on all telnet clients, including the FreeBSD client.
+ * This is not quite the same as the telnet client issuing a "mode
+ * character" command, but has most of the same benefits, and is
+ * preferable since some clients (like usofts) don't have the
+ * mode character command anyway and linemode breaks things.
+ * The most notable symptom of fix is that csh "set filec" operations
+ * like <ESC> (filename completion) and ^D (choices) keys now work
+ * in telnet sessions and can be used more than once on the same line.
+ * CR/LF handling is also corrected in some termio modes. This
+ * change resolves problem reports bin/771 and bin/1037.
+ */
+
+ linemode=1; /*Default to mode that works on bulk of clients*/
#ifdef CRAY
/*
highpty = getnpty();
#endif /* CRAY */
- while ((ch = getopt(argc, argv, valid_opts)) != EOF) {
+ while ((ch = getopt(argc, argv, valid_opts)) != -1) {
switch(ch) {
#ifdef AUTHENTICATION
*/
auth_level = -1;
} else {
- fprintf(stderr,
- "telnetd: unknown authorization level for -a\n");
+ warnx("unknown authorization level for -a");
}
break;
#endif /* AUTHENTICATION */
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;
keepalive = 0;
break;
+ case 'p':
+ altlogin = optarg;
+ break;
+
#ifdef CRAY
case 'r':
{
case 'S':
#ifdef HAS_GETTOS
if ((tos = parsetos(optarg, "tcp")) < 0)
- fprintf(stderr, "%s%s%s\n",
- "telnetd: Bad TOS argument '", optarg,
+ warnx("%s%s%s",
+ "bad TOS argument '", optarg,
"'; will try to use default TOS");
#else
- fprintf(stderr, "%s%s\n", "TOS option unavailable; ",
- "-S flag not supported\n");
+ warnx("TOS option unavailable; -S flag not supported");
#endif
break;
case 'u':
utmp_len = atoi(optarg);
+ if (utmp_len < 0)
+ utmp_len = -utmp_len;
+ if (utmp_len >= sizeof(remote_hostname))
+ utmp_len = sizeof(remote_hostname) - 1;
break;
case 'U':
break;
#endif /* AUTHENTICATION */
+ case '4':
+ family = AF_INET;
+ break;
+
+#ifdef INET6
+ case '6':
+ family = AF_INET6;
+ break;
+#endif
+
default:
- fprintf(stderr, "telnetd: %c: unknown option\n", ch);
+ warnx("%c: unknown option", ch);
/* FALLTHROUGH */
case '?':
usage();
argv += optind;
if (debug) {
- int s, ns, foo;
- struct servent *sp;
- static struct sockaddr_in sin = { AF_INET };
+ int s, ns, foo, error;
+ char *service = "telnet";
+ struct addrinfo hints, *res;
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;
+ } else if (argc == 1)
+ service = *argv;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_family = family;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = 0;
+ error = getaddrinfo(NULL, service, &hints, &res);
+
+ if (error) {
+ errx(1, "tcp/%s: %s\n", service, gai_strerror(error));
+ if (error == EAI_SYSTEM)
+ errx(1, "tcp/%s: %s\n", service, strerror(errno));
+ usage();
}
- s = socket(AF_INET, SOCK_STREAM, 0);
- if (s < 0) {
- perror("telnetd: socket");;
- exit(1);
- }
+ s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (s < 0)
+ err(1, "socket");
(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);
- }
+ if (bind(s, res->ai_addr, res->ai_addrlen) < 0)
+ err(1, "bind");
+ if (listen(s, 1) < 0)
+ err(1, "listen");
+ foo = res->ai_addrlen;
+ ns = accept(s, res->ai_addr, &foo);
+ if (ns < 0)
+ err(1, "accept");
(void) dup2(ns, 0);
(void) close(ns);
(void) close(s);
int szi = sizeof(int);
#endif /* SO_SEC_MULTI */
- memset((char *)&dv, 0, sizeof(dv));
+ bzero((char *)&dv, sizeof(dv));
- if (getsysv(&sysv, sizeof(struct sysv)) != 0) {
- perror("getsysv");
- exit(1);
- }
+ if (getsysv(&sysv, sizeof(struct sysv)) != 0)
+ err(1, "getsysv");
/*
* Get socket security label and set device values
(char *)&ss, &szss) < 0) ||
(getsockopt(0, SOL_SOCKET, SO_SEC_MULTI,
(char *)&sock_multi, &szi) < 0)) {
- perror("getsockopt");
- exit(1);
+ err(1, "getsockopt");
} else {
dv.dv_actlvl = ss.ss_actlabel.lt_level;
dv.dv_actcmp = ss.ss_actlabel.lt_compart;
openlog("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON);
fromlen = sizeof (from);
if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
- fprintf(stderr, "%s: ", progname);
- perror("getpeername");
+ warn("getpeername");
_exit(1);
}
if (keepalive &&
}
#if defined(IPPROTO_IP) && defined(IP_TOS)
- {
+ if (from.ss_family == AF_INET) {
# if defined(HAS_GETTOS)
struct tosent *tp;
if (tos < 0 && (tp = gettosbyname("telnet", "tcp")))
}
#endif /* defined(IPPROTO_IP) && defined(IP_TOS) */
net = 0;
- doit(&from);
+ doit((struct sockaddr *)&from);
/* NOTREACHED */
- exit(0);
+ return(0);
} /* end of main */
void
usage()
{
- fprintf(stderr, "Usage: telnetd");
+ fprintf(stderr, "usage: telnetd");
#ifdef AUTHENTICATION
fprintf(stderr, " [-a (debug|other|user|valid|off|none)]\n\t");
#endif
}
#endif
-#ifdef ENCRYPTION
- send_will(TELOPT_ENCRYPT, 1);
-#endif /* ENCRYPTION */
send_do(TELOPT_TTYPE, 1);
send_do(TELOPT_TSPEED, 1);
send_do(TELOPT_XDISPLOC, 1);
send_do(TELOPT_NEW_ENVIRON, 1);
send_do(TELOPT_OLD_ENVIRON, 1);
while (
-#ifdef ENCRYPTION
- his_do_dont_is_changing(TELOPT_ENCRYPT) ||
-#endif /* ENCRYPTION */
his_will_wont_is_changing(TELOPT_TTYPE) ||
his_will_wont_is_changing(TELOPT_TSPEED) ||
his_will_wont_is_changing(TELOPT_XDISPLOC) ||
his_will_wont_is_changing(TELOPT_OLD_ENVIRON)) {
ttloop();
}
-#ifdef ENCRYPTION
- /*
- * Wait for the negotiation of what type of encryption we can
- * send with. If autoencrypt is not set, this will just return.
- */
- if (his_state_is_will(TELOPT_ENCRYPT)) {
- encrypt_wait();
- }
-#endif /* ENCRYPTION */
if (his_state_is_will(TELOPT_TSPEED)) {
static unsigned char sb[] =
{ IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE };
- memmove(nfrontp, sb, sizeof sb);
- nfrontp += sizeof sb;
- DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2););
+ output_datalen(sb, sizeof sb);
}
if (his_state_is_will(TELOPT_XDISPLOC)) {
static unsigned char sb[] =
{ IAC, SB, TELOPT_XDISPLOC, TELQUAL_SEND, IAC, SE };
- memmove(nfrontp, sb, sizeof sb);
- nfrontp += sizeof sb;
- DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2););
+ output_datalen(sb, sizeof sb);
}
if (his_state_is_will(TELOPT_NEW_ENVIRON)) {
static unsigned char sb[] =
{ IAC, SB, TELOPT_NEW_ENVIRON, TELQUAL_SEND, IAC, SE };
- memmove(nfrontp, sb, sizeof sb);
- nfrontp += sizeof sb;
- DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2););
+ output_datalen(sb, sizeof sb);
}
else if (his_state_is_will(TELOPT_OLD_ENVIRON)) {
static unsigned char sb[] =
{ IAC, SB, TELOPT_OLD_ENVIRON, TELQUAL_SEND, IAC, SE };
- memmove(nfrontp, sb, sizeof sb);
- nfrontp += sizeof sb;
- DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2););
+ output_datalen(sb, sizeof sb);
}
if (his_state_is_will(TELOPT_TTYPE)) {
- memmove(nfrontp, ttytype_sbbuf, sizeof ttytype_sbbuf);
- nfrontp += sizeof ttytype_sbbuf;
- DIAG(TD_OPTIONS, printsub('>', ttytype_sbbuf + 2,
- sizeof ttytype_sbbuf - 2););
+ output_datalen(ttytype_sbbuf, sizeof ttytype_sbbuf);
}
if (his_state_is_will(TELOPT_TSPEED)) {
while (sequenceIs(tspeedsubopt, baseline))
* we have to just go with what we (might) have already gotten.
*/
if (his_state_is_will(TELOPT_TTYPE) && !terminaltypeok(terminaltype)) {
- (void) strncpy(first, terminaltype, sizeof(first));
+ (void) strncpy(first, terminaltype, sizeof(first)-1);
+ first[sizeof(first)-1] = '\0';
for(;;) {
/*
* Save the unknown name, and request the next name.
*/
- (void) strncpy(last, terminaltype, sizeof(last));
+ (void) strncpy(last, terminaltype, sizeof(last)-1);
+ last[sizeof(last)-1] = '\0';
_gettermname();
if (terminaltypeok(terminaltype))
break;
* the start of the list.
*/
_gettermname();
- if (strncmp(first, terminaltype, sizeof(first)) != 0)
- (void) strncpy(terminaltype, first, sizeof(first));
+ if (strncmp(first, terminaltype, sizeof(first)) != 0) {
+ (void) strncpy(terminaltype, first, sizeof(terminaltype)-1);
+ terminaltype[sizeof(terminaltype)-1] = '\0';
+ }
break;
}
}
if (his_state_is_wont(TELOPT_TTYPE))
return;
settimer(baseline);
- memmove(nfrontp, ttytype_sbbuf, sizeof ttytype_sbbuf);
- nfrontp += sizeof ttytype_sbbuf;
- DIAG(TD_OPTIONS, printsub('>', ttytype_sbbuf + 2,
- sizeof ttytype_sbbuf - 2););
+ output_datalen(ttytype_sbbuf, sizeof ttytype_sbbuf);
while (sequenceIs(ttypesubopt, baseline))
ttloop();
}
}
#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
+#define MAXHOSTNAMELEN 256
#endif /* MAXHOSTNAMELEN */
char *hostname;
char host_name[MAXHOSTNAMELEN];
-char remote_host_name[MAXHOSTNAMELEN];
-#ifndef convex
-extern void telnet P((int, int));
-#else
extern void telnet P((int, int, char *));
-#endif
+int level;
+char user_name[256];
/*
* Get a pty, scan input lines.
*/
-void
+ void
doit(who)
- struct sockaddr_in *who;
+ struct sockaddr *who;
{
- char *host = NULL, *inet_ntoa();
+ char *host = NULL;
+ int err;
struct hostent *hp;
- int level;
int ptynum;
- char user_name[256];
/*
* Find an available pty to use.
#else
for (;;) {
char *lp;
- extern char *line, *getpty();
if ((lp = getpty()) == NULL)
fatal(net, "Out of ptys");
- if ((pty = open(lp, O_RDWR)) >= 0) {
- strncpy(line,lp, sizeof(line)-1);
- line[sizeof(line)-1] = '\0';
+ if ((pty = open(lp, 2)) >= 0) {
+ strlcpy(line,lp,sizeof(line));
line[5] = 't';
break;
}
if (secflag) {
char slave_dev[16];
- sprintf(tty_dev, "/dev/pty/%03d", ptynum);
+ sprintf(tty_dev, "%spty/%03d", _PATH_DEV, ptynum);
if (setdevs(tty_dev, &dv) < 0)
fatal(net, "cannot set pty security");
- sprintf(slave_dev, "/dev/ttyp%03d", ptynum);
+ sprintf(slave_dev, "%sp%03d", _PATH_TTY, ptynum);
if (setdevs(slave_dev, &dv) < 0)
fatal(net, "cannot set tty security");
}
#endif /* _SC_CRAY_SECURE_SYS */
- /* get name of connected client */
- hp = gethostbyaddr((char *)&who->sin_addr, sizeof (struct in_addr),
- who->sin_family);
-
- if (hp == NULL && registerd_host_only) {
- fatal(net, "Couldn't resolve your address into a host name.\r\n\
- Please contact your net administrator");
- } else if (hp &&
- (strlen(hp->h_name) <= (unsigned int)((utmp_len < 0) ? -utmp_len
- : utmp_len))) {
- host = hp->h_name;
- } else {
- host = inet_ntoa(who->sin_addr);
- }
- /*
- * We must make a copy because Kerberos is probably going
- * to also do a gethost* and overwrite the static data...
- */
- strncpy(remote_host_name, host, sizeof(remote_host_name)-1);
- remote_host_name[sizeof(remote_host_name)-1] = 0;
- host = remote_host_name;
-
- (void) gethostname(host_name, sizeof (host_name));
+ /* get name of connected client */
+ hp = gethostbyaddr((char *)&((struct sockaddr_in *)who)->sin_addr, sizeof (struct in_addr),
+ ((struct sockaddr_in *)who)->sin_family);
+
+ if (hp == NULL && registerd_host_only) {
+ fatal(net, "Couldn't resolve your address into a host name.\r\n\
+ Please contact your net administrator");
+ } else if (hp &&
+ (strlen(hp->h_name) <= (unsigned int)((utmp_len < 0) ? -utmp_len
+ : utmp_len))) {
+ host = hp->h_name;
+ } else {
+ host = inet_ntoa(((struct sockaddr_in *)who)->sin_addr);
+ }
+ /*
+ * We must make a copy because Kerberos is probably going
+ * to also do a gethost* and overwrite the static data...
+ */
+ strncpy(remote_hostname, host, sizeof(remote_hostname)-1);
+ remote_hostname[sizeof(remote_hostname)-1] = 0;
+ host = remote_hostname;
+
+ (void) gethostname(host_name, sizeof(host_name) - 1);
+ host_name[sizeof(host_name) - 1] = '\0';
hostname = host_name;
-#if defined(AUTHENTICATION) || defined(ENCRYPTION)
- auth_encrypt_init(hostname, host, "TELNETD", 1);
+#if defined(AUTHENTICATION)
+ auth_encrypt_init(hostname, remote_hostname, "TELNETD", 1);
#endif
init_env();
level = getterminaltype(user_name);
setenv("TERM", terminaltype ? terminaltype : "network", 1);
- /*
- * Start up the login process on the slave side of the terminal
- */
-#ifndef convex
- startslave(host, level, user_name);
-
#if defined(_SC_CRAY_SECURE_SYS)
if (secflag) {
if (setulvl(dv.dv_actlvl) < 0)
}
#endif /* _SC_CRAY_SECURE_SYS */
- telnet(net, pty); /* begin server processing */
-#else
- telnet(net, pty, host);
-#endif
+ telnet(net, pty, remote_hostname); /* begin server process */
+
/*NOTREACHED*/
} /* end of doit */
* hand data to telnet receiver finite state machine.
*/
void
-#ifndef convex
-telnet(f, p)
-#else
telnet(f, p, host)
-#endif
int f, p;
-#ifdef convex
char *host;
-#endif
{
int on = 1;
#define TABBUFSIZ 512
char *HE;
char *HN;
char *IM;
+ char *IF;
+ char *if_buf;
+ int if_fd;
+ struct stat statbuf;
+
void netflush();
- int nfd;
/*
* Initialize the slc mapping table.
* mode, which we do not want.
*/
if (his_want_state_is_will(TELOPT_ECHO)) {
- DIAG(TD_OPTIONS,
- {sprintf(nfrontp, "td: simulating recv\r\n");
- nfrontp += strlen(nfrontp);});
+ DIAG(TD_OPTIONS, output_data("td: simulating recv\r\n"));
willoption(TELOPT_ECHO);
}
* side. Set up signal handler now.
*/
if ((int)signal(SIGUSR1, termstat) < 0)
- perror("signal");
+ warn("signal");
else if (ioctl(p, TCSIGME, (char *)SIGUSR1) < 0)
- perror("ioctl:TCSIGME");
+ warn("ioctl:TCSIGME");
/*
* Make processing loop check terminal characteristics early on.
*/
HE = Getstr("he", &cp);
HN = Getstr("hn", &cp);
IM = Getstr("im", &cp);
- if (HN && *HN) {
- (void) strncpy(host_name, HN, sizeof(host_name)-1);
- hostname[sizeof(host_name)-1] = '\0';
- }
+ IF = Getstr("if", &cp);
+ if (HN && *HN)
+ (void) strlcpy(host_name, HN, sizeof(host_name));
+ if (IF && (if_fd = open(IF, O_RDONLY, 000)) != -1)
+ IM = 0;
if (IM == 0)
IM = "";
} else {
edithost(HE, host_name);
if (hostinfo && *IM)
putf(IM, ptyibuf2);
+ else if (IF && if_fd != -1) {
+ fstat (if_fd, &statbuf);
+ if_buf = (char *) mmap (0, statbuf.st_size, PROT_READ,
+ 0, if_fd, 0);
+ putf(if_buf, ptyibuf2);
+ munmap (if_buf, statbuf.st_size);
+ close (if_fd);
+ }
if (pcc)
(void) strncat(ptyibuf2, ptyip, pcc+1);
localstat();
#endif /* LINEMODE */
- DIAG(TD_REPORT,
- {sprintf(nfrontp, "td: Entering processing loop\r\n");
- nfrontp += strlen(nfrontp);});
+ DIAG(TD_REPORT, output_data("td: Entering processing loop\r\n"));
-#ifdef convex
- startslave(host);
-#endif
+ /*
+ * Startup the login process on the slave side of the terminal
+ * now. We delay this until here to insure option negotiation
+ * is complete.
+ */
+ startslave(host, level, user_name);
- nfd = ((f > p) ? f : p) + 1;
for (;;) {
fd_set ibits, obits, xbits;
register int c;
if (!SYNCHing) {
FD_SET(f, &xbits);
}
- if ((c = select(nfd, &ibits, &obits, &xbits,
+ if ((c = select(16, &ibits, &obits, &xbits,
(struct timeval *)0)) < 1) {
if (c == -1) {
if (errno == EINTR) {
netip = netibuf;
}
DIAG((TD_REPORT | TD_NETDATA),
- {sprintf(nfrontp, "td: netread %d chars\r\n", ncc);
- nfrontp += strlen(nfrontp);});
+ output_data("td: netread %d chars\r\n", ncc));
DIAG(TD_NETDATA, printdata("nd", netip, ncc));
}
* royally if we send them urgent
* mode data.
*/
- *nfrontp++ = IAC;
- *nfrontp++ = DM;
+ output_data("%c%c", IAC, DM);
neturg = nfrontp-1; /* off by one XXX */
- DIAG(TD_OPTIONS,
- printoption("td: send IAC", DM));
-
#endif
}
if (his_state_is_will(TELOPT_LFLOW) &&
ptyibuf[0] & TIOCPKT_DOSTOP ? 1 : 0;
if (newflow != flowmode) {
flowmode = newflow;
- (void) sprintf(nfrontp,
- "%c%c%c%c%c%c",
+ output_data("%c%c%c%c%c%c",
IAC, SB, TELOPT_LFLOW,
flowmode ? LFLOW_ON
: LFLOW_OFF,
IAC, SE);
- nfrontp += 6;
- DIAG(TD_OPTIONS, printsub('>',
- (unsigned char *)nfrontp-4,
- 4););
}
}
pcc--;
break;
c = *ptyip++ & 0377, pcc--;
if (c == IAC)
- *nfrontp++ = c;
+ output_data("%c", c);
#if defined(CRAY2) && defined(UNICOS5)
else if (c == '\n' &&
my_state_is_wont(TELOPT_BINARY) && newmap)
- *nfrontp++ = '\r';
+ output_data("\r");
#endif /* defined(CRAY2) && defined(UNICOS5) */
- *nfrontp++ = c;
+ output_data("%c", c);
if ((c == '\r') && (my_state_is_wont(TELOPT_BINARY))) {
if (pcc > 0 && ((*ptyip & 0377) == '\n')) {
- *nfrontp++ = *ptyip++ & 0377;
+ output_data("%c", *ptyip++ & 0377);
pcc--;
} else
- *nfrontp++ = '\0';
+ output_data("%c", '\0');
}
}
#if defined(CRAY2) && defined(UNICOS5)
{
ptyflush(); /* half-hearted */
-#if defined(STREAMSPTY) && defined(TIOCSIGNAL)
- /* Streams PTY style ioctl to post a signal */
- {
- int sig = SIGINT;
- (void) ioctl(pty, TIOCSIGNAL, &sig);
- (void) ioctl(pty, I_FLUSH, FLUSHR);
- }
-#else
#ifdef TCSIG
(void) ioctl(pty, TCSIG, (char *)SIGINT);
#else /* TCSIG */
*pfrontp++ = slctab[SLC_IP].sptr ?
(unsigned char)*slctab[SLC_IP].sptr : '\177';
#endif /* TCSIG */
-#endif
}
/*
return;
}
#endif
- (void) strcpy(nfrontp, "\r\n[Yes]\r\n");
- nfrontp += 9;
+ output_data("\r\n[Yes]\r\n");
}
void