dslinux/user/telnetd Makefile authenc.c defs.h ext.h global.c logout.c logout.h logwtmp.c logwtmp.h pathnames.h slc.c state.c sys_term.c telnetd.c telnetd.h termstat.c utility.c

amadeus dslinux_amadeus at user.in-berlin.de
Thu Aug 31 11:32:33 CEST 2006


Update of /cvsroot/dslinux/dslinux/user/telnetd
In directory antilope:/tmp/cvs-serv14346/user/telnetd

Added Files:
	Makefile authenc.c defs.h ext.h global.c logout.c logout.h 
	logwtmp.c logwtmp.h pathnames.h slc.c state.c sys_term.c 
	telnetd.c telnetd.h termstat.c utility.c 
Log Message:
Add some more applications

--- NEW FILE: logout.c ---
/*
 * Copyright (c) 1988, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef EMBED
/*
 * From: @(#)logout.c	8.1 (Berkeley) 6/4/93
 * From: NetBSD: logout.c,v 1.5 1996/05/15 21:42:28 jtc Exp
 */
char rcsid_logout[] = 
  "$Id";
#endif

#include <sys/types.h>
#include <sys/time.h>

#include <fcntl.h>
#include <utmp.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/file.h>
#include "logout.h"

typedef struct utmp UTMP;

int
logout(const char *line)
{
#ifdef UTMP
	int fd, rval;
	UTMP ut;

	if ((fd = open(_PATH_UTMP, O_RDWR, 0)) < 0)
		return(0);
	rval = 0;
	while (read(fd, &ut, sizeof(UTMP)) == sizeof(UTMP)) {
		if (!ut.ut_name[0] || strncmp(ut.ut_line, line, UT_LINESIZE))
			continue;
		ut.ut_type = DEAD_PROCESS;
		bzero(ut.ut_name, UT_NAMESIZE);
		bzero(ut.ut_host, UT_HOSTSIZE);
		(void)time(&ut.ut_time);
		(void)lseek(fd, -(off_t)sizeof(UTMP), L_INCR);
		(void)write(fd, &ut, sizeof(UTMP));
		rval = 1;
	}
	(void)close(fd);
	return(rval);
#else
	return(0);
#endif
}

--- NEW FILE: telnetd.c ---
/*
 * Copyright (c) 1989 Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
[...1253 lines suppressed...]
    /* If there is room, add the yes, otherwise drop it on the floor */
    if ((&netobuf[BUFSIZ] - nfrontp) >= strlen(host_name) + 13) {
	sprintf(nfrontp, "\r\n[%s : yes]\r\n",host_name);
	nfrontp += strlen(nfrontp);
    }
}

void doeof(void) {
    init_termbuf();

#if	defined(LINEMODE) && defined(USE_TERMIO) && (VEOF == VMIN)
    if (!tty_isediting()) {
	extern char oldeofc;
	*pfrontp++ = oldeofc;
	return;
    }
#endif
    *pfrontp++ = slctab[SLC_EOF].sptr ?
	     (unsigned char)*slctab[SLC_EOF].sptr : '\004';
}

--- NEW FILE: state.c ---
/*
 * Copyright (c) 1989 Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
[...1399 lines suppressed...]

#else

#ifndef EMBED
static int envvarok(char *varp) {
    /*
     * Allow only these variables.
     */
    if (!strcmp(varp, "TERM")) return 1;
    if (!strcmp(varp, "DISPLAY")) return 1;
    if (!strcmp(varp, "USER")) return 1;
    if (!strcmp(varp, "LOGNAME")) return 1;
    if (!strcmp(varp, "POSIXLY_CORRECT")) return 1;

    /* optionally syslog(LOG_INFO) here */
    return 0;
}
#endif

#endif

--- NEW FILE: logwtmp.h ---
void logwtmp(const char *_line, const char *name, const char *host);

--- NEW FILE: slc.c ---
/*
 * Copyright (c) 1989 Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef EMBED
/*
 * From: @(#)slc.c	5.7 (Berkeley) 3/1/91
 */
char slc_rcsid[] = 
  "$Id: slc.c,v 1.2 2006-08-31 09:32:30 dslinux_amadeus Exp $";
#endif

#include "telnetd.h"

#ifdef LINEMODE
/*
 * local varibles
 */
static unsigned char *def_slcbuf = (unsigned char *)0;
static int def_slclen = 0;
static int slcchange;	/* change to slc is requested */
static unsigned char *slcptr;	/* pointer into slc buffer */
static unsigned char slcbuf[NSLC*6];	/* buffer for slc negotiation */

/*
 * send_slc
 *
 * Write out the current special characters to the client.
 */
void send_slc(void) {
    int i;

    /*
     * Send out list of triplets of special characters
     * to client.  We only send info on the characters
     * that are currently supported.
     */
    for (i = 1; i <= NSLC; i++) {
	if ((slctab[i].defset.flag & SLC_LEVELBITS) == SLC_NOSUPPORT)
	    continue;
	add_slc((unsigned char)i, slctab[i].current.flag,
		slctab[i].current.val);
    }
}

/*
 * default_slc
 *
 * Set pty special characters to all the defaults.
 */
void default_slc(void) {
    int i;
    for (i = 1; i <= NSLC; i++) {
	slctab[i].current.val = slctab[i].defset.val;
	if (slctab[i].current.val == (cc_t)(_POSIX_VDISABLE)) {
	    slctab[i].current.flag = SLC_NOSUPPORT;
	}
	else {
	    slctab[i].current.flag = slctab[i].defset.flag;
	}
	if (slctab[i].sptr) {
	    *(slctab[i].sptr) = slctab[i].defset.val;
	}
    }
    slcchange = 1;
}

#endif	/* LINEMODE */

/*
 * get_slc_defaults
 *
 * Initialize the slc mapping table.
 */
void get_slc_defaults(void) {
    int i;
    init_termbuf();
    for (i = 1; i <= NSLC; i++) {
	slctab[i].defset.flag = spcset(i, &slctab[i].defset.val, 
				       &slctab[i].sptr);
	slctab[i].current.flag = SLC_NOSUPPORT; 
	slctab[i].current.val = 0; 
    }
}

#ifdef LINEMODE
/*
 * add_slc
 *
 * Add an slc triplet to the slc buffer.
 */
void add_slc(char func, char flag, cc_t val) {
    if ((*slcptr++ = (unsigned char)func) == 0xff) {
	*slcptr++ = 0xff;
    }
    if ((*slcptr++ = (unsigned char)flag) == 0xff) {
		*slcptr++ = 0xff;
    }
    if ((*slcptr++ = (unsigned char)val) == 0xff) {
	*slcptr++ = 0xff;
    }
}

/*
 * start_slc
 *
 * Get ready to process incoming slc's and respond to them.
 *
 * The parameter getit is non-zero if it is necessary to grab a copy
 * of the terminal control structures.
 */
void start_slc(int getit) {
    slcchange = 0;
    if (getit) init_termbuf();
    sprintf(slcbuf, "%c%c%c%c", IAC, SB, TELOPT_LINEMODE, LM_SLC);
    slcptr = slcbuf + 4;
}

/*
 * end_slc
 *
 * Finish up the slc negotiation.  If something to send, then send it.
 */
int end_slc(unsigned char **bufp) {
    int len;
    /*
     * If a change has occured, store the new terminal control
     * structures back to the terminal driver.
     */
    if (slcchange) {
	set_termbuf();
    }

    /*
     * If the pty state has not yet been fully processed and there is a
     * deferred slc request from the client, then do not send any
     * sort of slc negotiation now.  We will respond to the client's
     * request very soon.
     */
    if (def_slcbuf && (terminit() == 0)) {
	return 0;
    }

    if (slcptr > (slcbuf + 4)) {
	if (bufp) {
	    *bufp = &slcbuf[4];
	    return(slcptr - slcbuf - 4);
	} 
	else {
	    sprintf(slcptr, "%c%c", IAC, SE);
	    slcptr += 2;
	    len = slcptr - slcbuf;
	    writenet(slcbuf, len);
	    netflush();  /* force it out immediately */
	}
    }
    return 0;
}

/*
 * process_slc
 *
 * Figure out what to do about the client's slc
 */
void process_slc(unsigned char func, unsigned char flag, cc_t val) {
    register int hislevel, mylevel, ack;

    /*
     * Ensure that we know something about this function
     */
    if (func > NSLC) {
	add_slc(func, SLC_NOSUPPORT, 0);
	return;
    }

    /*
     * Process the special case requests of 0 SLC_DEFAULT 0
     * and 0 SLC_VARIABLE 0.  Be a little forgiving here, don't
     * worry about whether the value is actually 0 or not.
     */
    if (func == 0) {
	if ((flag = flag & SLC_LEVELBITS) == SLC_DEFAULT) {
	    default_slc();
	    send_slc();
	} 
	else if (flag == SLC_VARIABLE) {
	    send_slc();
	}
	return;
    }

    /*
     * Appears to be a function that we know something about.  So
     * get on with it and see what we know.
     */
    
    hislevel = flag & SLC_LEVELBITS;
    mylevel = slctab[func].current.flag & SLC_LEVELBITS;
    ack = flag & SLC_ACK;
    /*
     * ignore the command if:
     * the function value and level are the same as what we already have;
     * or the level is the same and the ack bit is set
     */
    if (hislevel == mylevel && (val == slctab[func].current.val || ack)) {
	return;
    } 
    else if (ack) {
	/*
	 * If we get here, we got an ack, but the levels don't match.
	 * This shouldn't happen.  If it does, it is probably because
	 * we have sent two requests to set a variable without getting
	 * a response between them, and this is the first response.
	 * So, ignore it, and wait for the next response.
	 */
	return;
    } 
    else {
	change_slc(func, flag, val);
    }
}

/*
 * change_slc
 *
 * Process a request to change one of our special characters.
 * Compare client's request with what we are capable of supporting.
 */
void change_slc(char func, char flag, cc_t val) {
    register int hislevel, mylevel;
    
    hislevel = flag & SLC_LEVELBITS;
    mylevel = slctab[func].defset.flag & SLC_LEVELBITS;
    /*
     * If client is setting a function to NOSUPPORT
     * or DEFAULT, then we can easily and directly
     * accomodate the request.
     */
    if (hislevel == SLC_NOSUPPORT) {
	slctab[func].current.flag = flag;
	slctab[func].current.val = (cc_t)_POSIX_VDISABLE;
	flag |= SLC_ACK;
	add_slc(func, flag, val);
	return;
    }
    if (hislevel == SLC_DEFAULT) {
	/*
	 * Special case here.  If client tells us to use
	 * the default on a function we don't support, then
	 * return NOSUPPORT instead of what we may have as a
	 * default level of DEFAULT.
	 */
	if (mylevel == SLC_DEFAULT) {
	    slctab[func].current.flag = SLC_NOSUPPORT;
	} 
	else {
	    slctab[func].current.flag = slctab[func].defset.flag;
	}
	slctab[func].current.val = slctab[func].defset.val;
	add_slc(func, slctab[func].current.flag,
		slctab[func].current.val);
	return;
    }
    
    /*
     * Client wants us to change to a new value or he
     * is telling us that he can't change to our value.
     * Some of the slc's we support and can change,
     * some we do support but can't change,
     * and others we don't support at all.
     * If we can change it then we have a pointer to
     * the place to put the new value, so change it,
     * otherwise, continue the negotiation.
     */
    if (slctab[func].sptr) {
	/*
	 * We can change this one.
	 */
	slctab[func].current.val = val;
	*(slctab[func].sptr) = val;
	slctab[func].current.flag = flag;
	flag |= SLC_ACK;
	slcchange = 1;
	add_slc(func, flag, val);
    } 
    else {
	/*
	 * It is not possible for us to support this
	 * request as he asks.
	 *
	 * If our level is DEFAULT, then just ack whatever was
	 * sent. 
	 *
	 * If he can't change and we can't change,
	 * then degenerate to NOSUPPORT.
	 *
	 * Otherwise we send our level back to him, (CANTCHANGE
	 * or NOSUPPORT) and if CANTCHANGE, send
	 * our value as well.
	 */
	if (mylevel == SLC_DEFAULT) {
	    slctab[func].current.flag = flag;
	    slctab[func].current.val = val;
	    flag |= SLC_ACK;
	} 
	else if (hislevel == SLC_CANTCHANGE && mylevel == SLC_CANTCHANGE) {
	    flag &= ~SLC_LEVELBITS;
	    flag |= SLC_NOSUPPORT;
	    slctab[func].current.flag = flag;
	} 
	else {
	    flag &= ~SLC_LEVELBITS;
	    flag |= mylevel;
	    slctab[func].current.flag = flag;
	    if (mylevel == SLC_CANTCHANGE) {
		slctab[func].current.val = slctab[func].defset.val;
		val = slctab[func].current.val;
	    }
	}
	add_slc(func, flag, val);
    }
}

#if defined(USE_TERMIO) && (VEOF == VMIN)
cc_t oldeofc = '\004';
#endif

/*
 * check_slc
 *
 * Check the special characters in use and notify the client if any have
 * changed.  Only those characters that are capable of being changed are
 * likely to have changed.  If a local change occurs, kick the support level
 * and flags up to the defaults.
 */
void check_slc(void) {
    int i;
    for (i = 1; i <= NSLC; i++) {
#if defined(USE_TERMIO) && (VEOF == VMIN)
	/*
	 * In a perfect world this would be a neat little
	 * function.  But in this world, we should not notify
	 * client of changes to the VEOF char when
	 * ICANON is off, because it is not representing
	 * a special character.
	 */
	if (i == SLC_EOF) {
	    if (!tty_isediting()) continue;
	    else if (slctab[i].sptr) oldeofc = *(slctab[i].sptr);
	}
#endif	/* USE_TERMIO and VEOF==VMIN */

	if (slctab[i].sptr && (*(slctab[i].sptr) != slctab[i].current.val)) {
	    slctab[i].current.val = *(slctab[i].sptr);
	    if (*(slctab[i].sptr) == (cc_t)_POSIX_VDISABLE) {
		slctab[i].current.flag = SLC_NOSUPPORT;
	    }
	    else {
		slctab[i].current.flag = slctab[i].defset.flag;
	    }
	    add_slc((unsigned char)i, slctab[i].current.flag,
		    slctab[i].current.val);
	}
    }
}

/*
 * do_opt_slc
 *
 * Process an slc option buffer.  Defer processing of incoming slc's
 * until after the terminal state has been processed.  Save the first slc
 * request that comes along, but discard all others.
 *
 * ptr points to the beginning of the buffer, len is the length.
 */
void do_opt_slc(unsigned char  *ptr, int len) {
    unsigned char func, flag;
    cc_t val;
    unsigned char *end = ptr + len;

    if (terminit()) {  /* go ahead */
	while (ptr < end) {
	    func = *ptr++;
	    if (ptr >= end) break;
	    flag = *ptr++;
	    if (ptr >= end) break;
	    val = (cc_t)*ptr++;

	    process_slc(func, flag, val);
	    
	}
    } 
    else {
	/*
	 * save this slc buffer if it is the first, otherwise dump
	 * it.
	 */
	if (def_slcbuf == NULL) {
	    def_slclen = len;
	    def_slcbuf = malloc((unsigned)len);
	    if (def_slcbuf == NULL) return;  /* too bad */
	    bcopy(ptr, def_slcbuf, len);
	}
    }
}

/*
 * deferslc
 *
 * Do slc stuff that was deferred.
 */
void deferslc(void) {
    if (def_slcbuf) {
	start_slc(1);
	do_opt_slc(def_slcbuf, def_slclen);
	end_slc(0);
	free(def_slcbuf);
	def_slcbuf = (unsigned char *)0;
	def_slclen = 0;
    }
}

#endif	/* LINEMODE */

--- NEW FILE: Makefile ---

EXEC = telnetd
OBJS = telnetd.o state.o termstat.o slc.o sys_term.o \
	utility.o global.o authenc.o logwtmp.o logout.o

CFLAGS += -DPARANOID_TTYS -DUSE_TERMIO -DKLUDGELINEMODE -D_GNU_SOURCE -Wall

ifdef CONFIG_DEFAULTS_LIBC_UCLIBC
LDLIBS := -lutil $(LDLIBS)
endif

ifdef CONFIG_USER_TELNETD_DOES_NOT_USE_OPENPTY
CFLAGS += -DCONFIG_USER_TELNETD_DOES_NOT_USE_OPENPTY
endif


all: $(EXEC)

$(EXEC): $(OBJS)
	$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBUTIL) $(LDLIBS$(LDLIBS_$@))

romfs:
	$(ROMFSINST) /bin/$(EXEC)
	$(ROMFSINST) -e CONFIG_USER_TELNETD_TELNETD \
		-a "telnet  stream tcp nowait root /bin/telnetd" /etc/inetd.conf

clean:
	-rm -f $(EXEC) *.elf *.gdb *.o

$(OBJS): defs.h ext.h pathnames.h telnetd.h logwtmp.h logout.h


--- NEW FILE: sys_term.c ---
/*
 * Copyright (c) 1989 Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
[...1588 lines suppressed...]
	close(f);
    }
    if (found) {
	f = open(wtmpf, O_WRONLY|O_APPEND);
	if (f >= 0) {
	    SCPYN(wtmp.ut_line, line+5);
	    SCPYN(wtmp.ut_name, "");
	    SCPYN(wtmp.ut_host, "");
	    time(&wtmp.ut_time);
	    write(f, (char *)&wtmp, sizeof(wtmp));
	    close(f);
	}
    }
    chmod(line, 0666);
    chown(line, 0, 0);
    line[strlen("/dev/")] = 'p';
    chmod(line, 0666);
    chown(line, 0, 0);
}  /* end of rmut */
#endif	/* CRAY */

--- NEW FILE: logwtmp.c ---
/*
 * Copyright (c) 1988 The Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <string.h>
#include <unistd.h>
#include <utmp.h>
#include <fcntl.h>
#include <sys/stat.h>

#include "logwtmp.h"

void
logwtmp(const char *line, const char *name, const char *host)
{
#ifdef WTMP
	struct utmp ut;
	struct stat buf;
	int fd;

	if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) < 0)
		return;
	if (fstat(fd, &buf) == 0) {
		ut.ut_pid = getpid();
		ut.ut_type = (name[0] != '\0')? USER_PROCESS : DEAD_PROCESS;
		strncpy(ut.ut_id, "", 2);
		strncpy(ut.ut_line, line, sizeof(ut.ut_line));
		strncpy(ut.ut_name, name, sizeof(ut.ut_name));
		strncpy(ut.ut_host, host, sizeof(ut.ut_host));
		time(&ut.ut_time);
		if (write(fd, &ut, sizeof(struct utmp)) != sizeof(struct utmp))
			ftruncate(fd, buf.st_size);
	}
	close(fd);
#endif
}

--- NEW FILE: telnetd.h ---
/*
 * Copyright (c) 1989 The Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	from: @(#)telnetd.h	5.3 (Berkeley) 3/1/91
 *	$Id: telnetd.h,v 1.2 2006-08-31 09:32:31 dslinux_amadeus Exp $
 */


#include "defs.h"
#include "ext.h"

#ifdef	DIAGNOSTICS
#define	DIAG(a,b)	if (diagnostic & (a)) b
#else
#define	DIAG(a,b)
#endif

/* other external variables */
extern	char **environ;
extern	int errno;


--- NEW FILE: global.c ---
/*
 * Copyright (c) 1989 Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef EMBED
/*
 * From: @(#)global.c	5.2 (Berkeley) 6/1/90
 */
char global_rcsid[] = 
  "$Id: global.c,v 1.2 2006-08-31 09:32:30 dslinux_amadeus Exp $";
#endif

/*
 * Allocate global variables.  
 */

#include "defs.h"
#include "ext.h"

/*
 * Telnet server variable declarations
 */
#define extern
extern char	options[256];
extern char	do_dont_resp[256];
extern char	will_wont_resp[256];
extern int	linemode;	/* linemode on/off */
#ifdef	LINEMODE
extern int	uselinemode;	/* what linemode to use (on/off) */
extern int	editmode;	/* edit modes in use */
extern int	useeditmode;	/* edit modes to use */
extern int	alwayslinemode;	/* command line option */
# ifdef	KLUDGELINEMODE
extern int	lmodetype;	/* Client support for linemode */
# endif	/* KLUDGELINEMODE */
#endif	/* LINEMODE */
extern int	flowmode;	/* current flow control state */
#ifdef DIAGNOSTICS
extern int	diagnostic;	/* telnet diagnostic capabilities */
#endif /* DIAGNOSTICS */
#ifdef BFTPDAEMON
extern int	bftpd;		/* behave as bftp daemon */
#endif /* BFTPDAEMON */
#if	defined(SecurID)
extern int	require_SecurID;
#endif

extern slcfun	slctab[NSLC + 1];	/* slc mapping table */

extern char	*terminaltype;

/*
 * I/O data buffers, pointers, and counters.
 */
extern char	ptyobuf[BUFSIZ+NETSLOP], *pfrontp, *pbackp;

extern char	netibuf[BUFSIZ], *netip;

extern char	netobuf[BUFSIZ+NETSLOP], *nfrontp, *nbackp;
extern char	*neturg;		/* one past last bye of urgent data */

extern int	pcc, ncc;

#if defined(CRAY2) && defined(UNICOS5)
extern int unpcc;  /* characters left unprocessed by CRAY-2 terminal routine */
extern char *unptyip;  /* pointer to remaining characters in buffer */
#endif

extern int	pty, net;
extern int	SYNCHing;		/* we are in TELNET SYNCH mode */

struct _clocks clocks;

--- NEW FILE: logout.h ---
int logout(const char *line);

--- NEW FILE: pathnames.h ---
/*
 * Copyright (c) 1989 The Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	from: @(#)pathnames.h	5.5 (Berkeley) 6/28/90
 *	$Id: pathnames.h,v 1.2 2006-08-31 09:32:30 dslinux_amadeus Exp $
 */

#include <paths.h>

#ifndef _PATH_LOGIN
#define _PATH_LOGIN  "/bin/login"
#endif

--- NEW FILE: defs.h ---
/*
 * Copyright (c) 1989 The Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	from: @(#)defs.h	5.10 (Berkeley) 3/1/91
 *	$Id: defs.h,v 1.2 2006-08-31 09:32:30 dslinux_amadeus Exp $
 */

/*
 * Telnet server defines
 */
#include <sys/types.h>
#include <sys/param.h>

#define ENV_VAR		NEW_ENV_VAR
#define ENV_VALUE	NEW_ENV_VALUE
#define TELOPT_ENVIRON	TELOPT_NEW_ENVIRON

#ifndef	BSD
#define	BSD 43
#endif

#if defined(CRAY) && !defined(LINEMODE)
#define SYSV_TERMIO
#define LINEMODE
#define KLUDGELINEMODE
#define DIAGNOSTICS

#if defined(UNICOS50) && !defined(UNICOS5)
#define UNICOS5
#endif

#if !defined(UNICOS5)
#define BFTPDAEMON
#define HAS_IP_TOS
#endif
#endif /* CRAY */

#if defined(UNICOS5) && !defined(NO_SETSID)
#define NO_SETSID
#endif

#if defined(PRINTOPTIONS) && defined(DIAGNOSTICS)
#define TELOPTS
#define TELCMDS
#define	SLC_NAMES
#endif

#if defined(SYSV_TERMIO) && !defined(USE_TERMIO)
#define USE_TERMIO
#endif

#include <sys/socket.h>
#ifndef	CRAY
#include <sys/wait.h>
#endif	/* CRAY */
#include <fcntl.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/telnet.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <netdb.h>
#include <syslog.h>

#ifndef	LOG_DAEMON
#define	LOG_DAEMON	0
#endif

#ifndef	LOG_ODELAY
#define	LOG_ODELAY	0
#endif

#include <ctype.h>
#include <string.h>

#ifndef	USE_TERMIO
#error "sgtty is way obsolete"
#include <sgtty.h>
#else
#ifdef	SYSV_TERMIO
#include <termio.h>
#else
#include <termios.h>
#endif
#endif

#ifdef	__STDC__
#include <unistd.h>
#endif

#ifndef _POSIX_VDISABLE
#ifdef VDISABLE
#define _POSIX_VDISABLE VDISABLE
#else
#define _POSIX_VDISABLE ((unsigned char)'\377')
#endif
#endif


#ifdef	CRAY
#ifdef	CRAY1
#include <sys/pty.h>
#ifndef FD_ZERO
#include <sys/select.h>
#endif /* FD_ZERO */
#endif	/* CRAY1 */

#include <memory.h>
#endif	/* CRAY */

#if !defined(TIOCSCTTY) && defined(TCSETCTTY)
#define	TIOCSCTTY TCSETCTTY
#endif

#ifndef	FD_SET
#ifndef	HAVE_fd_set
typedef struct fd_set { int fds_bits[1]; } fd_set;
#endif

#define	FD_SET(n, p)	((p)->fds_bits[0] |= (1<<(n)))
#define	FD_CLR(n, p)	((p)->fds_bits[0] &= ~(1<<(n)))
#define	FD_ISSET(n, p)	((p)->fds_bits[0] & (1<<(n)))
#define FD_ZERO(p)	((p)->fds_bits[0] = 0)
#endif	/* FD_SET */

/*
 * I/O data buffers defines
 */
#define	NETSLOP	64
#ifdef CRAY
#undef BUFSIZ
#define BUFSIZ  2048
#endif

#define	NIACCUM(c)	{   *netip++ = c; \
			    ncc++; \
			}

/* clock manipulations */
#define	settimer(x)	(clocks.x = ++clocks.system)
#define	sequenceIs(x,y)	(clocks.x < clocks.y)

/*
 * Linemode support states, in decreasing order of importance
 */
#define REAL_LINEMODE	0x02
#define KLUDGE_LINEMODE	0x01
#define NO_LINEMODE	0x00

/*
 * Structures of information for each special character function.
 */
typedef struct {
	unsigned char flag;		/* the flags for this function */
	cc_t val;		/* the value of the special character */
} slcent, *Slcent;

typedef struct {
	slcent		defset;		/* the default settings */
	slcent		current;	/* the current settings */
	cc_t		*sptr;		/* a pointer to the char in */
					/* system data structures */
} slcfun, *Slcfun;

#ifdef DIAGNOSTICS
/*
 * Diagnostics capabilities
 */
#define	TD_REPORT	0x01	/* Report operations to client */
#define TD_EXERCISE	0x02	/* Exercise client's implementation */
#define TD_NETDATA	0x04	/* Display received data stream */
#define TD_PTYDATA	0x08	/* Display data passed to pty */
#define	TD_OPTIONS	0x10	/* Report just telnet options */
#endif /* DIAGNOSTICS */

/*
 * We keep track of each side of the option negotiation.
 */

#define	MY_STATE_WILL		0x01
#define	MY_WANT_STATE_WILL	0x02
#define	MY_STATE_DO		0x04
#define	MY_WANT_STATE_DO	0x08

/*
 * Macros to check the current state of things
 */

#define	my_state_is_do(opt)		(options[opt]&MY_STATE_DO)
#define	my_state_is_will(opt)		(options[opt]&MY_STATE_WILL)
#define my_want_state_is_do(opt)	(options[opt]&MY_WANT_STATE_DO)
#define my_want_state_is_will(opt)	(options[opt]&MY_WANT_STATE_WILL)

#define	my_state_is_dont(opt)		(!my_state_is_do(opt))
#define	my_state_is_wont(opt)		(!my_state_is_will(opt))
#define my_want_state_is_dont(opt)	(!my_want_state_is_do(opt))
#define my_want_state_is_wont(opt)	(!my_want_state_is_will(opt))

#define	set_my_state_do(opt)		(options[opt] |= MY_STATE_DO)
#define	set_my_state_will(opt)		(options[opt] |= MY_STATE_WILL)
#define	set_my_want_state_do(opt)	(options[opt] |= MY_WANT_STATE_DO)
#define	set_my_want_state_will(opt)	(options[opt] |= MY_WANT_STATE_WILL)

#define	set_my_state_dont(opt)		(options[opt] &= ~MY_STATE_DO)
#define	set_my_state_wont(opt)		(options[opt] &= ~MY_STATE_WILL)
#define	set_my_want_state_dont(opt)	(options[opt] &= ~MY_WANT_STATE_DO)
#define	set_my_want_state_wont(opt)	(options[opt] &= ~MY_WANT_STATE_WILL)

/*
 * Tricky code here.  What we want to know is if the MY_STATE_WILL
 * and MY_WANT_STATE_WILL bits have the same value.  Since the two
 * bits are adjacent, a little arithmatic will show that by adding
 * in the lower bit, the upper bit will be set if the two bits were
 * different, and clear if they were the same.
 */
#define my_will_wont_is_changing(opt) \
			((options[opt]+MY_STATE_WILL) & MY_WANT_STATE_WILL)

#define my_do_dont_is_changing(opt) \
			((options[opt]+MY_STATE_DO) & MY_WANT_STATE_DO)

/*
 * Make everything symetrical
 */

#define	HIS_STATE_WILL			MY_STATE_DO
#define	HIS_WANT_STATE_WILL		MY_WANT_STATE_DO
#define HIS_STATE_DO			MY_STATE_WILL
#define HIS_WANT_STATE_DO		MY_WANT_STATE_WILL

#define	his_state_is_do			my_state_is_will
#define	his_state_is_will		my_state_is_do
#define his_want_state_is_do		my_want_state_is_will
#define his_want_state_is_will		my_want_state_is_do

#define	his_state_is_dont		my_state_is_wont
#define	his_state_is_wont		my_state_is_dont
#define his_want_state_is_dont		my_want_state_is_wont
#define his_want_state_is_wont		my_want_state_is_dont

#define	set_his_state_do		set_my_state_will
#define	set_his_state_will		set_my_state_do
#define	set_his_want_state_do		set_my_want_state_will
#define	set_his_want_state_will		set_my_want_state_do

#define	set_his_state_dont		set_my_state_wont
#define	set_his_state_wont		set_my_state_dont
#define	set_his_want_state_dont		set_my_want_state_wont
#define	set_his_want_state_wont		set_my_want_state_dont

#define his_will_wont_is_changing	my_do_dont_is_changing
#define his_do_dont_is_changing		my_will_wont_is_changing

--- NEW FILE: authenc.c ---
/*-
 * Copyright (c) 1991 The Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted provided
 * that: (1) source distributions retain this entire copyright notice and
 * comment, and (2) distributions including binaries display the following
 * acknowledgement:  ``This product includes software developed by the
 * University of California, Berkeley and its contributors'' in the
 * documentation or other materials provided with the distribution and in
 * all advertising materials mentioning features or use of this software.
 * Neither the name of the University nor the names of its contributors may
 * be used to endorse or promote products derived from this software without
 * specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifndef EMBED
/*
 * From: @(#)authenc.c	5.1 (Berkeley) 3/1/91
 */
char authenc_rcsid[] =
  "$Id: authenc.c,v 1.2 2006-08-31 09:32:30 dslinux_amadeus Exp $";
#endif

#if	defined(ENCRYPT) || defined(AUTHENTICATE)
#include "telnetd.h"
#include <libtelnet/misc.h>

int
net_write(str, len)
    unsigned char *str;
    int len;
{
    if (nfrontp + len < netobuf + BUFSIZ) {
	bcopy((void *)str, (void *)nfrontp, len);
	nfrontp += len;
	return(len);
    }
    return(0);
}

void
net_encrypt()
{
#if	defined(ENCRYPT)
    char *s = (nclearto > nbackp) ? nclearto : nbackp;
    if (s < nfrontp && encrypt_output) {
	(*encrypt_output)((unsigned char *)s, nfrontp - s);
    }
    nclearto = nfrontp;
#endif
}

int
telnet_spin()
{
    ttloop();
    return(0);
}

char *
telnet_getenv(val)
    char *val;
{
    extern char *getenv();
    return(getenv(val));
}

char *
telnet_gets(prompt, result, length, echo)
    char *prompt;
    char *result;
    int length;
    int echo;
{
    return((char *)0);
}
#endif

--- NEW FILE: utility.c ---
/*
 * Copyright (c) 1989 Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
[...1194 lines suppressed...]
			sprintf(nfrontp, "%02x", *ptr);
			nfrontp += strlen(nfrontp); 
			if (isprint(*ptr)) {
				xbuf[i] = *ptr;
			} else {
				xbuf[i] = '.';
			}
			if (i % 2) { 
				*nfrontp = ' ';
				nfrontp++;
			}
			cnt--;
			ptr++;
		}
		xbuf[i] = '\0';
		sprintf(nfrontp, " %s\r\n", xbuf );
		nfrontp += strlen(nfrontp);
	} 
}
#endif /* DIAGNOSTICS */

--- NEW FILE: ext.h ---
/*
 * Copyright (c) 1989 The Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	from: @(#)ext.h	5.7 (Berkeley) 3/1/91
 *	$Id: ext.h,v 1.2 2006-08-31 09:32:30 dslinux_amadeus Exp $
 */

/*
 * Telnet server variable declarations
 */
extern char options[256];
extern char do_dont_resp[256];
extern char will_wont_resp[256];
extern int linemode;	/* linemode on/off */

#ifdef LINEMODE
extern int uselinemode;	/* what linemode to use (on/off) */
extern int editmode;	/* edit modes in use */
extern int useeditmode;	/* edit modes to use */
extern int alwayslinemode;	/* command line option */
#ifdef KLUDGELINEMODE
extern int lmodetype;	/* Client support for linemode */
#endif	/* KLUDGELINEMODE */
#endif	/* LINEMODE */

extern int flowmode;	/* current flow control state */

#ifdef DIAGNOSTICS
extern int diagnostic;	/* telnet diagnostic capabilities */
#endif /* DIAGNOSTICS */

#ifdef BFTPDAEMON
extern int bftpd;		/* behave as bftp daemon */
#endif /* BFTPDAEMON */

#if defined(SecurID)
extern int require_SecurID;
#endif

#if defined(AUTHENTICATE)
extern int auth_level;
#endif

extern slcfun slctab[NSLC + 1];	/* slc mapping table */

extern char *terminaltype;

extern char *loginprg;

/*
 * I/O data buffers, pointers, and counters.
 */
extern char ptyobuf[BUFSIZ+NETSLOP], *pfrontp, *pbackp;
extern char netibuf[BUFSIZ], *netip;
extern char netobuf[BUFSIZ+NETSLOP], *nfrontp, *nbackp;
extern char *neturg;		/* one past last byte of urgent data */
extern int pcc, ncc;

#if defined(CRAY2) && defined(UNICOS5)
extern int unpcc;  /* characters left unprocessed by CRAY-2 terminal routine */
extern char *unptyip;  /* pointer to remaining characters in buffer */
#endif

extern int pty, net;
extern char *line;
extern int SYNCHing;		/* we are in TELNET SYNCH mode */

void _termstat(void);
void add_slc(int, int, int);
void check_slc(void);
void change_slc(int, int, int);
void cleanup(int);
void clientstat(int, int, int);
void copy_termbuf(char *, int);
void deferslc(void);
void defer_terminit(void);
void do_opt_slc(unsigned char *, int);
void doeof(void);
void dooption(int);
void dontoption(int);
void edithost(const char *, const char *);
void fatal(int, const char *);
void fatalperror(int, const char *);
void get_slc_defaults(void);
void init_env(void);
void init_termbuf(void);
void interrupt(void);
void localstat(void);
void netclear(void);
void netflush(void);

#ifdef DIAGNOSTICS
void printoption(const char *, int);
void printdata(const char *, const char *, int);
void printsub(char, unsigned char *, int);
#endif

void ptyflush(void);
void putchr(int);
void putf(const char *, char *);
void recv_ayt(void);
void send_do(int, int);
void send_dont(int, int);
void send_slc(void);
void send_status(void);
void send_will(int, int);
void send_wont(int, int);
void sendbrk(void);
void sendsusp(void);
void set_termbuf(void);
void start_login(const char *, int, const char *);
void start_slc(int);
void startslave(const char *host, int autologin, char *autoname);

#if defined(AUTHENTICATE)
void start_slave(char *);
#else
void start_slave(char *, int, char *);
#endif

void suboption(void);
void telrcv(void);
void ttloop(void);
void tty_binaryin(int);
void tty_binaryout(int);

int end_slc(unsigned char **);
int getnpty(void);
int getpty(void);
int login_tty(int);
int spcset(int, cc_t *, cc_t **);
int stilloob(int);
int terminit(void);
int termstat(void);
int tty_flowmode(void);
int tty_isbinaryin(void);
int tty_isbinaryout(void);
int tty_iscrnl(void);
int tty_isecho(void);
int tty_isediting(void);
int tty_islitecho(void);
int tty_isnewmap(void);
int tty_israw(void);
int tty_issofttab(void);
int tty_istrapsig(void);
int tty_linemode(void);

void tty_rspeed(int);
void tty_setecho(int);
void tty_setedit(int);
void tty_setlinemode(int);
void tty_setlitecho(int);
void tty_setsig(int);
void tty_setsofttab(int);
void tty_tspeed(int);
void willoption(int);
void wontoption(int);
void writenet(unsigned char *, int);

#if defined(ENCRYPT)
extern void (*encrypt_output)(unsigned char *, int);
extern int (*decrypt_input)(int);
extern char *nclearto;
#endif


/*
 * The following are some clocks used to decide how to interpret
 * the relationship between various variables.
 */

extern struct _clocks {
    int system;			/* what the current time is */
    int echotoggle;		/* last time user entered echo character */
    int modenegotiated;		/* last time operating mode negotiated */
    int didnetreceive;		/* last time we read data from network */
    int ttypesubopt;		/* ttype subopt is received */
    int tspeedsubopt;		/* tspeed subopt is received */
    int environsubopt;		/* environ subopt is received */
    int xdisplocsubopt;		/* xdisploc subopt is received */
    int baseline;		/* time started to do timed action */
    int gotDM;			/* when did we last see a data mark */
} clocks;


#if defined(CRAY2) && defined(UNICOS5)
extern int needtermstat;
#endif

#ifndef	CRAY
#ifdef __linux__
#define DEFAULT_IM	"%i\r\n%s %r (%h) (%t)\r\n\r\n"
#else
#define DEFAULT_IM	"\r\n\r\n4.3 BSD UNIX (%h) (%t)\r\n\r\r\n\r"
#endif
#else
#define DEFAULT_IM	"\r\n\r\nCray UNICOS (%h) (%t)\r\n\r\r\n\r"
#endif


--- NEW FILE: termstat.c ---
/*
 * Copyright (c) 1989 Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef EMBED
/*
 * From: @(#)termstat.c	5.10 (Berkeley) 3/22/91
 */
char termstat_rcsid[] = 
  "$Id: termstat.c,v 1.2 2006-08-31 09:32:31 dslinux_amadeus Exp $";
#endif

#include "telnetd.h"

/*
 * local variables
 */
int def_tspeed = -1, def_rspeed = -1;
#ifdef	TIOCSWINSZ
int def_row = 0, def_col = 0;
#endif
#ifdef	LINEMODE
static int _terminit = 0;
#endif	/* LINEMODE */

#if	defined(CRAY2) && defined(UNICOS5)
int	newmap = 1;	/* nonzero if \n maps to ^M^J */
#endif

#ifdef	LINEMODE
/*
 * localstat
 *
 * This function handles all management of linemode.
 *
 * Linemode allows the client to do the local editing of data
 * and send only complete lines to the server.  Linemode state is
 * based on the state of the pty driver.  If the pty is set for
 * external processing, then we can use linemode.  Further, if we
 * can use real linemode, then we can look at the edit control bits
 * in the pty to determine what editing the client should do.
 *
 * Linemode support uses the following state flags to keep track of
 * current and desired linemode state.
 *	alwayslinemode : true if -l was specified on the telnetd
 * 	command line.  It means to have linemode on as much as
 *	possible.
 *
 * 	lmodetype: signifies whether the client can
 *	handle real linemode, or if use of kludgeomatic linemode
 *	is preferred.  It will be set to one of the following:
 *		REAL_LINEMODE : use linemode option
 *		KLUDGE_LINEMODE : use kludge linemode
 *		NO_LINEMODE : client is ignorant of linemode
 *
 *	linemode, uselinemode : linemode is true if linemode
 *	is currently on, uselinemode is the state that we wish
 *	to be in.  If another function wishes to turn linemode
 *	on or off, it sets or clears uselinemode.
 *
 *	editmode, useeditmode : like linemode/uselinemode, but
 *	these contain the edit mode states (edit and trapsig).
 *
 * The state variables correspond to some of the state information
 * in the pty.
 *	linemode:
 *		In real linemode, this corresponds to whether the pty
 *		expects external processing of incoming data.
 *		In kludge linemode, this more closely corresponds to the
 *		whether normal processing is on or not.  (ICANON in
 *		system V, or COOKED mode in BSD.)
 *		If the -l option was specified (alwayslinemode), then
 *		an attempt is made to force external processing on at
 *		all times.
 *
 * The following heuristics are applied to determine linemode
 * handling within the server.
 *	1) Early on in starting up the server, an attempt is made
 *	   to negotiate the linemode option.  If this succeeds
 *	   then lmodetype is set to REAL_LINEMODE and all linemode
 *	   processing occurs in the context of the linemode option.
 *	2) If the attempt to negotiate the linemode option failed,
 *	   then we try to use kludge linemode.  We test for this
 *	   capability by sending "do Timing Mark".  If a positive
 *	   response comes back, then we assume that the client
 *	   understands kludge linemode (ech!) and the
 *	   lmodetype flag is set to KLUDGE_LINEMODE.
 *	3) Otherwise, linemode is not supported at all and
 *	   lmodetype remains set to NO_LINEMODE (which happens
 *	   to be 0 for convenience).
 *	4) At any time a command arrives that implies a higher
 *	   state of linemode support in the client, we move to that
 *	   linemode support.
 *
 * A short explanation of kludge linemode is in order here.
 *	1) The heuristic to determine support for kludge linemode
 *	   is to send a do timing mark.  We assume that a client
 *	   that supports timing marks also supports kludge linemode.
 *	   A risky proposition at best.
 *	2) Further negotiation of linemode is done by changing the
 *	   the server's state regarding SGA.  If server will SGA,
 *	   then linemode is off, if server won't SGA, then linemode
 *	   is on.
 */
	void
localstat()
{
	void netflush();
	int need_will_echo = 0;

#if	defined(CRAY2) && defined(UNICOS5)
	/*
	 * Keep track of that ol' CR/NL mapping while we're in the
	 * neighborhood.
	 */
	newmap = tty_isnewmap();
#endif	/* defined(CRAY2) && defined(UNICOS5) */

	/*
	 * Check for state of BINARY options.
	 */
	if (tty_isbinaryin()) {
		if (his_want_state_is_wont(TELOPT_BINARY))
			send_do(TELOPT_BINARY, 1);
	} else {
		if (his_want_state_is_will(TELOPT_BINARY))
			send_dont(TELOPT_BINARY, 1);
	}

	if (tty_isbinaryout()) {
		if (my_want_state_is_wont(TELOPT_BINARY))
			send_will(TELOPT_BINARY, 1);
	} else {
		if (my_want_state_is_will(TELOPT_BINARY))
			send_wont(TELOPT_BINARY, 1);
	}

	/*
	 * Check for changes to flow control if client supports it.
	 */
	if (his_state_is_will(TELOPT_LFLOW)) {
		if (tty_flowmode() != flowmode) {
			flowmode = tty_flowmode();
			(void) sprintf(nfrontp, "%c%c%c%c%c%c", IAC, SB,
				TELOPT_LFLOW, flowmode, IAC, SE);
			nfrontp += 6;
		}
	}

	/*
	 * Check linemode on/off state
	 */
	uselinemode = tty_linemode();

	/*
	 * If alwayslinemode is on, and pty is changing to turn it off, then
	 * force linemode back on.
	 */
	if (alwayslinemode && linemode && !uselinemode) {
		uselinemode = 1;
		tty_setlinemode(uselinemode);
	}

#if	defined(ENCRYPT)
	/*
	 * If the terminal is not echoing, but editing is enabled,
	 * something like password input is going to happen, so
	 * if we the other side is not currently sending encrypted
	 * data, ask the other side to start encrypting.
	 */
	if (his_state_is_will(TELOPT_ENCRYPT)) {
		static int enc_passwd = 0;
		if (uselinemode && !tty_isecho() && tty_isediting()
		    && (enc_passwd == 0) && !decrypt_input) {
			encrypt_send_request_start();
			enc_passwd = 1;
		} else if (enc_passwd) {
			encrypt_send_request_end();
			enc_passwd = 0;
		}
	}
#endif

	/*
	 * Do echo mode handling as soon as we know what the
	 * linemode is going to be.
	 * If the pty has echo turned off, then tell the client that
	 * the server will echo.  If echo is on, then the server
	 * will echo if in character mode, but in linemode the
	 * client should do local echoing.  The state machine will
	 * not send anything if it is unnecessary, so don't worry
	 * about that here.
	 *
	 * If we need to send the WILL ECHO (because echo is off),
	 * then delay that until after we have changed the MODE.
	 * This way, when the user is turning off both editing
	 * and echo, the client will get editing turned off first.
	 * This keeps the client from going into encryption mode
	 * and then right back out if it is doing auto-encryption
	 * when passwords are being typed.
	 */
	if (uselinemode) {
		if (tty_isecho())
			send_wont(TELOPT_ECHO, 1);
		else
			need_will_echo = 1;
	}

	/*
	 * If linemode is being turned off, send appropriate
	 * command and then we're all done.
	 */
	 if (!uselinemode && linemode) {
# ifdef	KLUDGELINEMODE
		if (lmodetype == REAL_LINEMODE) {
# endif	/* KLUDGELINEMODE */
			send_dont(TELOPT_LINEMODE, 1);
# ifdef	KLUDGELINEMODE
		} else if (lmodetype == KLUDGE_LINEMODE)
			send_will(TELOPT_SGA, 1);
# endif	/* KLUDGELINEMODE */
		send_will(TELOPT_ECHO, 1);
		linemode = uselinemode;
		goto done;
	}

# ifdef	KLUDGELINEMODE
	/*
	 * If using real linemode check edit modes for possible later use.
	 * If we are in kludge linemode, do the SGA negotiation.
	 */
	if (lmodetype == REAL_LINEMODE) {
# endif	/* KLUDGELINEMODE */
		useeditmode = 0;
		if (tty_isediting())
			useeditmode |= MODE_EDIT;
		if (tty_istrapsig())
			useeditmode |= MODE_TRAPSIG;
		if (tty_issofttab())
			useeditmode |= MODE_SOFT_TAB;
		if (tty_islitecho())
			useeditmode |= MODE_LIT_ECHO;
# ifdef	KLUDGELINEMODE
	} else if (lmodetype == KLUDGE_LINEMODE) {
		if (tty_isediting() && uselinemode)
			send_wont(TELOPT_SGA, 1);
		else
			send_will(TELOPT_SGA, 1);
	}
# endif	/* KLUDGELINEMODE */

	/*
	 * Negotiate linemode on if pty state has changed to turn it on.
	 * Send appropriate command and send along edit mode, then all done.
	 */
	if (uselinemode && !linemode) {
# ifdef	KLUDGELINEMODE
		if (lmodetype == KLUDGE_LINEMODE) {
			send_wont(TELOPT_SGA, 1);
		} else if (lmodetype == REAL_LINEMODE) {
# endif	/* KLUDGELINEMODE */
			send_do(TELOPT_LINEMODE, 1);
			/* send along edit modes */
			(void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, SB,
				TELOPT_LINEMODE, LM_MODE, useeditmode,
				IAC, SE);
			nfrontp += 7;
			editmode = useeditmode;
# ifdef	KLUDGELINEMODE
		}
# endif	/* KLUDGELINEMODE */
		linemode = uselinemode;
		goto done;
	}

# ifdef	KLUDGELINEMODE
	/*
	 * None of what follows is of any value if not using
	 * real linemode.
	 */
	if (lmodetype < REAL_LINEMODE)
		goto done;
# endif	/* KLUDGELINEMODE */

	if (linemode && his_state_is_will(TELOPT_LINEMODE)) {
		/*
		 * If edit mode changed, send edit mode.
		 */
		 if (useeditmode != editmode) {
			/*
			 * Send along appropriate edit mode mask.
			 */
			(void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC, SB,
				TELOPT_LINEMODE, LM_MODE, useeditmode,
				IAC, SE);
			nfrontp += 7;
			editmode = useeditmode;
		}
							

		/*
		 * Check for changes to special characters in use.
		 */
		start_slc(0);
		check_slc();
		(void) end_slc(0);
	}

done:
	if (need_will_echo)
		send_will(TELOPT_ECHO, 1);
	/*
	 * Some things should be deferred until after the pty state has
	 * been set by the local process.  Do those things that have been
	 * deferred now.  This only happens once.
	 */
	if (_terminit == 0) {
		_terminit = 1;
		defer_terminit();
	}

	netflush();
	set_termbuf();
	return;

}  /* end of localstat */
#endif	/* LINEMODE */


/*
 * clientstat
 *
 * Process linemode related requests from the client.
 * Client can request a change to only one of linemode, editmode or slc's
 * at a time, and if using kludge linemode, then only linemode may be
 * affected.
 */
	void
clientstat(code, parm1, parm2)
	register int code, parm1, parm2;
{
	/*
	 * Get a copy of terminal characteristics.
	 */
	init_termbuf();

	/*
	 * Process request from client. code tells what it is.
	 */
	switch (code) {
#ifdef	LINEMODE
	case TELOPT_LINEMODE:
		/*
		 * Don't do anything unless client is asking us to change
		 * modes.
		 */
		uselinemode = (parm1 == WILL);
		if (uselinemode != linemode) {
# ifdef	KLUDGELINEMODE
			/*
			 * If using kludge linemode, make sure that
			 * we can do what the client asks.
			 * We can not turn off linemode if alwayslinemode
			 * and the ICANON bit is set.
			 */
			if (lmodetype == KLUDGE_LINEMODE) {
				if (alwayslinemode && tty_isediting()) {
					uselinemode = 1;
				}
			}
		
			/*
			 * Quit now if we can't do it.
			 */
			if (uselinemode == linemode)
				return;

			/*
			 * If using real linemode and linemode is being
			 * turned on, send along the edit mode mask.
			 */
			if (lmodetype == REAL_LINEMODE && uselinemode)
# else	/* KLUDGELINEMODE */
			if (uselinemode)
# endif	/* KLUDGELINEMODE */
			{
				useeditmode = 0;
				if (tty_isediting())
					useeditmode |= MODE_EDIT;
				if (tty_istrapsig)
					useeditmode |= MODE_TRAPSIG;
				if (tty_issofttab())
					useeditmode |= MODE_SOFT_TAB;
				if (tty_islitecho())
					useeditmode |= MODE_LIT_ECHO;
				(void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC,
					SB, TELOPT_LINEMODE, LM_MODE,
							useeditmode, IAC, SE);
				nfrontp += 7;
				editmode = useeditmode;
			}


			tty_setlinemode(uselinemode);

			linemode = uselinemode;

		}
		break;
	
	case LM_MODE:
	    {
		register int ack, changed;

		/*
		 * Client has sent along a mode mask.  If it agrees with
		 * what we are currently doing, ignore it; if not, it could
		 * be viewed as a request to change.  Note that the server
		 * will change to the modes in an ack if it is different from
		 * what we currently have, but we will not ack the ack.
		 */
		 useeditmode &= MODE_MASK;
		 ack = (useeditmode & MODE_ACK);
		 useeditmode &= ~MODE_ACK;

		 if (changed = (useeditmode ^ editmode)) {
			/*
			 * This check is for a timing problem.  If the
			 * state of the tty has changed (due to the user
			 * application) we need to process that info
			 * before we write in the state contained in the
			 * ack!!!  This gets out the new MODE request,
			 * and when the ack to that command comes back
			 * we'll set it and be in the right mode.
			 */
			if (ack)
				localstat();
			if (changed & MODE_EDIT)
				tty_setedit(useeditmode & MODE_EDIT);

			if (changed & MODE_TRAPSIG)
				tty_setsig(useeditmode & MODE_TRAPSIG);

			if (changed & MODE_SOFT_TAB)
				tty_setsofttab(useeditmode & MODE_SOFT_TAB);

			if (changed & MODE_LIT_ECHO)
				tty_setlitecho(useeditmode & MODE_LIT_ECHO);

			set_termbuf();

 			if (!ack) {
 				(void) sprintf(nfrontp, "%c%c%c%c%c%c%c", IAC,
					SB, TELOPT_LINEMODE, LM_MODE,
 					useeditmode|MODE_ACK,
 					IAC, SE);
 				nfrontp += 7;
 			}
 		
			editmode = useeditmode;
		}

		break;

	    }  /* end of case LM_MODE */
#endif	/* LINEMODE */

	case TELOPT_NAWS:
#ifdef	TIOCSWINSZ
	    {
		struct winsize ws;

		def_col = parm1;
		def_row = parm2;
#ifdef	LINEMODE
		/*
		 * Defer changing window size until after terminal is
		 * initialized.
		 */
		if (terminit() == 0)
			return;
#endif	/* LINEMODE */

		/*
		 * Change window size as requested by client.
		 */

		ws.ws_col = parm1;
		ws.ws_row = parm2;
		(void) ioctl(pty, TIOCSWINSZ, (char *)&ws);
	    }
#endif	/* TIOCSWINSZ */
		
		break;
	
	case TELOPT_TSPEED:
	    {
		def_tspeed = parm1;
		def_rspeed = parm2;
#ifdef	LINEMODE
		/*
		 * Defer changing the terminal speed.
		 */
		if (terminit() == 0)
			return;
#endif	/* LINEMODE */
		/*
		 * Change terminal speed as requested by client.
		 * We set the receive speed first, so that if we can't
		 * store seperate receive and transmit speeds, the transmit
		 * speed will take precedence.
		 */
		tty_rspeed(parm2);
		tty_tspeed(parm1);
		set_termbuf();

		break;

	    }  /* end of case TELOPT_TSPEED */

	default:
		/* What? */
		break;
	}  /* end of switch */

#if	defined(CRAY2) && defined(UNICOS5)
	/*
	 * Just in case of the likely event that we changed the pty state.
	 */
	rcv_ioctl();
#endif	/* defined(CRAY2) && defined(UNICOS5) */

	netflush();

}  /* end of clientstat */

#if	defined(CRAY2) && defined(UNICOS5)
	void
termstat()
{
	needtermstat = 1;
}

	void
_termstat()
{
	needtermstat = 0;
	init_termbuf();
	localstat();
	rcv_ioctl();
}
#endif	/* defined(CRAY2) && defined(UNICOS5) */

#ifdef	LINEMODE
/*
 * defer_terminit
 *
 * Some things should not be done until after the login process has started
 * and all the pty modes are set to what they are supposed to be.  This
 * function is called when the pty state has been processed for the first time. 
 * It calls other functions that do things that were deferred in each module.
 */
	void
defer_terminit()
{

	/*
	 * local stuff that got deferred.
	 */
	if (def_tspeed != -1) {
		clientstat(TELOPT_TSPEED, def_tspeed, def_rspeed);
		def_tspeed = def_rspeed = 0;
	}

#ifdef	TIOCSWINSZ
	if (def_col || def_row) {
		struct winsize ws;

		bzero((char *)&ws, sizeof(ws));
		ws.ws_col = def_col;
		ws.ws_row = def_row;
		(void) ioctl(pty, TIOCSWINSZ, (char *)&ws);
	}
#endif

	/*
	 * The only other module that currently defers anything.
	 */
	deferslc();

}  /* end of defer_terminit */

/*
 * terminit
 *
 * Returns true if the pty state has been processed yet.
 */
	int
terminit()
{
	return _terminit;

}  /* end of terminit */
#endif	/* LINEMODE */




More information about the dslinux-commit mailing list