mydir=appl
BUILDTOP=$(REL)..
-SUBDIRS= sample simple user_user gss-sample \
- libpty bsd gssftp telnet
+SUBDIRS= sample simple user_user gss-sample
+
+++ /dev/null
-thisconfigdir=.
-myfulldir=appl/bsd
-mydir=.
-BUILDTOP=$(REL)..$(S)..
-PROG_LIBPATH=-L$(TOPLIBD)
-PROG_RPATH=$(KRB5_LIBDIR)
-
-SETENVSRC=@SETENVSRC@
-SETENVOBJ=@SETENVOBJ@
-
-LOGINLIBS=@LOGINLIBS@
-LIBOBJS=@LIBOBJS@
-KRSHDLIBS=@KRSHDLIBS@
-
-SRCS= $(srcdir)/krcp.c $(srcdir)/krlogin.c $(srcdir)/krsh.c $(srcdir)/kcmd.c \
- $(srcdir)/forward.c $(srcdir)/login.c $(srcdir)/krshd.c \
- $(srcdir)/krlogind.c
-OBJS= krcp.o krlogin.o krsh.o kcmd.o forward.o $(SETENVOBJ) login.o krshd.o \
- krlogind.o $(LIBOBJS)
-
-UCB_RLOGIN = @UCB_RLOGIN@
-UCB_RSH = @UCB_RSH@
-UCB_RCP = @UCB_RCP@
-
-RSH= -DKRB5_PATH_RLOGIN=\"$(CLIENT_BINDIR)/rlogin\"
-BSD= -DUCB_RLOGIN=\"$(UCB_RLOGIN)\" \
- -DUCB_RSH=\"$(UCB_RSH)\" -DUCB_RCP=\"$(UCB_RCP)\"
-
-DEFINES = $(RSH) $(BSD) $(RPROGS) -DKERBEROS \
- -DLOGIN_PROGRAM=\"$(SERVER_BINDIR)/login.krb5\" -DKPROGDIR=\"$(CLIENT_BINDIR)\" \
- -DHEIMDAL_FRIENDLY
-
-all:: rsh rcp rlogin kshd klogind login.krb5
-
-clean::
- $(RM) rsh rcp rlogin kshd klogind login.krb5
-
-rsh: krsh.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(KRB5_BASE_DEPLIBS)
- $(CC_LINK) -o rsh krsh.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(KRB5_BASE_LIBS)
-
-rcp: krcp.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(KRB5_BASE_DEPLIBS)
- $(CC_LINK) -o rcp krcp.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(KRB5_BASE_LIBS)
-
-rlogin: krlogin.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(KRB5_BASE_DEPLIBS)
- $(CC_LINK) -o rlogin krlogin.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(KRB5_BASE_LIBS)
-
-install::
- for f in rsh rcp rlogin; do \
- ($(INSTALL_PROGRAM) $$f \
- $(DESTDIR)$(CLIENT_BINDIR)/`echo $$f|sed '$(transform)'` && \
- $(INSTALL_DATA) $(srcdir)/$$f.M \
- ${DESTDIR}$(CLIENT_MANDIR)/`echo $$f|sed '$(transform)'`.1 \
- ) || exit 1; \
- done
-
-kshd: krshd.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(PTY_DEPLIB) $(KRB5_BASE_DEPLIBS) $(APPUTILS_DEPLIB)
- $(CC_LINK) -o kshd krshd.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(KRSHDLIBS) $(PTY_LIB) $(UTIL_LIB) $(KRB5_BASE_LIBS) $(APPUTILS_LIB)
-
-klogind: krlogind.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(PTY_DEPLIB) $(KRB5_BASE_DEPLIBS) $(APPUTILS_DEPLIB)
- $(CC_LINK) -o klogind krlogind.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(PTY_LIB) $(UTIL_LIB) $(KRB5_BASE_LIBS) $(APPUTILS_LIB)
-
-install::
- for f in kshd klogind; do \
- ($(INSTALL_PROGRAM) $$f \
- $(DESTDIR)$(SERVER_BINDIR)/`echo $$f|sed '$(transform)'` && \
- $(INSTALL_DATA) $(srcdir)/$$f.M \
- ${DESTDIR}$(SERVER_MANDIR)/`echo $$f|sed '$(transform)'`.8 \
- ) || exit 1 ; \
- done
-
-# No program name transformation is done with login.krb5 since it is directly
-# referenced by klogind.
-#
-login.krb5: login.o $(SETENVOBJ) $(LIBOBJS) $(PTY_DEPLIB) $(KRB5_BASE_DEPLIBS)
- $(CC_LINK) -o login.krb5 login.o $(SETENVOBJ) $(LIBOBJS) $(LOGINLIBS) $(PTY_LIB) $(KRB5_BASE_LIBS)
-
-install::
- $(INSTALL_PROGRAM) login.krb5 $(DESTDIR)$(SERVER_BINDIR)/login.krb5
- $(INSTALL_DATA) $(srcdir)/login.M \
- ${DESTDIR}$(SERVER_MANDIR)/login.krb5.8
-
-getdtablesize.o: $(srcdir)/getdtablesize.c
-
-kcmd.o krcp.o krlogin.o krlogind.o krsh.o krshd.o forward.o: defines.h
+++ /dev/null
-K5_AC_INIT(krlogind.c)
-CONFIG_RULES
-KRB5_AC_INET6
-LOGINLIBS=
-AC_ARG_WITH([afs],
-[ --without-afs don't have afs libraries to build against (default)
- --with-afs=AFSDIR use preinstalled AFS library tree],
-,with_afs=no)dnl
-if test $with_afs != no; then
- AC_DEFINE(SETPAG,1,[Define if setpag should be used])
- LOGINLIBS="$LOGINLIBS -L$with_afs/lib -L$with_afs/lib/afs -lauth -lsys -lrx -llwp"
-fi
-AC_PROG_INSTALL
-dnl dbm libs for use of an_to_ln
-save_LIBS="$LIBS"
- LIBS=
- AC_CHECK_LIB(crypt,crypt)
- LOGINLIBS="$LOGINLIBS $LIBS"
-LIBS="$save_LIBS"
-dnl
-dnl AIX has them all; SCO might too
-AC_CHECK_LIB(odm,main,
- AC_CHECK_LIB(s,main,
- AC_CHECK_LIB(cfg,main,
- LOGINLIBS="$LOGINLIBS -lodm -ls -lcfg"
- )))
-dnl
-dnl Make our operating system-specific security checks and definitions for
-dnl login.
-dnl
-case $krb5_cv_host in
-*-*-aix3*)
- # AIX has streams include files but not streams TTY
- # Moreover, strops.h trashes sys/ioctl.h
- krb5_cv_has_streams=no
- ;;
-alpha*-dec-osf*)
- AC_CHECK_LIB(security,setluid,
- AC_DEFINE(HAVE_SETLUID,1,[Define if setluid is supplied by the OSF/1 security library])
- LOGINLIBS="$LOGINLIBS -lsecurity"
- )
- ;;
-esac
-dnl
-KRSHDLIBS="$LOGINLIBS"
-dnl
-AC_SUBST(KRSHDLIBS)
-AC_SUBST(LOGINLIBS)
-dnl
-AC_FUNC_VFORK
-AC_TYPE_MODE_T
-AC_CHECK_FUNCS(isatty inet_aton getenv gettosbyname killpg initgroups setpriority setreuid setresuid waitpid setsid ptsname setlogin tcgetpgrp tcsetpgrp setpgid strsave utimes rmufile rresvport_af)
-AC_CHECK_HEADERS(unistd.h stdlib.h string.h sys/filio.h sys/sockio.h sys/label.h sys/tty.h ttyent.h lastlog.h sys/select.h sys/ptyvar.h utmp.h sys/time.h sys/ioctl_compat.h paths.h arpa/nameser.h)
-AC_HEADER_STDARG
-AC_REPLACE_FUNCS(getdtablesize)
-dnl
-KRB5_AC_NEED_DAEMON
-dnl
-KRB5_SIGTYPE
-CHECK_SIGNALS
-CHECK_SETJMP
-CHECK_DIRENT
-CHECK_WAIT_TYPE
-AC_CHECK_HEADER(termios.h,[AC_CHECK_FUNC(cfsetispeed,AC_DEFINE(POSIX_TERMIOS,1,[Define if POSIX-compatible termios interface is found]))])
-CHECK_UTMP
-KRB5_GETSOCKNAME_ARGS
-dnl
-dnl Check for where the BSD rlogin, rcp, and rsh programs live.
-dnl
-save_path=$PATH
-ifdef([_AC_PROG_ECHO], [_AC_PROG_ECHO])
-ifdef([AC_PROG_ECHO_N], [AC_PROG_ECHO_N])
-AC_ARG_ENABLE([athena],
-[ --enable-athena build with MIT Project Athena configuration],
-[PATH=/usr/athena/bin:/bin:/usr/bin:/usr/bsd:/usr/ucb],
-[PATH=/bin:/usr/bin:/usr/bsd:/usr/ucb])
-AC_PATH_PROG(UCB_RLOGIN,rlogin,/usr/ucb/rlogin)
-AC_PATH_PROG(UCB_RSH,rsh,/usr/ucb/rsh)
-AC_PATH_PROG(UCB_RCP,rcp,/usr/ucb/rcp)
-PATH=$save_path
-ifdef([_AC_PROG_ECHO], [_AC_PROG_ECHO])
-ifdef([AC_PROG_ECHO_N], [AC_PROG_ECHO_N])
-dnl
-dnl
-AC_MSG_CHECKING([streams interface])
-AC_CACHE_VAL(krb5_cv_has_streams,
-[AC_TRY_COMPILE(
-[#include <sys/stream.h>
-#include <sys/stropts.h>], [],
-krb5_cv_has_streams=yes, krb5_cv_has_streams=no)])
-AC_MSG_RESULT($krb5_cv_has_streams)
-if test $krb5_cv_has_streams = yes; then
-AC_DEFINE(HAVE_STREAMS,1,[Define if the OS uses streams])
-fi
-dnl
-dnl
-AC_MSG_CHECKING([F_SETOWN])
-AC_CACHE_VAL(krb5_cv_f_setown,
-[AC_TRY_COMPILE(
-[#include <sys/types.h>
-#include <fcntl.h>], [1+F_SETOWN;],
-krb5_cv_f_setown=yes,krb5_cv_f_setown=no)])
-AC_MSG_RESULT($krb5_cv_f_setown)
-if test $krb5_cv_f_setown = yes; then
-AC_DEFINE(HAVE_SETOWN,1,[Define if F_SETOWN is available])
-fi
-dnl
-dnl
-AC_MSG_CHECKING([setenv])
-AC_CACHE_VAL(krb5_cv_setenv,
-[AC_TRY_LINK(
-[],[setenv("PATH","/bin",0);],
-krb5_cv_setenv=yes,krb5_cv_setenv=no)])
-AC_MSG_RESULT($krb5_cv_setenv)
-if test $krb5_cv_setenv = no; then
-SETENVSRC=setenv.c
-SETENVOBJ=setenv.o
-AC_SUBST([SETENVSRC])
-AC_SUBST([SETENVOBJ])
-AC_DEFINE([NEED_SETENV],1,[Define if setenv needs to be defined])
-fi
-dnl
-dnl
-AC_MSG_CHECKING([number of arguments to setpgrp])
-AC_CACHE_VAL(krb5_cv_setpgrp_args,
-[AC_TRY_COMPILE(
-[#ifndef __STDC__
-#define __STDC__ 1
-#endif
-#include <unistd.h>],[setpgrp(0,0)],
-krb5_cv_setpgrp_args=two, krb5_cv_setpgrp_args=void)])
-AC_MSG_RESULT($krb5_cv_setpgrp_args)
-if test $krb5_cv_setpgrp_args = two; then
-AC_DEFINE(SETPGRP_TWOARG,1,[Define if setpgrp takes two arguments])
-fi
-dnl
-dnl
-AC_MSG_CHECKING([shadow password support])
-AC_CACHE_VAL(krb5_cv_shadow_pwd,
-[AC_TRY_LINK(
-[#include <sys/types.h>
-#include <pwd.h>
-#include <shadow.h>],
-[struct spwd *sp = getspnam("root")],
-krb5_cv_shadow_pwd=yes, krb5_cv_shadow_pwd=no)])
-AC_MSG_RESULT($krb5_cv_shadow_pwd)
-if test $krb5_cv_shadow_pwd = yes; then
-AC_DEFINE(HAVE_SHADOW,1,[Define if shadow password interface is available])
-fi
-dnl
-dnl
-K5_AC_CHECK_FILES(/etc/environment /etc/TIMEZONE)
-dnl
-dnl
-AC_C_CONST
-
-KRB5_AC_LIBUTIL
-KRB5_BUILD_PROGRAM
-V5_AC_OUTPUT_MAKEFILE
+++ /dev/null
-#define OPTS_FORWARD_CREDS 0x00000020
-#define OPTS_FORWARDABLE_CREDS 0x00000010
-#define RCMD_BUFSIZ 5120
-
-enum kcmd_proto {
- /* Old protocol: DES encryption only. No subkeys. No protection
- for cleartext length. No ivec supplied. OOB hacks used for
- rlogin. Checksum may be omitted at connection startup. */
- KCMD_OLD_PROTOCOL = 1,
- /* New protocol: Any encryption scheme. Client-generated subkey
- required. Prepend cleartext-length to cleartext data (but don't
- include it in count). Starting ivec defined, chained. In-band
- signalling. Checksum required. */
- KCMD_NEW_PROTOCOL,
- /* Hack: Get credentials, and use the old protocol iff the session
- key type is single-DES. */
- KCMD_PROTOCOL_COMPAT_HACK,
- /* Using Kerberos version 4. */
- KCMD_V4_PROTOCOL,
- /* ??? */
- KCMD_UNKNOWN_PROTOCOL
-};
-
-extern int kcmd (int *sock, char **ahost, int /* u_short */ rport,
- char *locuser, char *remuser, char *cmd,
- int *fd2p, char *service, char *realm,
- krb5_creds **cred,
- krb5_int32 *seqno, krb5_int32 *server_seqno,
- struct sockaddr_in *laddr,
- struct sockaddr_in *faddr,
- krb5_auth_context *authconp,
- krb5_flags authopts,
- int anyport, int suppress_err,
- enum kcmd_proto *protonum /* input and output */
- );
-
-extern int rcmd_stream_read (int fd, char *buf, size_t len, int secondary);
-extern int rcmd_stream_write (int fd, char *buf, size_t len, int secondary);
-extern int getport (int * /* portnum */, int * /* addrfamily */);
-
-extern void rcmd_stream_init_krb5 (krb5_keyblock *in_keyblock,
- int encrypt_flag, int lencheck,
- int am_client, enum kcmd_proto protonum);
-
-extern void rcmd_stream_init_normal(void);
-
-#ifndef HAVE_STRSAVE
-extern char *strsave(const char *sp);
-#endif
-
-krb5_error_code rd_and_store_for_creds(krb5_context context,
- krb5_auth_context auth_context,
- krb5_data *inbuf, krb5_ticket *ticket,
- krb5_ccache *ccache);
-
-
-int princ_maps_to_lname(krb5_principal principal, char *luser);
-int default_realm(krb5_principal principal);
-
-#ifdef NEED_SETENV
-extern int setenv(char *, char *, int);
-#endif
-
-#include "fake-addrinfo.h"
-
-#ifdef KRB_DEFS
-krb5_error_code krb5_compat_recvauth(krb5_context, krb5_auth_context *,
- krb5_pointer, char *, krb5_principal,
- krb5_int32, krb5_keytab,
- krb5_int32, char *, char *,
- struct sockaddr_in *,
- struct sockaddr_in *, char *,
- krb5_ticket **, krb5_int32 *,
- AUTH_DAT **, Key_schedule, char *);
-
-krb5_error_code
-krb5_compat_recvauth_version(krb5_context, krb5_auth_context *,
- krb5_pointer, krb5_principal, krb5_int32,
- krb5_keytab, krb5_int32, char *, char *,
- struct sockaddr_in *, struct sockaddr_in *,
- char *, krb5_ticket **, krb5_int32*,
- AUTH_DAT **, Key_schedule, krb5_data *);
-#endif
-
-#include "port-sockets.h"
+++ /dev/null
-#
-# Generated makefile dependencies follow.
-#
-$(OUTPRE)krcp.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
- $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/fake-addrinfo.h \
- $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \
- $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \
- $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \
- $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/k5-util.h $(SRCTOP)/include/krb5.h \
- $(SRCTOP)/include/krb5/authdata_plugin.h $(SRCTOP)/include/krb5/locate_plugin.h \
- $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \
- $(SRCTOP)/include/socket-utils.h defines.h krcp.c
-$(OUTPRE)krlogin.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/fake-addrinfo.h \
- $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/krb5.h $(SRCTOP)/include/port-sockets.h \
- $(SRCTOP)/include/socket-utils.h defines.h krlogin.c \
- rpaths.h
-$(OUTPRE)krsh.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/fake-addrinfo.h \
- $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/krb5.h $(SRCTOP)/include/port-sockets.h \
- $(SRCTOP)/include/socket-utils.h defines.h krsh.c
-$(OUTPRE)kcmd.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
- $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/fake-addrinfo.h \
- $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \
- $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \
- $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \
- $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/authdata_plugin.h \
- $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \
- $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- defines.h kcmd.c
-$(OUTPRE)forward.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
- $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/fake-addrinfo.h \
- $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \
- $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \
- $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \
- $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/authdata_plugin.h \
- $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \
- $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- defines.h forward.c
-$(OUTPRE)login.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/libpty.h \
- $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
- $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \
- $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \
- $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \
- $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/authdata_plugin.h \
- $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \
- $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- login.c loginpaths.h
-$(OUTPRE)krshd.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/libpty.h \
- $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
- $(COM_ERR_DEPS) $(SRCTOP)/include/fake-addrinfo.h $(SRCTOP)/include/k5-buf.h \
- $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \
- $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \
- $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \
- $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/k5-util.h \
- $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/authdata_plugin.h \
- $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \
- $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- defines.h krshd.c loginpaths.h
-$(OUTPRE)krlogind.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/libpty.h \
- $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
- $(COM_ERR_DEPS) $(SRCTOP)/include/fake-addrinfo.h $(SRCTOP)/include/k5-buf.h \
- $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \
- $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \
- $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \
- $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/k5-util.h \
- $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/authdata_plugin.h \
- $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \
- $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- defines.h krlogind.c
+++ /dev/null
-/*
- * appl/bsd/forward.c
- */
-
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#if defined(KERBEROS) || defined(KRB5)
-#include <stdio.h>
-#include <netdb.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "k5-int.h"
-
-#include "defines.h"
-
-/* Decode, decrypt and store the forwarded creds in the local ccache. */
-krb5_error_code
-rd_and_store_for_creds(context, auth_context, inbuf, ticket, ccache)
- krb5_context context;
- krb5_auth_context auth_context;
- krb5_data *inbuf;
- krb5_ticket *ticket;
- krb5_ccache *ccache;
-{
- krb5_creds ** creds;
- krb5_error_code retval;
- char ccname[35];
-
- *ccache = NULL;
-
- retval = krb5_rd_cred(context, auth_context, inbuf, &creds, NULL);
- if (retval)
- return(retval);
-
- /* Set the KRB5CCNAME ENV variable to keep sessions
- * seperate. Use the process id of this process which is
- * the rlogind or rshd. Set the environment variable as well.
- */
-
- snprintf(ccname, sizeof(ccname), "FILE:/tmp/krb5cc_p%ld", (long) getpid());
- setenv("KRB5CCNAME", ccname, 1);
-
- retval = krb5_cc_resolve(context, ccname, ccache);
- if (retval)
- goto cleanup;
-
- retval = krb5_cc_initialize(context, *ccache, ticket->enc_part2->client);
- if (retval)
- goto cleanup;
-
- retval = krb5_cc_store_cred(context, *ccache, *creds);
- if (retval)
- goto cleanup;
-
-cleanup:
- krb5_free_creds(context, *creds);
- return retval;
-}
-
-#endif /* KERBEROS */
+++ /dev/null
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <limits.h>
-
-#ifdef _SC_OPEN_MAX
-int getdtablesize() {
- return sysconf(_SC_OPEN_MAX);
-}
-#else
-#include <sys/resource.h>
-/* Placed in the Public Domain by Mark Eichin, Cygnus Support 1994 */
-
-int getdtablesize() {
- struct rlimit rl;
- getrlimit(RLIMIT_NOFILE, &rl);
- return rl.rlim_cur;
-}
-#endif
+++ /dev/null
-/*
- * appl/bsd/kcmd.c
- */
-
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/*
- * Copyright (C) 1998 by the FundsXpress, INC.
- *
- * All rights reserved.
- *
- * Export of this software from the United States of America may require
- * a specific license from the United States Government. It is the
- * responsibility of any person or organization contemplating export to
- * obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of FundsXpress. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. FundsXpress makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/* derived from @(#)rcmd.c 5.17 (Berkeley) 6/27/88 */
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-#include <pwd.h>
-#include <sys/param.h>
-#ifndef _TYPES_
-#include <sys/types.h>
-#define _TYPES_
-#endif
-#include <fcntl.h>
-
-#ifndef MAXPATHLEN
-#define MAXPATHLEN 1024
-#endif
-#include <signal.h>
-#include <sys/file.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#ifdef _AIX
-#include <sys/select.h>
-#endif
-
-#ifndef POSIX_SIGNALS
-#ifndef sigmask
-#define sigmask(m) (1 << ((m)-1))
-#endif
-#endif
-
-#ifndef roundup
-#define roundup(x,y) ((((x)+(y)-1)/(y))*(y))
-#endif
-
-#include <netinet/in.h>
-#include <netdb.h>
-
-#include <errno.h>
-#include "k5-int.h"
-
-#include "defines.h"
-
-extern krb5_context bsd_context;
-
-
-#define START_PORT 5120 /* arbitrary */
-char *default_service = "host";
-
-#define KCMD_KEYUSAGE 1026 /* Key usage used with 3des or any old-protocol enctype*/
-/* New protocol enctypes that use cipher state have keyusage defined later*/
-
-#ifndef GETSOCKNAME_ARG3_TYPE
-#define GETSOCKNAME_ARG3_TYPE int
-#endif
-
-/*
- * Note that the encrypted rlogin packets take the form of a four-byte
- * length followed by encrypted data. On writing the data out, a significant
- * performance penalty is suffered (at least one RTT per character, two if we
- * are waiting for a shell to echo) by writing the data separately from the
- * length. So, unlike the input buffer, which just contains the output
- * data, the output buffer represents the entire packet.
- */
-
-static char des_inbuf[2*RCMD_BUFSIZ]; /* needs to be > largest read size */
-static char des_outpkt[2*RCMD_BUFSIZ+4]; /* needs to be > largest write size */
-static krb5_data desinbuf;
-static krb5_data desoutbuf;
-
-/* XXX Overloaded: use_ivecs!=0 -> new protocol, inband signalling, etc. */
-static int use_ivecs;
-static krb5_keyusage enc_keyusage_i[2], enc_keyusage_o[2];
-static krb5_data encivec_i[2], encivec_o[2];
-
-static krb5_keyblock *keyblock; /* key for encrypt/decrypt */
-static int (*input)(int, char *, size_t, int);
-static int (*output)(int, char *, size_t, int);
-static char storage[2*RCMD_BUFSIZ]; /* storage for the decryption */
-static size_t nstored = 0;
-static char *store_ptr = storage;
-static int twrite(int, char *, size_t, int);
-static int v5_des_read(int, char *, size_t, int),
- v5_des_write(int, char *, size_t, int);
-static int do_lencheck;
-
-#ifdef POSIX_SIGNALS
-typedef sigset_t masktype;
-#else
-typedef sigmasktype masktype;
-#endif
-
-static void
-block_urgent (masktype *oldmask)
-{
-#ifdef POSIX_SIGNALS
- sigset_t urgmask;
-
- sigemptyset(&urgmask);
- sigaddset(&urgmask, SIGURG);
- sigprocmask(SIG_BLOCK, &urgmask, oldmask);
-#else
- *oldmask = sigblock(sigmask(SIGURG));
-#endif /* POSIX_SIGNALS */
-}
-
-static void
-restore_sigs (masktype *oldmask)
-{
-#ifdef POSIX_SIGNALS
- sigprocmask(SIG_SETMASK, oldmask, (sigset_t*)0);
-#else
- sigsetmask(*oldmask);
-#endif /* POSIX_SIGNALS */
-}
-
-static int
-kcmd_connect (int *sp, int *addrfamilyp, struct sockaddr_in *sockinp,
- char *hname, char **host_save, unsigned int rport, int *lportp,
- struct sockaddr_in *laddrp)
-{
- int s, aierr;
- struct addrinfo *ap, *ap2, aihints;
- char rport_buf[10];
- GETSOCKNAME_ARG3_TYPE sin_len;
-
- if (rport == 0) {
- fprintf(stderr, "can't connect to %s port 0\n", hname);
- return -1;
- }
- snprintf(rport_buf, sizeof(rport_buf), "%d", ntohs(rport));
- memset(&aihints, 0, sizeof(aihints));
- aihints.ai_socktype = SOCK_STREAM;
- aihints.ai_flags = AI_CANONNAME;
- aihints.ai_family = *addrfamilyp;
- aierr = getaddrinfo(hname, rport_buf, &aihints, &ap);
- if (aierr) {
- const char *msg;
- /* We want to customize some messages. */
- switch (aierr) {
- case EAI_NONAME:
- msg = "host unknown";
- break;
- default:
- fprintf(stderr, "foo\n");
- msg = gai_strerror(aierr);
- break;
- }
- fprintf(stderr, "%s: %s\n", hname, msg);
- return -1;
- }
- if (ap == 0) {
- fprintf(stderr, "%s: no addresses?\n", hname);
- return -1;
- }
-
- *host_save = strdup(ap->ai_canonname ? ap->ai_canonname : hname);
-
- for (ap2 = ap; ap; ap = ap->ai_next) {
- char hostbuf[NI_MAXHOST];
- char portbuf[NI_MAXSERV];
- int oerrno;
- int af = ap->ai_family;
-
- /* @@ Debugging. Yuck. */
- switch (af) {
- case AF_INET:
- if (((struct sockaddr_in *)ap->ai_addr)->sin_port == 0) {
- fprintf(stderr, "internal error: got ipv4 address but port zero?\n");
- continue;
- }
- break;
-#ifdef KRB5_USE_INET6
- case AF_INET6:
- if (((struct sockaddr_in6 *)ap->ai_addr)->sin6_port == 0) {
- fprintf(stderr, "internal error: got ipv6 address but port zero?\n");
- continue;
- }
- break;
-#endif
- }
-
- for (;;) {
- s = getport(lportp, &af);
- if (s < 0) {
- if (errno == EAGAIN)
- fprintf(stderr, "socket: All ports in use\n");
- else
- perror("kcmd: socket");
- return -1;
- }
- if (connect(s, ap->ai_addr, ap->ai_addrlen) >= 0)
- goto connected;
- (void) close(s);
- if (errno != EADDRINUSE)
- break;
- if (lportp)
- (*lportp)--;
- }
-
- oerrno = errno;
- aierr = getnameinfo(ap->ai_addr, ap->ai_addrlen,
- hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf),
- NI_NUMERICHOST | NI_NUMERICSERV);
- if (aierr)
- fprintf(stderr, "connect to <error formatting address: %s>: ",
- gai_strerror (aierr));
- else
- fprintf(stderr, "connect to address %s port %s: ", hostbuf,
- portbuf);
- errno = oerrno;
- perror(0);
-
- if (ap->ai_next)
- fprintf(stderr, "Trying next address...\n");
- }
- freeaddrinfo(ap2);
- return -1;
-
-connected:
- sin_len = sizeof(struct sockaddr_in);
- if (getsockname(s, (struct sockaddr *)laddrp, &sin_len) < 0) {
- perror("getsockname");
- close(s);
- return -1;
- }
-
- *sp = s;
- *sockinp = *(struct sockaddr_in *) ap->ai_addr;
- *addrfamilyp = ap->ai_family;
- freeaddrinfo(ap2);
- return 0;
-}
-
-static int
-setup_secondary_channel (int s, int *fd2p, int *lportp, int *addrfamilyp,
- struct sockaddr_in *fromp, int anyport)
-{
- if (fd2p == 0) {
- write(s, "", 1);
- *lportp = 0;
- } else {
- char num[8];
- socklen_t len = sizeof (*fromp);
- size_t slen;
- int s2 = getport(lportp, addrfamilyp), s3;
- fd_set rfds, xfds;
- struct timeval waitlen;
- int n;
-
- *fd2p = -1;
- if (s2 < 0)
- return -1;
- FD_ZERO(&rfds);
- FD_ZERO(&xfds);
- FD_SET(s, &rfds);
- FD_SET(s, &xfds);
- listen(s2, 1);
- FD_SET(s2, &rfds);
- (void) snprintf(num, sizeof(num), "%d", *lportp);
- slen = strlen(num)+1;
- if (write(s, num, slen) != slen) {
- perror("write: setting up stderr");
- (void) close(s2);
- return -1;
- }
- waitlen.tv_sec = 600; /* long, but better than infinite */
- waitlen.tv_usec = 0;
- n = (s < s2) ? s2 : s;
- n = select(n+1, &rfds, 0, &xfds, &waitlen);
- if (n <= 0) {
- /* timeout or error */
- fprintf(stderr, "timeout in circuit setup\n");
- close(s2);
- *fd2p = -1;
- return -1;
- } else {
- if (FD_ISSET(s, &rfds) || FD_ISSET(s, &xfds)) {
- fprintf(stderr, "socket: protocol error or closed connection in circuit setup\n");
- close(s2);
- *fd2p = -1;
- return -1;
- }
- /* ready to accept a connection; yay! */
- }
- s3 = accept(s2, (struct sockaddr *)fromp, &len);
- (void) close(s2);
- if (s3 < 0) {
- perror("accept");
- *lportp = 0;
- return -1;
- }
- *fd2p = s3;
- fromp->sin_port = ntohs(fromp->sin_port);
- /* This check adds nothing when using Kerberos. */
- if (! anyport &&
- (fromp->sin_family != AF_INET ||
- fromp->sin_port >= IPPORT_RESERVED)) {
- fprintf(stderr, "socket: protocol failure in circuit setup.\n");
- close(s3);
- *fd2p = -1;
- return -1;
- }
- }
- return 0;
-}
-
-int
-kcmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, service, realm,
- cred, seqno, server_seqno, laddr, faddr, authconp, authopts, anyport,
- suppress_err, protonump)
- int *sock;
- char **ahost;
- u_short rport;
- char *locuser, *remuser, *cmd;
- int *fd2p;
- char *service;
- char *realm;
- krb5_creds **cred; /* output only */
- krb5_int32 *seqno;
- krb5_int32 *server_seqno;
- struct sockaddr_in *laddr, *faddr;
- krb5_auth_context *authconp;
- krb5_flags authopts;
- int anyport;
- int suppress_err; /* Don't print if authentication fails */
- enum kcmd_proto *protonump;
-{
- int s;
- masktype oldmask;
- struct sockaddr_in sockin, from, local_laddr;
- krb5_creds *get_cred = 0, *ret_cred = 0;
- char c;
- int lport;
- int rc;
- char *host_save;
- krb5_error_code status;
- krb5_ap_rep_enc_part *rep_ret;
- krb5_error *error = 0;
- krb5_ccache cc;
- krb5_data outbuf;
- krb5_flags options = authopts;
- krb5_auth_context auth_context = NULL;
- char *cksumbuf;
- krb5_data cksumdat;
- char *kcmd_version;
- enum kcmd_proto protonum = *protonump;
- int addrfamily = /* AF_INET */0;
-
- if (asprintf(&cksumbuf, "%u:%s%s", ntohs(rport), cmd, remuser) < 0) {
- fprintf(stderr, "Unable to allocate memory for checksum buffer.\n");
- return(-1);
- }
- cksumdat.data = cksumbuf;
- cksumdat.length = strlen(cksumbuf);
-
- block_urgent(&oldmask);
-
- if (!laddr) laddr = &local_laddr;
- if (kcmd_connect(&s, &addrfamily, &sockin, *ahost, &host_save, rport, 0, laddr) == -1) {
- restore_sigs(&oldmask);
- return -1;
- }
- *ahost = host_save;
- /* If no service is given set to the default service */
- if (!service) service = default_service;
-
- if (!(get_cred = (krb5_creds *)calloc(1, sizeof(krb5_creds)))) {
- fprintf(stderr,"kcmd: no memory\n");
- return(-1);
- }
- status = krb5_sname_to_principal(bsd_context, host_save, service,
- KRB5_NT_SRV_HST, &get_cred->server);
- if (status) {
- fprintf(stderr, "kcmd: krb5_sname_to_principal failed: %s\n",
- error_message(status));
- return(-1);
- }
-
- if (realm && *realm) {
- status = krb5_set_principal_realm(bsd_context, get_cred->server,
- realm);
- if (status) {
- fprintf(stderr, "kcmd: krb5_set_principal_realm failed %s\n",
- error_message(status));
- return(-1);
- }
- }
- status = setup_secondary_channel(s, fd2p, &lport, &addrfamily, &from,
- anyport);
- if (status)
- goto bad;
-
- if (faddr)
- *faddr = sockin;
-
- status = krb5_cc_default(bsd_context, &cc);
- if (status)
- goto bad2;
-
- status = krb5_cc_get_principal(bsd_context, cc, &get_cred->client);
- if (status) {
- (void) krb5_cc_close(bsd_context, cc);
- goto bad2;
- }
-
- /* Get ticket from credentials cache or kdc */
- status = krb5_get_credentials(bsd_context, 0, cc, get_cred, &ret_cred);
- krb5_free_creds(bsd_context, get_cred);
- (void) krb5_cc_close(bsd_context, cc);
- if (status) {
- fprintf (stderr, "error getting credentials: %s\n",
- error_message (status));
- goto bad2;
- }
-
- /* Reset internal flags; these should not be sent. */
- authopts &= (~OPTS_FORWARD_CREDS);
- authopts &= (~OPTS_FORWARDABLE_CREDS);
-
- if (krb5_auth_con_init(bsd_context, &auth_context))
- goto bad2;
-
- if (krb5_auth_con_set_req_cksumtype(bsd_context, auth_context, CKSUMTYPE_RSA_MD5) !=0 )
- goto bad2;
- if (krb5_auth_con_setflags(bsd_context, auth_context,
- KRB5_AUTH_CONTEXT_RET_TIME))
- goto bad2;
-
- /* Only need local address for mk_cred() to send to krlogind */
- status = krb5_auth_con_genaddrs(bsd_context, auth_context, s,
- KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR);
- if (status)
- goto bad2;
-
- if (protonum == KCMD_PROTOCOL_COMPAT_HACK) {
- krb5_boolean is_des;
- status = krb5_c_enctype_compare (bsd_context, ENCTYPE_DES_CBC_CRC,
- ret_cred->keyblock.enctype, &is_des);
- if (status)
- goto bad2;
- protonum = is_des ? KCMD_OLD_PROTOCOL : KCMD_NEW_PROTOCOL;
- }
-
- switch (protonum) {
- case KCMD_NEW_PROTOCOL:
- authopts |= AP_OPTS_USE_SUBKEY;
- kcmd_version = "KCMDV0.2";
- break;
- case KCMD_OLD_PROTOCOL:
- kcmd_version = "KCMDV0.1";
- break;
- default:
- status = EINVAL;
- goto bad2;
- }
-
- /* Call Kerberos library routine to obtain an authenticator,
- pass it over the socket to the server, and obtain mutual
- authentication. */
- status = krb5_sendauth(bsd_context, &auth_context, (krb5_pointer) &s,
- kcmd_version, ret_cred->client, ret_cred->server,
- authopts, &cksumdat, ret_cred, 0,
- &error, &rep_ret, NULL);
- free(cksumbuf);
- if (status) {
- if (!suppress_err)
- fprintf(stderr, "Couldn't authenticate to server: %s\n",
- error_message(status));
- if (error) {
- if (!suppress_err) {
- fprintf(stderr, "Server returned error code %d (%s)\n",
- error->error,
- error_message(ERROR_TABLE_BASE_krb5 +
- (int) error->error));
- if (error->text.length) {
- fprintf(stderr, "Error text sent from server: %s\n",
- error->text.data);
- }
- }
- krb5_free_error(bsd_context, error);
- error = 0;
- }
- }
- if (status) goto bad2;
- if (rep_ret && server_seqno) {
- *server_seqno = rep_ret->seq_number;
- krb5_free_ap_rep_enc_part(bsd_context, rep_ret);
- }
-
- (void) write(s, remuser, strlen(remuser)+1);
- (void) write(s, cmd, strlen(cmd)+1);
- (void) write(s, locuser, strlen(locuser)+1);
-
- if (options & OPTS_FORWARD_CREDS) { /* Forward credentials */
- status = krb5_fwd_tgt_creds(bsd_context, auth_context,
- host_save,
- ret_cred->client, ret_cred->server,
- 0, options & OPTS_FORWARDABLE_CREDS,
- &outbuf);
- if (status) {
- fprintf(stderr, "kcmd: Error getting forwarded creds: %s\n",
- error_message(status));
- goto bad2;
- }
-
- /* Send forwarded credentials */
- status = krb5_write_message(bsd_context, (krb5_pointer)&s, &outbuf);
- if (status)
- goto bad2;
- }
- else { /* Dummy write to signal no forwarding */
- outbuf.length = 0;
- status = krb5_write_message(bsd_context, (krb5_pointer)&s, &outbuf);
- if (status)
- goto bad2;
- }
-
- if ((rc=read(s, &c, 1)) != 1) {
- if (rc==-1) {
- perror(*ahost);
- } else {
- fprintf(stderr,"kcmd: bad connection with remote host\n");
- }
- status = -1;
- goto bad2;
- }
- if (c != 0) {
- while (read(s, &c, 1) == 1) {
- (void) write(2, &c, 1);
- if (c == '\n')
- break;
- }
- status = -1;
- goto bad2;
- }
- restore_sigs(&oldmask);
- *sock = s;
- *protonump = protonum;
-
- /* pass back credentials if wanted */
- if (cred) krb5_copy_creds(bsd_context, ret_cred, cred);
- krb5_free_creds(bsd_context, ret_cred);
- if (authconp)
- *authconp = auth_context;
-
- return (0);
- bad2:
- if (lport)
- (void) close(*fd2p);
- bad:
- (void) close(s);
- restore_sigs(&oldmask);
- if (ret_cred)
- krb5_free_creds(bsd_context, ret_cred);
- return (status);
-}
-
-
-static int
-setup_socket (struct sockaddr *sa, GETSOCKNAME_ARG3_TYPE len)
-{
- int s;
-
- s = socket(sa->sa_family, SOCK_STREAM, 0);
- if (s < 0)
- return -1;
-
- if (bind(s, sa, len) < 0)
- return -1;
- if (getsockname(s, sa, &len) < 0) {
- close(s);
- return -1;
- }
- return s;
-}
-
-
-int
-getport(alport, family)
- int *alport, *family;
-{
- int s;
-
- if (*family == 0) {
-#ifdef KRB5_USE_INET6
- *family = AF_INET6;
- s = getport (alport, family);
- if (s >= 0)
- return s;
-#endif
- *family = AF_INET;
- }
-
-#ifdef KRB5_USE_INET6
- if (*family == AF_INET6) {
- struct sockaddr_in6 sockin6;
-
- memset(&sockin6, 0, sizeof(sockin6));
- sockin6.sin6_family = AF_INET6;
- sockin6.sin6_addr = in6addr_any;
-
- s = setup_socket((struct sockaddr *)&sockin6, sizeof (sockin6));
- if (s >= 0 && alport)
- *alport = ntohs(sockin6.sin6_port);
- return s;
- }
-#endif
-
- if (*family == AF_INET) {
- struct sockaddr_in sockin;
-
- memset(&sockin, 0, sizeof(sockin));
- sockin.sin_family = AF_INET;
- sockin.sin_addr.s_addr = INADDR_ANY;
-
- s = setup_socket((struct sockaddr *)&sockin, sizeof (sockin));
- if (s >= 0 && alport)
- *alport = ntohs(sockin.sin_port);
- return s;
- }
-
- return -1;
-}
-
-static int
-normal_read (int fd, char *buf, size_t len, int secondary)
-{
- return read (fd, buf, len);
-}
-
-void rcmd_stream_init_normal()
-{
- input = normal_read;
- output = twrite;
-}
-
-void rcmd_stream_init_krb5(in_keyblock, encrypt_flag, lencheck, am_client,
- protonum)
- krb5_keyblock *in_keyblock;
- int encrypt_flag;
- int lencheck;
- int am_client;
- enum kcmd_proto protonum;
-{
- krb5_error_code status;
- size_t blocksize;
- int i;
- krb5_error_code ret;
-
- if (!encrypt_flag) {
- rcmd_stream_init_normal();
- return;
- }
- desinbuf.data = des_inbuf;
- desoutbuf.data = des_outpkt+4; /* Set up des buffers */
- keyblock = in_keyblock;
-
- do_lencheck = lencheck;
- input = v5_des_read;
- output = v5_des_write;
- enc_keyusage_i[0] = KCMD_KEYUSAGE;
- enc_keyusage_i[1] = KCMD_KEYUSAGE;
- enc_keyusage_o[0] = KCMD_KEYUSAGE;
- enc_keyusage_o[1] = KCMD_KEYUSAGE;
-
- if (protonum == KCMD_OLD_PROTOCOL) {
- use_ivecs = 0;
- return;
- }
-
- use_ivecs = 1;
- switch (in_keyblock->enctype) {
- /*
- * For the DES-based enctypes and the 3DES enctype we want to use
- * a non-zero IV because that's what we did. In the future we
- * use different keyusage for each channel and direction and a fresh
- * cipher state
- */
- case ENCTYPE_DES_CBC_CRC:
- case ENCTYPE_DES_CBC_MD4:
- case ENCTYPE_DES_CBC_MD5:
- case ENCTYPE_DES3_CBC_SHA1:
-
- status = krb5_c_block_size(bsd_context, keyblock->enctype,
- &blocksize);
- if (status) {
- /* XXX what do I do? */
- abort();
- }
-
- encivec_i[0].length = encivec_i[1].length = encivec_o[0].length
- = encivec_o[1].length = blocksize;
-
- if ((encivec_i[0].data = malloc(encivec_i[0].length * 4)) == NULL) {
- /* XXX what do I do? */
- abort();
- }
- encivec_i[1].data = encivec_i[0].data + encivec_i[0].length;
- encivec_o[0].data = encivec_i[1].data + encivec_i[0].length;
- encivec_o[1].data = encivec_o[0].data + encivec_i[0].length;
-
- /* is there a better way to initialize this? */
- memset(encivec_i[0].data, am_client, blocksize);
- memset(encivec_o[0].data, 1 - am_client, blocksize);
- memset(encivec_i[1].data, 2 | am_client, blocksize);
- memset(encivec_o[1].data, 2 | (1 - am_client), blocksize);
- break;
- default:
- if (am_client) {
- enc_keyusage_i[0] = 1028;
- enc_keyusage_i[1] = 1030;
- enc_keyusage_o[0] = 1032;
- enc_keyusage_o[1] = 1034;
- } else { /*am_client*/
- enc_keyusage_i[0] = 1032;
- enc_keyusage_i[1] = 1034;
- enc_keyusage_o[0] = 1028;
- enc_keyusage_o[1] = 1030;
- }
- for (i = 0; i < 2; i++) {
- ret = krb5_c_init_state (bsd_context, in_keyblock, enc_keyusage_i[i],
- &encivec_i[i]);
- if (ret)
- goto fail;
- ret = krb5_c_init_state (bsd_context, in_keyblock, enc_keyusage_o[i],
- &encivec_o[i]);
- if (ret)
- goto fail;
- }
- break;
- }
- return;
- fail:
- com_err ("kcmd", ret, "Initializing cipher state");
- abort();
- }
-
-int rcmd_stream_read(fd, buf, len, sec)
- int fd;
- register char *buf;
- size_t len;
- int sec;
-{
- return (*input)(fd, buf, len, sec);
-}
-
-int rcmd_stream_write(fd, buf, len, sec)
- int fd;
- register char *buf;
- size_t len;
- int sec;
-{
- return (*output)(fd, buf, len, sec);
-}
-
-/* Because of rcp lossage, translate fd 0 to 1 when writing. */
-static int twrite(fd, buf, len, secondary)
- int fd;
- char *buf;
- size_t len;
- int secondary;
-{
- return write((fd == 0) ? 1 : fd, buf, len);
-}
-
-static int v5_des_read(fd, buf, len, secondary)
- int fd;
- char *buf;
- size_t len;
- int secondary;
-{
- int nreturned = 0;
- size_t net_len,rd_len;
- int cc;
- unsigned char c;
- krb5_error_code ret;
- krb5_data plain;
- krb5_enc_data cipher;
-
- if (nstored >= len) {
- memcpy(buf, store_ptr, len);
- store_ptr += len;
- nstored -= len;
- return(len);
- } else if (nstored) {
- memcpy(buf, store_ptr, nstored);
- nreturned += nstored;
- buf += nstored;
- len -= nstored;
- nstored = 0;
- }
-
- while (1) {
- cc = krb5_net_read(bsd_context, fd, &c, 1);
- /* we should check for non-blocking here, but we'd have
- to make it save partial reads as well. */
- if (cc <= 0) return cc; /* read error */
- if (cc == 1) {
- if (c == 0 || !do_lencheck) break;
- }
- }
-
- rd_len = c;
- if ((cc = krb5_net_read(bsd_context, fd, &c, 1)) != 1) return 0;
- rd_len = (rd_len << 8) | c;
- if ((cc = krb5_net_read(bsd_context, fd, &c, 1)) != 1) return 0;
- rd_len = (rd_len << 8) | c;
- if ((cc = krb5_net_read(bsd_context, fd, &c, 1)) != 1) return 0;
- rd_len = (rd_len << 8) | c;
-
- ret = krb5_c_encrypt_length(bsd_context, keyblock->enctype,
- use_ivecs ? rd_len + 4 : rd_len,
- &net_len);
- if (ret) {
- errno = ret;
- return(-1);
- }
-
- if ((net_len <= 0) || (net_len > sizeof(des_inbuf))) {
- /* preposterous length, probably out of sync */
- errno = EIO;
- return(-1);
- }
- if ((cc = krb5_net_read(bsd_context, fd, desinbuf.data, net_len)) != net_len) {
- /* probably out of sync */
- errno = EIO;
- return(-1);
- }
-
- cipher.enctype = ENCTYPE_UNKNOWN;
- cipher.ciphertext.length = net_len;
- cipher.ciphertext.data = desinbuf.data;
- plain.length = sizeof(storage);
- plain.data = storage;
-
- /* decrypt info */
- ret = krb5_c_decrypt(bsd_context, keyblock, enc_keyusage_i[secondary],
- use_ivecs ? encivec_i + secondary : 0,
- &cipher, &plain);
- if (ret) {
- /* probably out of sync */
- errno = EIO;
- return(-1);
- }
- store_ptr = storage;
- nstored = rd_len;
- if (use_ivecs) {
- int rd_len2;
- rd_len2 = storage[0] & 0xff;
- rd_len2 <<= 8; rd_len2 |= storage[1] & 0xff;
- rd_len2 <<= 8; rd_len2 |= storage[2] & 0xff;
- rd_len2 <<= 8; rd_len2 |= storage[3] & 0xff;
- if (rd_len2 != rd_len) {
- /* cleartext length trashed? */
- errno = EIO;
- return -1;
- }
- store_ptr += 4;
- }
- if (nstored > len) {
- memcpy(buf, store_ptr, len);
- nreturned += len;
- store_ptr += len;
- nstored -= len;
- } else {
- memcpy(buf, store_ptr, nstored);
- nreturned += nstored;
- nstored = 0;
- }
-
- return(nreturned);
-}
-
-
-
-static int v5_des_write(fd, buf, len, secondary)
- int fd;
- char *buf;
- size_t len;
- int secondary;
-{
- krb5_data plain;
- krb5_enc_data cipher;
- char tmpbuf[2*RCMD_BUFSIZ+8];
- unsigned char *len_buf = (unsigned char *) tmpbuf;
-
- if (use_ivecs) {
- unsigned char *lenbuf2 = (unsigned char *) tmpbuf;
- if (len + 4 > sizeof(tmpbuf))
- abort ();
- lenbuf2[0] = (len & 0xff000000) >> 24;
- lenbuf2[1] = (len & 0xff0000) >> 16;
- lenbuf2[2] = (len & 0xff00) >> 8;
- lenbuf2[3] = (len & 0xff);
- memcpy (tmpbuf + 4, buf, len);
-
- plain.data = tmpbuf;
- plain.length = len + 4;
- } else {
- plain.data = buf;
- plain.length = len;
- }
-
- cipher.ciphertext.length = sizeof(des_outpkt)-4;
- cipher.ciphertext.data = desoutbuf.data;
-
- if (krb5_c_encrypt(bsd_context, keyblock, enc_keyusage_o[secondary],
- use_ivecs ? encivec_o + secondary : 0,
- &plain, &cipher)) {
- errno = EIO;
- return(-1);
- }
-
- desoutbuf.length = cipher.ciphertext.length;
-
- len_buf = (unsigned char *) des_outpkt;
- len_buf[0] = (len & 0xff000000) >> 24;
- len_buf[1] = (len & 0xff0000) >> 16;
- len_buf[2] = (len & 0xff00) >> 8;
- len_buf[3] = (len & 0xff);
-
- if (write(fd, des_outpkt,desoutbuf.length+4) != desoutbuf.length+4){
- errno = EIO;
- return(-1);
- }
-
- else return(len);
-}
-
-
-#ifndef HAVE_STRSAVE
-/* Strsave was a routine in the version 4 krb library: we put it here
- for compatablilty with version 5 krb library, since kcmd.o is linked
- into all programs. */
-
-char *
-strsave(sp)
- const char *sp;
-{
- register char *ret;
-
- if((ret = strdup(sp)) == NULL) {
- fprintf(stderr, "no memory for saving args\n");
- exit(1);
- }
- return(ret);
-}
-#endif
-
-/* Server side authentication, etc */
-
-int princ_maps_to_lname(principal, luser)
- krb5_principal principal;
- char *luser;
-{
- char kuser[10];
- if (!(krb5_aname_to_localname(bsd_context, principal,
- sizeof(kuser), kuser))
- && (strcmp(kuser, luser) == 0)) {
- return 1;
- }
- return 0;
-}
-
-int default_realm(principal)
- krb5_principal principal;
-{
- char *def_realm;
- int retval;
-
- if ((retval = krb5_get_default_realm(bsd_context, &def_realm))) {
- return 0;
- }
-
- if (!data_eq_string(*krb5_princ_realm(bsd_context, principal),
- def_realm)) {
- free(def_realm);
- return 0;
- }
- free(def_realm);
- return 1;
-}
+++ /dev/null
-.\" Copyright (c) 1983 Regents of the University of California.
-.\" All rights reserved. The Berkeley software License Agreement
-.\" specifies the terms and conditions for redistribution.
-.\"
-.\" @(#)rlogind.8 6.3 (Berkeley) 5/24/86
-.\"
-.TH KLOGIND 8
-.SH NAME
-klogind \- remote login server
-.SH SYNOPSIS
-.B klogind
-[
-.B \-rcpPef
-]
-[[ \fB\-w\fP[\fBip\fP|\fImaxhostlen\fP[\fB,\fP[\fBno\fP]\fBstriplocal\fP ]] ]
-[ \fB\-D\fP \fIport\fP ]
-.SH DESCRIPTION
-.I Klogind
-is the server for the
-.IR rlogin (1)
-program. The server is
-based on rlogind(8) but uses Kerberos authentication.
-.PP
-The
-.I klogind
-server is invoked by \fIinetd(8)\fP when it receives a connection on
-the port indicated in /etc/inetd.conf. A typical /etc/inetd.conf
-configuration line for \fIklogind\fP might be:
-
-klogin stream tcp nowait root /usr/cygnus/sbin/klogind klogind -e5c
-
-When a service request is received, the following protocol is initiated:
-
-.IP 1)
-Check authentication.
-.IP 2)
-Check authorization via the access-control files \fI.k5login\fP and
-\fI.klogin\fP in the user's home directory.
-.IP 3)
-Prompt for password if any checks fail and the \fI-p\fP option was supplied.
-.PP
-If the authentication succeeds, login the user by calling the accompanying
-login.krb5.
-.PP
-klogind allows Kerberos V5 authentication with the \fI.k5login\fP
-access control file to be trusted. If this authorization check is
-passed, then the user is allowed to log in. If the user has no
-\fI.k5login\fP file, the login will be authorized if the results of
-krb5_aname_to_localname conversion matches the account name. Unless
-special rules are configured, this will be true if and only if the
-Kerberos principal of the connecting user is in the default local
-realm and the principal portion matches the account name.
-.PP
-The configuration of \fIklogind\fP is done
-by command line arguments passed by inetd. The options are:
-
-.IP \fB\-P\fP
-Prompt the user for a password.
-If the -P option is passed, then the password is verified in addition
-to all other checks.
-
-.IP \fB\-e\fP
-Create an encrypted session.
-
-.IP \fB\-c\fP
-Require Kerberos V5 clients to present a cryptographic checksum of
-initial connection information like the name of the user that the
-client is trying to access in the initial authenticator. This
-checksum provides additionl security by preventing an attacker from
-changing the initial connection information. If this option is
-specified, older Kerberos V5 clients that do not send a checksum in
-the authenticator will not be able to authenticate to this server.
-This option is mutually exclusive with the \fB-i\fP option.
-
- If neither the \fB-c\fP or \fB-i\fP options are specified,then
-checksums are validated if presented. Since it is difficult to remove
-a checksum from an authenticator without making the authenticator
-invalid, this default mode is almost as significant of a security
-improvement as \fB-c\fP if new clients are used. It has the additional
-advantage of backwards compatability with some clients.
-Unfortunately, clients before Kerberos V5, Beta5, generate invalid
-checksums; if these clients are used, the \fB-i\fP option must be
-used.
-
-.IP \fB\-i\fP
-Ignore authenticator checksums if provided. This option
-ignore authenticator checksusm presented by current Kerberos clients
-to protect initial connection information; it is the opposite of
-\fB-c\fP. This option is provided because some older
-clients--particularly clients predating the release of Kerberos V5
-Beta5 (May 1995)--present bogus checksums that prevent Kerberos
-authentication from succeeding in the default mode.
-
-.PP
-The parent of the login process manipulates the master side of the
-pseduo terminal, operating as an intermediary between the login
-process and the client instance of the
-.I rlogin(1)
-program. In normal operation, the packet protocol described in
-.IR pty (4)
-is invoked to provide ^S/^Q type facilities and propagate interrupt
-signals to the remote programs. The login process propagates the
-client terminal's baud rate and terminal type, as found in the
-environment variable, ``TERM''; see
-.IR environ (7).
-The screen or
-window size of the terminal is requested from the client, and window
-size changes from the client are propagated to the pseudo terminal.
-
-.PP
-.I Klogind
-supports the following options to control the form of the hostname
-passed to login(1):
-
-.TP
-\fB\-w \fP[\fBip\fP|\fImaxhostlen\fP[\fB,\fP[\fBno\fP]\fBstriplocal\fP]]
-Controls the form of the remote hostname passed to login(1).
-Specifying \fBip\fP results in the numeric IP address always being
-passed to login(1). Specifying a number, \fImaxhostlen\fP, sets the
-maximum length of the hostname passed to login(1) before it will be
-passed as a numeric IP address. If \fImaxhostlen\fP is 0, then the
-system default, as determined by the utmp or utmpx structures, is
-used. The \fBnostriplocal\fP and \fBstriplocal\fP options, which must
-be preceded by a comma, control whether or not the local host domain
-is stripped from the remote hostname. By default, the equivalent of
-\fBstriplocal\fP is in effect.
-
-.PP
-.I Klogind
-supports five options which are used for testing
-purposes:
-
-.IP \fB\-S\ keytab\fP 10
-Set the \fIkeytab\fP file to use.
-
-.IP \fB\-M\ realm\fP
-Set the Kerberos realm to use.
-
-.IP \fB\-L\ login\fP
-Set the login program to use. This option only has an effect if
-DO_NOT_USE_K_LOGIN was not defined when
-.I klogind
-was compiled.
-
-.IP \fB\-D\ port\fP
-Run in standalone mode, listening on \fBport\fP. The daemon will exit
-after one connection and will not background itself.
-
-.IP \fB\-f\fP
-Allows for standalone daemon operation. A new child is started for
-each incoming connection and waits for it to finish before accepting
-the next connection. This automagically figures out which port to bind
-to if no port is specified.
-
-.SH DIAGNOSTICS
-All diagnostic messages are returned on the connection
-associated with the
-.BR stderr ,
-after which any network connections are closed.
-An error is indicated by a leading byte with a value of 1.
-.PP
-.B ``Try again.''
-.br
-A
-.I fork
-by the server failed.
-.PP
-.B ``/bin/sh: ...''
-.br
-The user's login shell could not be started.
-.SH SEE ALSO
-rlogind(8), rlogin(1)
-.SH BUGS
-A more extensible protocol should be used.
+++ /dev/null
-/*
- * appl/bsd/krcp.c
- */
-
-/*
- * Copyright (c) 1983 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef lint
-char copyright[] =
- "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
- All rights reserved.\n";
-#endif /* not lint */
-
-/* based on @(#)rcp.c 5.10 (Berkeley) 9/20/88 */
-
- /*
- * rcp
- */
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#include <sys/param.h>
-#ifndef _TYPES_
-#include <sys/types.h>
-#define _TYPES_
-#endif
-#include <sys/file.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/ioctl.h>
-
-#include <netinet/in.h>
-
-#include <stdio.h>
-#include <signal.h>
-#include <pwd.h>
-#include <ctype.h>
-#include <netdb.h>
-#include <errno.h>
-#include <string.h>
-#ifdef HAVE_VFORK_H
-#include <vfork.h>
-#endif
-#include <stdarg.h>
-#include <sys/wait.h>
-
-#ifdef KERBEROS
-#include "k5-int.h"
-#include <k5-util.h>
-#include <com_err.h>
-
-#include "defines.h"
-
-#define RCP_BUFSIZ 4096
-
-int sock;
-char *krb_realm = NULL;
-char *krb_cache = NULL;
-char *krb_config = NULL;
-krb5_encrypt_block eblock; /* eblock for encrypt/decrypt */
-krb5_context bsd_context;
-
-void try_normal(char **);
-char **save_argv(int, char **);
-#ifndef HAVE_STRSAVE
-char *strsave();
-#endif
-int rcmd_stream_write(), rcmd_stream_read();
-void usage(void), sink(int, char **),
- source(int, char **), rsource(char *, struct stat *), verifydir(char *),
- answer_auth(char *, char *);
-int response(void), hosteq(char *, char *), okname(char *),
- susystem(char *);
-int encryptflag = 0;
-
-#ifndef UCB_RCP
-#define UCB_RCP "/bin/rcp"
-#endif
-
-#endif /* KERBEROS */
-
-int rem;
-char *colon(char *);
-int errs;
-krb5_sigtype lostconn(int);
-int iamremote, targetshouldbedirectory;
-int iamrecursive;
-int pflag;
-int forcenet;
-struct passwd *pwd;
-int userid;
-int port = 0;
-
-struct buffer {
- unsigned int cnt;
- char *buf;
-};
-
-struct buffer *allocbuf(struct buffer *, int, int);
-
-#define NULLBUF (struct buffer *) 0
-
-void error (char *fmt, ...)
-#if !defined (__cplusplus) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7))
- __attribute__ ((__format__ (__printf__, 1, 2)))
-#endif
- ;
-
-#define ga() (void) rcmd_stream_write(rem, "", 1, 0)
-
-int main(argc, argv)
- int argc;
- char **argv;
-{
- char *targ, *host, *src;
- char *suser, *tuser, *thost;
- int i;
- char buf[RCP_BUFSIZ], cmdbuf[30];
- char *cmd = cmdbuf;
- struct servent *sp;
- static char curhost[256];
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
-#endif
-#ifdef KERBEROS
- krb5_flags authopts;
- krb5_error_code status;
- int euid;
- char **orig_argv = save_argv(argc, argv);
- krb5_auth_context auth_context;
- enum kcmd_proto kcmd_proto = KCMD_PROTOCOL_COMPAT_HACK;
-
- status = krb5_init_context(&bsd_context);
- if (status) {
- com_err(argv[0], status, "while initializing krb5");
- exit(1);
- }
-#endif
-
- pwd = getpwuid(userid = getuid());
- if (pwd == 0) {
- fprintf(stderr, "who are you?\n");
- exit(1);
- }
-
- for (argc--, argv++; argc > 0 && **argv == '-'; argc--, argv++) {
- (*argv)++;
- while (**argv) switch (*(*argv)++) {
-
- case 'r':
- iamrecursive++;
- break;
-
- case 'p': /* preserve mtimes and atimes */
- pflag++;
- break;
-
- case 'D':
- argc--, argv++;
- if (argc == 0)
- usage();
- port = htons(atoi(*argv));
- goto next_arg;
-
- case 'N':
- forcenet++;
- break;
-
-#ifdef KERBEROS
- case 'x':
- encryptflag++;
- break;
- case 'k': /* Change kerberos realm */
- argc--, argv++;
- if (argc == 0)
- usage();
- if(!(krb_realm = strdup(*argv))){
- fprintf(stderr, "rcp: Cannot malloc.\n");
- exit(1);
- }
- goto next_arg;
- case 'c': /* Change default ccache file */
- argc--, argv++;
- if (argc == 0)
- usage();
- if(!(krb_cache = strdup(*argv))){
- fprintf(stderr, "rcp: Cannot malloc.\n");
- exit(1);
- }
- goto next_arg;
- case 'C': /* Change default config file */
- argc--, argv++;
- if (argc == 0)
- usage();
- if(!(krb_config = strdup(*argv))){
- fprintf(stderr, "rcp: Cannot malloc.\n");
- exit(1);
- }
- goto next_arg;
- case 'P':
- if (!strcmp (*argv, "O"))
- kcmd_proto = KCMD_OLD_PROTOCOL;
- else if (!strcmp (*argv, "N"))
- kcmd_proto = KCMD_NEW_PROTOCOL;
- else
- usage ();
- goto next_arg;
-#endif /* KERBEROS */
- /* The rest of these are not for users. */
- case 'd':
- targetshouldbedirectory = 1;
- break;
-
- case 'f': /* "from" */
- iamremote = 1;
- rcmd_stream_init_normal();
-#if defined(KERBEROS)
- if (encryptflag)
- answer_auth(krb_config, krb_cache);
-#endif /* KERBEROS */
-
- (void) response();
- source(--argc, ++argv);
- exit(errs);
-
- case 't': /* "to" */
- iamremote = 1;
- rcmd_stream_init_normal();
-#if defined(KERBEROS)
- if (encryptflag)
- answer_auth(krb_config, krb_cache);
-#endif /* KERBEROS */
-
- sink(--argc, ++argv);
- exit(errs);
-
- default:
- usage();
- }
- next_arg: ;
- }
-
- if (argc < 2)
- usage();
- if (argc > 2)
- targetshouldbedirectory = 1;
- rem = -1;
-
-
- if (port == 0) {
-#ifdef KERBEROS
- sp = getservbyname("kshell", "tcp");
-#else
- sp = getservbyname("shell", "tcp");
-#endif /* KERBEROS */
-
- if (sp == NULL) {
-#ifdef KERBEROS
- fprintf(stderr, "rcp: kshell/tcp: unknown service\n");
- try_normal(orig_argv);
-#else
- fprintf(stderr, "rcp: shell/tcp: unknown service\n");
- exit(1);
-#endif /* KERBEROS */
- }
- port = sp->s_port;
- }
-
-#ifdef KERBEROS
- if (asprintf(&cmd, "%srcp %s%s%s%s%s%s%s%s%s",
- encryptflag ? "-x " : "",
-
- iamrecursive ? " -r" : "", pflag ? " -p" : "",
- targetshouldbedirectory ? " -d" : "",
- krb_realm != NULL ? " -k " : "",
- krb_realm != NULL ? krb_realm : "",
- krb_cache != NULL ? " -c " : "",
- krb_cache != NULL ? krb_cache : "",
- krb_config != NULL ? " -C " : "",
- krb_config != NULL ? krb_config : "") < 0) {
- fprintf(stderr, "rcp: Cannot malloc.\n");
- exit(1);
- }
-
-#else /* !KERBEROS */
- (void) snprintf(cmd, sizeof(cmdbuf), "rcp%s%s%s",
- iamrecursive ? " -r" : "", pflag ? " -p" : "",
- targetshouldbedirectory ? " -d" : "");
-#endif /* KERBEROS */
-
-#ifdef POSIX_SIGNALS
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = lostconn;
- (void) sigaction(SIGPIPE, &sa, (struct sigaction *)0);
-#else
- (void) signal(SIGPIPE, lostconn);
-#endif
- targ = colon(argv[argc - 1]);
-
- /* Check if target machine is the current machine. */
-
- gethostname(curhost, sizeof(curhost));
- if (targ) { /* ... to remote */
- *targ++ = 0;
- if (hosteq(argv[argc - 1], curhost)) {
-
- /* If so, pretend there wasn't even one given
- * check for an argument of just "host:", it
- * should become "."
- */
-
- if (*targ == 0) {
- targ = ".";
- argv[argc - 1] = targ;
- }
- else
- argv[argc - 1] = targ;
- targ = 0;
- }
- }
- if (targ) {
- /* Target machine is some remote machine */
- if (*targ == 0)
- targ = ".";
- thost = strchr(argv[argc - 1], '@');
- if (thost) {
- *thost++ = 0;
- tuser = argv[argc - 1];
- if (*tuser == '\0')
- tuser = NULL;
- else if (!okname(tuser))
- exit(1);
- } else {
- thost = argv[argc - 1];
- tuser = NULL;
- }
- for (i = 0; i < argc - 1; i++) {
- src = colon(argv[i]);
- if (src) { /* remote to remote */
- *src++ = 0;
- if (*src == 0)
- src = ".";
- host = strchr(argv[i], '@');
- if (host) {
- *host++ = 0;
- suser = argv[i];
- if (*suser == '\0')
- suser = pwd->pw_name;
- else if (!okname(suser))
- continue;
- (void) snprintf(buf, sizeof(buf),
-#if defined(hpux) || defined(__hpux)
- "remsh %s -l %s -n %s %s '%s%s%s:%s'",
-#else
- "rsh %s -l %s -n %s %s '%s%s%s:%s'",
-#endif
- host, suser, cmd, src,
- tuser ? tuser : "",
- tuser ? "@" : "",
- thost, targ);
- } else
- (void) snprintf(buf, sizeof(buf),
-#if defined(hpux) || defined(__hpux)
- "remsh %s -n %s %s '%s%s%s:%s'",
-#else
- "rsh %s -n %s %s '%s%s%s:%s'",
-#endif
- argv[i], cmd, src,
- tuser ? tuser : "",
- tuser ? "@" : "",
- thost, targ);
- (void) susystem(buf);
- } else { /* local to remote */
- krb5_creds *cred;
- if (rem == -1) {
- (void) snprintf(buf, sizeof(buf), "%s -t %s",
- cmd, targ);
- host = thost;
-#ifdef KERBEROS
- authopts = AP_OPTS_MUTUAL_REQUIRED;
- status = kcmd(&sock, &host,
- port,
- pwd->pw_name,
- tuser ? tuser :
- pwd->pw_name,
- buf,
- 0,
- "host",
- krb_realm,
- &cred,
- 0, /* No seq # */
- 0, /* No server seq # */
- (struct sockaddr_in *) 0,
- (struct sockaddr_in *) 0,
- &auth_context, authopts,
- 0, /* Not any port # */
- 0,
- &kcmd_proto);
- if (status) {
- if (kcmd_proto == KCMD_NEW_PROTOCOL)
- /* Don't fall back to less safe methods. */
- exit (1);
- try_normal(orig_argv);
- }
- else {
- krb5_boolean similar;
- krb5_keyblock *key = &cred->keyblock;
-
- status = krb5_c_enctype_compare(bsd_context,
- ENCTYPE_DES_CBC_CRC,
- cred->keyblock.enctype,
- &similar);
- if (status)
- try_normal(orig_argv); /* doesn't return */
-
- if (!similar) {
- status = krb5_auth_con_getsendsubkey (bsd_context,
- auth_context,
- &key);
- if ((status || !key) && encryptflag)
- try_normal(orig_argv);
- }
- if (key == 0)
- key = &cred->keyblock;
-
- rcmd_stream_init_krb5(key, encryptflag, 0, 1,
- kcmd_proto);
- }
- rem = sock;
-#else
- rem = rcmd(&host, port, pwd->pw_name,
- tuser ? tuser : pwd->pw_name,
- buf, 0);
- if (rem < 0)
- exit(1);
-#endif /* KERBEROS */
- if (response() < 0)
- exit(1);
- }
- source(1, argv+i);
- }
- }
- } else { /* ... to local */
- if (targetshouldbedirectory)
- verifydir(argv[argc - 1]);
- for (i = 0; i < argc - 1; i++) {
- src = colon(argv[i]);
- /* Check if source machine is current machine */
- if (src) {
- *src++ = 0;
- if (hosteq(argv[i], curhost)) {
-
- /* If so, pretend src machine never given */
-
- if (*src == 0) {
- error("rcp: no path given in arg: %s:\n",
- argv[i]);
- errs++;
- continue;
- }
- argv[i] = src;
- src = 0;
- } else {
- /* not equiv, return colon */
- *(--src) = ':';
- }
- }
- if (src == 0) { /* local to local */
- (void) snprintf(buf, sizeof(buf), "/bin/cp%s%s %s %s",
- iamrecursive ? " -r" : "",
- pflag ? " -p" : "",
- argv[i], argv[argc - 1]);
- (void) susystem(buf);
- } else { /* remote to local */
- krb5_creds *cred;
- *src++ = 0;
- if (*src == 0)
- src = ".";
- host = strchr(argv[i], '@');
- if (host) {
- *host++ = 0;
- suser = argv[i];
- if (*suser == '\0')
- suser = pwd->pw_name;
- else if (!okname(suser))
- continue;
- } else {
- host = argv[i];
- suser = pwd->pw_name;
- }
- (void) snprintf(buf, sizeof(buf), "%s -f %s", cmd, src);
-#ifdef KERBEROS
- authopts = AP_OPTS_MUTUAL_REQUIRED;
- status = kcmd(&sock, &host,
- port,
- pwd->pw_name, suser,
- buf,
- 0,
- "host",
- krb_realm,
- &cred,
- 0, /* No seq # */
- 0, /* No server seq # */
- (struct sockaddr_in *) 0,
- (struct sockaddr_in *) 0,
- &auth_context, authopts,
- 0, /* Not any port # */
- 0,
- &kcmd_proto);
- if (status) {
- if (kcmd_proto == KCMD_NEW_PROTOCOL)
- /* Don't fall back to less safe methods. */
- exit (1);
- try_normal(orig_argv);
- } else {
- krb5_keyblock *key = &cred->keyblock;
-
- if (kcmd_proto == KCMD_NEW_PROTOCOL) {
- status = krb5_auth_con_getsendsubkey (bsd_context,
- auth_context,
- &key);
- if (status) {
- com_err (argv[0], status,
- "determining subkey for session");
- exit (1);
- }
- if (!key) {
- com_err (argv[0], 0,
- "no subkey negotiated for connection");
- exit (1);
- }
- }
-
- rcmd_stream_init_krb5(key, encryptflag, 0, 1, kcmd_proto);
- }
- rem = sock;
-
- euid = geteuid();
- if (euid == 0) {
- if (setuid(0)) {
- perror("rcp setuid 0"); errs++; exit(errs);
- }
- if(krb5_seteuid(userid)) {
- perror("rcp seteuid user"); errs++; exit(errs);
- }
- }
- sink(1, argv+argc-1);
- if (euid == 0) {
- if(krb5_seteuid(0)) {
- perror("rcp seteuid 0"); errs++; exit(errs);
- }
- }
-#else
- rem = rcmd(&host, port, pwd->pw_name, suser,
- buf, 0);
- if (rem < 0)
- continue;
- rcmd_stream_init_normal();
-#ifdef HAVE_SETREUID
- if (setreuid(0, userid)) {
- perror("rcp setreuid 0,user"); errs++; exit(errs);
- }
- sink(1, argv+argc-1);
- if (setreuid(userid, 0)) {
- perror("rcp setreuid user,0"); errs++; exit(errs);
- }
-#else
- if (setuid(0)) {
- perror("rcp setuid 0"); errs++; exit(errs);
- }
- if(seteuid(userid)) {
- perror("rcp seteuid user"); errs++; exit(errs);
- }
- sink(1, argv+argc-1);
- if(seteuid(0)) {
- perror("rcp seteuid 0"); errs++; exit(errs);
- }
-#endif
-#endif /* KERBEROS */
- (void) close(rem);
- rem = -1;
- }
- }
- }
- exit(errs);
-}
-
-
-
-void verifydir(cp)
- char *cp;
-{
- struct stat stb;
-
- if (stat(cp, &stb) >= 0) {
- if ((stb.st_mode & S_IFMT) == S_IFDIR)
- return;
- errno = ENOTDIR;
- }
- error("rcp: %s: %s.\n", cp, error_message(errno));
- exit(1);
-}
-
-
-
-char *colon(cp)
- char *cp;
-{
-
- while (*cp) {
- if (*cp == ':')
- return (cp);
- if (*cp == '/')
- return (0);
- cp++;
- }
- return (0);
-}
-
-
-
-int okname(cp0)
- char *cp0;
-{
- register char *cp = cp0;
- register int c;
-
- do {
- c = *cp;
- if (c & 0200)
- goto bad;
- if (!isalpha(c) && !isdigit(c) && c != '_' && c != '-')
- goto bad;
- cp++;
- } while (*cp);
- return (1);
- bad:
- fprintf(stderr, "rcp: invalid user name %s\n", cp0);
- return (0);
-}
-
-
-
-int susystem(s)
- char *s;
-{
- int status;
- pid_t pid, w;
-#ifdef POSIX_SIGNALS
- struct sigaction sa, isa, qsa;
-#else
- register krb5_sigtype (bsd_context, *istat)(), (*qstat)();
-#endif
-
- if ((pid = vfork()) == 0) {
- execl("/bin/sh", "sh", "-c", s, (char *)0);
- _exit(127);
- }
-
-#ifdef POSIX_SIGNALS
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_IGN;
- (void) sigaction(SIGINT, &sa, &isa);
- (void) sigaction(SIGQUIT, &sa, &qsa);
-#else
- istat = signal(SIGINT, SIG_IGN);
- qstat = signal(SIGQUIT, SIG_IGN);
-#endif
-
-#ifdef HAVE_WAITPID
- w = waitpid(pid, &status, 0);
-#else
- while ((w = wait(&status)) != pid && w != -1) /*void*/ ;
-#endif
- if (w == (pid_t)-1)
- status = -1;
-
-#ifdef POSIX_SIGNALS
- (void) sigaction(SIGINT, &isa, (struct sigaction *)0);
- (void) sigaction(SIGQUIT, &qsa, (struct sigaction *)0);
-#else
- (void) signal(SIGINT, istat);
- (void) signal(SIGQUIT, qstat);
-#endif
-
- return (status);
-}
-
-void source(argc, argv)
- int argc;
- char **argv;
-{
- char *last, *name;
- struct stat stb;
- static struct buffer buffer;
- struct buffer *bp;
- int x, readerr, f;
- unsigned int amt;
- off_t i;
- char buf[RCP_BUFSIZ];
-
- for (x = 0; x < argc; x++) {
- name = argv[x];
- if ((f = open(name, 0)) < 0) {
- error("rcp: %s: %s\n", name, error_message(errno));
- continue;
- }
- if (fstat(f, &stb) < 0)
- goto notreg;
- switch (stb.st_mode&S_IFMT) {
-
- case S_IFREG:
- break;
-
- case S_IFDIR:
- if (iamrecursive) {
- (void) close(f);
- rsource(name, &stb);
- continue;
- }
- /* fall into ... */
- default:
- notreg:
- (void) close(f);
- error("rcp: %s: not a plain file\n", name);
- continue;
- }
- last = strrchr(name, '/');
- if (last == 0)
- last = name;
- else
- last++;
- if (pflag) {
- /*
- * Make it compatible with possible future
- * versions expecting microseconds.
- */
- (void) snprintf(buf, sizeof(buf), "T%ld 0 %ld 0\n",
- stb.st_mtime, stb.st_atime);
- (void) rcmd_stream_write(rem, buf, strlen(buf), 0);
- if (response() < 0) {
- (void) close(f);
- continue;
- }
- }
- (void) snprintf(buf, sizeof(buf), "C%04o %ld %s\n",
- (int) stb.st_mode&07777, (long ) stb.st_size, last);
- (void) rcmd_stream_write(rem, buf, strlen(buf), 0);
- if (response() < 0) {
- (void) close(f);
- continue;
- }
- if ((bp = allocbuf(&buffer, f, RCP_BUFSIZ)) == NULLBUF) {
- (void) close(f);
- continue;
- }
- readerr = 0;
- for (i = 0; i < stb.st_size; i += bp->cnt) {
- amt = bp->cnt;
- if (i + amt > stb.st_size)
- amt = stb.st_size - i;
- if (readerr == 0 && read(f, bp->buf, amt) != amt)
- readerr = errno;
- (void) rcmd_stream_write(rem, bp->buf, amt, 0);
- }
- (void) close(f);
- if (readerr == 0)
- ga();
- else
- error("rcp: %s: %s\n", name, error_message(readerr));
- (void) response();
- }
-}
-
-
-
-#ifndef USE_DIRENT_H
-#include <sys/dir.h>
-#else
-#include <dirent.h>
-#endif
-
-void rsource(name, statp)
- char *name;
- struct stat *statp;
-{
- DIR *d = opendir(name);
- char *last;
-#ifdef USE_DIRENT_H
- struct dirent *dp;
-#else
- struct direct *dp;
-#endif
- char buf[RCP_BUFSIZ];
- char *bufv[1];
-
- if (d == 0) {
- error("rcp: %s: %s\n", name, error_message(errno));
- return;
- }
- last = strrchr(name, '/');
- if (last == 0)
- last = name;
- else
- last++;
- if (pflag) {
- (void) snprintf(buf, sizeof(buf), "T%ld 0 %ld 0\n",
- statp->st_mtime, statp->st_atime);
- (void) rcmd_stream_write(rem, buf, strlen(buf), 0);
- if (response() < 0) {
- closedir(d);
- return;
- }
- }
- (void) snprintf(buf, sizeof(buf), "D%04lo %d %s\n",
- (long) statp->st_mode&07777, 0, last);
- (void) rcmd_stream_write(rem, buf, strlen(buf), 0);
- if (response() < 0) {
- closedir(d);
- return;
- }
- while ((dp = readdir(d)) != NULL) {
- if (dp->d_ino == 0)
- continue;
- if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
- continue;
- if (strlen(name) + 1 + strlen(dp->d_name) >= RCP_BUFSIZ - 1) {
- error("%s/%s: Name too long.\n", name, dp->d_name);
- continue;
- }
- (void) snprintf(buf, sizeof(buf), "%s/%s", name, dp->d_name);
- bufv[0] = buf;
- source(1, bufv);
- }
- closedir(d);
- (void) rcmd_stream_write(rem, "E\n", 2, 0);
- (void) response();
-}
-
-
-
-int response()
-{
- char resp, c, rbuf[RCP_BUFSIZ], *cp = rbuf;
- if (rcmd_stream_read(rem, &resp, 1, 0) != 1)
- lostconn(0);
- switch (resp) {
-
- case 0: /* ok */
- return (0);
-
- default:
- *cp++ = resp;
- /* fall into... */
- case 1: /* error, followed by err msg */
- case 2: /* fatal error, "" */
- do {
- if (rcmd_stream_read(rem, &c, 1, 0) != 1)
- lostconn(0);
- *cp++ = c;
- } while (cp < &rbuf[RCP_BUFSIZ] && c != '\n');
- if (iamremote == 0)
- (void) write(2, rbuf, (unsigned) (cp - rbuf));
- errs++;
- if (resp == 1)
- return (-1);
- exit(1);
- }
- /*NOTREACHED*/
-}
-
-
-
-krb5_sigtype
- lostconn(signumber)
- int signumber;
-{
- if (iamremote == 0)
- fprintf(stderr, "rcp: lost connection\n");
- exit(1);
-}
-
-
-#if !defined(HAVE_UTIMES)
-#include <utime.h>
-#include <sys/time.h>
-
-/*
- * We emulate utimes() instead of utime() as necessary because
- * utimes() is more powerful than utime(), and rcp actually tries to
- * set the microsecond values; we don't want to take away
- * functionality unnecessarily.
- */
-int utimes(file, tvp)
-const char *file;
-struct timeval *tvp;
-{
- struct utimbuf times;
-
- times.actime = tvp[0].tv_sec;
- times.modtime = tvp[1].tv_sec;
- return(utime(file, ×));
-}
-#endif
-
-
-void sink(argc, argv)
- int argc;
- char **argv;
-{
- mode_t mode;
- mode_t mask = umask(0);
- off_t i, j;
- char *targ, *whopp, *cp;
- int of, wrerr, exists, first;
- off_t size;
- unsigned int amt, count;
- struct buffer *bp;
- static struct buffer buffer;
- struct stat stb;
- int targisdir = 0;
- char *myargv[1];
- char cmdbuf[RCP_BUFSIZ], nambuf[RCP_BUFSIZ];
- int setimes = 0;
- struct timeval tv[2];
-#define atime tv[0]
-#define mtime tv[1]
-#define SCREWUP(str) { whopp = str; goto screwup; }
-
- if (!pflag)
- (void) umask(mask);
- if (argc != 1) {
- error("rcp: ambiguous target\n");
- exit(1);
- }
- targ = *argv;
- if (targetshouldbedirectory)
- verifydir(targ);
- ga();
- if (stat(targ, &stb) == 0 && (stb.st_mode & S_IFMT) == S_IFDIR)
- targisdir = 1;
- for (first = 1; ; first = 0) {
- cp = cmdbuf;
- if (rcmd_stream_read(rem, cp, 1, 0) <= 0)
- return;
- if (*cp++ == '\n')
- SCREWUP("unexpected '\\n'");
- do {
- if (rcmd_stream_read(rem, cp, 1, 0) != 1)
- SCREWUP("lost connection");
- } while (*cp++ != '\n');
- *cp = 0;
- if (cmdbuf[0] == '\01' || cmdbuf[0] == '\02') {
- if (iamremote == 0)
- (void) write(2, cmdbuf+1, strlen(cmdbuf+1));
- if (cmdbuf[0] == '\02')
- exit(1);
- errs++;
- continue;
- }
- *--cp = 0;
- cp = cmdbuf;
- if (*cp == 'E') {
- ga();
- return;
- }
-
-#define getnum(t) (t) = 0; while (isdigit((int) *cp)) (t) = (t) * 10 + (*cp++ - '0');
- if (*cp == 'T') {
- setimes++;
- cp++;
- getnum(mtime.tv_sec);
- if (*cp++ != ' ')
- SCREWUP("mtime.sec not delimited");
- getnum(mtime.tv_usec);
- if (*cp++ != ' ')
- SCREWUP("mtime.usec not delimited");
- getnum(atime.tv_sec);
- if (*cp++ != ' ')
- SCREWUP("atime.sec not delimited");
- getnum(atime.tv_usec);
- if (*cp++ != '\0')
- SCREWUP("atime.usec not delimited");
- ga();
- continue;
- }
- if (*cp != 'C' && *cp != 'D') {
- /*
- * Check for the case "rcp remote:foo\* local:bar".
- * In this case, the line "No match." can be returned
- * by the shell before the rcp command on the remote is
- * executed so the ^Aerror_message convention isn't
- * followed.
- */
- if (first) {
- error("%s\n", cp);
- exit(1);
- }
- SCREWUP("expected control record");
- }
- cp++;
- mode = 0;
- for (; cp < cmdbuf+5; cp++) {
- if (*cp < '0' || *cp > '7')
- SCREWUP("bad mode");
- mode = (mode << 3) | (*cp - '0');
- }
- if (*cp++ != ' ')
- SCREWUP("mode not delimited");
- size = 0;
- while (isdigit((int) *cp))
- size = size * 10 + (*cp++ - '0');
- if (*cp++ != ' ')
- SCREWUP("size not delimited");
- if (targisdir) {
- if(strlen(targ) + strlen(cp) + 2 >= sizeof(nambuf))
- SCREWUP("target name too long");
- (void) snprintf(nambuf, sizeof(nambuf), "%s%s%s", targ,
- *targ ? "/" : "", cp);
- } else {
- if (strlen(targ) + 1 >= sizeof (nambuf))
- SCREWUP("target name too long");
- (void) strncpy(nambuf, targ, sizeof(nambuf) - 1);
- }
- nambuf[sizeof(nambuf) - 1] = '\0';
- exists = stat(nambuf, &stb) == 0;
- if (cmdbuf[0] == 'D') {
- if (exists) {
- if ((stb.st_mode&S_IFMT) != S_IFDIR) {
- errno = ENOTDIR;
- goto bad;
- }
- if (pflag)
- (void) chmod(nambuf, mode);
- } else if (mkdir(nambuf, mode) < 0)
- goto bad;
- myargv[0] = nambuf;
- sink(1, myargv);
- if (setimes) {
- setimes = 0;
- if (utimes(nambuf, tv) < 0)
- error("rcp: can't set times on %s: %s\n",
- nambuf, error_message(errno));
- }
- continue;
- }
- if ((of = open(nambuf, O_WRONLY|O_CREAT, mode)) < 0) {
- bad:
- error("rcp: %s: %s\n", nambuf, error_message(errno));
- continue;
- }
- if (exists && pflag) {
-#ifdef NOFCHMOD
- (void) chmod(nambuf, mode);
-#else
- (void) fchmod(of, mode);
-#endif
- }
- ga();
- if ((bp = allocbuf(&buffer, of, RCP_BUFSIZ)) == NULLBUF) {
- (void) close(of);
- continue;
- }
- cp = bp->buf;
- count = 0;
- wrerr = 0;
- for (i = 0; i < size; i += RCP_BUFSIZ) {
- amt = RCP_BUFSIZ;
- if (i + amt > size)
- amt = size - i;
- count += amt;
- do {
- j = rcmd_stream_read(rem, cp, amt, 0);
- if (j <= 0) {
- if (j == 0)
- error("rcp: dropped connection");
- else
- error("rcp: %s\n", error_message(errno));
- exit(1);
- }
- amt -= j;
- cp += j;
- } while (amt > 0);
- if (count == bp->cnt) {
- if (wrerr == 0 &&
- write(of, bp->buf, count) != count)
- wrerr++;
- count = 0;
- cp = bp->buf;
- }
- }
- if (count != 0 && wrerr == 0 &&
- write(of, bp->buf, count) != count)
- wrerr++;
- if (ftruncate(of, size))
- error("rcp: can't truncate %s: %s\n", nambuf, error_message(errno));
- if (close(of) != 0)
- error("rcp: error closing %s: %s\n", nambuf, error_message(errno));
- (void) response();
- if (setimes) {
- setimes = 0;
- if (utimes(nambuf, tv) < 0)
- error("rcp: can't set times on %s: %s\n",
- nambuf, error_message(errno));
- }
- if (wrerr)
- error("rcp: %s: %s\n", nambuf, error_message(errno));
- else
- ga();
- }
- screwup:
- error("rcp: protocol screwup: %s\n", whopp);
- exit(1);
-}
-
-
-
-struct buffer *allocbuf(bp, fd, blksize)
- struct buffer *bp;
- int fd, blksize;
-{
- struct stat stb;
- int size;
-
- if (fstat(fd, &stb) < 0) {
- error("rcp: fstat: %s\n", error_message(errno));
- return (NULLBUF);
- }
-
- size = blksize;
- if (bp->cnt < size) {
- if (bp->buf != 0)
- free(bp->buf);
- bp->buf = (char *)malloc((unsigned) size);
- if (bp->buf == 0) {
- error("rcp: malloc: out of memory\n");
- return (NULLBUF);
- }
- }
- bp->cnt = size;
- return (bp);
-}
-
-void
-#ifdef HAVE_STDARG_H
-error(char *fmt, ...)
-#else
-/*VARARGS1*/
-error(fmt, va_alist)
- char *fmt;
- va_dcl
-#endif
-{
- va_list ap;
- char buf[RCP_BUFSIZ], *cp = buf;
-
-#ifdef HAVE_STDARG_H
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
-
- errs++;
- *cp++ = 1;
- (void) vsnprintf(cp, sizeof(buf) - (cp - buf), fmt, ap);
- va_end(ap);
-
- if (iamremote)
- (void) rcmd_stream_write(rem, buf, strlen(buf), 0);
- else
- (void) write(2, buf+1, strlen(buf+1));
-}
-
-
-
-void usage()
-{
-#ifdef KERBEROS
- fprintf(stderr,
- "Usage: \trcp [-PN | -PO] [-p] [-x] [-k realm] f1 f2; or:\n\trcp [-PN | -PO] [-r] [-p] [-x] [-k realm] f1 ... fn d2\n");
-#else
- fputs("usage: rcp [-p] f1 f2; or: rcp [-rp] f1 ... fn d2\n", stderr);
-#endif
- exit(1);
-}
-
-
-
-int hosteq(h1, h2)
- char *h1, *h2;
-{
- struct hostent *h_ptr;
- char hname1[256];
-
- if (forcenet)
- return(0);
-
- /* get the official names for the two hosts */
-
- if ((h_ptr = gethostbyname(h1)) == NULL)
- return(0);
- strncpy(hname1, h_ptr->h_name, sizeof (hname1));
- hname1[sizeof (hname1) - 1] = '\0';
- if ((h_ptr = gethostbyname(h2)) == NULL)
- return(0);
-
- /*return if they are equal (strcmp returns 0 for equal - I return 1) */
-
- return(!strcmp(hname1, h_ptr->h_name));
-}
-
-
-
-#ifdef KERBEROS
-void try_normal(argv)
- char **argv;
-{
- register int i;
-#ifndef KRB5_ATHENA_COMPAT
- if (!encryptflag)
-#endif
- {
- fprintf(stderr,"trying normal rcp (%s)\n", UCB_RCP);
- fflush(stderr);
- /* close all but stdin, stdout, stderr */
- for (i = getdtablesize(); i > 2; i--)
- (void) close(i);
- execv(UCB_RCP, argv);
- perror("exec");
- }
- exit(1);
-}
-
-
-
-char **save_argv(argc, argv)
- int argc;
- char **argv;
-{
- register int i;
-
- char **local_argv = (char **)calloc((unsigned) argc+1,
- (unsigned) sizeof(char *));
- /* allocate an extra pointer, so that it is initialized to NULL
- and execv() will work */
- for (i = 0; i < argc; i++)
- local_argv[i] = strsave(argv[i]);
- return(local_argv);
-}
-
-
-
-#ifdef unicos61
-#define SIZEOF_INADDR SIZEOF_in_addr
-#else
-#define SIZEOF_INADDR sizeof(struct in_addr)
-#endif
-
-
-/* This function is mostly vestigial, since under normal operation
- * the -x flag doesn't get set for the server process for encrypted
- * rcp. It only gets called by beta clients attempting user-to-user
- * authentication. */
-void
- answer_auth(config_file, ccache_file)
- char *config_file;
- char *ccache_file;
-{
- krb5_data pname_data, msg;
- krb5_creds creds, *new_creds;
- krb5_ccache cc;
- krb5_error_code status;
- krb5_auth_context auth_context = NULL;
-
- if (config_file) {
- const char * filenames[2];
- filenames[1] = NULL;
- filenames[0] = config_file;
- if ((status = krb5_set_config_files(bsd_context, filenames)))
- exit(1);
- }
-
- memset (&creds, 0, sizeof(creds));
-
- if ((status = krb5_read_message(bsd_context, (krb5_pointer)&rem,
- &pname_data)))
- exit(1);
-
- if ((status = krb5_read_message(bsd_context, (krb5_pointer) &rem,
- &creds.second_ticket)))
- exit(1);
-
- if (ccache_file == NULL) {
- if ((status = krb5_cc_default(bsd_context, &cc)))
- exit(1);
- } else {
- if ((status = krb5_cc_resolve(bsd_context, ccache_file, &cc)))
- exit(1);
- }
-
- if ((status = krb5_cc_get_principal(bsd_context, cc, &creds.client)))
- exit(1);
-
- if ((status = krb5_parse_name(bsd_context, pname_data.data,
- &creds.server)) )
- exit(1);
-
- krb5_free_data_contents(bsd_context, &pname_data);
-
- if ((status = krb5_get_credentials(bsd_context, KRB5_GC_USER_USER, cc,
- &creds, &new_creds)))
- exit(1);
-
- if ((status = krb5_mk_req_extended(bsd_context, &auth_context,
- AP_OPTS_USE_SESSION_KEY,
- NULL, new_creds, &msg)))
- exit(1);
-
- if ((status = krb5_write_message(bsd_context, (krb5_pointer) &rem,
- &msg))) {
- krb5_free_data_contents(bsd_context, &msg);
- exit(1);
- }
-
- rcmd_stream_init_krb5(&new_creds->keyblock, encryptflag, 0, 0,
- KCMD_OLD_PROTOCOL);
-
- /* cleanup */
- krb5_free_cred_contents(bsd_context, &creds);
- krb5_free_creds(bsd_context, new_creds);
- krb5_free_data_contents(bsd_context, &msg);
-
- return;
-}
-
-
-
-char storage[2*RCP_BUFSIZ]; /* storage for the decryption */
-int nstored = 0;
-char *store_ptr = storage;
-
-#endif /* KERBEROS */
+++ /dev/null
-/*
- * appl/bsd/krlogin.c
- */
-
-/*
- * Copyright (c) 1983 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/*
- * Copyright (C) 1998 by the FundsXpress, INC.
- *
- * All rights reserved.
- *
- * Export of this software from the United States of America may require
- * a specific license from the United States Government. It is the
- * responsibility of any person or organization contemplating export to
- * obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of FundsXpress. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. FundsXpress makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef lint
-char copyright[] =
- "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
- All rights reserved.\n";
-#endif /* not lint */
-
-/* based on @(#)rlogin.c 5.12 (Berkeley) 9/19/88 */
-
-
- /*
- * rlogin - remote login
- */
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/ioctl.h>
-#include <sys/errno.h>
-#include <sys/file.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/wait.h>
-#include <fcntl.h>
-
-#include <netinet/in.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <pwd.h>
-#include <signal.h>
-#include <setjmp.h>
-#include <netdb.h>
-
-#ifdef HAVE_SYS_FILIO_H
-/* Solaris needs <sys/filio.h> for FIONREAD */
-#include <sys/filio.h>
-#endif
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-#if HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-
-#ifdef POSIX_TERMIOS
-#include <termios.h>
-#ifndef CNUL
-#define CNUL (char) 0
-#endif
-
-#else /* POSIX_TERMIOS */
-#include <sgtty.h>
-#endif /* POSIX_TERMIOS */
-
-#ifdef HAVE_SYS_SOCKIO_H
-/* for SIOCATMARK */
-#include <sys/sockio.h>
-#endif
-
-#ifdef HAVE_STREAMS
-#include <sys/stream.h>
-#include <sys/stropts.h>
-#endif
-
-#ifdef __SCO__
-/* for TIOCPKT_* */
-#include <sys/spt.h>
-/* for struct winsize */
-#include <sys/ptem.h>
-#endif
-
-#ifdef HAVE_STREAMS
-#ifdef HAVE_SYS_PTYVAR_H
-#include <sys/tty.h>
-#include <sys/ttold.h>
-/* solaris actually uses packet mode, so the real macros are needed too */
-#include <sys/ptyvar.h>
-#endif
-#endif
-
-#ifndef TIOCPKT_NOSTOP
-/* These values are over-the-wire protocol, *not* local values */
-#define TIOCPKT_NOSTOP 0x10
-#define TIOCPKT_DOSTOP 0x20
-#define TIOCPKT_FLUSHWRITE 0x02
-#endif
-
-#ifdef HAVE_SYS_IOCTL_COMPAT_H
-#include <sys/ioctl_compat.h>
-#endif
-
-#ifdef CRAY
-#include <sys/ttold.h>
-#endif
-
-
-#ifdef KERBEROS
-#include <krb5.h>
-#include <com_err.h>
-#include "defines.h"
-
-#define RLOGIN_BUFSIZ 5120
-
-void try_normal();
-char *krb_realm = (char *)0;
-int encrypt_flag = 0;
-int fflag = 0, Fflag = 0;
-krb5_creds *cred;
-struct sockaddr_in local, foreign;
-krb5_context bsd_context;
-krb5_auth_context auth_context;
-
-#ifndef UCB_RLOGIN
-#define UCB_RLOGIN "/usr/ucb/rlogin"
-#endif
-
-#include "rpaths.h"
-#endif /* KERBEROS */
-
-# ifndef TIOCPKT_WINDOW
-# define TIOCPKT_WINDOW 0x80
-# endif /* TIOCPKT_WINDOW */
-
-#ifndef ONOCR
-#define ONOCR 0
-#endif
-
-#ifdef POSIX_TERMIOS
-struct termios deftty;
-#endif
-
-char *getenv();
-
-char *name;
-int rem = -1; /* Remote socket fd */
-int do_inband = 0;
-char cmdchar = '~';
-int eight = 1; /* Default to 8 bit transmission */
-int no_local_escape = 0;
-int null_local_username = 0;
-int flow = 1; /* Default is to allow flow
- control at the local terminal */
-int flowcontrol; /* Since emacs can alter the
- flow control characteristics
- of a session we need a
- variable to keep track of
- the original characteristics */
-int confirm = 0; /* ask if ~. is given before dying. */
-int litout;
-#if defined(hpux) || defined(__hpux)
-char *speeds[] =
-{ "0", "50", "75", "110", "134", "150", "200", "300", "600",
- "900", "1200", "1800", "2400", "3600", "4800", "7200", "9600",
- "19200", "38400", "EXTA", "EXTB" };
-#else
-/* Solaris note: There are higher values we could use. But Casper Dik
- <Casper.Dik@Holland.Sun.Com> mentions in article
- <casper.938167062@uk-usenet.uk.sun.com> in comp.protocols.kerberos
- on 1999-09-24 some problems in sending higher values to remote
- systems (for non-Kerberos rlogind?). So let's stick with this
- list. Even if our current klogind doesn't have the problems, older
- versions are likely to.
-
- Daniel S. Riley <dsr@mail.lns.cornell.edu> gives 57600, 76800,
- 115200, 153600, 230400, 307200, 460800 as the higher values.
- (article <sh6711s713.fsf@lnscu4.lns.cornell.edu> in
- comp.protocols.kerberos, 1999-09-23) */
-char *speeds[] =
-{ "0", "50", "75", "110", "134", "150", "200", "300",
- "600", "1200", "1800", "2400", "4800", "9600", "19200", "38400" };
-#endif
-char term[256] = "network";
-
-#ifndef POSIX_SIGNALS
-#ifndef sigmask
-#define sigmask(m) (1 << ((m)-1))
-#endif
-#endif /* POSIX_SIGNALS */
-
-#ifdef NO_WINSIZE
-struct winsize {
- unsigned short ws_row, ws_col;
- unsigned short ws_xpixel, ws_ypixel;
-};
-#endif /* NO_WINSIZE */
-int dosigwinch = 0;
-struct winsize winsize;
-
-char *host=0; /* external, so it can be
- reached from confirm_death() */
-
-krb5_sigtype sigwinch (int);
-int server_message (int);
-void oob (void);
-krb5_sigtype lostpeer (int);
-void setsignal (int sig, krb5_sigtype (*act)());
-static int read_wrapper(int fd, char *buf, int size, int *got_esc);
-static void prf(char *f);
-void try_normal(char **);
-static void mode(int);
-#ifdef POSIX_SIGNALS
-static int reader(sigset_t *);
-static void doit(sigset_t *);
-#else
-static int reader(int);
-static void doit(int);
-#endif
-static int control(char *, unsigned int);
-static void sendwindow(void);
-static void stop(int), echo(int);
-static void writer(void), done(int);
-static int confirm_death (void);
-
-
-/* to allow exits from signal handlers, without conflicting declarations */
-static krb5_sigtype exit_handler() {
- exit(1);
-}
-
-
-/*
- * The following routine provides compatibility (such as it is)
- * between 4.2BSD Suns and others. Suns have only a `ttysize',
- * so we convert it to a winsize.
- */
-#ifdef TIOCGWINSZ
-#define get_window_size(fd, wp) ioctl(fd, TIOCGWINSZ, wp)
-#else
-#ifdef SYSV
-#ifndef SIGWINCH
-#define SIGWINCH SIGWINDOW
-#endif
-struct ttysize {
- int ts_lines;
- int ts_cols;
-};
-#define DEFAULT_LINES 24
-#define DEFAULT_COLS 80
-#endif
-
-
-
-int
- get_window_size(fd, wp)
-int fd;
-struct winsize *wp;
-{
- struct ttysize ts;
- int error;
-#ifdef SYSV
- char *envbuf;
- ts.ts_lines = DEFAULT_LINES;
- ts.ts_cols = DEFAULT_COLS;
- if (( envbuf = getenv("LINES")) != (char *) 0)
- ts.ts_lines = atoi(envbuf);
- if (( envbuf = getenv("COLUMNS")) != (char *) 0)
- ts.ts_cols = atoi(envbuf);
-#else
- if ((error = ioctl(0, TIOCGSIZE, &ts)) != 0)
- return (error);
-#endif
-
- wp->ws_row = ts.ts_lines;
- wp->ws_col = ts.ts_cols;
- wp->ws_xpixel = 0;
- wp->ws_ypixel = 0;
- return (0);
-}
-#endif /* TIOCGWINSZ */
-
-
-#ifdef POSIX_TERMIOS
-/* Globals for terminal modes and flow control */
-struct termios defmodes;
-struct termios ixon_state;
-#else
-#ifdef USE_TERMIO
-/* Globals for terminal modes and flow control */
-struct termio defmodes;
-struct termio ixon_state;
-#endif
-#endif
-
-
-int
-main(argc, argv)
- int argc;
- char **argv;
-{
- char *cp = (char *) NULL;
-#ifdef POSIX_TERMIOS
- struct termios ttyb;
-#else
-#ifdef USE_TERMIO
- struct termio ttyb;
-#else
- struct sgttyb ttyb;
-#endif
-#endif
- struct passwd *pwd;
- struct servent *sp;
- struct servent defaultservent;
- int uid, options = 0;
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
- sigset_t *oldmask, omask, urgmask;
-#else
- int oldmask;
-#endif
- int on = 1;
-#ifdef KERBEROS
- char **orig_argv = argv;
- int sock;
- krb5_flags authopts;
- krb5_error_code status;
-#endif
- int port, debug_port = 0;
- enum kcmd_proto kcmd_proto = KCMD_PROTOCOL_COMPAT_HACK;
-
- memset(&defaultservent, 0, sizeof(struct servent));
- if (strrchr(argv[0], '/'))
- argv[0] = strrchr(argv[0], '/')+1;
-
- if ( argc < 2 ) goto usage;
- argc--;
- argv++;
-
- another:
- if (argc > 0 && host == 0 && strncmp(*argv, "-", 1)) {
- host = *argv;
- argv++, argc--;
- goto another;
- }
-
- if (argc > 0 && !strcmp(*argv, "-D")) {
- argv++; argc--;
- if (*argv == NULL) {
- fprintf (stderr,
- "rlogin: -D flag must be followed by the debug port.\n");
- exit (1);
- }
- debug_port = htons(atoi(*argv));
- argv++; argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-d")) {
- argv++, argc--;
- options |= SO_DEBUG;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-c")) {
- confirm = 1;
- argv++; argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-a")) { /* ask -- make remote */
- argv++; argc--; /* machine ask for password */
- null_local_username = 1; /* by giving null local user */
- goto another; /* id */
- }
- if (argc > 0 && !strcmp(*argv, "-t")) {
- argv++; argc--;
- if (argc == 0) goto usage;
- cp = *argv++; argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-n")) {
- no_local_escape = 1;
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-7")) { /* Pass only 7 bits */
- eight = 0;
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-noflow")) {
- flow = 0; /* Turn off local flow control so
- that ^S can be passed to emacs. */
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-l")) {
- argv++, argc--;
- if (argc == 0)
- goto usage;
- name = *argv++; argc--;
- goto another;
- }
- if (argc > 0 && !strncmp(*argv, "-e", 2)) {
- cmdchar = argv[0][2];
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-8")) {
- eight = 1;
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-L")) {
- litout = 1;
- argv++, argc--;
- goto another;
- }
-#ifdef KERBEROS
- if (argc > 0 && !strcmp(*argv, "-k")) {
- argv++, argc--;
- if (argc == 0) {
- fprintf(stderr,
- "rlogin: -k flag must be followed with a realm name.\n");
- exit (1);
- }
- if(!(krb_realm = strdup(*argv))){
- fprintf(stderr, "rlogin: Cannot malloc.\n");
- exit(1);
- }
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-x")) {
- encrypt_flag++;
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-f")) {
- if (Fflag) {
- fprintf(stderr, "rlogin: Only one of -f and -F allowed\n");
- goto usage;
- }
- fflag++;
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-F")) {
- if (fflag) {
- fprintf(stderr, "rlogin: Only one of -f and -F allowed\n");
- goto usage;
- }
- Fflag++;
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-PO")) {
- kcmd_proto = KCMD_OLD_PROTOCOL;
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-PN")) {
- kcmd_proto = KCMD_NEW_PROTOCOL;
- argv++, argc--;
- goto another;
- }
-#endif /* KERBEROS */
- if (host == 0)
- goto usage;
- if (argc > 0)
- goto usage;
- pwd = getpwuid(getuid());
- if (pwd == 0) {
- fprintf(stderr, "Who are you?\n");
- exit(1);
- }
-#ifdef KERBEROS
- status = krb5_init_context(&bsd_context);
- if (status) {
- com_err(argv[0], status, "while initializing krb5");
- exit(1);
- }
-#endif
-
-
- if (debug_port)
- port = debug_port;
- else {
-#ifdef KERBEROS
- /*
- * if there is an entry in /etc/services for Kerberos login,
- * attempt to login with Kerberos.
- * If we fail at any step, use the standard rlogin
- */
- if (encrypt_flag)
- sp = getservbyname("eklogin","tcp");
- else
- sp = getservbyname("klogin","tcp");
- if (sp == 0) {
- sp = &defaultservent; /* ANL */
- sp->s_port = encrypt_flag ? htons(2105) : htons(543);
- }
-#else
- sp = getservbyname("login", "tcp");
- if (sp == 0) {
- fprintf(stderr, "rlogin: login/tcp: unknown service\n");
- exit(2);
- }
-#endif /* KERBEROS */
-
- port = sp->s_port;
- }
-
-
- if (cp == (char *) NULL) cp = getenv("TERM");
- if (cp) {
- (void) strncpy(term, cp, sizeof (term));
- term[sizeof (term) - 1] = '\0';
- }
-#ifdef POSIX_TERMIOS
- if (tcgetattr(0, &ttyb) == 0) {
- int ospeed = cfgetospeed (&ttyb);
-
- term[sizeof(term) - 1] = '\0';
- (void) strncat(term, "/", sizeof(term) - 1 - strlen(term));
- if (ospeed >= 50)
- /* On some systems, ospeed is the baud rate itself,
- not a table index. */
- snprintf (term + strlen (term),
- sizeof(term) - strlen(term), "%d", ospeed);
- else if (ospeed >= sizeof(speeds)/sizeof(char*))
- /* Past end of table, but not high enough to
- look like a real speed. */
- (void) strncat (term, speeds[sizeof(speeds)/sizeof(char*) - 1], sizeof(term) - 1 - strlen(term));
- else {
- (void) strncat(term, speeds[ospeed], sizeof(term) - 1 - strlen(term));
- }
- term[sizeof (term) - 1] = '\0';
- }
-#else
- if (ioctl(0, TIOCGETP, &ttyb) == 0) {
- (void) strncat(term, "/", sizeof(term) - 1 - strlen(term));
- (void) strncat(term, speeds[ttyb.sg_ospeed], sizeof(term) - 1 - strlen(term));
- }
-#endif
- (void) get_window_size(0, &winsize);
-
-#ifdef POSIX_TERMIOS
- tcgetattr(0, &defmodes);
- tcgetattr(0, &ixon_state);
-#else
-#ifdef USE_TERMIO
- /**** moved before rcmd call so that if get a SIGPIPE in rcmd **/
- /**** we will have the defmodes set already. ***/
- (void)ioctl(fileno(stdin), TIOCGETP, &defmodes);
- (void)ioctl(fileno(stdin), TIOCGETP, &ixon_state);
-#endif
-#endif
-
- /* Catch SIGPIPE, as that means we lost the connection */
- /* will use SIGUSR1 for window size hack, so hold it off */
-#ifdef POSIX_SIGNALS
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = lostpeer;
- (void) sigaction(SIGPIPE, &sa, (struct sigaction *)0);
-
- (void) sigemptyset(&urgmask);
- (void) sigaddset(&urgmask, SIGUSR1);
- oldmask = &omask;
- (void) sigprocmask(SIG_BLOCK, &urgmask, oldmask);
-#else
- (void) signal(SIGPIPE, lostpeer);
-#ifdef sgi
- oldmask = sigignore( sigmask(SIGUSR1));
-#else
- oldmask = sigblock( sigmask(SIGUSR1));
-#endif
-#endif /* POSIX_SIGNALS */
-
-#ifdef KERBEROS
- authopts = AP_OPTS_MUTUAL_REQUIRED;
-
- /* Piggy-back forwarding flags on top of authopts; */
- /* they will be reset in kcmd */
- if (fflag || Fflag)
- authopts |= OPTS_FORWARD_CREDS;
- if (Fflag)
- authopts |= OPTS_FORWARDABLE_CREDS;
-
- status = kcmd(&sock, &host, port,
- null_local_username ? "" : pwd->pw_name,
- name ? name : pwd->pw_name, term,
- 0, "host", krb_realm,
- &cred,
- 0, /* No need for sequence number */
- 0, /* No need for server seq # */
- &local, &foreign,
- &auth_context, authopts,
- 0, /* Not any port # */
- 0,
- &kcmd_proto);
- if (status) {
- if (kcmd_proto == KCMD_NEW_PROTOCOL && encrypt_flag)
- /* Don't fall back to something less secure. */
- exit (1);
- try_normal(orig_argv);
- } else {
- krb5_keyblock *key = 0;
-
- if (kcmd_proto == KCMD_NEW_PROTOCOL) {
- do_inband = 1;
-
- status = krb5_auth_con_getsendsubkey (bsd_context, auth_context,
- &key);
- if ((status || !key) && encrypt_flag)
- try_normal(orig_argv);
- }
- if (key == 0)
- key = &cred->keyblock;
-
- rcmd_stream_init_krb5(key, encrypt_flag, 1, 1, kcmd_proto);
- }
-
- rem = sock;
-
-#else
- rem = rcmd(&host, port,
- null_local_username ? "" : pwd->pw_name,
- name ? name : pwd->pw_name, term, 0);
-#endif /* KERBEROS */
-
- if (rem < 0)
- exit(1);
-
- if (options & SO_DEBUG &&
- setsockopt(rem, SOL_SOCKET, SO_DEBUG, (char*)&on, sizeof (on)) < 0)
- perror("rlogin: setsockopt (SO_DEBUG)");
- uid = getuid();
- if (setuid(uid) < 0) {
- perror("rlogin: setuid");
- exit(1);
- }
- flowcontrol = flow; /* Set up really correct non-volatile variable */
- doit(oldmask);
- /*NOTREACHED*/
- usage:
-#ifdef KERBEROS
- fprintf (stderr,
- "usage: rlogin host [-option] [-option...] [-k realm ] [-t ttytype] [-l username]\n");
- fprintf (stderr, " where option is e, 7, 8, noflow, n, a, x, f, F, c, PO, or PN\n");
-#else /* !KERBEROS */
- fprintf (stderr,
- "usage: rlogin host [-option] [-option...] [-t ttytype] [-l username]\n");
- fprintf (stderr, " where option is e, 7, 8, noflow, n, a, or c\n");
-#endif /* KERBEROS */
- exit(1);
-}
-
-
-
-static int confirm_death ()
-{
- char hostname[33];
- char input;
- int answer;
- if (!confirm) return (1); /* no confirm, just die */
-
- if (gethostname (hostname, sizeof(hostname)-1) != 0)
- strlcpy (hostname, "???", sizeof(hostname));
- else
- hostname[sizeof(hostname)-1] = '\0';
-
- fprintf (stderr, "\r\nKill session on %s from %s (y/n)? ",
- host, hostname);
- fflush (stderr);
- if (read(0, &input, 1) != 1)
- answer = EOF; /* read from stdin */
- else
- answer = (int) input;
- fprintf (stderr, "%c\r\n", answer);
- fflush (stderr);
- return (answer == 'y' || answer == 'Y' || answer == EOF ||
- answer == 4); /* control-D */
-}
-
-
-
-#define CRLF "\r\n"
-
-int child;
-krb5_sigtype catchild (int);
-krb5_sigtype writeroob (int);
-
-int defflags, tabflag;
-int deflflags;
-char deferase, defkill;
-
-#ifdef USE_TERMIO
-char defvtim, defvmin;
-#if defined(hpux) || defined(__hpux)
-#include <sys/bsdtty.h>
-#include <sys/ptyio.h>
-#endif
-struct tchars {
- char t_intrc; /* interrupt */
- char t_quitc; /* quit */
- char t_startc; /* start output */
- char t_stopc; /* stop output */
- char t_eofc; /* end-of-file */
- char t_brkc; /* input delimiter (like nl) */
-};
-#endif
-
-
-#ifndef POSIX_TERMIOS
-#ifdef TIOCGLTC
-/*
- * POSIX 1003.1-1988 does not define a 'suspend' character.
- * POSIX 1003.1-1990 does define an optional VSUSP but not a VDSUSP character.
- * Some termio implementations (A/UX, Ultrix 4.2) include both.
- *
- * However, since this is all derived from the BSD ioctl() and ltchars
- * concept, all these implementations generally also allow for the BSD-style
- * ioctl(). So we'll simplify the problem by only testing for the ioctl().
- */
-struct ltchars defltc;
-struct ltchars noltc = { -1, -1, -1, -1, -1, -1 };
-#endif
-struct tchars deftc;
-struct tchars notc = { -1, -1, -1, -1, -1, -1 };
-#endif
-
-static void doit(oldmask)
-#ifdef POSIX_SIGNALS
- sigset_t *oldmask;
-#else
- int oldmask;
-#endif
-{
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
-#endif
-
-#ifdef POSIX_TERMIOS
- (void) tcgetattr(0, &deftty);
-#ifdef VLNEXT
- /* there's a POSIX way of doing this, but do we need it general? */
- deftty.c_cc[VLNEXT] = 0;
-#endif
-#else
-#ifdef USE_TERMIO
- struct termio sb;
-#else
- struct sgttyb sb;
-#endif
-
- (void) ioctl(0, TIOCGETP, (char *)&sb);
- defflags = sb.sg_flags;
-#ifdef USE_TERMIO
- tabflag = sb.c_oflag & TABDLY;
- defflags |= ECHO;
- deferase = sb.c_cc[VERASE];
- defkill = sb.c_cc[VKILL];
- sb.c_cc[VMIN] = 1;
- sb.c_cc[VTIME] = 1;
- defvtim = sb.c_cc[VTIME];
- defvmin = sb.c_cc[VMIN];
- deftc.t_quitc = CQUIT;
- deftc.t_startc = CSTART;
- deftc.t_stopc = CSTOP ;
- deftc.t_eofc = CEOF;
- deftc.t_brkc = '\n';
-#else
- tabflag = defflags & TBDELAY;
- defflags &= ECHO | CRMOD;
- deferase = sb.sg_erase;
- defkill = sb.sg_kill;
- (void) ioctl(0, TIOCLGET, (char *)&deflflags);
- (void) ioctl(0, TIOCGETC, (char *)&deftc);
-#endif
-
- notc.t_startc = deftc.t_startc;
- notc.t_stopc = deftc.t_stopc;
- (void) ioctl(0, TIOCGLTC, (char *)&defltc);
-#endif
-#ifdef POSIX_SIGNALS
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_IGN;
- (void) sigaction(SIGINT, &sa, (struct sigaction *)0);
-#else
- (void) signal(SIGINT, SIG_IGN);
-#endif
-
- setsignal(SIGHUP, exit_handler);
- setsignal(SIGQUIT, exit_handler);
-
- child = fork();
- if (child == -1) {
- perror("rlogin: fork");
- done(1);
- }
- if (child == 0) {
- mode(1);
- if (reader(oldmask) == 0) {
- prf("Connection closed.");
- exit(0);
- }
- sleep(1);
- prf("\007Connection closed.");
- exit(3);
- }
-
-#ifdef POSIX_SIGNALS
- /* "sa" has already been initialized above. */
-
- sa.sa_handler = writeroob;
- (void) sigaction(SIGUSR1, &sa, (struct sigaction *)0);
-
- sigprocmask(SIG_SETMASK, oldmask, (sigset_t*)0);
-
- sa.sa_handler = catchild;
- (void) sigaction(SIGCHLD, &sa, (struct sigaction *)0);
-#else
- (void) signal(SIGUSR1, writeroob);
-#ifndef sgi
- (void) sigsetmask(oldmask);
-#endif
- (void) signal(SIGCHLD, catchild);
-#endif /* POSIX_SIGNALS */
- writer();
- prf("Closed connection.");
- done(0);
-}
-
-
-
-/*
- * Trap a signal, unless it is being ignored.
- */
-void
-setsignal(sig, act)
- int sig;
- krb5_sigtype (*act)();
-{
-#ifdef POSIX_SIGNALS
- sigset_t omask, igmask;
- struct sigaction sa;
-
- sigemptyset(&igmask);
- sigaddset(&igmask, sig);
- sigprocmask(SIG_BLOCK, &igmask, &omask);
-#else
-#ifdef sgi
- int omask = sigignore(sigmask(sig));
-#else
- int omask = sigblock(sigmask(sig));
-#endif
-#endif /* POSIX_SIGNALS */
-
-#ifdef POSIX_SIGNALS
- (void) sigaction(sig, (struct sigaction *)0, &sa);
- if (sa.sa_handler != SIG_IGN) {
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = act;
- (void) sigaction(sig, &sa, (struct sigaction *)0);
- }
- sigprocmask(SIG_SETMASK, &omask, (sigset_t*)0);
-#else
- if (signal(sig, act) == SIG_IGN)
- (void) signal(sig, SIG_IGN);
-#ifndef sgi
- (void) sigsetmask(omask);
-#endif
-#endif
-}
-
-
-
-static void
-done(status)
- int status;
-{
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
-#endif
-#ifndef HAVE_WAITPID
- pid_t w;
-#endif
-
- mode(0);
- if (child > 0) {
- /* make sure catchild does not snap it up */
-#ifdef POSIX_SIGNALS
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_DFL;
- (void) sigaction(SIGCHLD, &sa, (struct sigaction *)0);
-#else
- (void) signal(SIGCHLD, SIG_DFL);
-#endif
-
- if (kill(child, SIGKILL) >= 0) {
-#ifdef HAVE_WAITPID
- (void) waitpid(child, 0, 0);
-#else
- while ((w = wait(0)) > 0 && w != child)
- /*void*/;
-#endif
- }
- }
- exit(status);
-}
-
-
-
-
-
-
-/*
- * This is called when the reader process gets the out-of-band (urgent)
- * request to turn on the window-changing protocol.
- */
-krb5_sigtype
- writeroob(signo)
-int signo;
-{
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
-#endif
-
- if (dosigwinch == 0) {
- sendwindow();
-#ifdef POSIX_SIGNALS
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = sigwinch;
- (void) sigaction(SIGWINCH, &sa, (struct sigaction *)0);
-#else
- (void) signal(SIGWINCH, sigwinch);
-#endif
- }
- dosigwinch = 1;
-}
-
-
-
-krb5_sigtype
- catchild(signo)
-int signo;
-{
-#ifdef WAIT_USES_INT
- int status;
-#else
- union wait status;
-#endif
- int pid;
-
- again:
-#ifdef HAVE_WAITPID
- pid = waitpid(-1, &status, WNOHANG|WUNTRACED);
-#else
- pid = wait3(&status, WNOHANG|WUNTRACED, (struct rusage *)0);
-#endif
- if (pid == 0)
- return;
- /*
- * if the child (reader) dies, just quit
- */
-#ifdef WAIT_USES_INT
- if (pid < 0 || (pid == child && !WIFSTOPPED(status)))
- done(status);
-#else
- if ((pid < 0) || ((pid == child) && (!WIFSTOPPED(status))))
- done((int)(status.w_termsig | status.w_retcode));
-#endif
- goto again;
-}
-
-
-
-/*
- * writer: write to remote: 0 -> line.
- * ~. terminate
- * ~^Z suspend rlogin process.
- * ~^Y suspend rlogin process, but leave reader alone.
- */
-static void writer()
-{
- int n_read;
- char buf[1024];
- int got_esc; /* set to true by read_wrapper if an escape char
- was encountered */
- char c;
-
-#ifdef ultrix
- fd_set waitread;
- register n;
-
- /* we need to wait until the reader() has set up the terminal, else
- the read() below may block and not unblock when the terminal
- state is reset.
- */
- for (;;) {
- FD_ZERO(&waitread);
- FD_SET(0, &waitread);
- n = select(1, &waitread, 0, 0, 0, 0);
- if (n < 0 && errno == EINTR)
- continue;
- if (n > 0)
- break;
- else
- if (n < 0) {
- perror("select");
- break;
- }
- }
-#endif /* ultrix */
-
- /* This loop works as follows. Call read_wrapper to get data until
- we would block or until we read a cmdchar at the beginning of a line.
- If got_esc is false, we just send everything we got back. If got_esc
- is true, we send everything except the cmdchar at the end and look at
- the next char. If its a "." we break out of the loop and terminate.
- If its ^Z or ^Y we call stop with the value of the char and continue.
- If its none of those, we send the cmdchar and then send the char we
- just read, unless that char is also the cmdchar (in which case we are
- only supposed to send one of them). When this loop ends, so does the
- program.
- */
-
- for (;;) {
-
- /* read until we would block or we get a cmdchar */
- n_read = read_wrapper(0,buf,sizeof(buf),&got_esc);
-
- /* if read returns an error or 0 bytes, just quit */
- if (n_read <= 0) {
- break;
- }
-
- if (!got_esc) {
- if (rcmd_stream_write(rem, buf, (unsigned) n_read, 0) == 0) {
- prf("line gone");
- break;
- }
- continue;
- }
- else {
- /* This next test is necessary to avoid sending 0 bytes of data
- in the event that we got just a cmdchar */
- if (n_read > 1) {
- if (rcmd_stream_write(rem, buf, (unsigned) (n_read-1), 0) == 0) {
- prf("line gone");
- break;
- }
- }
- if (read_wrapper(0,&c,1,&got_esc) <= 0) {
- break;
- }
-
-#ifdef POSIX_TERMIOS
- if (c == '.' || c == deftty.c_cc[VEOF])
-#else
- if (c == '.' || c == deftc.t_eofc)
-#endif
- {
- if (confirm_death()) {
- echo(c);
- break;
- }
- }
-
-#ifdef POSIX_TERMIOS
- if ( (
- (c == deftty.c_cc[VSUSP])
-#ifdef VDSUSP
- || (c == deftty.c_cc[VDSUSP])
-#endif
- )
- && !no_local_escape) {
- echo(c);
- stop(c);
- continue;
- }
-#else /*POSIX_TERMIOS*/
-#ifdef TIOCGLTC
- if ((c == defltc.t_suspc || c == defltc.t_dsuspc)
- && !no_local_escape) {
- echo(c);
- stop(c);
- continue;
- }
-#endif /*TIOCGLTC*/
-#endif
-
-
- if (c != cmdchar) {
- rcmd_stream_write(rem, &cmdchar, 1, 0);
- }
-
- if (rcmd_stream_write(rem,&c,1,0) == 0) {
- prf("line gone");
- break;
- }
- }
- }
-}
-
-/* This function reads up to size bytes from file desciptor fd into buf.
- It will copy as much data as it can without blocking, but will never
- copy more than size bytes. In addition, if it encounters a cmdchar
- at the beginning of a line, it will copy everything up to and including
- the cmdchar, but nothing after that. In this instance *esc_char is set
- to true and any remaining data is buffered and copied on a subsequent
- call. Otherwise, *esc_char will be set to false and the minimum of size,
- 1024, and the number of bytes that can be read without blocking will
- be copied. In all cases, a non-negative return value indicates the number
- of bytes actually copied and a return value of -1 indicates that there
- was a read error (other than EINTR) and errno is set appropriately.
-*/
-
-static int read_wrapper(fd,buf,size,got_esc)
- int fd;
- char *buf;
- int size;
- int *got_esc;
-{
- static char tbuf[1024];
- static char *data_start = tbuf;
- static char *data_end = tbuf;
- static int bol = 1;
- unsigned int return_length = 0;
- char c;
-
- /* if we have no data buffered, get more */
- if (data_start == data_end) {
- int n_read;
- while ((n_read = read(fd, tbuf, sizeof(tbuf))) <= 0) {
- if (n_read < 0 && errno == EINTR)
- continue;
- return n_read;
- }
- data_start = tbuf;
- data_end = tbuf+n_read;
- }
-
- *got_esc = 0;
-
- /* We stop when we've fully checked the buffer or have checked size
- bytes. We break out and set *got_esc if we encounter a cmdchar
- at the beginning of a line.
- */
-
- while (data_start+return_length < data_end && return_length < size) {
-
- c = *(data_start+return_length);
- return_length++;
-
- if (bol == 1 && c == cmdchar) {
- bol = 0;
- *got_esc = 1;
- break;
- }
-
-#ifdef POSIX_TERMIOS
- bol = (c == deftty.c_cc[VKILL] ||
- c == deftty.c_cc[VINTR] ||
- c == '\r' || c == '\n');
-
-#else /* !POSIX_TERMIOS */
- bol = c == defkill || c == deftc.t_eofc ||
- c == deftc.t_intrc || c == defltc.t_suspc ||
- c == '\r' || c == '\n';
-#endif
- }
-
- memcpy(buf, data_start, return_length);
- data_start = data_start + return_length;
- return return_length;
-}
-
-static void echo(c)
- register char c;
-{
- char buf[8];
- register char *p = buf;
-
- c &= 0177;
- *p++ = cmdchar;
- if (c < ' ') {
- *p++ = '^';
- *p++ = c + '@';
- } else if (c == 0177) {
- *p++ = '^';
- *p++ = '?';
- } else
- *p++ = c;
- *p++ = '\r';
- *p++ = '\n';
- (void) write(1, buf, (unsigned) (p - buf));
-}
-
-
-
-static void stop(cmdc)
- char cmdc;
-{
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
-#endif
-
- mode(0);
-
-#ifdef POSIX_SIGNALS
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_IGN;
- (void) sigaction(SIGCHLD, &sa, (struct sigaction *)0);
-#else
- (void) signal(SIGCHLD, SIG_IGN);
-#endif
-
-#ifdef POSIX_TERMIOS
- (void) kill(cmdc == deftty.c_cc[VSUSP] ? 0 : getpid(), SIGTSTP);
-#else
-#ifdef TIOCGLTC
- (void) kill(cmdc == defltc.t_suspc ? 0 : getpid(), SIGTSTP);
-#endif
-#endif
-#ifdef POSIX_SIGNALS
- sa.sa_handler = catchild;
- (void) sigaction(SIGCHLD, &sa, (struct sigaction *)0);
-#else
- (void) signal(SIGCHLD, catchild);
-#endif
-
- mode(1);
- sigwinch(SIGWINCH); /* check for size changes */
-}
-
-
-
-krb5_sigtype
- sigwinch(signo)
-int signo;
-{
- struct winsize ws;
-
- if (dosigwinch && get_window_size(0, &ws) == 0 &&
- memcmp(&winsize, &ws, sizeof (ws))) {
- winsize = ws;
- sendwindow();
- }
-}
-
-
-
-/*
- * Send the window size to the server via the magic escape
- */
-static void sendwindow()
-{
- char obuf[4 + sizeof (struct winsize)];
- struct winsize *wp = (struct winsize *)(void *)(obuf+4);
-
- obuf[0] = 0377;
- obuf[1] = 0377;
- obuf[2] = 's';
- obuf[3] = 's';
- wp->ws_row = htons(winsize.ws_row);
- wp->ws_col = htons(winsize.ws_col);
- wp->ws_xpixel = htons(winsize.ws_xpixel);
- wp->ws_ypixel = htons(winsize.ws_ypixel);
- (void) rcmd_stream_write(rem, obuf, sizeof(obuf), 0);
-}
-
-
-
-/*
- * reader: read from remote: line -> 1
- */
-#define READING 1
-#define WRITING 2
-
-char rcvbuf[8 * 1024];
-int rcvcnt;
-int rcvstate;
-int ppid;
-
-/* returns 1 if flush, 0 otherwise */
-
-int server_message(mark)
- int mark;
-{
-#ifndef POSIX_TERMIOS
- int out = FWRITE;
-#endif
-#ifdef POSIX_TERMIOS
- struct termios tty;
-#else
-#ifdef USE_TERMIO
- struct termio sb;
-#else
- struct sgttyb sb;
-#endif
-#endif
-
- if (mark & TIOCPKT_WINDOW) {
- /*
- * Let server know about window size changes
- */
- (void) kill(ppid, SIGUSR1);
- }
-#ifdef POSIX_TERMIOS
- if (!eight && (mark & TIOCPKT_NOSTOP)) {
- (void) tcgetattr(0, &tty);
- tty.c_iflag &= ~IXON;
- (void) tcsetattr(0, TCSADRAIN, &tty);
- }
- if (!eight && (mark & TIOCPKT_DOSTOP)) {
- (void) tcgetattr(0, &tty);
- tty.c_iflag |= IXON;
- (void) tcsetattr(0, TCSADRAIN, &tty);
- }
-#else
- if (!eight && (mark & TIOCPKT_NOSTOP)) {
- (void) ioctl(0, TIOCGETP, (char *)&sb);
-#ifdef USE_TERMIO
- sb.c_iflag |= IXOFF;
- sb.sg_flags &= ~ICANON;
-#else
- sb.sg_flags &= ~CBREAK;
- sb.sg_flags |= RAW;
- notc.t_stopc = -1;
- notc.t_startc = -1;
- (void) ioctl(0, TIOCSETC, (char *)¬c);
-#endif
- (void) ioctl(0, TIOCSETN, (char *)&sb);
- }
- if (!eight && (mark & TIOCPKT_DOSTOP)) {
- (void) ioctl(0, TIOCGETP, (char *)&sb);
-#ifdef USE_TERMIO
- sb.sg_flags |= ICANON;
- sb.c_iflag |= IXON;
-#else
- sb.sg_flags &= ~RAW;
- sb.sg_flags |= CBREAK;
- notc.t_stopc = deftc.t_stopc;
- notc.t_startc = deftc.t_startc;
- (void) ioctl(0, TIOCSETC, (char *)¬c);
-#endif
- (void) ioctl(0, TIOCSETN, (char *)&sb);
- }
-#endif
- if (mark & TIOCPKT_FLUSHWRITE) {
-#ifdef POSIX_TERMIOS
- (void) tcflush(1, TCOFLUSH);
-#else
-#ifdef TIOCFLUSH
- (void) ioctl(1, TIOCFLUSH, (char *)&out);
-#else
- (void) ioctl(1, TCFLSH, 1);
-#endif
-#endif
- return(1);
- }
-
- return(0);
-}
-
-void oob()
-{
- char mark;
- static char waste[RLOGIN_BUFSIZ];
- int atmark, n;
-
- mark = 0;
-
- recv(rem, &mark, 1, MSG_OOB);
-
- if (server_message(mark)) {
- for (;;) {
- if (ioctl(rem, SIOCATMARK, &atmark) < 0) {
- perror("ioctl");
- return;
- }
- if (atmark)
- break;
- n = read(rem, waste, sizeof (waste));
- if (n <= 0)
- break;
- }
- }
-}
-
-/* two control messages are defined:
-
- a double flag byte of 'o' indicates a one-byte message which is
- identical to what was once carried out of band.
-
- a double flag byte of 'q' indicates a zero-byte message. This
- message is interpreted as two \377 data bytes. This is just a
- quote rule so that binary data from the server does not confuse the
- client. */
-
-static int control(cp, n)
- char *cp;
- unsigned int n;
-{
- if ((n >= 5) && (cp[2] == 'o') && (cp[3] == 'o')) {
- if (server_message(cp[4]))
- return(-5);
- return(5);
- } else if ((n >= 4) && (cp[2] == 'q') && (cp[3] == 'q')) {
- /* this is somewhat of a hack */
- cp[2] = '\377';
- cp[3] = '\377';
- return(2);
- }
-
- return(0);
-}
-
-/*
- * reader: read from remote: line -> 1
- */
-static int
-reader(oldmask)
-#ifdef POSIX_SIGNALS
- sigset_t *oldmask;
-#else
- int oldmask;
-#endif
-{
- fd_set readset, excset, writeset;
- int n, remaining;
- unsigned int left;
- char *bufp = rcvbuf;
- char *cp;
-
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
-
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_IGN;
- (void) sigaction(SIGTTOU, &sa, (struct sigaction *)0);
-
-#else
- (void) signal(SIGTTOU, SIG_IGN);
-#endif
-
- ppid = getppid();
- FD_ZERO(&readset);
- FD_ZERO(&excset);
- FD_ZERO(&writeset);
-#ifdef POSIX_SIGNALS
- sigprocmask(SIG_SETMASK, oldmask, (sigset_t*)0);
-#else
-#ifndef sgi
- (void) sigsetmask(oldmask);
-#endif
-#endif /* POSIX_SIGNALS */
-
- for (;;) {
- if ((remaining = rcvcnt - (bufp - rcvbuf)) > 0) {
- FD_SET(1,&writeset);
- rcvstate = WRITING;
- FD_CLR(rem, &readset);
- } else {
- bufp = rcvbuf;
- rcvcnt = 0;
- rcvstate = READING;
- FD_SET(rem,&readset);
- FD_CLR(1,&writeset);
- }
- if (!do_inband)
- FD_SET(rem,&excset);
- if (select(rem+1, &readset, &writeset, &excset, 0) > 0 ) {
- if (!do_inband)
- if (FD_ISSET(rem, &excset))
- oob();
- if (FD_ISSET(1,&writeset)) {
- n = write(1, bufp, remaining);
- if (n < 0) {
- if (errno != EINTR)
- return (-1);
- continue;
- }
- bufp += n;
- }
- if (FD_ISSET(rem, &readset)) {
- rcvcnt = rcmd_stream_read(rem, rcvbuf, sizeof (rcvbuf), 0);
- if (rcvcnt == 0)
- return (0);
- if (rcvcnt < 0)
- goto error;
-
- if (do_inband) {
- for (cp = rcvbuf; cp < rcvbuf+rcvcnt-1; cp++) {
- if (cp[0] == '\377' &&
- cp[1] == '\377') {
- left = (rcvbuf+rcvcnt) - cp;
- n = control(cp, left);
- /* |n| <= left */
- if (n < 0) {
- left -= (-n);
- rcvcnt = 0;
- /* flush before, and (-n) bytes */
- if (left > 0)
- memmove(rcvbuf, cp+(-n), left);
- cp = rcvbuf-1;
- } else if (n) {
- left -= n;
- rcvcnt -= n;
- if (left > 0)
- memmove(cp, cp+n, left);
- cp--;
- }
- }
- }
- }
- }
- } else
-error:
- {
- if (errno == EINTR)
- continue;
- perror("read");
- return (-1);
- }
- }
-}
-
-
-
-static void mode(f)
-int f;
-{
-#ifdef POSIX_TERMIOS
- struct termios newtty;
-#ifndef IEXTEN
-#define IEXTEN 0 /* No effect*/
-#endif
-#ifndef _POSIX_VDISABLE
-#define _POSIX_VDISABLE 0 /*A good guess at the disable-this-character character*/
-#endif
-
- switch(f) {
- case 0:
- (void) tcsetattr(0, TCSADRAIN, &deftty);
- break;
- case 1:
- (void) tcgetattr(0, &newtty);
- /* was __svr4__ */
-#ifdef VLNEXT
- /* there's a POSIX way of doing this, but do we need it general? */
- newtty.c_cc[VLNEXT] = _POSIX_VDISABLE;
-#endif
-
- newtty.c_lflag &= ~(ICANON|ISIG|ECHO|IEXTEN);
- newtty.c_iflag &= ~(ISTRIP|INLCR|ICRNL);
-
- if (!flow) {
- newtty.c_iflag &= ~(BRKINT|IXON|IXANY);
- newtty.c_oflag &= ~(OPOST);
- } else {
- /* XXX - should we set ixon ? */
- newtty.c_iflag &= ~(IXON|IXANY);
- newtty.c_iflag |= (BRKINT);
- newtty.c_oflag &= ~(ONLCR|ONOCR);
- newtty.c_oflag |= (OPOST);
- }
-#ifdef TABDLY
- /* preserve tab delays, but turn off XTABS */
- if ((newtty.c_oflag & TABDLY) == TAB3)
- newtty.c_oflag &= ~TABDLY;
-#endif
- if (!eight)
- newtty.c_iflag |= ISTRIP;
- if (litout)
- newtty.c_oflag &= ~OPOST;
-
- newtty.c_cc[VMIN] = 1;
- newtty.c_cc[VTIME] = 0;
- (void) tcsetattr(0, TCSADRAIN, &newtty);
- break;
- default:
- return;
- /* NOTREACHED */
- }
-#else
- struct ltchars *ltc;
-#ifdef USE_TERMIO
- struct termio sb;
-#else
- struct tchars *tc;
- struct sgttyb sb;
- int lflags;
- (void) ioctl(0, TIOCLGET, (char *)&lflags);
-#endif
-
- (void) ioctl(0, TIOCGETP, (char *)&sb);
- switch (f) {
-
- case 0:
-#ifdef USE_TERMIO
- /*
- ** remember whether IXON was set, so it can be restored
- ** when mode(1) is next done
- */
- (void) ioctl(fileno(stdin), TIOCGETP, &ixon_state);
- /*
- ** copy the initial modes we saved into sb; this is
- ** for restoring to the initial state
- */
- sb = defmodes;
-#else
- sb.sg_flags &= ~(CBREAK|RAW|TBDELAY);
- sb.sg_flags |= defflags|tabflag;
- sb.sg_kill = defkill;
- sb.sg_erase = deferase;
- lflags = deflflags;
- tc = &deftc;
-#endif
- ltc = &defltc;
- break;
-
- case 1:
-#ifdef USE_TERMIO
- /*
- ** turn off output mappings
- */
- sb.c_oflag &= ~(ONLCR|OCRNL);
- /*
- ** turn off canonical processing and character echo;
- ** also turn off signal checking -- ICANON might be
- ** enough to do this, but we're being careful
- */
- sb.c_lflag &= ~(ECHO|ICANON|ISIG);
- sb.c_cc[VTIME] = 1;
- sb.c_cc[VMIN] = 1;
- if (eight)
- sb.c_iflag &= ~(ISTRIP);
-#ifdef TABDLY
- /* preserve tab delays, but turn off tab-to-space expansion */
- if ((sb.c_oflag & TABDLY) == TAB3)
- sb.c_oflag &= ~TAB3;
-#endif
- /*
- ** restore current flow control state
- */
- if ((ixon_state.c_iflag & IXON) && flow ) {
- sb.c_iflag |= IXON;
- } else {
- sb.c_iflag &= ~IXON;
- }
-#else /* ! USE_TERMIO */
- sb.sg_flags &= ~(CBREAK|RAW);
- sb.sg_flags |= (!flow ? RAW : CBREAK);
- /* preserve tab delays, but turn off XTABS */
- if ((sb.sg_flags & TBDELAY) == XTABS)
- sb.sg_flags &= ~TBDELAY;
- sb.sg_kill = sb.sg_erase = -1;
-#ifdef LLITOUT
- if (litout)
- lflags |= LLITOUT;
-#endif
-#ifdef LPASS8
- if (eight)
- lflags |= LPASS8;
-#endif /* LPASS8 */
- tc = ¬c;
- sb.sg_flags &= ~defflags;
-#endif /* USE_TERMIO */
-
- ltc = &noltc;
- break;
-
- default:
- return;
- }
- (void) ioctl(0, TIOCSLTC, (char *)ltc);
-#ifndef USE_TERMIO
- (void) ioctl(0, TIOCSETC, (char *)tc);
- (void) ioctl(0, TIOCLSET, (char *)&lflags);
-#endif
- (void) ioctl(0, TIOCSETN, (char *)&sb);
-#endif /* !POSIX_TERMIOS */
-}
-
-
-
-static void
-prf(f)
- char *f;
-{
- fprintf(stderr, "%s", f);
- fprintf(stderr, CRLF);
-}
-
-
-
-#ifdef KERBEROS
-void try_normal(argv)
- char **argv;
-{
- register char *nhost;
-#ifdef POSIX_SIGNALS
- sigset_t mask;
-#endif
-
-#ifndef KRB5_ATHENA_COMPAT
- if (encrypt_flag)
- exit(1);
-#endif
- fprintf(stderr,"trying normal rlogin (%s)\n",
- UCB_RLOGIN);
- fflush(stderr);
-
- nhost = strrchr(argv[0], '/');
- if (nhost)
- nhost++;
- else
- nhost = argv[0];
- if (!strcmp(nhost, "rlogin") || !strcmp(nhost, "rsh"))
- argv[0] = UCB_RLOGIN;
-
-#ifdef POSIX_SIGNALS
- sigemptyset(&mask);
- sigprocmask(SIG_SETMASK, &mask, NULL);
-#endif
-
- execv(UCB_RLOGIN, argv);
- perror("exec");
- exit(1);
-}
-#endif
-
-
-
-krb5_sigtype lostpeer(signo)
- int signo;
-{
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
-
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_IGN;
- (void) sigaction(SIGPIPE, &sa, (struct sigaction *)0);
-#else
- (void) signal(SIGPIPE, SIG_IGN);
-#endif
-
- prf("\007Connection closed.");
- done(1);
-}
+++ /dev/null
-/*
- * appl/bsd/krlogind.c
- */
-
-/*
- * Copyright (c) 1983 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/*
- * Copyright (C) 1998 by the FundsXpress, INC.
- *
- * All rights reserved.
- *
- * Export of this software from the United States of America may require
- * a specific license from the United States Government. It is the
- * responsibility of any person or organization contemplating export to
- * obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of FundsXpress. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. FundsXpress makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef lint
-char copyright[] =
- "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
- All rights reserved.\n";
-#endif /* not lint */
-
-/* based on @(#)rlogind.c 5.17 (Berkeley) 8/31/88 */
-
- /*
- * remote login server:
- * remuser\0
- * locuser\0
- * terminal info\0
- * data
- */
-
-/*
- * This is the rlogin daemon. The very basic protocol for checking
- * authentication and authorization is:
- * 1) Check authentication.
- * 2) Check authorization via the access-control files:
- * ~/.k5login (using krb5_kuserok) and/or
- * 3) Prompt for password if any checks fail, or if so configured.
- * Allow login if all goes well either by calling the accompanying
- * login.krb5 or /bin/login, according to the definition of
- * DO_NOT_USE_K_LOGIN.l
- *
- * The configuration is done either by command-line arguments passed by
- * inetd, or by the name of the daemon. If command-line arguments are
- * present, they take priority. The options are:
- * -k means trust krb5
- * -p and -P means prompt for password.
- * If the -P option is passed, then the password is verified in
- * addition to all other checks. If -p is not passed with -k or -r,
- * and both checks fail, then login permission is denied.
- * - -e means use encryption.
- *
- * If no command-line arguments are present, then the presence of the
- * letters kKrRexpP in the program-name before "logind" determine the
- * behaviour of the program exactly as with the command-line arguments.
- *
- * If the ruserok check is to be used, then the client should connect
- * from a privileged port, else deny permission.
- */
-
-/* DEFINES:
- * KERBEROS - Define this if application is to be kerberised.
- * CRYPT - Define this if encryption is to be an option.
- * DO_NOT_USE_K_LOGIN - Define this if you want to use /bin/login
- * instead of the accompanying login.krb5.
- * LOG_ALL_LOGINS - Define this if you want to log all logins.
- * LOG_OTHER_USERS - Define this if you want to log all principals
- * that do not map onto the local user.
- * LOG_REMOTE_REALM - Define this if you want to log all principals from
- * remote realms.
- * Note: Root logins are always logged.
- */
-
-/*
- * This is usually done in the Makefile. Actually, these sources may
- * not work without the KERBEROS #defined.
- *
- * #define KERBEROS
- */
-#define LOG_REMOTE_REALM
-#define CRYPT
-#define USE_LOGIN_F
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef __SCO__
-#include <sys/unistd.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#ifndef KERBEROS
-/* Ultrix doesn't protect it vs multiple inclusion, and krb.h includes it */
-#include <sys/socket.h>
-#endif
-#include <sys/ioctl.h>
-#include <sys/wait.h>
-#include <sys/file.h>
-#include <sys/time.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <errno.h>
-#include <pwd.h>
-
-#ifdef HAVE_SYS_LABEL_H
-/* only SunOS 4? */
-#include <sys/label.h>
-#include <sys/audit.h>
-#include <pwdadj.h>
-#endif
-
-#include <signal.h>
-
-#if defined(hpux) || defined(__hpux)
-#include <sys/ptyio.h>
-#endif
-#ifdef sysvimp
-#include <compat.h>
-#endif
-
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-#ifdef HAVE_STREAMS
-#include <sys/stream.h>
-#include <sys/stropts.h>
-#endif
-
-#if defined(POSIX_TERMIOS) && !defined(ultrix)
-#include <termios.h>
-#else
-#include <sgtty.h>
-#endif
-
-#ifndef KERBEROS
-/* Ultrix doesn't protect it vs multiple inclusion, and krb.h includes it */
-#include <netdb.h>
-#endif
-#include <syslog.h>
-#include <string.h>
-#include <sys/param.h>
-
-#ifdef HAVE_STREAMS
-/* krlogin doesn't test sys/tty... */
-#ifdef HAVE_SYS_TTY_H
-#include <sys/tty.h>
-#endif
-
-#ifdef HAVE_SYS_PTYVAR_H
-/* Solaris actually uses packet mode, so the real macros are needed too */
-#include <sys/ptyvar.h>
-#endif
-#endif
-
-
-#ifndef TIOCPKT_NOSTOP
-/* These values are over-the-wire protocol, *not* local values */
-#define TIOCPKT_NOSTOP 0x10
-#define TIOCPKT_DOSTOP 0x20
-#define TIOCPKT_FLUSHWRITE 0x02
-#endif
-
-#ifdef HAVE_SYS_FILIO_H
-/* get FIONBIO from sys/filio.h, so what if it is a compatibility feature */
-#include <sys/filio.h>
-#endif
-
-#ifndef HAVE_KILLPG
-#define killpg(pid, sig) kill(-(pid), (sig))
-#endif
-
-#ifdef HAVE_PTSNAME
-/* HP/UX 9.04 has but does not declare ptsname. */
-extern char *ptsname ();
-#endif
-
-#ifdef NO_WINSIZE
-struct winsize {
- unsigned short ws_row, ws_col;
- unsigned short ws_xpixel, ws_ypixel;
-};
-#endif /* NO_WINSIZE */
-
-#ifndef roundup
-#define roundup(x,y) ((((x)+(y)-1)/(y))*(y))
-#endif
-
-#include "fake-addrinfo.h"
-
-#ifdef KERBEROS
-
-#include "k5-int.h"
-#include <libpty.h>
-#ifdef HAVE_UTMP_H
-#include <utmp.h>
-#include <k5-util.h>
-#endif
-
-int non_privileged = 0; /* set when connection is seen to be from */
- /* a non-privileged port */
-
-#include "com_err.h"
-#include "defines.h"
-
-#define SECURE_MESSAGE "This rlogin session is encrypting all data transmissions.\r\n"
-
-krb5_authenticator *kdata;
-krb5_ticket *ticket = 0;
-krb5_context bsd_context;
-krb5_ccache ccache = NULL;
-
-krb5_keytab keytab = NULL;
-
-#define ARGSTR "k5ciepPD:S:M:L:fw:?"
-#else /* !KERBEROS */
-#define ARGSTR "rpPD:f?"
-#endif /* KERBEROS */
-
-#ifndef LOGIN_PROGRAM
-#ifdef DO_NOT_USE_K_LOGIN
-#ifdef sysvimp
-#define LOGIN_PROGRAM "/bin/remlogin"
-#else
-#define LOGIN_PROGRAM "/bin/login"
-#endif
-#else /* DO_NOT_USE_K_LOGIN */
-#define LOGIN_PROGRAM KRB5_PATH_LOGIN
-#endif /* DO_NOT_USE_K_LOGIN */
-#endif /* LOGIN_PROGRAM */
-
-char *login_program = LOGIN_PROGRAM;
-
-#define MAXRETRIES 4
-#define MAX_PROG_NAME 16
-
-#ifndef UT_NAMESIZE /* linux defines it directly in <utmp.h> */
-#define UT_NAMESIZE sizeof(((struct utmp *)0)->ut_name)
-#endif
-
-#if HAVE_ARPA_NAMESER_H
-#include <arpa/nameser.h>
-#endif
-
-#ifndef MAXDNAME
-#define MAXDNAME 256 /*per the rfc*/
-#endif
-
-char lusername[UT_NAMESIZE+1];
-char rusername[UT_NAMESIZE+1];
-char *krusername = 0;
-char term[64];
-char rhost_name[MAXDNAME];
-char rhost_addra[16];
-krb5_principal client;
-int do_inband = 0;
-
-int reapchild();
-char *progname;
-
-static int Pfd;
-
-#if defined(NEED_DAEMON_PROTO)
-extern int daemon(int, int);
-#endif
-
-#if (defined(_AIX) && defined(i386)) || defined(ibm032) || (defined(vax) && !defined(ultrix)) || (defined(SunOS) && SunOS > 40) || defined(solaris20)
-#define VHANG_FIRST
-#endif
-
-#if defined(ultrix)
-#define VHANG_LAST /* vhangup must occur on close, not open */
-#endif
-
-void fatal(int, const char *), fatalperror(int, const char *), doit(int, struct sockaddr *), usage(void), do_krb_login(char *, char *), getstr(int, char *, int, char *);
-void protocol(int, int);
-int princ_maps_to_lname(krb5_principal, char *), default_realm(krb5_principal);
-krb5_sigtype cleanup(int);
-krb5_error_code recvauth(int *);
-
-int do_encrypt = 0, passwd_req = 0;
-int checksum_required = 0, checksum_ignored = 0;
-
-int stripdomain = 1;
-int maxhostlen = 0;
-int always_ip = 0;
-
-int main(argc, argv)
- int argc;
- char **argv;
-{
- extern int opterr, optind;
- extern char * optarg;
- int on = 1, ch;
- socklen_t fromlen;
- struct sockaddr_storage from;
- int debug_port = 0;
- int fd;
- int do_fork = 0;
-#ifdef KERBEROS
- krb5_error_code status;
-#endif
-
- progname = *argv;
-
- pty_init();
-
-#ifndef LOG_NDELAY
-#define LOG_NDELAY 0
-#endif
-
-#ifndef LOG_AUTH /* 4.2 syslog */
- openlog(progname, LOG_PID | LOG_NDELAY);
-#else
- openlog(progname, LOG_PID | LOG_NDELAY, LOG_AUTH);
-#endif /* 4.2 syslog */
-
-#ifdef KERBEROS
- status = krb5_init_context(&bsd_context);
- if (status) {
- syslog(LOG_ERR, "Error initializing krb5: %s",
- error_message(status));
- exit(1);
- }
-#endif
-
- /* Analyse parameters. */
- opterr = 0;
- while ((ch = getopt(argc, argv, ARGSTR)) != -1)
- switch (ch) {
-#ifdef KERBEROS
- case 'k':
- break;
-
- case '5':
- break;
- case 'c':
- checksum_required = 1;
- break;
- case 'i':
- checksum_ignored = 1;
- break;
-
-#ifdef CRYPT
- case 'x': /* Use encryption. */
- case 'X':
- case 'e':
- case 'E':
- do_encrypt = 1;
- break;
-#endif
- case 'S':
- if ((status = krb5_kt_resolve(bsd_context, optarg, &keytab))) {
- com_err(progname, status, "while resolving srvtab file %s",
- optarg);
- exit(2);
- }
- break;
- case 'M':
- krb5_set_default_realm(bsd_context, optarg);
- break;
-#endif
- case 'p':
- break;
- case 'P': /* passwd is a must */
- passwd_req = 1;
- break;
- case 'D':
- debug_port = atoi(optarg);
- break;
- case 'L':
- login_program = optarg;
- break;
- case 'f':
- do_fork = 1;
- break;
- case 'w':
- if (!strcmp(optarg, "ip"))
- always_ip = 1;
- else {
- char *cp;
- cp = strchr(optarg, ',');
- if (cp == NULL)
- maxhostlen = atoi(optarg);
- else if (*(++cp)) {
- if (!strcmp(cp, "striplocal"))
- stripdomain = 1;
- else if (!strcmp(cp, "nostriplocal"))
- stripdomain = 0;
- else {
- usage();
- exit(1);
- }
- *(--cp) = '\0';
- maxhostlen = atoi(optarg);
- }
- }
- break;
- case '?':
- default:
- usage();
- exit(1);
- break;
- }
- argc -= optind;
- argv += optind;
-
- fromlen = sizeof (from);
-
- if (debug_port || do_fork) {
- int s;
- struct servent *ent;
- struct sockaddr_in sock_in;
-
- if (!debug_port) {
- if (do_encrypt) {
- ent = getservbyname("eklogin", "tcp");
- if (ent == NULL)
- debug_port = 2105;
- else
- debug_port = ent->s_port;
- } else {
- ent = getservbyname("klogin", "tcp");
- if (ent == NULL)
- debug_port = 543;
- else
- debug_port = ent->s_port;
- }
- }
- if ((s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0) {
- fprintf(stderr, "Error in socket: %s\n", strerror(errno));
- exit(2);
- }
- memset(&sock_in, 0,sizeof(sock_in));
- sock_in.sin_family = AF_INET;
- sock_in.sin_port = htons(debug_port);
- sock_in.sin_addr.s_addr = INADDR_ANY;
-
- if (!do_fork)
- (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
- (char *)&on, sizeof(on));
-
- if ((bind(s, (struct sockaddr *) &sock_in, sizeof(sock_in))) < 0) {
- fprintf(stderr, "Error in bind: %s\n", strerror(errno));
- exit(2);
- }
-
- if ((listen(s, 5)) < 0) {
- fprintf(stderr, "Error in listen: %s\n", strerror(errno));
- exit(2);
- }
-
- if (do_fork) {
- if (daemon(0, 0)) {
- fprintf(stderr, "daemon() failed\n");
- exit(2);
- }
- while (1) {
- int child_pid;
-
- fd = accept(s, (struct sockaddr *) &from, &fromlen);
- if (fd < 0) {
- if (errno != EINTR)
- syslog(LOG_ERR, "accept: %s", error_message(errno));
- continue;
- }
- child_pid = fork();
- switch (child_pid) {
- case -1:
- syslog(LOG_ERR, "fork: %s", error_message(errno));
- case 0:
- (void) close(s);
- doit(fd, (struct sockaddr *) &from);
- close(fd);
- exit(0);
- default:
- wait(0);
- close(fd);
- }
- }
- }
-
- if ((fd = accept(s, (struct sockaddr *) &from, &fromlen)) < 0) {
- fprintf(stderr, "Error in accept: %s\n", strerror(errno));
- exit(2);
- }
-
- close(s);
- } else { /* !do_fork && !debug_port */
- if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
- syslog(LOG_ERR,"Can't get peer name of remote host: %m");
-#ifdef STDERR_FILENO
- fatal(STDERR_FILENO, "Can't get peer name of remote host");
-#else
- fatal(2, "Can't get peer name of remote host");
-#endif
- }
- fd = 0;
- }
-
- doit(fd, (struct sockaddr *) &from);
- return 0;
-}
-
-
-
-#ifndef LOG_AUTH
-#define LOG_AUTH 0
-#endif
-
-int child;
-int netf;
-char line[MAXPATHLEN];
-extern char *inet_ntoa();
-
-#ifdef TIOCSWINSZ
-struct winsize win = { 0, 0, 0, 0 };
-#endif
-
-int pid; /* child process id */
-
-void doit(f, fromp)
- int f;
- struct sockaddr *fromp;
-{
- int p, t, on = 1;
- char c;
- char hname[NI_MAXHOST];
- char buferror[255];
- struct passwd *pwd;
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
-#endif
- int retval;
- char *rhost_sane;
- int syncpipe[2];
-
- netf = -1;
- if (setsockopt(f, SOL_SOCKET, SO_KEEPALIVE,
- (const char *) &on, sizeof (on)) < 0)
- syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
-
- if (checksum_required&&checksum_ignored) {
- syslog( LOG_CRIT, "Checksums are required and ignored; these options are mutually exclusive--check the documentation.");
- fatal(f, "Configuration error: mutually exclusive options specified");
- }
-
- alarm(60);
- read(f, &c, 1);
-
- if (c != 0){
- exit(1);
- }
-
- alarm(0);
- /* Initialize syncpipe */
- if (pipe( syncpipe ) < 0 )
- fatalperror ( f , "");
-
-
-#ifdef POSIX_SIGNALS
- /* Initialize "sa" structure. */
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
-#endif
-
- retval = getnameinfo(fromp, socklen(fromp), hname, sizeof(hname), 0, 0,
- NI_NUMERICHOST);
- if (retval)
- fatal(f, gai_strerror(retval));
- strncpy(rhost_addra, hname, sizeof(rhost_addra));
- rhost_addra[sizeof (rhost_addra) -1] = '\0';
-
- retval = getnameinfo(fromp, socklen(fromp), hname, sizeof(hname), 0, 0, 0);
- if (retval)
- fatal(f, gai_strerror(retval));
- strncpy(rhost_name, hname, sizeof(rhost_name));
- rhost_name[sizeof (rhost_name) - 1] = '\0';
-
-#ifndef KERBEROS
- if (fromp->sin_family != AF_INET)
- /* Not a real problem, we just haven't bothered to update
- the port number checking code to handle ipv6. */
- fatal(f, "Permission denied - Malformed from address\n");
-
- if (fromp->sin_port >= IPPORT_RESERVED ||
- fromp->sin_port < IPPORT_RESERVED/2)
- fatal(f, "Permission denied - Connection from bad port");
-#endif /* KERBEROS */
-
- /* Set global netf to f now : we may need to drop everything
- in do_krb_login. */
- netf = f;
-
-#if defined(KERBEROS)
- /* All validation, and authorization goes through do_krb_login() */
- do_krb_login(rhost_addra, rhost_name);
-#else
- getstr(f, rusername, sizeof(rusername), "remuser");
- getstr(f, lusername, sizeof(lusername), "locuser");
- getstr(f, term, sizeof(term), "Terminal type");
- rcmd_stream_init_normal();
-#endif
-
- write(f, "", 1);
- if ((retval = pty_getpty(&p,line, sizeof(line)))) {
- com_err(progname, retval, "while getting master pty");
- exit(2);
- }
-
- Pfd = p;
-#ifdef TIOCSWINSZ
- (void) ioctl(p, TIOCSWINSZ, &win);
-#endif
-
-#ifdef POSIX_SIGNALS
- sa.sa_handler = cleanup;
- (void) sigaction(SIGCHLD, &sa, (struct sigaction *)0);
- (void) sigaction(SIGTERM, &sa, (struct sigaction *)0);
-#else
- signal(SIGCHLD, cleanup);
- signal(SIGTERM, cleanup);
-#endif
- pid = fork();
- if (pid < 0)
- fatalperror(f, "");
- if (pid == 0) {
-#if defined(POSIX_TERMIOS) && !defined(ultrix)
- struct termios new_termio;
-#else
- struct sgttyb b;
-#endif /* POSIX_TERMIOS */
- if ((retval = pty_open_slave(line, &t))) {
- fatal(f, error_message(retval));
- exit(1);
- }
-
-
-#if defined(POSIX_TERMIOS) && !defined(ultrix)
- tcgetattr(t,&new_termio);
-#if !defined(USE_LOGIN_F)
- new_termio.c_lflag &= ~(ICANON|ECHO|ISIG|IEXTEN);
- new_termio.c_iflag &= ~(IXON|IXANY|BRKINT|INLCR|ICRNL);
-#else
- new_termio.c_lflag |= (ICANON|ECHO|ISIG|IEXTEN);
- new_termio.c_oflag |= (ONLCR|OPOST);
- new_termio.c_iflag |= (IXON|IXANY|BRKINT|INLCR|ICRNL);
-#endif /*Do we need binary stream?*/
- new_termio.c_iflag &= ~(ISTRIP);
- /* new_termio.c_iflag = 0; */
- /* new_termio.c_oflag = 0; */
- new_termio.c_cc[VMIN] = 1;
- new_termio.c_cc[VTIME] = 0;
- tcsetattr(t,TCSANOW,&new_termio);
-#else
- (void)ioctl(t, TIOCGETP, &b);
- b.sg_flags = RAW|ANYP;
- (void)ioctl(t, TIOCSETP, &b);
-#endif /* POSIX_TERMIOS */
-
- pid = 0; /*reset pid incase exec fails*/
-
- /*
- ** signal the parent that we have turned off echo
- ** on the slave side of the pty ... he's waiting
- ** because otherwise the rlogin protocol junk gets
- ** echo'd to the user (locuser^@remuser^@term/baud)
- ** and we don't get the right tty affiliation, and
- ** other kinds of hell breaks loose ...
- */
- (void) write(syncpipe[1], &c, 1);
- (void) close(syncpipe[1]);
- (void) close(syncpipe[0]);
-
- close(f), close(p);
- dup2(t, 0), dup2(t, 1), dup2(t, 2);
- if (t > 2)
- close(t);
-
-#if defined(sysvimp)
- setcompat (COMPAT_CLRPGROUP | (getcompat() & ~COMPAT_BSDTTY));
-#endif
-
- /* Log access to account */
- pwd = (struct passwd *) getpwnam(lusername);
- if (pwd && (pwd->pw_uid == 0)) {
- if (passwd_req)
- syslog(LOG_NOTICE, "ROOT login by %s (%s@%s (%s)) forcing password access",
- krusername ? krusername : "",
- rusername, rhost_addra, rhost_name);
- else
- syslog(LOG_NOTICE, "ROOT login by %s (%s@%s (%s))",
- krusername ? krusername : "",
- rusername, rhost_addra, rhost_name);
- }
-#ifdef KERBEROS
-#if defined(LOG_REMOTE_REALM) && !defined(LOG_OTHER_USERS) && !defined(LOG_ALL_LOGINS)
- /* Log if principal is from a remote realm */
- else if (client && !default_realm(client))
-#endif /* LOG_REMOTE_REALM */
-
-#if defined(LOG_OTHER_USERS) && !defined(LOG_ALL_LOGINS)
- /* Log if principal name does not map to local username */
- else if (client && !princ_maps_to_lname(client, lusername))
-#endif /* LOG_OTHER_USERS */
-
-#if defined(LOG_ALL_LOGINS)
- else
-#endif /* LOG_ALL_LOGINS */
-
-#if defined(LOG_REMOTE_REALM) || defined(LOG_OTHER_USERS) || defined(LOG_ALL_LOGINS)
- {
- if (passwd_req)
- syslog(LOG_NOTICE,
- "login by %s (%s@%s (%s)) as %s forcing password access",
- krusername ? krusername : "", rusername,
- rhost_addra, rhost_name, lusername);
- else
- syslog(LOG_NOTICE,
- "login by %s (%s@%s (%s)) as %s",
- krusername ? krusername : "", rusername,
- rhost_addra, rhost_name, lusername);
- }
-#endif /* LOG_REMOTE_REALM || LOG_OTHER_USERS || LOG_ALL_LOGINS */
-#endif /* KERBEROS */
-
-#ifndef NO_UT_PID
- {
-
- pty_update_utmp(PTY_LOGIN_PROCESS, getpid(), "rlogin", line,
- ""/*host*/, PTY_TTYSLOT_USABLE);
- }
-#endif
-
-#ifdef USE_LOGIN_F
-/* use the vendors login, which has -p and -f. Tested on
- * AIX 4.1.4 and HPUX 10
- */
- {
- char *cp;
- if ((cp = strchr(term,'/')))
- *cp = '\0';
- setenv("TERM",term, 1);
- }
-
- retval = pty_make_sane_hostname((struct sockaddr *) fromp, maxhostlen,
- stripdomain, always_ip,
- &rhost_sane);
- if (retval)
- fatalperror(f, "failed make_sane_hostname");
- if (passwd_req)
- execl(login_program, "login", "-p", "-h", rhost_sane,
- lusername, (char *)NULL);
- else
- execl(login_program, "login", "-p", "-h", rhost_sane,
- "-f", lusername, (char *)NULL);
-#else /* USE_LOGIN_F */
- execl(login_program, "login", "-r", rhost_sane, (char *)NULL);
-#endif /* USE_LOGIN_F */
- syslog(LOG_ERR, "failed exec of %s: %s",
- login_program, error_message(errno));
- fatalperror(f, login_program);
- /*NOTREACHED*/
- } /* if (pid == 0) */
-
- /*
- ** wait for child to start ... read one byte
- ** -- see the child, who writes one byte after
- ** turning off echo on the slave side ...
- ** The master blocks here until it reads a byte.
- */
-
-(void) close(syncpipe[1]);
- if (read(syncpipe[0], &c, 1) != 1) {
- /*
- * Problems read failed ...
- */
- snprintf(buferror, sizeof(buferror), "Cannot read slave pty %s ",line);
- fatalperror(p,buferror);
- }
- close(syncpipe[0]);
-
-
-#if defined(KERBEROS)
- if (do_encrypt) {
- if (rcmd_stream_write(f, SECURE_MESSAGE, sizeof(SECURE_MESSAGE), 0) < 0){
- snprintf(buferror, sizeof(buferror),
- "Cannot encrypt-write network.");
- fatal(p,buferror);
- }
- }
- else
- /*
- * if encrypting, don't turn on NBIO, else the read/write routines
- * will fail to work properly
- */
-#endif /* KERBEROS */
- ioctl(f, FIONBIO, &on);
- ioctl(p, FIONBIO, &on);
-
- /* FIONBIO doesn't always work on ptys, use fcntl to set O_NDELAY? */
- (void) fcntl(p,F_SETFL,fcntl(p,F_GETFL,0) | O_NDELAY);
-
-#ifdef POSIX_SIGNALS
- sa.sa_handler = SIG_IGN;
- (void) sigaction(SIGTSTP, &sa, (struct sigaction *)0);
-#else
- signal(SIGTSTP, SIG_IGN);
-#endif
-
-
-#if !defined(USE_LOGIN_F)
- /* Pass down rusername and lusername to login. */
- (void) write(p, rusername, strlen(rusername) +1);
- (void) write(p, lusername, strlen(lusername) +1);
- /* stuff term info down to login */
- if ((write(p, term, strlen(term)+1) != (int) strlen(term)+1)) {
- /*
- * Problems write failed ...
- */
- snprintf(buferror, sizeof(buferror), "Cannot write slave pty %s ",
- line);
- fatalperror(f,buferror);
- }
-
-#endif
- protocol(f, p);
- signal(SIGCHLD, SIG_IGN);
- cleanup(0);
-}
-
-unsigned char magic[2] = { 0377, 0377 };
-#ifdef TIOCSWINSZ
-#ifndef TIOCPKT_WINDOW
-#define TIOCPKT_WINDOW 0x80
-#endif
-unsigned char oobdata[] = {TIOCPKT_WINDOW};
-#else
-char oobdata[] = {0};
-#endif
-
-static
-void sendoob(fd, byte)
- int fd;
- char *byte;
-{
- char message[5];
- int cc;
-
- if (do_inband) {
- message[0] = '\377';
- message[1] = '\377';
- message[2] = 'o';
- message[3] = 'o';
- message[4] = *byte;
-
- cc = rcmd_stream_write(fd, message, sizeof(message), 0);
- while (cc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) {
- /* also shouldn't happen */
- sleep(5);
- cc = rcmd_stream_write(fd, message, sizeof(message), 0);
- }
- } else {
- send(fd, byte, 1, MSG_OOB);
- }
-}
-
-/*
- * Handle a "control" request (signaled by magic being present)
- * in the data stream. For now, we are only willing to handle
- * window size changes.
- */
-static int control(pty, cp, n)
- int pty;
- unsigned char *cp;
- int n;
-{
- struct winsize w;
- int pgrp, got_pgrp;
-
- if (n < (int) 4+sizeof (w) || cp[2] != 's' || cp[3] != 's')
- return (0);
-#ifdef TIOCSWINSZ
- oobdata[0] &= ~TIOCPKT_WINDOW; /* we know he heard */
- memcpy(&w, cp+4, sizeof(w));
- w.ws_row = ntohs(w.ws_row);
- w.ws_col = ntohs(w.ws_col);
- w.ws_xpixel = ntohs(w.ws_xpixel);
- w.ws_ypixel = ntohs(w.ws_ypixel);
- (void)ioctl(pty, TIOCSWINSZ, &w);
-#ifdef HAVE_TCGETPGRP
- pgrp = tcgetpgrp (pty);
- got_pgrp = pgrp != -1;
-#else
- got_pgrp = ioctl(pty, TIOCGPGRP, &pgrp) >= 0;
-#endif
- if (got_pgrp)
- (void) killpg(pgrp, SIGWINCH);
-#endif
- return (4+sizeof (w));
-}
-
-
-
-/*
- * rlogin "protocol" machine.
- */
-void protocol(f, p)
- int f, p;
-{
- unsigned char pibuf[BUFSIZ], qpibuf[BUFSIZ*2], fibuf[BUFSIZ], *pbp=0, *fbp=0;
- register int pcc = 0, fcc = 0;
- int cc;
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
-#endif
-#ifdef TIOCPKT
- register int tiocpkt_on = 0;
- int on = 1;
-#endif
-
-#if defined(TIOCPKT) && !(defined(__svr4__) || defined(HAVE_STREAMS)) \
- || defined(solaris20)
- /* if system has TIOCPKT, try to turn it on. Some drivers
- * may not support it. Save flag for later.
- */
- if ( ioctl(p, TIOCPKT, &on) < 0)
- tiocpkt_on = 0;
- else tiocpkt_on = 1;
-#endif
-
- /*
- * Must ignore SIGTTOU, otherwise we'll stop
- * when we try and set slave pty's window shape
- * (our controlling tty is the master pty).
- */
-#ifdef POSIX_SIGNALS
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_IGN;
- (void) sigaction(SIGTTOU, &sa, (struct sigaction *)0);
-#else
- signal(SIGTTOU, SIG_IGN);
-#endif
-#ifdef TIOCSWINSZ
- sendoob(f, oobdata);
-#endif
- for (;;) {
- fd_set ibits, obits, ebits;
-
- FD_ZERO(&ibits);
- FD_ZERO(&obits);
- FD_ZERO(&ebits);
-
- if (fcc)
- FD_SET(p, &obits);
- else
- FD_SET(f, &ibits);
- if (pcc >= 0) {
- if (pcc) {
- FD_SET(f, &obits);
- } else {
- FD_SET(p, &ibits);
- }
- }
-
- if (select(((p > f) ? p : f) + 1, &ibits, &obits, &ebits, 0) < 0) {
- if (errno == EINTR)
- continue;
- fatalperror(f, "select");
- }
-#define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP))
- if (FD_ISSET(f, &ibits)) {
- fcc = rcmd_stream_read(f, fibuf, sizeof (fibuf), 0);
- if (fcc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) {
- fcc = 0;
- } else {
- register unsigned char *cp;
- int n;
- size_t left;
-
- if (fcc <= 0)
- break;
- fbp = fibuf;
-
- for (cp = fibuf; cp < fibuf+fcc-1; cp++) {
- if (cp[0] == magic[0] &&
- cp[1] == magic[1]) {
- left = (fibuf+fcc) - cp;
- n = control(p, cp, left);
- if (n) {
- left -= n;
- fcc -= n;
- if (left > 0)
- memmove(cp, cp+n, left);
- cp--;
- }
- }
- }
- }
- }
-
- if (FD_ISSET(p, &obits) && fcc > 0) {
- cc = write(p, fbp, fcc);
- if (cc > 0) {
- fcc -= cc;
- fbp += cc;
- }
- }
-
- if (FD_ISSET(p, &ibits)) {
- pcc = read(p, pibuf, sizeof (pibuf));
- pbp = pibuf;
- if (pcc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) {
- pcc = 0;
- } else if (pcc <= 0) {
- break;
- }
-#ifdef TIOCPKT
- else if (tiocpkt_on) {
- if (pibuf[0] == 0) {
- pbp++, pcc--;
- } else {
- if (pkcontrol(pibuf[0])) {
- pibuf[0] |= oobdata[0];
- sendoob(f, pibuf);
- }
- pcc = 0;
- }
- }
-#endif
-
- /* quote any double-\377's if necessary */
-
- if (do_inband) {
- unsigned char *qpbp;
- int qpcc, i;
-
- qpbp = qpibuf;
- qpcc = 0;
-
- for (i=0; i<pcc;) {
- if (pbp[i] == 0377u && (i+1)<pcc && pbp[i+1] == 0377u) {
- qpbp[qpcc] = '\377';
- qpbp[qpcc+1] = '\377';
- qpbp[qpcc+2] = 'q';
- qpbp[qpcc+3] = 'q';
- i += 2;
- qpcc += 4;
- } else {
- qpbp[qpcc] = pbp[i];
- i++;
- qpcc++;
- }
- }
-
- pbp = qpbp;
- pcc = qpcc;
- }
- }
-
- if (FD_ISSET(f, &obits) && pcc > 0) {
- cc = rcmd_stream_write(f, pbp, pcc, 0);
- if (cc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) {
- /* also shouldn't happen */
- sleep(5);
- continue;
- }
- if (cc > 0) {
- pcc -= cc;
- pbp += cc;
- }
- }
- }
-}
-
-
-
-krb5_sigtype cleanup(signumber)
- int signumber;
-{
- pty_cleanup (line, pid, 1);
- shutdown(netf, 2);
- if (ccache)
- krb5_cc_destroy(bsd_context, ccache);
- exit(1);
-}
-
-
-void fatal(f, msg)
- int f;
- const char *msg;
-{
- char buf[512];
- int out = 1 ; /* Output queue of f */
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
-#endif
-
- buf[0] = '\01'; /* error indicator */
- (void) snprintf(buf + 1, sizeof(buf) - 1, "%s: %s.\r\n", progname, msg);
- if ((f == netf) && (pid > 0))
- (void) rcmd_stream_write(f, buf, strlen(buf), 0);
- else
- (void) write(f, buf, strlen(buf));
- syslog(LOG_ERR,"%s\n",msg);
- if (pid > 0) {
-#ifdef POSIX_SIGNALS
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_IGN;
- (void) sigaction(SIGCHLD, &sa, (struct sigaction *)0);
-#else
- signal(SIGCHLD,SIG_IGN);
-#endif
- kill(pid,SIGKILL);
-#ifdef TIOCFLUSH
- (void) ioctl(f, TIOCFLUSH, (char *)&out);
-#else
- (void) ioctl(f, TCFLSH, out);
-#endif
- cleanup(0);
- }
- exit(1);
-}
-
-
-
-void fatalperror(f, msg)
- int f;
- const char *msg;
-{
- char buf[512];
-
- (void) snprintf(buf, sizeof(buf), "%s: %s", msg, error_message(errno));
- fatal(f, buf);
-}
-
-#ifdef KERBEROS
-
-void
-do_krb_login(host_addr, hostname)
- char *host_addr, *hostname;
-{
- krb5_error_code status;
- char *msg_fail = NULL;
- int valid_checksum;
-
- if (getuid()) {
- exit(1);
- }
-
- /* Check authentication. */
- if ((status = recvauth(&valid_checksum))) {
- if (ticket)
- krb5_free_ticket(bsd_context, ticket);
- if (status != 255)
- syslog(LOG_ERR,
- "Authentication failed from %s (%s): %s\n",host_addr,
- hostname,error_message(status));
- fatal(netf, "Kerberos authentication failed");
- return;
- }
-
- /* OK we have authenticated this user - now check authorization. */
- /* The Kerberos authenticated programs must use krb5_kuserok or kuserok*/
-
- /* krb5_kuserok returns 1 if OK */
- if (!client || !krb5_kuserok(bsd_context, client, lusername)) {
- if (asprintf(&msg_fail,
- "User %s is not authorized to login to account %s",
- krusername, lusername) >= 0)
- fatal(netf, msg_fail);
- else
- fatal(netf,
- "User is not authorized to login to specified account");
- }
-
- if (checksum_required && !valid_checksum) {
- syslog(LOG_WARNING, "Client did not supply required checksum--connection rejected.");
-
- fatal(netf, "You are using an old Kerberos5 without initial connection support; only newer clients are authorized.");
- }
-}
-
-#endif /* KERBEROS */
-
-
-
-void getstr(fd, buf, cnt, err)
- int fd;
- char *buf;
- int cnt;
- char *err;
-{
-
- char c;
-
- do {
- if (read(fd, &c, 1) != 1) {
- exit(1);
- }
- if (--cnt < 0) {
- printf("%s too long\r\n", err);
- exit(1);
- }
- *buf++ = c;
- } while (c != 0);
-}
-
-
-
-void usage()
-{
-#ifdef KERBEROS
- syslog(LOG_ERR,
- "usage: klogind [-ePf] [-D port] [-w[ip|maxhostlen[,[no]striplocal]]] or [r/R][k/K][x/e][p/P]logind");
-#else
- syslog(LOG_ERR,
- "usage: rlogind [-rPf] [-D port] or [r/R][p/P]logind");
-#endif
-}
-
-
-
-#ifdef KERBEROS
-
-#ifndef KRB_SENDAUTH_VLEN
-#define KRB_SENDAUTH_VLEN 8 /* length for version strings */
-#endif
-
-#define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN
- chars */
-
-krb5_error_code
-recvauth(valid_checksum)
- int *valid_checksum;
-{
- krb5_auth_context auth_context = NULL;
- krb5_error_code status;
- struct sockaddr_storage peersin, laddr;
- socklen_t len;
- krb5_data inbuf;
- krb5_data version;
- krb5_authenticator *authenticator;
- krb5_rcache rcache;
- enum kcmd_proto kcmd_proto;
- krb5_keyblock *key;
-
- *valid_checksum = 0;
- len = sizeof(laddr);
- if (getsockname(netf, (struct sockaddr *)&laddr, &len)) {
- exit(1);
- }
-
- len = sizeof(peersin);
- if (getpeername(netf, (struct sockaddr *)&peersin, &len)) {
- syslog(LOG_ERR, "get peer name failed %d", netf);
- exit(1);
- }
-
- if ((status = krb5_auth_con_init(bsd_context, &auth_context)))
- return status;
-
- /* Only need remote address for rd_cred() to verify client */
- if ((status = krb5_auth_con_genaddrs(bsd_context, auth_context, netf,
- KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR)))
- return status;
-
- status = krb5_auth_con_getrcache(bsd_context, auth_context, &rcache);
- if (status) return status;
-
- if (! rcache) {
- krb5_principal server;
-
- status = krb5_sname_to_principal(bsd_context, 0, 0,
- KRB5_NT_SRV_HST, &server);
- if (status) return status;
-
- status = krb5_get_server_rcache(bsd_context,
- krb5_princ_component(bsd_context, server, 0),
- &rcache);
- krb5_free_principal(bsd_context, server);
- if (status) return status;
-
- status = krb5_auth_con_setrcache(bsd_context, auth_context, rcache);
- if (status) return status;
- }
-
- status = krb5_recvauth_version(bsd_context, &auth_context, &netf,
- NULL, 0, keytab, &ticket, &version);
- if (status) {
- /*
- * clean up before exiting
- */
- getstr(netf, lusername, sizeof (lusername), "locuser");
- getstr(netf, term, sizeof(term), "Terminal type");
- getstr(netf, rusername, sizeof(rusername), "remuser");
- return status;
- }
-
- getstr(netf, lusername, sizeof (lusername), "locuser");
- getstr(netf, term, sizeof(term), "Terminal type");
-
- kcmd_proto = KCMD_UNKNOWN_PROTOCOL;
- if (version.length != 9) {
- fatal (netf, "bad application version length");
- }
- if (!memcmp (version.data, "KCMDV0.1", 9))
- kcmd_proto = KCMD_OLD_PROTOCOL;
- else if (!memcmp (version.data, "KCMDV0.2", 9))
- kcmd_proto = KCMD_NEW_PROTOCOL;
-
- if (!(checksum_ignored && kcmd_proto == KCMD_OLD_PROTOCOL)) {
-
- if ((status = krb5_auth_con_getauthenticator(bsd_context, auth_context,
- &authenticator)))
- return status;
-
- if (authenticator->checksum) {
- struct sockaddr_in adr;
- socklen_t adr_length = sizeof(adr);
- krb5_data chksumbuf;
- krb5_boolean valid = 0;
-
- chksumbuf.data = NULL;
- if (getsockname(netf, (struct sockaddr *) &adr, &adr_length) != 0)
- goto error_cleanup;
- if (asprintf(&chksumbuf.data, "%u:%s%s", ntohs(adr.sin_port), term, lusername) < 0)
- goto error_cleanup;
-
- chksumbuf.length = strlen(chksumbuf.data);
- status = krb5_c_verify_checksum(bsd_context,
- ticket->enc_part2->session,
- KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM,
- &chksumbuf, authenticator->checksum,
- &valid);
- if (status == 0 && !valid) status = KRB5KRB_AP_ERR_BAD_INTEGRITY;
-
- error_cleanup:
- if (chksumbuf.data)
- free(chksumbuf.data);
- if (status) {
- krb5_free_authenticator(bsd_context, authenticator);
- return status;
- }
- *valid_checksum = 1;
- }
- krb5_free_authenticator(bsd_context, authenticator);
- }
-
- if ((status = krb5_copy_principal(bsd_context, ticket->enc_part2->client,
- &client)))
- return status;
-
- key = 0;
- status = krb5_auth_con_getrecvsubkey (bsd_context, auth_context, &key);
- if (status)
- fatal (netf, "Server can't get session subkey");
- if (!key && do_encrypt && kcmd_proto == KCMD_NEW_PROTOCOL)
- fatal (netf, "No session subkey sent");
- if (key && kcmd_proto == KCMD_OLD_PROTOCOL) {
-#ifdef HEIMDAL_FRIENDLY
- key = 0;
-#else
- fatal (netf, "Session subkey not permitted under old kcmd protocol");
-#endif
- }
- if (key == 0)
- key = ticket->enc_part2->session;
-
- rcmd_stream_init_krb5 (key, do_encrypt, 1, 0, kcmd_proto);
-
- do_inband = (kcmd_proto == KCMD_NEW_PROTOCOL);
-
- getstr(netf, rusername, sizeof(rusername), "remuser");
-
- if ((status = krb5_unparse_name(bsd_context, client, &krusername)))
- return status;
-
- if ((status = krb5_read_message(bsd_context, (krb5_pointer)&netf, &inbuf)))
- fatal(netf, "Error reading message");
-
- if ((inbuf.length) && /* Forwarding being done, read creds */
- (status = rd_and_store_for_creds(bsd_context, auth_context, &inbuf,
- ticket, &ccache))) {
- fatal(netf, "Can't get forwarded credentials");
- }
- return 0;
-}
-
-#endif /* KERBEROS */
+++ /dev/null
-/*
- * appl/bsd/krsh.c
- */
-
-/*
- * Copyright (c) 1983 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef lint
-char copyright[] =
- "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
- All rights reserved.\n";
-#endif /* not lint */
-
-/* based on @(#)rsh.c 5.7 (Berkeley) 9/20/88 */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/file.h>
-#include <sys/time.h>
-
-#include <netinet/in.h>
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#include <strings.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <stdio.h>
-#include <errno.h>
-#include <signal.h>
-#include <pwd.h>
-#include <netdb.h>
-
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-#ifdef HAVE_SYS_FILIO_H
-/* get FIONBIO from sys/filio.h, so what if it is a compatibility feature */
-#include <sys/filio.h>
-#endif
-
-#ifdef KERBEROS
-#include <krb5.h>
-#include <com_err.h>
-#include "defines.h"
-#endif /* KERBEROS */
-
-/*
- * rsh - remote shell
- */
-#define SECURE_MESSAGE "This rsh session is encrypting input/output data transmissions.\r\n"
-
-int error();
-
-int options;
-int rfd2;
-int nflag;
-krb5_sigtype sendsig(int);
-
-#ifdef KERBEROS
-
-#ifndef UCB_RSH
-#define UCB_RSH "/usr/ucb/rsh"
-#endif
-
-krb5_context bsd_context;
-krb5_creds *cred;
-
-int encrypt_flag = 0;
-char *krb_realm = (char *)0;
-void try_normal(char **);
-
-#endif /* KERBEROS */
-
-#ifndef RLOGIN_PROGRAM
-#ifdef KERBEROS
-#define RLOGIN_PROGRAM KRB5_PATH_RLOGIN
-#else /* KERBEROS */
-#ifndef UCB_RLOGIN
-#define UCB_RLOGIN "/usr/ucb/rlogin"
-#endif
-#define RLOGIN_PROGRAM UCB_RLOGIN
-#endif /* KERBEROS */
-#endif /* !RLOGIN_PROGRAM */
-
-#ifndef POSIX_SIGNALS
-#define mask(s) (1 << ((s) - 1))
-#endif /* POSIX_SIGNALS */
-
-int
-main(argc, argv0)
- int argc;
- char **argv0;
-{
- int rem, pid = 0;
- char *host=0, **ap, buf[RCMD_BUFSIZ], *args, **argv = argv0, *user = 0;
- register int cc;
- struct passwd *pwd;
- fd_set readfrom, ready;
- int one = 1;
- struct servent *sp;
- struct servent defaultservent;
- struct sockaddr_in local, foreign;
- int suppress = 0;
-
-#ifdef POSIX_SIGNALS
- sigset_t omask, igmask;
- struct sigaction sa, osa;
-#else
- int omask;
-#endif
-#ifdef KERBEROS
- krb5_flags authopts;
- krb5_error_code status;
- krb5_auth_context auth_context;
- int fflag = 0, Fflag = 0;
-#endif /* KERBEROS */
- int debug_port = 0;
- enum kcmd_proto kcmd_proto = KCMD_PROTOCOL_COMPAT_HACK;
-
- memset(&defaultservent, 0, sizeof(struct servent));
- if (strrchr(argv[0], '/'))
- argv[0] = strrchr(argv[0], '/')+1;
-
- if ( argc < 2 ) goto usage;
- argc--;
- argv++;
-
- another:
- if (argc > 0 && host == 0 && strncmp(*argv, "-", 1)) {
- host = *argv;
- argv++, argc--;
- goto another;
- }
-
- if (argc > 0 && !strcmp(*argv, "-D")) {
- argv++; argc--;
- debug_port = htons(atoi(*argv));
- argv++; argc--;
- goto another;
- }
-
- if (argc > 0 && !strcmp(*argv, "-l")) {
- argv++, argc--;
- if (argc > 0)
- user = *argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-n")) {
- argv++, argc--;
- nflag++;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-d")) {
- argv++, argc--;
- options |= SO_DEBUG;
- goto another;
- }
-#ifdef KERBEROS
- if (argc > 0 && !strcmp(*argv, "-k")) {
- argv++, argc--;
- if (argc == 0) {
- fprintf(stderr, "rsh(kerberos): -k flag must have a realm after it.\n");
- exit (1);
- }
- if(!(krb_realm = strdup(*argv))){
- fprintf(stderr, "rsh(kerberos): Cannot malloc.\n");
- exit(1);
- }
- argv++, argc--;
- goto another;
- }
- /*
- * Ignore -x from kerberos rlogin
- */
- if (argc > 0 && !strncmp(*argv, "-x", 2)) {
- argv++, argc--;
- encrypt_flag++;
- goto another;
- }
- if (argc > 0 && !strncmp(*argv, "-f", 2)) {
- if (Fflag) {
- fprintf(stderr, "rsh: Only one of -f and -F allowed\n");
- goto usage;
- }
- fflag++;
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strncmp(*argv, "-F", 2)) {
- if (fflag) {
- fprintf(stderr, "rsh: Only one of -f and -F allowed\n");
- goto usage;
- }
- Fflag++;
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strncmp(*argv, "-A", 2)) {
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-PO")) {
- argv++, argc--;
- kcmd_proto = KCMD_OLD_PROTOCOL;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-PN")) {
- argv++, argc--;
- kcmd_proto = KCMD_NEW_PROTOCOL;
- goto another;
- }
-#endif /* KERBEROS */
- /*
- * Ignore the -L, -w, -e and -8 flags to allow aliases with rlogin
- * to work
- *
- * There must be a better way to do this! -jmb
- */
- if (argc > 0 && !strncmp(*argv, "-L", 2)) {
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strncmp(*argv, "-w", 2)) {
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strncmp(*argv, "-e", 2)) {
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strncmp(*argv, "-8", 2)) {
- argv++, argc--;
- goto another;
- }
-#ifdef ATHENA
- /* additional Athena flags to be ignored */
- if (argc > 0 && !strcmp(*argv, "-noflow")) { /* No local flow control option for rlogin */
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-7")) {
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-c")) {
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-a")) {
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-n")) {
- argv++, argc--;
- goto another;
- }
- /*
- ** Also ignore -t ttytype
- */
- if (argc > 0 && !strcmp(*argv, "-t")) {
- argv++; argv++; argc--; argc--;
- goto another;
- }
-#endif /* ATHENA */
- if (host == 0)
- goto usage;
- if (argv[0] == 0) {
- execv(RLOGIN_PROGRAM, argv0);
- perror(RLOGIN_PROGRAM);
- exit(1);
- }
-
- pwd = getpwuid(getuid());
- if (pwd == 0) {
- fprintf(stderr, "who are you?\n");
- exit(1);
- }
- cc = 0;
- for (ap = argv; *ap; ap++)
- cc += strlen(*ap) + 1;
- if (encrypt_flag)
- cc += 3;
- args = (char *) malloc((unsigned) cc);
- *args = '\0';
- if (encrypt_flag)
- strlcpy(args, "-x ", cc);
- for (ap = argv; *ap; ap++) {
- (void) strlcat(args, *ap, cc);
- if (ap[1])
- strlcat(args, " ", cc);
- }
-
- if(debug_port == 0) {
-#ifdef KERBEROS
- sp = getservbyname("kshell", "tcp");
-#else
- sp = getservbyname("shell", "tcp");
-#endif /* KERBEROS */
- if (sp == 0) {
-#ifdef KERBEROS
- sp = &defaultservent;
- sp->s_port = htons(544);
-#else
- fprintf(stderr, "rsh: shell/tcp: unknown service\n");
- exit(1);
-#endif /* KERBEROS */
- }
-
- debug_port = sp->s_port;
- }
-
-#ifdef KERBEROS
- status = krb5_init_context(&bsd_context);
- if (status) {
- com_err(argv[0], status, "while initializing krb5");
- exit(1);
- }
- authopts = AP_OPTS_MUTUAL_REQUIRED;
-
- /* Piggy-back forwarding flags on top of authopts; */
- /* they will be reset in kcmd */
- if (fflag || Fflag)
- authopts |= OPTS_FORWARD_CREDS;
- if (Fflag)
- authopts |= OPTS_FORWARDABLE_CREDS;
-#ifdef HAVE_ISATTY
- suppress = !isatty(fileno(stderr));
-#endif
- status = kcmd(&rem, &host, debug_port,
- pwd->pw_name,
- user ? user : pwd->pw_name,
- args, &rfd2, "host", krb_realm,
- &cred,
- 0, /* No need for sequence number */
- 0, /* No need for server seq # */
- &local, &foreign,
- &auth_context, authopts,
- 1, /* Always set anyport, there is no need not to. --proven */
- suppress,
- &kcmd_proto);
- if (status) {
- /* If new protocol requested, don't fall back to less secure
- ones. */
- if (kcmd_proto == KCMD_NEW_PROTOCOL)
- exit (1);
- try_normal(argv0);
- } else {
- krb5_keyblock *key = &cred->keyblock;
-
- if (kcmd_proto == KCMD_NEW_PROTOCOL) {
- status = krb5_auth_con_getsendsubkey (bsd_context, auth_context,
- &key);
- if (status) {
- com_err (argv[0], status, "determining subkey for session");
- exit (1);
- }
- if (!key) {
- com_err (argv[0], 0, "no subkey negotiated for connection");
- exit (1);
- }
- }
-
- rcmd_stream_init_krb5(key, encrypt_flag, 0, 1, kcmd_proto);
- }
-
-#ifdef HAVE_ISATTY
- if(encrypt_flag&&isatty(2)) {
- write(2,SECURE_MESSAGE, strlen(SECURE_MESSAGE));
- }
-#endif
-
-#else /* !KERBEROS */
- rem = rcmd(&host, debug_port, pwd->pw_name,
- user ? user : pwd->pw_name, args, &rfd2);
- if (rem < 0)
- exit(1);
-#endif /* KERBEROS */
- if (rfd2 < 0) {
- fprintf(stderr, "rsh: can't establish stderr\n");
- exit(2);
- }
- if (options & SO_DEBUG) {
- if (setsockopt(rem, SOL_SOCKET, SO_DEBUG,
- (const char *) &one, sizeof (one)) < 0)
- perror("setsockopt (stdin)");
- if (setsockopt(rfd2, SOL_SOCKET, SO_DEBUG,
- (const char *) &one, sizeof (one)) < 0)
- perror("setsockopt (stderr)");
- }
- (void) setuid(getuid());
-#ifdef POSIX_SIGNALS
- sigemptyset(&igmask);
- sigaddset(&igmask, SIGINT);
- sigaddset(&igmask, SIGQUIT);
- sigaddset(&igmask, SIGTERM);
- sigprocmask(SIG_BLOCK, &igmask, &omask);
-
- (void)sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = sendsig;
-
- (void)sigaction(SIGINT, (struct sigaction *)0, &osa);
- if (osa.sa_handler != SIG_IGN)
- (void)sigaction(SIGINT, &sa, (struct sigaction *)0);
-
- (void)sigaction(SIGQUIT, (struct sigaction *)0, &osa);
- if (osa.sa_handler != SIG_IGN)
- (void)sigaction(SIGQUIT, &sa, (struct sigaction *)0);
-
- (void)sigaction(SIGTERM, (struct sigaction *)0, &osa);
- if (osa.sa_handler != SIG_IGN)
- (void)sigaction(SIGTERM, &sa, (struct sigaction *)0);
-#else
-#ifdef sgi
- omask = sigignore(mask(SIGINT)|mask(SIGQUIT)|mask(SIGTERM));
-#else
- omask = sigblock(mask(SIGINT)|mask(SIGQUIT)|mask(SIGTERM));
-#endif
- if (signal(SIGINT, SIG_IGN) != SIG_IGN)
- signal(SIGINT, sendsig);
- if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
- signal(SIGQUIT, sendsig);
- if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
- signal(SIGTERM, sendsig);
-#endif /* POSIX_SIGNALS */
- if (nflag == 0) {
- pid = fork();
- if (pid < 0) {
- perror("fork");
- exit(1);
- }
- }
- if (!encrypt_flag) {
- ioctl(rfd2, FIONBIO, &one);
- ioctl(rem, FIONBIO, &one);
- }
- if (nflag == 0 && pid == 0) {
- char *bp;
- int wc;
- fd_set rembits;
-
- (void) close(rfd2);
- reread:
- errno = 0;
- cc = read(0, buf, sizeof buf);
- if (cc <= 0)
- goto done;
- bp = buf;
- rewrite:
- FD_ZERO(&rembits);
- FD_SET(rem, &rembits);
- if (select(rem + 1, 0, &rembits, 0, 0) < 0) {
- if (errno != EINTR) {
- perror("select");
- exit(1);
- }
- goto rewrite;
- }
- if (FD_ISSET(rem, &rembits) == 0)
- goto rewrite;
- wc = rcmd_stream_write(rem, bp, cc, 0);
- if (wc < 0) {
- if ((errno == EWOULDBLOCK) || (errno == EAGAIN))
- goto rewrite;
- goto done;
- }
- cc -= wc; bp += wc;
- if (cc == 0)
- goto reread;
- goto rewrite;
- done:
- (void) shutdown(rem, 1);
-#ifdef KERBEROS
- krb5_free_context(bsd_context);
-#endif
- exit(0);
- }
-#ifdef POSIX_SIGNALS
- sigprocmask(SIG_SETMASK, &omask, (sigset_t*)0);
-#else
-#ifndef sgi
- sigsetmask(omask);
-#endif
-#endif /* POSIX_SIGNALS */
- FD_ZERO(&readfrom);
- FD_SET(rfd2, &readfrom);
- FD_SET(rem, &readfrom);
- do {
- ready = readfrom;
- if (select(((rfd2 > rem) ? rfd2 : rem) + 1, &ready, 0, 0, 0) < 0) {
- if (errno != EINTR) {
- perror("select");
- exit(1);
- }
- continue;
- }
- if (FD_ISSET(rfd2, &ready)) {
- errno = 0;
- cc = rcmd_stream_read(rfd2, buf, sizeof buf, 1);
- if (cc <= 0) {
- if ((errno != EWOULDBLOCK) && (errno != EAGAIN))
- FD_CLR(rfd2, &readfrom);
- } else
- (void) write(2, buf, (unsigned) cc);
- }
- if (FD_ISSET(rem, &ready)) {
- errno = 0;
- cc = rcmd_stream_read(rem, buf, sizeof buf, 0);
- if (cc <= 0) {
- if ((errno != EWOULDBLOCK) && (errno != EAGAIN))
- FD_CLR(rem, &readfrom);
- } else
- (void) write(1, buf, (unsigned) cc);
- }
- } while (FD_ISSET(rem, &readfrom) || FD_ISSET(rfd2, &readfrom));
- if (nflag == 0)
- (void) kill(pid, SIGKILL);
-#ifdef KERBEROS
- krb5_free_context(bsd_context);
-#endif
- exit(0);
- usage:
- fprintf(stderr,
- "usage: \trsh host [ -PN / -PO ] [ -l login ] [ -n ] [ -x ] [ -f / -F] command\n");
- fprintf(stderr,
- "OR \trsh [ -PN / -PO ] [ -l login ] [-n ] [ -x ] [ -f / -F ] host command\n");
- exit(1);
-}
-
-
-
-krb5_sigtype sendsig(signo)
- char signo;
-{
- (void) rcmd_stream_write(rfd2, &signo, 1, 1);
-}
-
-
-
-#ifdef KERBEROS
-void try_normal(argv)
- char **argv;
-{
- char *host;
-
-#ifndef KRB5_ATHENA_COMPAT
- if (encrypt_flag)
- exit(1);
-#endif
- /*
- * if we were invoked as 'rsh host mumble', strip off the rsh
- * from arglist.
- *
- * We always want to call the Berkeley rsh as 'host mumble'
- */
- host = strrchr(argv[0], '/');
- if (host)
- host++;
- else
- host = argv[0];
-
- if (!strcmp(host, "rsh"))
- argv++;
-
- fprintf(stderr,"trying normal rsh (%s)\n",
- UCB_RSH);
- fflush(stderr);
- execv(UCB_RSH, argv);
- perror("exec");
- exit(1);
-}
-#endif /* KERBEROS */
+++ /dev/null
-/*
- * appl/bsd/krshd.c
- */
-
-/*
- * Copyright (c) 1983 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef lint
-char copyright[] =
- "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
- All rights reserved.\n";
-#endif /* not lint */
-
-/* based on @(#)rshd.c 5.12 (Berkeley) 9/12/88 */
-
- /*
- * remote shell server:
- * remuser\0
- * locuser\0
- * command\0
- * data
- */
-
-/*
- * This is the rshell daemon. The very basic protocol for checking
- * authentication and authorization is:
- * 1) Check authentication.
- * 2) Check authorization via the access-control files:
- * ~/.k5login (using krb5_kuserok)
- * Execute command if configured authoriztion checks pass, else deny
- * permission.
- */
-
-/* DEFINES:
- * KERBEROS - Define this if application is to be kerberised.
- * LOG_ALL_LOGINS - Define this if you want to log all logins.
- * LOG_OTHER_USERS - Define this if you want to log all principals that do
- * not map onto the local user.
- * LOG_REMOTE_REALM - Define this if you want to log all principals from
- * remote realms.
- * LOG_CMD - Define this if you want to log not only the user but also the
- * command executed. This only decides the type of information
- * logged. Whether or not to log is still decided by the above
- * three DEFINES.
- * Note: Root account access is always logged.
- */
-
-#define SERVE_NON_KRB
-#define LOG_REMOTE_REALM
-#define LOG_CMD
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef __SCO__
-#include <sys/unistd.h>
-#endif
-
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-
-#include <fcntl.h>
-
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <stdio.h>
-#include <grp.h>
-#include <errno.h>
-#include <pwd.h>
-#include <ctype.h>
-#include <string.h>
-#include <libpty.h>
-#include <sys/wait.h>
-
-#ifdef HAVE_SYS_LABEL_H
-/* only SunOS 4? */
-#include <sys/label.h>
-#include <sys/audit.h>
-#include <pwdadj.h>
-#endif
-#include <stdarg.h>
-
-#include <signal.h>
-#include <netdb.h>
-
-#ifdef CRAY
-#ifndef NO_UDB
-#include <udb.h>
-#endif /* !NO_UDB */
-#include <sys/category.h>
-#include <netinet/ip.h>
-#include <sys/tfm.h>
-#include <sys/nal.h>
-#include <sys/secparm.h>
-#include <sys/usrv.h>
-#include <sys/utsname.h>
-#include <sys/sysv.h>
-#include <sys/slrec.h>
-#include <sys/unistd.h>
-#include <path.h>
-#endif /* CRAY */
-
-#include <syslog.h>
-
-#ifdef POSIX_TERMIOS
-#include <termios.h>
-#endif
-
-#ifdef HAVE_SYS_FILIO_H
-/* get FIONBIO from sys/filio.h, so what if it is a compatibility feature */
-#include <sys/filio.h>
-#endif
-
-#ifdef KERBEROS
-#include "k5-int.h"
-#include <com_err.h>
-#include "loginpaths.h"
-#include <k5-util.h>
-#include <k5-platform.h>
-
-#ifdef HAVE_PATHS_H
-#include <paths.h>
-#endif
-
-#if defined(_PATH_NOLOGIN)
-#define NOLOGIN _PATH_NOLOGIN
-#else
-#define NOLOGIN "/etc/nologin"
-#endif
-
-#include "defines.h"
-
-#if HAVE_ARPA_NAMESER_H
-#include <arpa/nameser.h>
-#endif
-
-#ifndef MAXDNAME
-#define MAXDNAME 256 /*per the rfc*/
-#endif
-
-#define ARGSTR "ek5ciD:S:M:AP:?L:w:"
-
-
-
-
-#define MAXRETRIES 4
-
-krb5_context bsd_context;
-char *srvtab = NULL;
-krb5_keytab keytab = NULL;
-krb5_ccache ccache = NULL;
-
-void fatal(int, const char *);
-
-int require_encrypt = 0;
-int do_encrypt = 0;
-int anyport = 0;
-char *kprogdir = KPROGDIR;
-int netf;
-int maxhostlen = 0;
-int stripdomain = 1;
-int always_ip = 0;
-
-static krb5_error_code recvauth(int netfd, struct sockaddr *peersin,
- int *valid_checksum);
-
-#else /* !KERBEROS */
-
-#define ARGSTR "RD:?"
-
-#endif /* KERBEROS */
-
-static int accept_a_connection (int debug_port, struct sockaddr *from,
- socklen_t *fromlenp);
-
-#ifndef HAVE_KILLPG
-#define killpg(pid, sig) kill(-(pid), (sig))
-#endif
-
-int checksum_required = 0, checksum_ignored = 0;
-char *progname;
-
-#define MAX_PROG_NAME 10
-
-/* Leave room for 4 environment variables to be passed */
-#define MAXENV 4
-#define SAVEENVPAD 0,0,0,0 /* padding for envinit slots */
-char *save_env[MAXENV];
-int num_env = 0;
-
-#ifdef CRAY
-int secflag;
-extern
-#endif /* CRAY */
-
-void error (char *fmt, ...)
-#if !defined (__cplusplus) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7))
- __attribute__ ((__format__ (__printf__, 1, 2)))
-#endif
- ;
-
-void usage(void), getstr(int, char *, int, char *),
- doit(int, struct sockaddr *);
-
-#ifndef HAVE_INITGROUPS
-int initgroups(char* name, gid_t basegid) {
- gid_t others[NGROUPS_MAX+1];
- int ngrps;
-
- others[0] = basegid;
- ngrps = getgroups(NGROUPS_MAX, others+1);
- return setgroups(ngrps+1, others);
-}
-#endif
-
-
-int main(argc, argv)
- int argc;
- char **argv;
-{
-#if defined(BSD) && BSD+0 >= 43
- struct linger linger;
-#endif
- int on = 1;
- socklen_t fromlen;
- struct sockaddr_storage from;
- extern int opterr, optind;
- extern char *optarg;
- int ch;
- int fd;
- int debug_port = 0;
-#ifdef KERBEROS
- krb5_error_code status;
-#endif
-
-#ifdef CRAY
- secflag = sysconf(_SC_CRAY_SECURE_SYS);
-#endif
-
- progname = strrchr (*argv, '/');
- progname = progname ? progname + 1 : *argv;
-
-#ifndef LOG_ODELAY /* 4.2 syslog */
- openlog(progname, LOG_PID);
-#else
-#ifndef LOG_AUTH
-#define LOG_AUTH 0
-#endif
- openlog(progname, LOG_PID | LOG_ODELAY, LOG_AUTH);
-#endif /* 4.2 syslog */
-
-#ifdef KERBEROS
- status = krb5_init_context(&bsd_context);
- if (status) {
- syslog(LOG_ERR, "Error initializing krb5: %s",
- error_message(status));
- exit(1);
- }
-#endif
-
- /* Analyze parameters. */
- opterr = 0;
- while ((ch = getopt(argc, argv, ARGSTR)) != -1)
- switch (ch) {
-#ifdef KERBEROS
- case 'k':
- break;
-
- case '5':
- break;
- case 'c':
- checksum_required = 1;
- break;
- case 'i':
- checksum_ignored = 1;
- break;
-
- case 'e':
- require_encrypt = 1;
- break;
-
- case 'S':
- if ((status = krb5_kt_resolve(bsd_context, optarg, &keytab))) {
- com_err(progname, status, "while resolving srvtab file %s",
- optarg);
- exit(2);
- }
- break;
-
- case 'M':
- krb5_set_default_realm(bsd_context, optarg);
- break;
-
- case 'A':
- anyport = 1;
- break;
-
- case 'P':
- kprogdir = optarg;
- break;
-
- case 'L':
- if (num_env < MAXENV) {
- save_env[num_env] = strdup(optarg);
- if(!save_env[num_env++]) {
- com_err(progname, ENOMEM, "in saving environment");
- exit(2);
- }
- } else {
- fprintf(stderr, "%s: Only %d -L arguments allowed\n",
- progname, MAXENV);
- exit(2);
- }
- break;
-#endif
- case 'D':
- debug_port = atoi(optarg);
- break;
- case 'w':
- if (!strcmp(optarg, "ip"))
- always_ip = 1;
- else {
- char *cp;
- cp = strchr(optarg, ',');
- if (cp == NULL)
- maxhostlen = atoi(optarg);
- else if (*(++cp)) {
- if (!strcmp(cp, "striplocal"))
- stripdomain = 1;
- else if (!strcmp(cp, "nostriplocal"))
- stripdomain = 0;
- else {
- usage();
- exit(1);
- }
- *(--cp) = '\0';
- maxhostlen = atoi(optarg);
- }
- }
- break;
- case '?':
- default:
- usage();
- exit(1);
- break;
- }
-
- if (optind == 0) {
- usage();
- exit(1);
- }
-
- argc -= optind;
- argv += optind;
-
- fromlen = sizeof (from);
-
- if (debug_port)
- fd = accept_a_connection(debug_port, (struct sockaddr *)&from,
- &fromlen);
- else {
- if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
- fprintf(stderr, "%s: ", progname);
- perror("getpeername");
- _exit(1);
- }
-
- fd = 0;
- }
-
-/*
- * AIX passes an IPv4-mapped IPv6 address back from getpeername, but if
- * that address is later used in connect(), it returns an error. Convert
- * IPv4-mapped IPv6 addresses to simple IPv4 addresses on AIX (but don't
- * do this everywhere since it isn't always the right thing to do, just
- * the least wrong on AIX).
- */
-#if defined(_AIX) && defined(KRB5_USE_INET6)
- if (((struct sockaddr*)&from)->sa_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sa2sin6(&from)->sin6_addr)) {
- sa2sin(&from)->sin_len = sizeof(struct sockaddr_in);
- sa2sin(&from)->sin_family = AF_INET;
- sa2sin(&from)->sin_port = sa2sin6(&from)->sin6_port;
- memmove(&(sa2sin(&from)->sin_addr.s_addr), &(sa2sin6(&from)->sin6_addr.u6_addr.u6_addr8[12]), 4);
- }
-#endif
-
- if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&on,
- sizeof (on)) < 0)
- syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
-#if defined(BSD) && BSD+0 >= 43
- linger.l_onoff = 1;
- linger.l_linger = 60; /* XXX */
- if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *)&linger,
- sizeof (linger)) < 0)
- syslog(LOG_WARNING , "setsockopt (SO_LINGER): %m");
-#endif
-
- if (checksum_required&&checksum_ignored) {
- syslog(LOG_CRIT, "Checksums are required and ignored; these options are mutually exclusive--check the documentation.");
- fatal(fd, "Configuration error: mutually exclusive options specified");
- }
-
- doit(dup(fd), (struct sockaddr *) &from);
- return 0;
-}
-
-#ifdef CRAY
-char username[32] = "LOGNAME=";
-#include <tmpdir.h>
-char tmpdir[64] = "TMPDIR=";
-#else
-char username[20] = "USER=";
-#endif
-
-char homedir[64] = "HOME=";
-char shell[64] = "SHELL=";
-char term[64] = "TERM=network";
-char path_rest[] = RPATH;
-
-char remote_addr[64+NI_MAXHOST]; /* = "KRB5REMOTEADDR=" */
-char remote_port[64+NI_MAXSERV]; /* = "KRB5REMOTEPORT=" */
-char local_addr[64+NI_MAXHOST]; /* = "KRB5LOCALADDR=" */
-char local_port[64+NI_MAXSERV]; /* = "KRB5LOCALPORT=" */
-#define ADDRPAD 0,0,0,0
-#define KRBPAD 0 /* KRB5CCNAME, optional */
-
-/* The following include extra space for TZ and MAXENV pointers... */
-#define COMMONVARS homedir, shell, 0/*path*/, username, term
-#ifdef CRAY
-char *envinit[] =
-{COMMONVARS, "TZ=GMT0", tmpdir, SAVEENVPAD, KRBPAD, ADDRPAD, 0};
-#define TMPDIRENV 6
-char *getenv();
-#else /* CRAY */
-#ifdef KERBEROS
-char *envinit[] =
-{COMMONVARS, 0/*tz*/, SAVEENVPAD, KRBPAD, ADDRPAD, 0};
-#else /* KERBEROS */
-char *envinit[] =
-{COMMONVARS, 0/*tz*/, SAVEENVPAD, ADDRPAD, 0};
-#endif /* KERBEROS */
-#endif /* CRAY */
-
-#define TZENV 5
-#define PATHENV 2
-
-extern char **environ;
-char ttyn[12]; /* Line string for wtmp entries */
-
-#ifdef CRAY
-#define SIZEOF_INADDR SIZEOF_in_addr
-int maxlogs;
-#else
-#define SIZEOF_INADDR sizeof(struct in_addr)
-#endif
-
-#ifndef NCARGS
-/* linux doesn't seem to have it... */
-#define NCARGS 1024
-#endif
-
-#define NMAX 16
-
-int pid;
-char locuser[NMAX+1];
-char remuser[NMAX +1];
-char cmdbuf[NCARGS+1];
-char *kremuser;
-krb5_principal client;
-krb5_authenticator *kdata;
-
-static void
-ignore_signals()
-{
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
-
- (void)sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_IGN;
- (void)sigaction(SIGINT, &sa, (struct sigaction *)0);
- (void)sigaction(SIGQUIT, &sa, (struct sigaction *)0);
- (void)sigaction(SIGTERM, &sa, (struct sigaction *)0);
- (void)sigaction(SIGPIPE, &sa, (struct sigaction *)0);
- (void)sigaction(SIGHUP, &sa, (struct sigaction *)0);
-
- (void)kill(-pid, SIGTERM);
-#else
- signal(SIGINT, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
- signal(SIGTERM, SIG_IGN);
- signal(SIGPIPE, SIG_IGN);
- signal(SIGHUP, SIG_IGN);
-
- killpg(pid, SIGTERM);
-#endif
-}
-
-static krb5_sigtype
-cleanup(signumber)
- int signumber;
-{
- ignore_signals();
- wait(0);
-
- pty_logwtmp(ttyn,"","");
- syslog(LOG_INFO ,"Daemon terminated via signal %d.", signumber);
- if (ccache)
- krb5_cc_destroy(bsd_context, ccache);
- exit(0);
-}
-
-
-void doit(f, fromp)
- int f;
- struct sockaddr *fromp;
-{
- char *cp;
-#ifdef KERBEROS
- krb5_error_code status;
-#endif
- int valid_checksum;
- int cnt;
- char *crypt();
- struct passwd *pwd;
- char *path;
-#ifdef CRAY
-#ifndef NO_UDB
- struct udb *ue;
- struct udb ue_static;
- extern struct udb *getudbnam();
-#endif
- extern struct passwd *getpwnam(), *getpwuid();
- static int jid;
- int error();
- int paddr;
- struct nal nal;
- int nal_error;
- struct usrv usrv;
- struct sysv sysv;
- char *makejtmp(), *jtmpnam = 0;
- int packet_level; /* Packet classification level */
- long packet_compart; /* Packet compartments */
-#endif /* CRAY */
-
- int s = -1;
- char hostname[NI_MAXHOST];
- char *sane_host;
- char hostaddra[NI_MAXHOST];
- int aierr;
- short port;
- int pv[2], pw[2], px[2], cc;
- fd_set ready, readfrom;
- char buf[RCMD_BUFSIZ], sig;
- struct sockaddr_storage localaddr;
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
-#endif
-
-#ifdef IP_TOS
-/* solaris has IP_TOS, but only IPTOS_* values */
-#ifdef HAVE_GETTOSBYNAME
- struct tosent *tp;
-
-
- if ((tp = gettosbyname("interactive", "tcp")) &&
- (setsockopt(f, IPPROTO_IP, IP_TOS, &tp->t_tos, sizeof(int)) < 0))
-#ifdef TOS_WARN
- syslog(LOG_NOTICE, "setsockopt (IP_TOS): %m");
-#else
- ; /* silently ignore TOS errors in 6E */
-#endif
-#endif
-#endif /* IP_TOS */
-
- {
- socklen_t sin_len = sizeof (localaddr);
- if (getsockname(f, (struct sockaddr*)&localaddr, &sin_len) < 0) {
- perror("getsockname");
- exit(1);
- }
- }
-
-#ifdef POSIX_SIGNALS
- (void)sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_DFL;
- (void)sigaction(SIGINT, &sa, (struct sigaction *)0);
- (void)sigaction(SIGQUIT, &sa, (struct sigaction *)0);
- (void)sigaction(SIGTERM, &sa, (struct sigaction *)0);
-#else
- signal(SIGINT, SIG_DFL);
- signal(SIGQUIT, SIG_DFL);
- signal(SIGTERM, SIG_DFL);
-#endif
-#ifdef DEBUG
- { int t = open("/dev/tty", 2);
- if (t >= 0) {
- ioctl(t, TIOCNOTTY, (char *)0);
- (void) close(t);
- }
- }
-#endif
- if (fromp->sa_family != AF_INET
-#if defined(KRB5_USE_INET6) && defined(KERBEROS)
- && fromp->sa_family != AF_INET6
-#endif
- ) {
- syslog(LOG_ERR , "malformed from address\n");
- exit(1);
- }
-#ifdef KERBEROS
- netf = f;
-#else
- {
- struct sockaddr_in *frompin = sa2sin(fromp);
- frompin->sin_port = ntohs((u_short)frompin->sin_port);
- if (frompin->sin_port >= IPPORT_RESERVED ||
- frompin->sin_port < IPPORT_RESERVED/2) {
- syslog(LOG_ERR , "connection from bad port\n");
- exit(1);
- }
- }
-#endif /* KERBEROS */
-
-#ifdef CRAY
-
- /* If this is a secure system then get the packet classification
- of f. ( Note IP_SECURITY is checked in get_packet_classification:
- if it's not set then the user's (root) default
- classification level and compartments are returned. )
- Then set this process to that level/compart so that the stderr
- connection will be labeled appropriately.
- */
- if (secflag) {
- if (get_packet_classification(f,getuid(),
- &packet_level,&packet_compart) < 0) {
- syslog(LOG_ERR, "cannot get ip packet level\n");
- exit(1);
- }
- if(secflag == TFM_UDB_5) {
- if(setucmp(packet_compart, C_PROC) != 0) {
- error("Unable to setucmp.\n");
- exit(1);
- }
- } else if(secflag == TFM_UDB_6) {
- if(setulvl(packet_level,C_PROC) != 0) {
- error("Unable to setulvl.\n");
- exit(1);
- }
- if(setucmp(packet_compart, C_PROC) != 0) {
- error("Unable to setucmp.\n");
- exit(1);
- }
- }
-
- }
-#endif /* CRAY */
-
- (void) alarm(60);
- port = 0;
- for (;;) {
- char c;
- if ((cc = read(f, &c, 1)) != 1) {
- if (cc < 0)
- syslog(LOG_NOTICE , "read: %m");
- shutdown(f, 1+1);
- exit(1);
- }
- if (c == 0)
- break;
- port = port * 10 + c - '0';
- }
- (void) alarm(0);
- if (port != 0) {
- if (anyport) {
- int addrfamily = fromp->sa_family;
- s = getport(0, &addrfamily);
- } else {
- int lport = IPPORT_RESERVED - 1;
-#ifdef HAVE_RRESVPORT_AF
- s = rresvport_af(&lport, fromp->sa_family);
-#else
- s = rresvport(&lport);
-#endif
- }
- if (s < 0) {
- syslog(LOG_ERR ,
- "can't get stderr port: %m");
- exit(1);
- }
-#ifndef KERBEROS
- if (port >= IPPORT_RESERVED) {
- syslog(LOG_ERR , "2nd port not reserved\n");
- exit(1);
- }
-#endif /* KERBEROS */
- switch (fromp->sa_family) {
- case AF_INET:
- sa2sin(fromp)->sin_port = htons((u_short)port);
- break;
-#ifdef KRB5_USE_INET6
- case AF_INET6:
- sa2sin6(fromp)->sin6_port = htons((u_short)port);
- break;
-#endif
- }
- if (connect(s, (struct sockaddr *)fromp, socklen(fromp)) < 0) {
- syslog(LOG_INFO ,
- "connect second port: %m");
- exit(1);
- }
- }
- dup2(f, 0);
- dup2(f, 1);
- dup2(f, 2);
- aierr = getnameinfo(fromp, socklen(fromp), hostname, sizeof(hostname),
- 0, 0, 0);
- if (aierr) {
- error("failed to get remote host address: %s", gai_strerror(aierr));
- exit(1);
- }
- aierr = getnameinfo(fromp, socklen(fromp), hostaddra, sizeof(hostaddra),
- 0, 0, NI_NUMERICHOST);
- if (aierr) {
- error("failed to get remote host address: %s", gai_strerror(aierr));
- exit(1);
- }
-
-#ifdef KERBEROS
- status = pty_make_sane_hostname((struct sockaddr *) fromp, maxhostlen,
- stripdomain, always_ip, &sane_host);
- if (status) {
- error("failed make_sane_hostname: %s\n", error_message(status));
- exit(1);
- }
-
- if ((status = recvauth(f, fromp, &valid_checksum))) {
- error("Authentication failed: %s\n", error_message(status));
- exit(1);
- }
-#else
- getstr(f, remuser, sizeof(remuser), "remuser");
- getstr(f, locuser, sizeof(locuser), "locuser");
- getstr(f, cmdbuf, sizeof(cmdbuf), "command");
- rcmd_stream_init_normal();
-#endif /* KERBEROS */
-
-#ifdef CRAY
- paddr = inet_addr(inet_ntoa(fromp->sin_addr));
- if(secflag){
- /*
- * check network authorization list
- */
- if (fetchnal(paddr,&nal) < 0) {
- /*
- * NAL file inaccessible, abort connection.
- */
- error("Permission denied.\n");
- exit(1);
- }
- }
-#endif /* CRAY */
-
- pwd = getpwnam(locuser);
- if (pwd == (struct passwd *) 0 ) {
- syslog(LOG_ERR ,
- "Principal %s (%s@%s (%s)) for local user %s has no account.\n",
- kremuser, remuser, hostaddra, hostname,
- locuser); /* xxx sprintf buffer in syslog*/
- error("Login incorrect.\n");
- exit(1);
- }
-
-#ifdef CRAY
- /* Setup job entry, and validate udb entry.
- ( against packet level also ) */
- if ((jid = setjob(pwd->pw_uid, 0)) < 0) {
- error("Unable to create new job.\n");
- exit(1);
- }
- if ((jtmpnam = makejtmp(pwd->pw_uid, pwd->pw_gid, jid))) {
- register int pid, tpid;
- int status;
- switch(pid = fork()) {
- case -1:
- cleanjtmp(locuser, jtmpnam);
- envinit[TMPDIRENV] = 0;
- break;
- case 0:
- break;
- default:
- close(0);
- close(1);
- close(2);
- close(f);
- if (port)
- close(s);
- while ((tpid = wait(&status)) != pid) {
- if (tpid < 0)
- break;
- }
- cleanjtmp(locuser, jtmpnam);
- exit(status>>8);
- /* NOTREACHED */
- }
- } else {
- envinit[TMPDIRENV] = 0;
- }
-#ifndef NO_UDB
- (void)getsysudb();
-
- if ((ue = getudbnam(pwd->pw_name)) == (struct udb *)NULL) {
- error("Unable to fetch account id.\n");
- exit(1);
- }
- ue_static = *ue; /* save from setlimits call */
- endudb();
- if (secflag) {
- if(getsysv(&sysv, sizeof(struct sysv)) != 0) {
- loglogin(sane_host, SLG_LLERR, 0, ue);
- error("Permission denied.\n");
- exit(1);
- }
- if ((packet_level != ue->ue_deflvl) ||
- ((packet_compart & ue->ue_comparts) != packet_compart )){
- loglogin(sane_host, SLG_LLERR, 0, ue);
- error("Permission denied.\n");
- exit(1);
- }
- if (ue->ue_disabled != 0) {
- loglogin(sane_host,SLG_LOCK,ue->ue_logfails,ue);
- error("Permission denied.\n");
- exit(1);
- }
- maxlogs = sysv.sy_maxlogs;
- }
- if (acctid(getpid(), ue->ue_acids[0]) == -1) {
- error("Unable to set account id.\n");
- exit(1);
- }
- if (setshares(pwd->pw_uid, acctid(0, -1), error, 1, 0)) {
- error("Unable to set shares.\n");
- exit(1);
- }
- if (setlimits(pwd->pw_name, C_PROC, getpid(), UDBRC_INTER)) {
- error("Unable to set limits.\n");
- exit(1);
- }
- if (setlimits(pwd->pw_name, C_JOB, jid, UDBRC_INTER)) {
- error("Unable to set limits.\n");
- exit(1);
- }
- ue = &ue_static; /* restore after setlimits call */
- endudb(); /* setlimits opens udb and leaves it
- open so close it here. */
-#endif /* !NO_UDB */
-#endif /*CRAY*/
-
- /* Setup wtmp entry : we do it here so that if this is a CRAY
- the Process Id is correct and we have not lost our trusted
- privileges. */
- if (port) {
- /* Place entry into wtmp */
- snprintf(ttyn,sizeof(ttyn),"krsh%ld",(long) (getpid() % 9999999));
- pty_logwtmp(ttyn,locuser,sane_host);
- }
- /* We are simply execing a program over rshd : log entry into wtmp,
- as kexe(pid), then finish out the session right after that.
- Syslog should have the information as to what was exec'd */
- else {
- pty_logwtmp(ttyn,locuser,sane_host);
- }
-
-#ifdef CRAY
-
- /* If we are a secure system then we need to get rid of our
- trusted facility, so that MAC on the chdir we work. Before we
- do this make an entry into wtmp, and any other audit recording. */
-
- if (secflag) {
- if (getusrv(&usrv)){
- syslog(LOG_ERR,"Cannot getusrv");
- error("Permission denied.\n");
- loglogin(sane_host, SLG_LVERR, ue->ue_logfails,ue);
- goto signout_please;
- }
- /*
- * 6.0 no longer allows any form ofTRUSTED_PROCESS logins.
- */
- if((ue->ue_valcat & TFM_TRUSTED) ||
- (sysv.sy_oldtfm &&
- ((ue->ue_comparts & TRUSTED_SUBJECT) == TRUSTED_SUBJECT))) {
- loglogin(sane_host, SLG_TRSUB, ue->ue_logfails,ue);
- error("Permission denied.\n");
- goto signout_please;
- }
-
- loglogin(sane_host, SLG_OKLOG, ue->ue_logfails,ue);
-
- /* Setup usrv structure with user udb info and
- packet_level and packet_compart. */
- usrv.sv_actlvl = packet_level;
- usrv.sv_actcmp = packet_compart; /*Note get_packet_level sets
- compartment to users default
- compartments....*/
- usrv.sv_permit = ue->ue_permits;
- usrv.sv_intcls = ue->ue_intcls;
- usrv.sv_maxcls = ue->ue_maxcls;
- usrv.sv_intcat = ue->ue_intcat;
- usrv.sv_valcat = ue->ue_valcat;
- usrv.sv_savcmp = 0;
- usrv.sv_savlvl = 0;
-
- /*
- * Set user values to workstation boundaries
- */
-#ifdef MIN
-#undef MIN
-#endif
-#ifdef MAX
-#undef MAX
-#endif
-
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-
- nal_error = 0;
-
- if (nal.na_sort) {
- if ((ue->ue_minlvl > nal.na_smax) ||
- (ue->ue_maxlvl < nal.na_smin))
- nal_error++;
- else {
- usrv.sv_minlvl=MAX(ue->ue_minlvl, nal.na_smin);
- usrv.sv_maxlvl=MIN(ue->ue_maxlvl, nal.na_smax);
-
-#ifndef IP_SECURITY
-
- if (usrv.sv_actlvl < usrv.sv_minlvl)
- usrv.sv_actlvl = usrv.sv_minlvl;
- if (usrv.sv_actlvl > usrv.sv_maxlvl)
- usrv.sv_actlvl = usrv.sv_maxlvl;
-
-#else /*IP_SECURITY*/
- if (usrv.sv_actlvl < usrv.sv_minlvl)
- nal_error++;
- if (usrv.sv_actlvl > usrv.sv_maxlvl)
- nal_error++;
- if (usrv.sv_actlvl != ue->ue_deflvl)
- nal_error++;
-
- usrv.sv_valcmp = ue->ue_comparts & nal.na_scmp;
- usrv.sv_actcmp &= nal.na_scmp;
-#endif /*IP_SECURITY*/
- usrv.sv_valcmp = ue->ue_comparts & nal.na_scmp;
- usrv.sv_actcmp = (usrv.sv_valcmp &
- ue->ue_defcomps);
- }
- } else {
- /*
- * If the user's minimum level is greater than
- * zero, they cannot log on from this (ie. an
- * unclassified) host.
- */
- if (ue->ue_minlvl > 0)
- nal_error++;
- /*
- * Address not in NAL, if EXEMPT_NAL is not
- * true, then even an unclassified user is
- * not allowed.
- */
- if (!EXEMPT_NAL)
- nal_error++;
- else {
- usrv.sv_minlvl = 0;
- usrv.sv_maxlvl = 0;
- usrv.sv_valcmp = 0;
- usrv.sv_actcmp = 0;
- usrv.sv_actlvl = 0;
- }
- }
- if (nal_error) {
- loglogin(sane_host, SLG_LVERR, ue->ue_logfails,ue);
- error("Permission denied.\n");
- goto signout_please;
- }
-#undef MIN
-#undef MAX
- /* Before the setusrv is done then do a sethost for paddr */
- sethost(paddr);
-
- if (setusrv(&usrv) == -1) {
- loglogin(sane_host, SLG_LVERR, ue->ue_logfails,ue);
- error("Permission denied.\n");
- goto signout_please;
- }
- if (getusrv(&usrv) == -1) {
- error("Getusrv Permission denied.\n");
- goto signout_please;
- }
-
- }
-#endif /*CRAY*/
-
- if (chdir(pwd->pw_dir) < 0) {
- if(chdir("/") < 0) {
- error("No remote directory.\n");
- goto signout_please;
- }
- pwd->pw_dir = "/";
- }
-
-#ifdef KERBEROS
- /* krb5_kuserok returns 1 if OK */
- if (!krb5_kuserok(bsd_context, client, locuser)){
- syslog(LOG_ERR ,
- "Principal %s (%s@%s (%s)) for local user %s failed krb5_kuserok.\n",
- kremuser, remuser, hostaddra, hostname, locuser);
- error("Permission denied.\n");
- goto signout_please;
- }
-#else
- if (pwd->pw_passwd != 0 && *pwd->pw_passwd != '\0' &&
- ruserok(hostname[0] ? hostname : hostaddra,
- pwd->pw_uid == 0, remuser, locuser) < 0) {
- error("Permission denied.\n");
- goto signout_please;
- }
-#endif /* KERBEROS */
-
-
- if (checksum_required && !valid_checksum) {
- syslog(LOG_WARNING, "Client did not supply required checksum--connection rejected.");
- error( "You are using an old Kerberos5 client without checksum support; only newer clients are authorized.\n");
- goto signout_please;
- }
- if (require_encrypt&&(!do_encrypt)) {
- error("You must use encryption.\n");
- goto signout_please;
- }
-
- if (pwd->pw_uid && !access(NOLOGIN, F_OK)) {
- error("Logins currently disabled.\n");
- goto signout_please;
- }
-
- /* Log access to account */
- pwd = (struct passwd *) getpwnam(locuser);
- if (pwd && (pwd->pw_uid == 0)) {
-#ifdef LOG_CMD
- syslog(LOG_NOTICE, "Executing %s for principal %s (%s@%s (%s)) as ROOT",
- cmdbuf, kremuser, remuser, hostaddra, hostname);
-#else
- syslog(LOG_NOTICE ,"Access as ROOT by principal %s (%s@%s (%s))",
- kremuser, remuser, hostaddra, hostname);
-#endif
- }
-#if defined(KERBEROS) && defined(LOG_REMOTE_REALM) && !defined(LOG_OTHER_USERS) && !defined(LOG_ALL_LOGINS)
- /* Log if principal is from a remote realm */
- else if (client && !default_realm(client))
-#endif
-
-#if defined(KERBEROS) && defined(LOG_OTHER_USERS) && !defined(LOG_ALL_LOGINS)
- /* Log if principal name does not map to local username */
- else if (client && !princ_maps_to_lname(client, locuser))
-#endif /* LOG_OTHER_USERS */
-
-#ifdef LOG_ALL_LOGINS /* Log everything */
- else
-#endif
-
-#if defined(LOG_REMOTE_REALM) || defined(LOG_OTHER_USERS) || defined(LOG_ALL_LOGINS)
- {
-#ifdef LOG_CMD
- syslog(LOG_NOTICE, "Executing %s for principal %s (%s@%s (%s)) as local user %s",
- cmdbuf, kremuser, remuser, hostaddra, hostname, locuser);
-#else
- syslog(LOG_NOTICE ,"Access as %s by principal %s (%s@%s (%s))",
- locuser, kremuser, remuser, hostaddra, hostname);
-#endif
- }
-#endif
-
- (void) write(2, "", 1);
-
- if (port||do_encrypt) {
- if (port&&(pipe(pv) < 0)) {
- error("Can't make pipe.\n");
- goto signout_please;
- }
- if (pipe(pw) < 0) {
- error("Can't make pipe 2.\n");
- goto signout_please;
- }
- if (pipe(px) < 0) {
- error("Can't make pipe 3.\n");
- goto signout_please;
- }
- pid = fork();
- if (pid == -1) {
- error("Fork failed.\n");
- goto signout_please;
- }
- if (pid) {
- int maxfd;
-#ifdef POSIX_SIGNALS
- sa.sa_handler = cleanup;
- (void)sigaction(SIGINT, &sa, (struct sigaction *)0);
- (void)sigaction(SIGQUIT, &sa, (struct sigaction *)0);
- (void)sigaction(SIGTERM, &sa, (struct sigaction *)0);
- (void)sigaction(SIGHUP, &sa, (struct sigaction *)0);
-
- sa.sa_handler = SIG_IGN;
- /* SIGPIPE is a crutch that we don't need if we check
- the exit status of write. */
- (void)sigaction(SIGPIPE, &sa, (struct sigaction *)0);
- (void)sigaction(SIGCHLD, &sa, (struct sigaction *)0);
-#else
- signal(SIGINT, cleanup);
- signal(SIGQUIT, cleanup);
- signal(SIGTERM, cleanup);
- signal(SIGHUP, cleanup);
- /* SIGPIPE is a crutch that we don't need if we check
- the exit status of write. */
- signal(SIGPIPE, SIG_IGN);
- signal(SIGCHLD,SIG_IGN);
-#endif
-
- (void) close(0); (void) close(1); (void) close(2);
- if(port)
- (void) close(pv[1]);
- (void) close(pw[1]);
- (void) close(px[0]);
-
-
-
- FD_ZERO(&readfrom);
- FD_SET(f, &readfrom);
- maxfd = f;
- if(port) {
- FD_SET(s, &readfrom);
- if (s > maxfd)
- maxfd = s;
- FD_SET(pv[0], &readfrom);
- if (pv[0] > maxfd)
- maxfd = pv[0];
- }
- FD_SET(pw[0], &readfrom);
- if (pw[0] > maxfd)
- maxfd = pw[0];
-
- /* read from f, write to px[1] -- child stdin */
- /* read from s, signal child */
- /* read from pv[0], write to s -- child stderr */
- /* read from pw[0], write to f -- child stdout */
-
- do {
- ready = readfrom;
- if (select(maxfd + 1, &ready, (fd_set *)0,
- (fd_set *)0, (struct timeval *)0) < 0) {
- if (errno == EINTR) {
- continue;
- } else {
- break;
- }
- }
-
- if (port&&FD_ISSET(pv[0], &ready)) {
- /* read from the child stderr, write to the net */
- errno = 0;
- cc = read(pv[0], buf, sizeof (buf));
- if (cc <= 0) {
- shutdown(s, 1+1);
- FD_CLR(pv[0], &readfrom);
- } else {
- (void) rcmd_stream_write(s, buf, (unsigned) cc, 1);
- }
- }
- if (FD_ISSET(pw[0], &ready)) {
- /* read from the child stdout, write to the net */
- errno = 0;
- cc = read(pw[0], buf, sizeof (buf));
- if (cc <= 0) {
- shutdown(f, 1+1);
- FD_CLR(pw[0], &readfrom);
- } else {
- (void) rcmd_stream_write(f, buf, (unsigned) cc, 0);
- }
- }
- if (port&&FD_ISSET(s, &ready)) {
- /* read from the alternate channel, signal the child */
- if (rcmd_stream_read(s, &sig, 1, 1) <= 0) {
- FD_CLR(s, &readfrom);
- } else {
-#ifdef POSIX_SIGNALS
- sa.sa_handler = cleanup;
- (void)sigaction(sig, &sa, (struct sigaction *)0);
- kill(-pid, sig);
-#else
- signal(sig, cleanup);
- killpg(pid, sig);
-#endif
- }
- }
- if (FD_ISSET(f, &ready)) {
- /* read from the net, write to child stdin */
- errno = 0;
- cc = rcmd_stream_read(f, buf, sizeof(buf), 0);
- if (cc <= 0) {
- (void) close(px[1]);
- FD_CLR(f, &readfrom);
- } else {
- int wcc;
- wcc = write(px[1], buf, (unsigned) cc);
- if (wcc == -1) {
- /* pipe closed, don't read any more */
- /* might check for EPIPE */
- (void) close(px[1]);
- FD_CLR(f, &readfrom);
- } else if (wcc != cc) {
- syslog(LOG_INFO, "only wrote %d/%d to child",
- wcc, cc);
- }
- }
- }
- } while ((port&&FD_ISSET(s, &readfrom)) ||
- FD_ISSET(f, &readfrom) ||
- (port&&FD_ISSET(pv[0], &readfrom) )||
- FD_ISSET(pw[0], &readfrom));
- ignore_signals();
-#ifdef KERBEROS
- syslog(LOG_INFO ,
- "Shell process completed.");
-#endif
- /* Finish session in wmtp */
- pty_logwtmp(ttyn,"","");
- if (ccache)
- krb5_cc_destroy(bsd_context, ccache);
- exit(0);
- }
-#if defined(HAVE_SETSID)&&(!defined(ULTRIX))
- setsid();
-#else
-#ifdef SETPGRP_TWOARG
- setpgrp(0, getpid());
-#else
- setpgrp();
-#endif /*setpgrp_twoarg*/
-#endif /*HAVE_SETSID*/
- (void) close(s);
- (void) close(f);
- (void) close(pw[0]);
- if (port)
- (void) close(pv[0]);
- (void) close(px[1]);
-
- (void) dup2(px[0], 0);
- (void) dup2(pw[1], 1);
- if(port)
- (void) dup2(pv[1], 2);
- else dup2(pw[1], 2);
-
- (void) close(px[0]);
- (void) close(pw[1]);
- if(port)
- (void) close(pv[1]);
- }
-
- /* We are simply execing a program over rshd : log entry into wtmp,
- as kexe(pid), then finish out the session right after that.
- Syslog should have the information as to what was exec'd */
- else {
- pty_logwtmp(ttyn,"","");
- }
-
- if (*pwd->pw_shell == '\0')
- pwd->pw_shell = "/bin/sh";
- (void) close(f);
- (void) setgid((gid_t)pwd->pw_gid);
-#ifndef sgi
- if (getuid() == 0 || getuid() != pwd->pw_uid) {
- /* For testing purposes, we don't call initgroups if we
- already have the right uid, and it is not root. This is
- because on some systems initgroups outputs an error message
- if not called by root. */
- initgroups(pwd->pw_name, pwd->pw_gid);
- }
-#endif
-#ifdef HAVE_SETLUID
- /*
- * If we're on a system which keeps track of login uids, then
- * set the login uid.
- */
- if (setluid((uid_t) pwd->pw_uid) < 0) {
- perror("setluid");
- _exit(1);
- }
-#endif /* HAVE_SETLUID */
- if (setuid((uid_t)pwd->pw_uid) < 0) {
- perror("setuid");
- _exit(1);
- }
- /* if TZ is set in the parent, drag it in */
- {
- char **findtz = environ;
- while(*findtz) {
- if(!strncmp(*findtz,"TZ=",3)) {
- envinit[TZENV] = *findtz;
- break;
- }
- findtz++;
- }
- }
- strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
- strncat(shell, pwd->pw_shell, sizeof(shell)-7);
- strncat(username, pwd->pw_name, sizeof(username)-6);
- if (asprintf(&path, "PATH=%s:%s", kprogdir, path_rest) < 0) {
- perror("malloc");
- _exit(1);
- }
- envinit[PATHENV] = path;
-
- /* If we have KRB5CCNAME set, then copy into the
- * child's environment. This can't really have
- * a fixed position because tz may or may not be set.
- */
- if (getenv("KRB5CCNAME")) {
- int i;
- char *buf2;
- if (asprintf(&buf2, "KRB5CCNAME=%s",getenv("KRB5CCNAME")) >= 0) {
-
- for (i = 0; envinit[i]; i++);
- envinit[i] = buf2;
- }
- }
-
- {
- char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
- int i;
- /* these four are covered by ADDRPAD */
-
- for (i = 0; envinit[i]; i++);
-
- aierr = getnameinfo((struct sockaddr *)&localaddr,
- socklen((struct sockaddr *)&localaddr),
- hbuf, sizeof(hbuf), sbuf, sizeof(sbuf),
- NI_NUMERICHOST | NI_NUMERICSERV);
- if (aierr)
- goto skip_localaddr_env;
- snprintf(local_addr, sizeof(local_addr), "KRB5LOCALADDR=%s", hbuf);
- envinit[i++] =local_addr;
-
- snprintf(local_port, sizeof(local_port), "KRB5LOCALPORT=%s", sbuf);
- envinit[i++] =local_port;
- skip_localaddr_env:
-
- aierr = getnameinfo(fromp, socklen(fromp),
- hbuf, sizeof(hbuf), sbuf, sizeof(sbuf),
- NI_NUMERICHOST | NI_NUMERICSERV);
- if (aierr)
- goto skip_remoteaddr_env;
- snprintf(remote_addr, sizeof(remote_addr), "KRB5REMOTEADDR=%s", hbuf);
- envinit[i++] =remote_addr;
-
- snprintf(remote_port, sizeof(remote_port), "KRB5REMOTEPORT=%s", sbuf);
- envinit[i++] =remote_port;
-
- skip_remoteaddr_env:
- ;
- }
-
- /* If we do anything else, make sure there is space in the array. */
-
- for(cnt=0; cnt < num_env; cnt++) {
- int i;
- char *buf2;
-
- if(getenv(save_env[cnt])) {
- if (asprintf(&buf2, "%s=%s", save_env[cnt],
- getenv(save_env[cnt])) >= 0) {
- for (i = 0; envinit[i]; i++);
- envinit[i] = buf2;
- }
- }
- }
-
- /* XXX - If we do anything else, make sure there is space in the array. */
-
- environ = envinit;
-
-#ifdef KERBEROS
- /* To make Kerberos rcp work correctly, we must ensure that we
- invoke Kerberos rcp on this end, not normal rcp, even if the
- shell startup files change PATH. */
- if (!strncmp(cmdbuf, "rcp ", 4) ||
- (do_encrypt && !strncmp(cmdbuf, "-x rcp ", 7))) {
- char *copy;
- struct stat s2;
- int offst = 0;
-
- copy = strdup(cmdbuf);
- if (copy == NULL) {
- perror("malloc");
- _exit(1);
- }
- if (do_encrypt && !strncmp(cmdbuf, "-x ", 3)) {
- offst = 3;
- }
-
- strlcpy(cmdbuf + offst, kprogdir, sizeof(cmdbuf) - offst);
- cp = copy + 3 + offst;
-
- strlcat(cmdbuf, "/rcp", sizeof(cmdbuf));
-
- if (stat((char *)cmdbuf + offst, &s2) >= 0)
- strlcat(cmdbuf, cp, sizeof(cmdbuf));
- else
- strlcpy(cmdbuf, copy, sizeof(cmdbuf));
- free(copy);
- }
-#endif
-
- cp = strrchr(pwd->pw_shell, '/');
- if (cp)
- cp++;
- else
- cp = pwd->pw_shell;
-
- if (do_encrypt && !strncmp(cmdbuf, "-x ", 3)) {
- execl(pwd->pw_shell, cp, "-c", (char *)cmdbuf + 3, (char *)NULL);
- }
- else {
- execl(pwd->pw_shell, cp, "-c", cmdbuf, (char *)NULL);
- }
- perror(pwd->pw_shell);
- perror(cp);
- exit(1);
-
- signout_please:
- if (ccache)
- krb5_cc_destroy(bsd_context, ccache);
- ccache = NULL;
- pty_logwtmp(ttyn,"","");
- exit(1);
-}
-
-
-void
-#ifdef HAVE_STDARG_H
-error(char *fmt, ...)
-#else
-/*VARARGS1*/
-error(fmt, va_alist)
- char *fmt;
- va_dcl
-#endif
-{
- va_list ap;
- char buf[RCMD_BUFSIZ], *cp = buf;
-
-#ifdef HAVE_STDARG_H
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
-
- *cp++ = 1;
- (void) snprintf(cp, sizeof(buf) - (cp - buf), "%s: ", progname);
- (void) vsnprintf(buf+strlen(buf), sizeof(buf) - strlen(buf), fmt, ap);
- va_end(ap);
- (void) write(2, buf, strlen(buf));
- syslog(LOG_ERR ,"%s",buf+1);
-}
-
-
-void getstr(fd, buf, cnt, err)
- int fd;
- char *buf;
- int cnt;
- char *err;
-{
- char c;
-
- do {
- if (read(fd, &c, 1) != 1)
- exit(1);
- *buf++ = c;
- if (--cnt == 0) {
- error("%s too long\n", err);
- exit(1);
- }
- } while (c != 0);
-}
-
-#ifdef CRAY
-char *makejtmp(uid, gid, jid)
- register int uid, gid, jid;
-{
- register char *endc, *tdp = &tmpdir[strlen(tmpdir)];
- register int i;
-
- snprintf(tdp, sizeof(tmpdir) - (tdp - tmpdir), "%s/jtmp.%06d",
- JTMPDIR, jid);
- endc = &tmpdir[strlen(tmpdir)];
-
- endc[1] = '\0';
- for (i = 0; i < 26; i++) {
- endc[0] = 'a' + i;
- if (mkdir(tdp, JTMPMODE) != -1) {
- chown(tdp, uid, gid);
- return (tdp);
- } else if (errno != EEXIST)
- break;
- }
- return(NULL);
-}
-
-
-
-cleanjtmp(user, tpath)
- register char *user, *tpath;
-{
- switch(fork()) {
- case -1:
- break;
- case 0:
- if (secflag) {
- execl("/bin/rm", "rm", "-rf", tpath, 0);
- error("exec of %s failed; errno = %d\n",
- "/bin/rm", errno);
- } else {
- execl(CLEANTMPCMD, CLEANTMPCMD, user, tpath, 0);
- error("exec of %s failed; errno = %d\n",
- CLEANTMPCMD, errno);
- }
- exit(1);
- break;
- default:
- /*
- * Just forget about the child, let init will pick it
- * up after we exit.
- */
- break;
- }
-}
-
-
-
-/***get_packet_classification
- *
- *
- * int get_packet_classification():
- * Obtain packet level and compartments from passed fd...
- *
- * Returns:
- * -1: If could not get user defaults.
- * 0: success
- */
-#ifdef IP_SECURITY
-static int get_packet_classification(fd,useruid,level,comp)
- int fd;
- uid_t useruid;
- int *level;
- long *comp;
-{
- struct socket_security pkt_sec;
- struct udb *udb;
- int retval;
- int sockoptlen;
-
- retval = 0;
- getsysudb ();
- udb = getudbuid ((int) useruid);
- endudb ();
- if (udb == (struct udb *) 0) return(-1);
- /* Get packet IP packet label */
- sockoptlen = SIZEOF_sec;
- if ( getsockopt(fd,SOL_SOCKET,SO_SECURITY,
- (char *) &pkt_sec,&sockoptlen)){ /* Failed */
- return(-2);
- }
- *level = pkt_sec.sec_level;
- *comp = udb->ue_defcomps;
- return(0);
-}
-
-#else /* If no IP_SECURITY set level to users default */
-
-static int get_packet_classification(fd,useruid,level,comp)
- int fd;
- uid_t useruid;
- int *level;
- long *comp;
-{
- struct udb *udb;
- getsysudb ();
- udb = getudbuid ((int) useruid);
- endudb ();
- if (udb == (struct udb *) 0) return(-1);
- *level = udb->ue_deflvl;
- *comp = udb->ue_defcomps;
- return(0);
-}
-
-#endif /* IP_SECURITY */
-
-
-
-/*
- * Make a security log entry for the login attempt.
- * host = pointer to host id
- * flag = status of login
- * failures = current losing streak in login attempts
- */
-/* Make a security log entry for the login attempt.
- * host = pointer to host id
- * flag = status of login
- * failures = current losing streak in login attempts
- */
-
-loglogin(host, flag, failures, ue)
- char *host;
- int flag;
- int failures;
- struct udb * ue;
-{
- char urec[sizeof(struct slghdr) + sizeof(struct slglogin)];
- struct slghdr *uhdr = (struct slghdr *)urec;
- struct slglogin *ulogin=(struct slglogin *)&urec[sizeof(struct slghdr)];
-
- strncpy(ulogin->sl_line, ttyn, sizeof(ulogin->sl_line));
- strncpy(ulogin->sl_host, host, sizeof(ulogin->sl_host));
- ulogin->sl_failures = failures;
- if ( maxlogs && (failures >= maxlogs))
- flag |= SLG_DSABL;
- ulogin->sl_result = flag;
- uhdr->sl_uid = ue->ue_uid;
- uhdr->sl_ruid = ue->ue_uid;
- uhdr->sl_juid = ue->ue_uid;
- uhdr->sl_gid = ue->ue_gids[0];
- uhdr->sl_rgid = ue->ue_gids[0];
- uhdr->sl_slvl = ue->ue_deflvl;
- /* uhdr->sl_scls = ue->ue_defcls; enable for integrity policy */
- uhdr->sl_olvl = 0;
- uhdr->sl_len = sizeof(urec);
-
-#ifdef CRAY2
- slgentry(SLG_LOGN, (word *)urec);
-#else /* ! CRAY2 */
- slgentry(SLG_LOGN, (waddr_t)urec);
-#endif
- return;
-}
-
-#endif /* CRAY */
-
-
-
-void usage()
-{
-#ifdef KERBEROS
- syslog(LOG_ERR, "usage: kshd [-eciK] ");
-#else
- syslog(LOG_ERR, "usage: rshd");
-#endif
-}
-
-
-#ifdef KERBEROS
-
-#ifndef KRB_SENDAUTH_VLEN
-#define KRB_SENDAUTH_VLEN 8 /* length for version strings */
-#endif
-
-#define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN
- chars */
-
-static krb5_error_code
-recvauth(netfd, peersin, valid_checksum)
- int netfd;
- struct sockaddr *peersin;
- int *valid_checksum;
-{
- krb5_auth_context auth_context = NULL;
- krb5_error_code status;
- struct sockaddr_in laddr;
- socklen_t len;
- krb5_data inbuf;
- krb5_authenticator *authenticator;
- krb5_ticket *ticket;
- krb5_rcache rcache;
- struct passwd *pwd;
- uid_t uid;
- gid_t gid;
- enum kcmd_proto kcmd_proto;
- krb5_data version;
-
- *valid_checksum = 0;
- len = sizeof(laddr);
- if (getsockname(netfd, (struct sockaddr *)&laddr, &len)) {
- exit(1);
- }
-
-#ifdef unicos61
-#define SIZEOF_INADDR SIZEOF_in_addr
-#else
-#define SIZEOF_INADDR sizeof(struct in_addr)
-#endif
-
- status = krb5_auth_con_init(bsd_context, &auth_context);
- if (status)
- return status;
-
- status = krb5_auth_con_genaddrs(bsd_context, auth_context, netfd,
- KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR);
- if (status)
- return status;
-
- status = krb5_auth_con_getrcache(bsd_context, auth_context, &rcache);
- if (status) return status;
-
- if (! rcache) {
- krb5_principal server;
-
- status = krb5_sname_to_principal(bsd_context, 0, 0,
- KRB5_NT_SRV_HST, &server);
- if (status) return status;
-
- status = krb5_get_server_rcache(bsd_context,
- krb5_princ_component(bsd_context, server, 0),
- &rcache);
- krb5_free_principal(bsd_context, server);
- if (status) return status;
-
- status = krb5_auth_con_setrcache(bsd_context, auth_context, rcache);
- if (status) return status;
- }
-
- status = krb5_recvauth_version(bsd_context, &auth_context, &netfd,
- NULL, /* daemon principal */
- 0, /* no flags */
- keytab, /* normally NULL to use v5srvtab */
- &ticket, /* return ticket */
- &version); /* application version string */
- if (status) {
- /*
- * clean up before exiting
- */
- getstr(netfd, locuser, sizeof(locuser), "locuser");
- getstr(netfd, cmdbuf, sizeof(cmdbuf), "command");
- getstr(netfd, remuser, sizeof(locuser), "remuser");
- return status;
- }
-
- getstr(netfd, locuser, sizeof(locuser), "locuser");
- getstr(netfd, cmdbuf, sizeof(cmdbuf), "command");
-
- /* Must be V5 */
-
- kcmd_proto = KCMD_UNKNOWN_PROTOCOL;
- if (version.length != 9)
- fatal (netfd, "bad application version length");
- if (!memcmp (version.data, "KCMDV0.1", 9))
- kcmd_proto = KCMD_OLD_PROTOCOL;
- if (!memcmp (version.data, "KCMDV0.2", 9))
- kcmd_proto = KCMD_NEW_PROTOCOL;
-
- getstr(netfd, remuser, sizeof(locuser), "remuser");
-
- if ((status = krb5_unparse_name(bsd_context, ticket->enc_part2->client,
- &kremuser)))
- return status;
-
- if ((status = krb5_copy_principal(bsd_context, ticket->enc_part2->client,
- &client)))
- return status;
- if ((status = krb5_auth_con_getauthenticator(bsd_context, auth_context,
- &authenticator)))
- return status;
-
- if (authenticator->checksum && !checksum_ignored) {
- struct sockaddr_storage adr;
- unsigned int adr_length = sizeof(adr);
- int e;
- char namebuf[32];
- krb5_boolean valid = 0;
- krb5_data chksumbuf;
-
- chksumbuf.data = NULL;
- if (getsockname(netfd, (struct sockaddr *) &adr, &adr_length) != 0)
- goto error_cleanup;
-
- e = getnameinfo((struct sockaddr *)&adr, adr_length, 0, 0,
- namebuf, sizeof(namebuf), NI_NUMERICSERV);
- if (e)
- fatal(netfd, "local error: can't examine port number");
- if (asprintf(&chksumbuf.data, "%s:%s%s", namebuf, cmdbuf, locuser) < 0)
- goto error_cleanup;
-
- chksumbuf.length = strlen(chksumbuf.data);
- status = krb5_c_verify_checksum(bsd_context,
- ticket->enc_part2->session,
- KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM,
- &chksumbuf, authenticator->checksum,
- &valid);
- if (status == 0 && !valid) status = KRB5KRB_AP_ERR_BAD_INTEGRITY;
-
- error_cleanup:
- if (chksumbuf.data)
- free(chksumbuf.data);
- if (status) {
- krb5_free_authenticator(bsd_context, authenticator);
- return status;
- }
- *valid_checksum = 1;
- }
- krb5_free_authenticator(bsd_context, authenticator);
-
-
- if (!strncmp(cmdbuf, "-x ", 3))
- do_encrypt = 1;
-
- {
- krb5_keyblock *key;
- status = krb5_auth_con_getrecvsubkey (bsd_context, auth_context,
- &key);
- if (status)
- fatal (netfd, "Server can't get session subkey");
- if (!key && do_encrypt && kcmd_proto == KCMD_NEW_PROTOCOL)
- fatal (netfd, "No session subkey sent");
- if (key && kcmd_proto == KCMD_OLD_PROTOCOL) {
-#ifdef HEIMDAL_FRIENDLY
- key = 0;
-#else
- fatal (netfd, "Session subkey not allowed in old kcmd protocol");
-#endif
- }
- if (key == 0)
- key = ticket->enc_part2->session;
- rcmd_stream_init_krb5 (key, do_encrypt, 0, 0, kcmd_proto);
- }
-
- /* Null out the "session" because kcmd.c references the session
- * key here, and we do not want krb5_free_ticket() to destroy it. */
- ticket->enc_part2->session = 0;
-
- if ((status = krb5_read_message(bsd_context, (krb5_pointer)&netfd,
- &inbuf))) {
- error("Error reading message: %s\n", error_message(status));
- exit(1);
- }
-
- if (inbuf.length) { /* Forwarding being done, read creds */
- pwd = getpwnam(locuser);
- if (!pwd) {
- error("Login incorrect.\n");
- exit(1);
- }
- uid = pwd->pw_uid;
- gid = pwd->pw_gid;
- if ((status = rd_and_store_for_creds(bsd_context, auth_context, &inbuf,
- ticket, &ccache))) {
- error("Can't get forwarded credentials: %s\n",
- error_message(status));
- exit(1);
- }
- if (chown(krb5_cc_get_name(bsd_context, ccache), uid, gid) == -1) {
- error("Can't chown forwarded credentials: %s\n",
- error_message(errno));
- exit(1);
- }
- }
- krb5_free_ticket(bsd_context, ticket);
- return 0;
-}
-#endif /* KERBEROS */
-
-
-
-void fatal(f, msg)
- int f;
- const char *msg;
-{
- char buf[512];
-#ifndef POSIX_TERMIOS
- int out = 1 ; /* Output queue of f */
-#endif
-
- buf[0] = '\01'; /* error indicator */
- (void) snprintf(buf + 1, sizeof(buf) - 1, "%s: %s.\r\n",progname, msg);
- if ((f == netf) && (pid > 0))
- (void) rcmd_stream_write(f, buf, strlen(buf), 0);
- else
- (void) write(f, buf, strlen(buf));
- syslog(LOG_ERR,"%s\n",msg);
- if (pid > 0) {
- signal(SIGCHLD,SIG_IGN);
- kill(pid,SIGKILL);
-#ifdef POSIX_TERMIOS
- (void) tcflush(1, TCOFLUSH);
-#else
- (void) ioctl(f, TIOCFLUSH, (char *)&out);
-#endif
- cleanup(-1);
- }
- exit(1);
-}
-
-static int
-accept_a_connection (int debug_port, struct sockaddr *from,
- socklen_t *fromlenp)
-{
- int n, s, fd, s4 = -1, s6 = -1, on = 1;
- fd_set sockets;
-
- FD_ZERO(&sockets);
-
-#ifdef KRB5_USE_INET6
- {
- struct sockaddr_in6 sock_in6;
-
- if ((s = socket(AF_INET6, SOCK_STREAM, PF_UNSPEC)) < 0) {
- if ((errno == EPROTONOSUPPORT) || (errno == EAFNOSUPPORT))
- goto skip_ipv6;
- fprintf(stderr, "Error in socket(INET6): %s\n", strerror(errno));
- exit(2);
- }
-
- memset(&sock_in6, 0,sizeof(sock_in6));
- sock_in6.sin6_family = AF_INET6;
- sock_in6.sin6_port = htons(debug_port);
- sock_in6.sin6_addr = in6addr_any;
-
- (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
- (char *)&on, sizeof(on));
-
- if ((bind(s, (struct sockaddr *) &sock_in6, sizeof(sock_in6))) < 0) {
- fprintf(stderr, "Error in bind(INET6): %s\n", strerror(errno));
- exit(2);
- }
-
- if ((listen(s, 5)) < 0) {
- fprintf(stderr, "Error in listen(INET6): %s\n", strerror(errno));
- exit(2);
- }
- s6 = s;
- FD_SET(s, &sockets);
- skip_ipv6:
- ;
- }
-#endif
-
- {
- struct sockaddr_in sock_in;
-
- if ((s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0) {
- fprintf(stderr, "Error in socket: %s\n", strerror(errno));
- exit(2);
- }
-
- memset(&sock_in, 0,sizeof(sock_in));
- sock_in.sin_family = AF_INET;
- sock_in.sin_port = htons(debug_port);
- sock_in.sin_addr.s_addr = INADDR_ANY;
-
- (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
- (char *)&on, sizeof(on));
-
- if ((bind(s, (struct sockaddr *) &sock_in, sizeof(sock_in))) < 0) {
- if (s6 >= 0 && errno == EADDRINUSE)
- goto try_ipv6_only;
- fprintf(stderr, "Error in bind: %s\n", strerror(errno));
- exit(2);
- }
-
- if ((listen(s, 5)) < 0) {
- fprintf(stderr, "Error in listen: %s\n", strerror(errno));
- exit(2);
- }
- s4 = s;
- FD_SET(s, &sockets);
- try_ipv6_only:
- ;
- }
- if (s4 == -1 && s6 == -1) {
- fprintf(stderr, "No valid sockets established, exiting\n");
- exit(2);
- }
- n = select(((s4 < s6) ? s6 : s4) + 1, &sockets, 0, 0, 0);
- if (n < 0) {
- fprintf(stderr, "select error: %s\n", strerror(errno));
- exit(2);
- } else if (n == 0) {
- fprintf(stderr, "internal error? select returns 0\n");
- exit(2);
- }
- if (s6 != -1 && FD_ISSET(s6, &sockets)) {
- if (s4 != -1)
- close(s4);
- s = s6;
- } else if (FD_ISSET(s4, &sockets)) {
- if (s6 != -1)
- close(s6);
- s = s4;
- } else {
- fprintf(stderr,
- "internal error? select returns positive, "
- "but neither fd available\n");
- exit(2);
- }
-
- if ((fd = accept(s, from, fromlenp)) < 0) {
- fprintf(stderr, "Error in accept: %s\n", strerror(errno));
- exit(2);
- }
-
- close(s);
- return fd;
-}
+++ /dev/null
-.\" Copyright (c) 1983 Regents of the University of California.
-.\" All rights reserved. The Berkeley software License Agreement
-.\" specifies the terms and conditions for redistribution.
-.\"
-.\" @(#)rshd.8 6.3 (Berkeley) 5/24/86
-.\"
-.TH KRSHD 8
-.SH NAME
-kshd \- kerberized remote shell server
-.SH SYNOPSIS
-.B /usr/local/sbin/kshd
-[
-.B \-kr45ec
-]
-[\fB\-D\fP \fIport\fP]
-[\fB\-L\fP \fIvariable\fP]
-.SH DESCRIPTION
-.I Krshd
-is the server for the
-.IR rcmd (3)
-routine and, consequently, for the
-.IR rsh (1)
-program. The server provides remote execution facilities
-with authentication based on privileged port numbers from trusted hosts or
-the Kerberos authentication system.
-.PP
-The
-.I kshd
-server is invoked by \fIinetd(8c)\fP when it receives a connection
-on the port indicated in /etc/inetd.conf. A typical /etc/inetd.conf
-configuration line for \fIkrshd\fP might be:
-
-kshell stream tcp nowait root /usr/local/sbin/kshd kshd -5c
-
-When a service request is received, the following protocol is initiated:
-
-.IP 1)
-Authentication is checked
-.IP 2)
-Check authorization via the access-control files \fI.k5login\fP and
-\fI.klogin\fP in the user's home directory.
-.IP 3)
-A null byte is returned on the initial socket
-and the command line is passed to the normal login
-shell of the user. The
-shell inherits the network connections established
-by
-.IR krshd .
-
-\fIKrshd\fP can be configured by command-line arguments passed
-by \fIinetd(8)\fP.
- The options are:
-
-.IP \fB\-5\fP 10
-Allow Kerberos5 authentication with the \fI.k5login\fP access control file
-to be trusted. If this authentication system is used by the client and
-the authorization check is passed, then the user is allowed to log in. If
-the user has no \fI.k5login\fP file, the login will be authorized if the
-results of krb5_aname_to_localname conversion matches the account name.
-Unless special rules are configured, this will be true if and only if the
-Kerberos principal of the connecting user is in the default local realm
-and the principal portion matches the account name.
-
-.IP \fB\-4\fP
-Allow Kerberos4 authentication with the \fI.klogin\fP access control file
-to be trusted. If this authentication system is used by the client and the
-authorization check is passed, then the user is allowed to log in.
-
-.IP \fB\-k\fP
-Allow Kerberos5 and Kerberos4 as acceptable authentication
-mechanisms. This is the same as including \fB\-4\fP and \fB\-5\fP.
-
-.IP \fB\-e\fP
-Require the client to encrypt the connection. Only Kerberos5 clients
-support encryption.
-
-.IP \fB\-L\ variable\fP
-Carry through the current value of the specified variable into the
-environment of the child. This option can be used to preserve up to
-four variables.
-
-
-.IP \fB\-c\fP
-Require Kerberos5 clients to present a cryptographic
-checksum of initial connection information like the name of the user
-that the client is trying to access in the initial authenticator.
-This checksum provides additionl security by preventing an attacker
-from changing the initial connection information. To benefit from
-this security, only Kerberos5 should be trusted; Kerberos4 and rhosts
-authentication do not include this checksum. If this option is
-specified, older Kerberos5 clients that do not send a checksum in the
-authenticator will not be able to authenticate to this server. This
-option is mutually exclusive with the \fB-i\fP option.
-
- If neither the \fB-c\fP or \fB-i\fP options are specified,then
-checksums are validated if presented. Since it is difficult to remove
-a checksum from an authenticator without making the authenticator
-invalid, this default mode is almost as significant of a security
-improvement as \fB-c\fP if new clients are used. It has the additional
-advantage of backwards compatability with some clients.
-Unfortunately, clients before Kerberos V5, Beta5, generate invalid
-checksums; if these clients are used, the \fB-i\fP option must be
-used.
-
-.IP \fB\-i\fP
-Ignore authenticator checksums if provided. This option
-ignore authenticator checksusm presented by current Kerberos clients
-to protect initial connection information; it is the opposite of
-\fB-c\fP. This option is provided because some older
-clients--particularly clients predating the release of Kerberos V5
-Beta5 (May 1995)--present bogus checksums that prevent Kerberos
-authentication from succeeding in the default mode.
-
-
-.PP
-\fIKrshd\fP supports six options which may be used for testing:
-
-.IP \fB\-S\ keytab\fP 10
-Set the \fIkeytab\fP file to use.
-
-.IP \fB\-M\ realm\fP
-Set the Kerberos realm to use.
-
-.IP \fB\-A\fP
-Don't allocate a reserved port for the stderr connection.
-
-.IP \fB\-P\ path\fP
-Use the argument to find the Kerberos binaries. Normally a compiled
-in argument is used.
-
-.IP \fB\-D\ port\fP
-Run in standalone mode, listening on \fBport\fP. The daemon will exit
-after one connection and will not background itself.
-
-.TP
-\fB\-w \fP[\fBip\fP|\fImaxhostlen\fP[\fB,\fP[\fBno\fP]\fBstriplocal\fP]]
-Controls the form of the remote hostname passed to login(1).
-Specifying \fBip\fP results in the numeric IP address always being
-passed to login(1). Specifying a number, \fImaxhostlen\fP, sets the
-maximum length of the hostname passed to login(1) before it will be
-passed as a numeric IP address. If \fImaxhostlen\fP is 0, then the
-system default, as determined by the utmp or utmpx structures, is
-used. The \fBnostriplocal\fP and \fBstriplocal\fP options, which must
-be preceded by a comma, control whether or not the local host domain
-is stripped from the remote hostname. By default, the equivalent of
-\fBstriplocal\fP is in effect.
-
-.SH DIAGNOSTICS
-Except for the last one listed below,
-all diagnostic messages
-are returned on the initial socket,
-after which any network connections are closed.
-An error is indicated by a leading byte with a value of
-1 (0 is returned in step 3 above upon successful completion
-of all the steps prior to the execution of the login shell).
-.PP
-.B ``locuser too long''
-.br
-The name of the user on the client's machine is
-longer than 16 characters.
-.PP
-.B ``remuser too long''
-.br
-The name of the user on the remote machine is
-longer than 16 characters.
-.PP
-.B ``command too long ''
-.br
-The command line passed exceeds the size of the argument
-list (as configured into the system).
-.PP
-.B ``Login incorrect.''
-.br
-No password file entry for the user name existed.
-.PP
-.B ``No remote directory.''
-.br
-The
-.I chdir
-command to the home directory failed.
-.PP
-.B ``Permission denied.''
-.br
-The authentication procedure described above failed.
-.PP
-.B ``Can't make pipe.''
-.br
-The pipe needed for the
-.BR stderr ,
-wasn't created.
-.PP
-.B ``Try again.''
-.br
-A
-.I fork
-by the server failed.
-.PP
-.B ``<shellname>: ...''
-.br
-The user's login shell could not be started. This message is returned
-on the connection associated with the
-.BR stderr ,
-and is not preceded by a flag byte.
-.SH SEE ALSO
-rshd(8), rsh(1),
-rcmd(3)
-.SH BUGS
-A facility to allow all data exchanges to be encrypted should be
-present.
-.PP
-A more extensible protocol should be used.
+++ /dev/null
-.\" login.1
-.\"
-.TH LOGIN 8
-.SH NAME
-login.krb5 \- kerberos enhanced login program
-.SH SYNOPSIS
-.B login.krb5
-[\fB\-p\fP] [\fB\-fFe\fP \fIusername\fP]
-[\fB\-r | \-k | \-K | \-h \fP\fIhostname\fP]
-.SH DESCRIPTION
-.I login.krb5
-is a modification of the BSD login program which is used for two
-functions. It is the sub-process used by krlogind and telnetd to
-initiate a user session and it is a replacement for the command-line
-login program which, when invoked with a password, acquires Kerberos
-tickets for the user.
-.PP
-.I login.krb5
-will prompt for a username, or take one on the command line, as
-.I login.krb5 username
-and will then prompt for a password. This password will be used to
-acquire Kerberos Version 5 tickets (if possible.) It will also attempt
-to run
-.I aklog
-to get \fIAFS\fP tokens for the user. The version 5 tickets will be
-tested against a local
-.I krb5.keytab
-if it is available, in order to verify the tickets, before letting the
-user in. However, if the password matches the entry in
-\fI/etc/passwd\fP the user will be unconditionally allowed (permitting
-use of the machine in case of network failure.)
-.SH OPTIONS
-.TP
-\fB\-p\fP
-preserve the current environment
-.TP
-\fB\-r\fP \fIhostname\fP
-pass hostname to rlogind. Must be the last argument.
-.TP
-\fB\-h\fP \fIhostname\fP
-pass hostname to telnetd, etc. Must be the last argument.
-.TP
-\fB\-f\fP \fIname\fP
-Perform pre-authenticated login, e.g., datakit, xterm, etc.;
-allows preauthenticated login as root.
-.TP
-\fB\-F\fP \fIname\fP
-Perform pre-authenticated login, e.g., datakit, xterm, etc.; allows
-preauthenticated login as root.
-.TP
-\fB\-e\fP \fIname\fP
-Perform pre-authenticated, encrypted login. Must do term negotiation.
-.SH CONFIGURATION
-.I login.krb5
-is also configured via
-.I krb5.conf
-using the
-.I login
-stanza. A collection of options dealing with initial authentication are
-provided:
-.IP krb5_get_tickets
-Use password to get V5 tickets. Default value true.
-.IP krb_run_aklog
-Attempt to run aklog. Default value false.
-.IP aklog_path
-Where to find it [not yet implemented.] Default value
-.I $(prefix)/bin/aklog.
-.IP accept_passwd
-Don't accept plaintext passwords [not yet implemented]. Default value false.
-
-.SH DIAGNOSTICS
-All diagnostic messages are returned on the connection or tty
-associated with
-.BR stderr.
-.PP
-.SH SEE ALSO
-rlogind(8), rlogin(1), telnetd(8)
+++ /dev/null
-/*
- * appl/bsd/login.c
- */
-
-/*
- * Copyright (c) 1980, 1987, 1988 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef lint
-char copyright[] =
-"@(#) Copyright (c) 1980, 1987, 1988 The Regents of the University of California.\n\
- All rights reserved.\n";
-#endif /* not lint */
-
-/* based on @(#)login.c 5.25 (Berkeley) 1/6/89 */
-
-/* The configuration, with defaults as listed, is of the form:
- [login]
- # login stanza
- krb5_get_tickets = 1
- # use password to get v5 tickets
- krb_run_aklog = 0
- # attempt to run aklog
- aklog_path = $(prefix)/bin/aklog
- # where to find it [not yet implemented]
- accept_passwd = 0
- # don't accept plaintext passwords [not yet implemented]
-*/
-#define KRB5_GET_TICKETS
-int login_krb5_get_tickets = 1;
-
-#define KRB_RUN_AKLOG
-int login_krb_run_aklog = 0;
-
-int login_accept_passwd = 0;
-
-/*
- * login [ name ]
- * login -r hostname (for rlogind)
- * login -h hostname (for telnetd, etc.)
- * login -f name (for pre-authenticated login: datakit, xterm, etc.,
- * does allow preauthenticated login as root)
- * login -F name (for pre-authenticated login: datakit, xterm, etc.,
- * allows preauthenticated login as root)
- * login -e name (for pre-authenticated encrypted, must do term
- * negotiation)
- *
- * only one of: -r -f -e -k -K -F
- * only one of: -r -h -k -K
- */
-
-#include <libpty.h>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#include <sys/types.h>
-#include <sys/param.h>
-#ifdef OQUOTA
-#include <sys/quota.h>
-#endif
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-
-#include <utmp.h>
-#include <signal.h>
-
-#include <assert.h>
-
-#ifdef HAVE_LASTLOG_H
-#include <lastlog.h>
-#endif
-
-#ifdef linux
-/* linux has V* but not C* in headers. Perhaps we shouldn't be
- * initializing these values anyway -- tcgetattr *should* give
- * them reasonable defaults... */
-#define NO_INIT_CC
-#endif
-
-#include <errno.h>
-#ifdef HAVE_TTYENT_H
-#include <ttyent.h>
-#endif
-#include <syslog.h>
-#include <stdio.h>
-#include <grp.h>
-#include <pwd.h>
-#include <string.h>
-
-#include <setjmp.h>
-#ifndef POSIX_SETJMP
-#undef sigjmp_buf
-#undef sigsetjmp
-#undef siglongjmp
-#define sigjmp_buf jmp_buf
-#define sigsetjmp(j,s) setjmp(j)
-#define siglongjmp longjmp
-#endif
-
-#ifdef POSIX_SIGNALS
-typedef struct sigaction handler;
-#define handler_init(H,F) (sigemptyset(&(H).sa_mask), \
- (H).sa_flags=0, \
- (H).sa_handler=(F))
-#define handler_swap(S,NEW,OLD) sigaction(S, &NEW, &OLD)
-#define handler_set(S,OLD) sigaction(S, &OLD, NULL)
-#else
-typedef sigtype (*handler)();
-#define handler_init(H,F) ((H) = (F))
-#define handler_swap(S,NEW,OLD) ((OLD) = signal ((S), (NEW)))
-#define handler_set(S,OLD) (signal ((S), (OLD)))
-#endif
-
-
-#ifdef HAVE_SHADOW
-#include <shadow.h>
-#endif
-
-#ifdef KRB5_GET_TICKETS
-/* #include "krb5.h" */
-/* need k5-int.h to get ->profile from krb5_context */
-#include "k5-int.h"
-#include "com_err.h"
-#include "osconf.h"
-#endif /* KRB5_GET_TICKETS */
-
-#ifndef __STDC__
-#ifndef volatile
-#define volatile
-#endif
-#endif
-
-#ifdef HAVE_PATHS_H
-#include <paths.h>
-#endif
-
-#include "loginpaths.h"
-
-#ifdef POSIX_TERMIOS
-#include <termios.h>
-#ifndef CNUL
-#define CNUL (char) 0
-#endif
-
-#endif
-
-#ifdef _IBMR2
-#include <usersec.h>
-#include <sys/id.h>
-#endif
-
-#if defined(_AIX)
-#define PRIO_OFFSET 20
-#else
-#define PRIO_OFFSET 0
-#endif
-
-#if !defined(TAB3)
-#define TAB3 0
-#endif
-
-#define TTYGRPNAME "tty" /* name of group to own ttys */
-
-#if defined(_PATH_MAILDIR)
-#define MAILDIR _PATH_MAILDIR
-#else
-#define MAILDIR "/usr/spool/mail"
-#endif
-#if defined(_PATH_NOLOGIN)
-#define NOLOGIN _PATH_NOLOGIN
-#else
-#define NOLOGIN "/etc/nologin"
-#endif
-#if defined(_PATH_LASTLOG)
-#define LASTLOG _PATH_LASTLOG
-#else
-#define LASTLOG "/usr/adm/lastlog"
-#endif
-#if defined(_PATH_BSHELL)
-#define BSHELL _PATH_BSHELL
-#else
-#define BSHELL "/bin/sh"
-#endif
-
-#if (defined(BSD) && (BSD >= 199103)) /* no /usr/ucb */
-#define QUOTAWARN "/usr/bin/quota"
-#endif
-
-#define MOTDFILE "/etc/motd"
-#define HUSHLOGIN ".hushlogin"
-
-#if !defined(OQUOTA) && !defined(QUOTAWARN)
-#define QUOTAWARN "/usr/ucb/quota" /* warn user about quotas */
-#endif
-
-#ifndef NO_UT_HOST
-#ifndef UT_HOSTSIZE
-/* linux defines it directly in <utmp.h> */
-#define UT_HOSTSIZE sizeof(((struct utmp *)0)->ut_host)
-#endif /* UT_HOSTSIZE */
-#endif
-#ifndef UT_NAMESIZE
-/* linux defines it directly in <utmp.h> */
-#define UT_NAMESIZE sizeof(((struct utmp *)0)->ut_name)
-#endif
-
-#ifndef HAVE_SETPRIORITY
-/* if we don't have it, punt it cleanly */
-#define setpriority(which,who,prio)
-#endif /* HAVE_SETPRIORITY */
-
-#define MAXENVIRON 32
-
-#ifdef NEED_SETENV
-extern int setenv(char *, char *, int);
-#endif
-
-/*
- * This bounds the time given to login. Not a define so it can
- * be patched on machines where it's too small.
- */
-int timeout = 300;
-
-#if 0
-char term[64], *hostname, *username;
-#else
-char term[64], *username;
-#endif
-
-
-
-#ifdef KRB5_GET_TICKETS
-#define MAXPWSIZE 128 /* Biggest string accepted for KRB5
- passsword */
-#endif
-
-#if defined(__SVR4) || defined(sgi)
-#define NO_MOTD
-#define NO_MAILCHECK
-#endif
-
-char *getenv();
-void dofork(void);
-
-char *stypeof(char *);
-void term_init(int);
-int doremotelogin(char *), do_krb_login(char *, int), rootterm(char *);
-void lgetstr(char *, int, char *), getloginname(void), checknologin(void);
-void dolastlog(char *, int, char *), motd(void), check_mail(void);
-void sleepexit(int);
-
-#ifndef HAVE_STRSAVE
-char * strsave(char *);
-#endif
-
-typedef krb5_sigtype sigtype;
-
-sigtype timedout(int);
-
-
-#ifndef HAVE_INITGROUPS
-static int initgroups(char* name, gid_t basegid) {
- gid_t others[NGROUPS_MAX+1];
- int ngrps;
-
- others[0] = basegid;
- ngrps = getgroups(NGROUPS_MAX, others+1);
- return setgroups(ngrps+1, others);
-}
-#endif
-
-static struct login_confs {
- char *flagname;
- int *flag;
-} login_conf_set[] = {
-#ifdef KRB5_GET_TICKETS
- {"krb5_get_tickets", &login_krb5_get_tickets},
- {"krb_run_aklog", &login_krb_run_aklog},
-#endif
-};
-
-static char *conf_yes[] = {
- "y", "yes", "true", "t", "1", "on",
- 0
-};
-
-static char *conf_no[] = {
- "n", "no", "false", "nil", "0", "off",
- 0
-};
-
-/* 1 = true, 0 = false, -1 = ambiguous */
-static int conf_affirmative(s)
- char *s;
-{
- char **p;
-
- for(p=conf_yes; *p; p++) {
- if (!strcasecmp(*p,s))
- return 1;
- }
-
- for(p=conf_no; *p; p++) {
- if (!strcasecmp(*p,s))
- return 0;
- }
-
- /* ambiguous */
- return -1;
-}
-
-#ifdef KRB5_GET_TICKETS
-krb5_data tgtname = {
- 0,
- KRB5_TGS_NAME_SIZE,
- KRB5_TGS_NAME
-};
-#endif
-
-/* get flags (listed above) from the profile */
-static void login_get_kconf(k)
- krb5_context k;
-{
- int i, max_i;
- const char* kconf_names[3];
- char **kconf_val;
- int retval;
-
- max_i = sizeof(login_conf_set)/sizeof(struct login_confs);
- for (i = 0; i<max_i; i++) {
- kconf_names[0] = "login";
- kconf_names[1] = login_conf_set[i].flagname;
- kconf_names[2] = 0;
- retval = profile_get_values(k->profile,
- kconf_names, &kconf_val);
- if (retval) {
- /* ignore most (all?) errors */
- } else if (kconf_val && *kconf_val) {
- switch(conf_affirmative(*kconf_val)) {
- case 1:
- *login_conf_set[i].flag = 1;
- break;
- case 0:
- *login_conf_set[i].flag = 0;
- break;
- default:
- case -1:
- com_err("login/kconf", 0,
- "invalid flag value %s for flag %s",
- *kconf_val, kconf_names[1]);
- break;
- }
- }
- }
-}
-
-/* UNIX password support */
-
-struct passwd *pwd;
-static char *salt;
-
-#ifdef HAVE_SHADOW
-struct spwd *spwd;
-#endif
-
-static void lookup_user (name)
- char *name;
-{
- pwd = getpwnam (name);
- salt = pwd ? pwd->pw_passwd : "xx";
-#ifdef HAVE_SHADOW
- spwd = getspnam (name);
- if (spwd)
- salt = spwd->sp_pwdp;
-#endif
-}
-
-static int unix_needs_passwd ()
-{
-#ifdef HAVE_SHADOW
- if (spwd)
- return spwd->sp_pwdp[0] != 0;
-#endif
- if (pwd)
- return pwd->pw_passwd[0] != 0;
- return 1;
-}
-
-static int unix_passwd_okay (pass)
- char *pass;
-{
- char user_pwcopy[9], *namep;
- char *crypt ();
-
- assert (pwd != 0);
-
- /* copy the first 8 chars of the password for unix crypt */
- strncpy(user_pwcopy, pass, sizeof(user_pwcopy));
- user_pwcopy[sizeof(user_pwcopy) - 1]='\0';
- namep = crypt(user_pwcopy, salt);
- memset (user_pwcopy, 0, sizeof(user_pwcopy));
- /* ... and wipe the copy now that we have the string */
-
- /* verify the local password string */
-#ifdef HAVE_SHADOW
- if (spwd)
- return !strcmp(namep, spwd->sp_pwdp);
-#endif
- return !strcmp (namep, pwd->pw_passwd);
-}
-
-/* Kerberos support */
-#ifdef KRB5_GET_TICKETS
-krb5_context kcontext;
-krb5_ccache ccache;
-krb5_creds my_creds;
-static int got_v5_tickets, forwarded_v5_tickets;
-char ccfile[MAXPATHLEN+6]; /* FILE:path+\0 */
-int krbflag; /* set if tickets have been obtained */
-#endif /* KRB5_GET_TICKETS */
-
-void k_init (ttyn)
- char *ttyn;
-{
-#ifdef KRB5_GET_TICKETS
- krb5_error_code retval;
-
- retval = krb5_init_secure_context(&kcontext);
- if (retval) {
- com_err("login", retval, "while initializing krb5");
- exit(1);
- }
-
- login_get_kconf(kcontext);
-
- /* Set up the credential cache environment variable */
- if (!getenv(KRB5_ENV_CCNAME)) {
- snprintf(ccfile, sizeof(ccfile), "FILE:/tmp/krb5cc_p%ld",
- (long) getpid());
- setenv(KRB5_ENV_CCNAME, ccfile, 1);
- krb5_cc_set_default_name(kcontext, ccfile);
- unlink(ccfile+strlen("FILE:"));
- } else {
- /* note it correctly */
- strncpy(ccfile, getenv(KRB5_ENV_CCNAME), sizeof(ccfile));
- ccfile[sizeof(ccfile) - 1] = '\0';
- }
-#endif
-
-#ifdef BIND_HACK
- /* Set name server timeout to be reasonable,
- so that people don't take 5 minutes to
- log in. Can you say abstraction violation? */
- _res.retrans = 1;
-#endif /* BIND_HACK */
-}
-
-#ifdef KRB5_GET_TICKETS
-static int k5_get_password (user_pwstring, pwsize)
- char *user_pwstring;
- unsigned int pwsize;
-{
- krb5_error_code code;
- char prompt[255];
- snprintf(prompt, sizeof(prompt), "Password for %s", username);
-
- /* reduce opportunities to be swapped out */
- code = krb5_read_password(kcontext, prompt, 0, user_pwstring, &pwsize);
- if (code || pwsize == 0) {
- fprintf(stderr, "Error while reading password for '%s'\n", username);
- /* reading password failed... */
- return 0;
- }
- if (pwsize == 0) {
- fprintf(stderr, "No password read\n");
- /* reading password failed... */
- return 0;
- }
- return 1;
-}
-
-static int try_krb5 (me_p, pass)
- krb5_principal *me_p;
- char *pass;
-{
- krb5_error_code code;
- krb5_principal me;
-
- code = krb5_parse_name(kcontext, username, &me);
- if (code) {
- com_err ("login", code, "when parsing name %s",username);
- return 0;
- }
-
- *me_p = me;
-
- code = krb5_get_init_creds_password(kcontext, &my_creds, me, pass,
- krb5_prompter_posix, NULL,
- 0, NULL, NULL);
- if (code) {
- if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY)
- fprintf (stderr,
- "%s: Kerberos password incorrect\n",
- username);
- else
- com_err ("login", code,
- "while getting initial credentials");
- return 0;
- }
-
- krbflag = got_v5_tickets = 1;
-
- return 1;
-}
-
-static int have_v5_tickets (me)
- krb5_principal *me;
-{
- if (krb5_cc_default (kcontext, &ccache))
- return 0;
- if (krb5_cc_get_principal (kcontext, ccache, me)) {
- krb5_cc_close (kcontext, ccache);
- return 0;
- }
- krbflag = 1;
- return 1;
-}
-#endif /* KRB5_GET_TICKETS */
-
-/* Kerberos ticket-handling routines */
-
-static void destroy_tickets()
-{
-#ifdef KRB5_GET_TICKETS
- krb5_ccache cache;
-
- if (login_krb5_get_tickets) {
- if(!krb5_cc_default(kcontext, &cache))
- krb5_cc_destroy (kcontext, cache);
- }
-#endif
-}
-
-/* AFS support routines */
-#ifdef SETPAG
-
-int pagflag = 0; /* true if setpag() has been called */
-
-/* This doesn't seem to be declared in the AFS header files. */
-extern ktc_ForgetAllTokens (), setpag ();
-
-#ifdef SIGSYS
-static sigjmp_buf setpag_buf;
-
-static sigtype sigsys ()
-{
- siglongjmp(setpag_buf, 1);
-}
-
-static int try_afscall (scall)
- int (*scall)();
-{
- handler sa, osa;
- volatile int retval = 0;
-
- (void) &retval;
- handler_init (sa, sigsys);
- handler_swap (SIGSYS, sa, osa);
- if (sigsetjmp(setpag_buf, 1) == 0) {
- (*scall)();
- retval = 1;
- }
- handler_set (SIGSYS, osa);
- return retval;
-}
-
-#define try_setpag() try_afscall(setpag)
-#define try_unlog() try_afscall(ktc_ForgetAllTokens)
-#else
-#define try_setpag() (setpag() == 0)
-#define try_unlog() (ktc_ForgetAllTokens() == 0)
-#endif /* SIGSYS */
-#endif /* SETPAG */
-
-static void
-afs_login ()
-{
-#if defined(SETPAG)
- if (login_krb5_get_tickets && pwd->pw_uid) {
- /* Only reset the pag for non-root users. */
- /* This allows root to become anything. */
- pagflag = try_setpag ();
- }
-#endif
-#ifdef KRB_RUN_AKLOG
- if (got_v5_tickets && login_krb_run_aklog) {
- /* KPROGDIR is $(prefix)/bin */
- char aklog_path[MAXPATHLEN];
- struct stat st;
- /* construct the name */
- /* get this from profile later */
- aklog_path[sizeof(aklog_path) - 1] = '\0';
- strncpy (aklog_path, KPROGDIR, sizeof(aklog_path) - 1);
- strncat (aklog_path, "/aklog", sizeof(aklog_path) - 1 - strlen(aklog_path));
- /* only run it if we can find it */
- if (stat (aklog_path, &st) == 0) {
- system(aklog_path);
- }
- }
-#endif /* KRB_RUN_AKLOG */
-}
-
-static void
-afs_cleanup ()
-{
-#ifdef SETPAG
- if (pagflag)
- try_unlog ();
-#endif
-}
-
-/* Main routines */
-#define EXCL_AUTH_TEST if (rflag || kflag || Kflag || eflag || fflag ) { \
- fprintf(stderr, \
- "login: only one of -r, -k, -K, -e, -F, and -f allowed.\n"); \
- exit(1); \
-}
-
-#define EXCL_HOST_TEST if (rflag || kflag || Kflag || hflag) { \
- fprintf(stderr, \
- "login: only one of -r, -k, -K, and -h allowed.\n"); \
- exit(1); \
-}
-
-#if defined(HAVE_ETC_ENVIRONMENT) || defined(HAVE_ETC_TIMEZONE)
-static void
-read_env_vars_from_file (filename)
- char *filename;
-{
- FILE *fp;
- char *p, *eq;
- char tbuf[MAXPATHLEN+2];
-
- if ((fp = fopen(filename, "r")) != NULL) {
- while (fgets(tbuf, sizeof(tbuf), fp)) {
- if (tbuf[0] == '#')
- continue;
- eq = strchr(tbuf, '=');
- if (eq == 0)
- continue;
- p = strchr (tbuf, '\n');
- if (p)
- *p = 0;
- *eq++ = 0;
- /* Don't override, in case -p was used. */
- setenv (tbuf, eq, 0);
- }
- fclose(fp);
- }
-}
-#endif
-
-static void
-log_repeated_failures (tty, hostname)
- char *tty, *hostname;
-{
- if (hostname) {
-#ifdef UT_HOSTSIZE
- syslog(LOG_ERR,
- "REPEATED LOGIN FAILURES ON %s FROM %.*s, %.*s",
- tty, UT_HOSTSIZE, hostname, UT_NAMESIZE,
- username);
-#else
- syslog(LOG_ERR,
- "REPEATED LOGIN FAILURES ON %s FROM %s, %.*s",
- tty, hostname, UT_NAMESIZE,
- username);
-#endif
- } else {
- syslog(LOG_ERR,
- "REPEATED LOGIN FAILURES ON %s, %.*s",
- tty, UT_NAMESIZE, username);
- }
-}
-
-int main(argc, argv)
- int argc;
- char **argv;
-{
- extern int optind;
- extern char *optarg, **environ;
- struct group *gr;
- int ch;
- char *p;
- int fflag, hflag, pflag, rflag, cnt;
- int kflag, Kflag, eflag;
- int quietlog, passwd_req, ioctlval;
- char *domain, **envinit, *ttyn, *tty;
- char tbuf[MAXPATHLEN + 2];
- char *ttyname(), *crypt(), *getpass();
- time_t login_time;
- int retval;
- int rewrite_ccache = 1; /*try to write out ccache*/
-#ifdef KRB5_GET_TICKETS
- krb5_principal me;
- krb5_creds save_v5creds;
- krb5_ccache xtra_creds = NULL;
-#endif
- char *ccname = 0; /* name of forwarded cache */
- char *tz = 0;
- char *hostname = 0;
-
- off_t lseek();
- handler sa;
-
- handler_init (sa, timedout);
- handler_set (SIGALRM, sa);
- (void)alarm((u_int)timeout);
-
- handler_init (sa, SIG_IGN);
- handler_set (SIGQUIT, sa);
- handler_set (SIGINT, sa);
- setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET);
-#ifdef OQUOTA
- (void)quota(Q_SETUID, 0, 0, 0);
-#endif
-
- /*
- * -p is used by getty to tell login not to destroy the environment
- * -r is used by rlogind to cause the autologin protocol;
- * -f is used to skip a second login authentication
- * -F is used to skip a second login authentication, allows login as root
- * -e is used to skip a second login authentication, but allows
- * login as root.
- * -h is used by other servers to pass the name of the
- * remote host to login so that it may be placed in utmp and wtmp
- */
- (void)gethostname(tbuf, sizeof(tbuf));
- domain = strchr(tbuf, '.');
-
- fflag = hflag = pflag = rflag = kflag = Kflag = eflag = 0;
- passwd_req = 1;
- while ((ch = getopt(argc, argv, "Ffeh:pr:k:K:")) != -1)
- switch (ch) {
- case 'f':
- EXCL_AUTH_TEST;
- fflag = 1;
- break;
- case 'F':
- EXCL_AUTH_TEST;
- fflag = 1;
- break;
- case 'h':
- EXCL_HOST_TEST;
- if (getuid()) {
- fprintf(stderr,
- "login: -h for super-user only.\n");
- exit(1);
- }
- hflag = 1;
- if (domain && (p = strchr(optarg, '.')) && strcmp(p, domain) == 0)
- *p = 0;
- hostname = optarg;
- break;
- case 'p':
- pflag = 1;
- break;
- case 'r':
- EXCL_AUTH_TEST;
- EXCL_HOST_TEST;
- if (getuid()) {
- fprintf(stderr,
- "login: -r for super-user only.\n");
- exit(1);
- }
- /* "-r hostname" must be last args */
- if (optind != argc) {
- fprintf(stderr, "Syntax error.\n");
- exit(1);
- }
- rflag = 1;
- passwd_req = (doremotelogin(optarg) == -1);
- if (domain && (p = strchr(optarg, '.')) && !strcmp(p, domain))
- *p = '\0';
- hostname = optarg;
- break;
- case 'e':
- EXCL_AUTH_TEST;
- if (getuid()) {
- fprintf(stderr,
- "login: -e for super-user only.\n");
- exit(1);
- }
- eflag = 1;
- passwd_req = 0;
- break;
- case '?':
- default:
- fprintf(stderr, "usage: login [-fp] [username]\n");
- exit(1);
- }
- argc -= optind;
- argv += optind;
- /* Throw away too-long names, they can't be usernames. */
- if (*argv) {
- if (strlen (*argv) <= UT_NAMESIZE)
- username = *argv;
- else
- fprintf (stderr, "login name '%s' too long\n", *argv);
- }
-
-#if !defined(POSIX_TERMIOS) && defined(TIOCLSET)
- ioctlval = 0;
- /* Only do this we we're not using POSIX_TERMIOS */
- (void)ioctl(0, TIOCLSET, (char *)&ioctlval);
-#endif
-
-#ifdef TIOCNXCL
- (void)ioctl(0, TIOCNXCL, (char *)0);
-#endif
-
- ioctlval = fcntl(0, F_GETFL);
-#ifdef O_NONBLOCK
- ioctlval &= ~O_NONBLOCK;
-#endif
-#ifdef O_NDELAY
- ioctlval &= ~O_NDELAY;
-#endif
- (void)fcntl(0, F_SETFL, ioctlval);
-
- /*
- * If talking to an rlogin process, propagate the terminal type and
- * baud rate across the network.
- */
- if (eflag) {
- lgetstr(term, sizeof(term), "Terminal type");
- } else if (!(kflag || Kflag)) {/* Preserve terminal if not read over net */
- if (getenv("TERM")) {
- strncpy(term, getenv("TERM"), sizeof(term));
- term[sizeof(term) - 1] = '\0';
- }
- }
-
- term_init (rflag || kflag || Kflag || eflag);
-
- for (cnt = getdtablesize(); cnt > 2; cnt--)
- (void) close(cnt);
-
- ttyn = ttyname(0);
- if (ttyn == NULL || *ttyn == '\0')
- ttyn = "/dev/tty??";
-
- /* This allows for tty names of the form /dev/pts/4 as well */
- if ((tty = strchr(ttyn, '/')) && (tty = strchr(tty+1, '/')))
- ++tty;
- else
- tty = ttyn;
-
-#ifndef LOG_ODELAY /* 4.2 syslog ... */
- openlog("login", 0);
-#else
- openlog("login", LOG_ODELAY, LOG_AUTH);
-#endif /* 4.2 syslog */
-
-/******* begin askpw *******/
- /* overall:
- ask for username if we don't have it already
- look it up in local pw or shadow file (to get crypt string)
- ask for password
- try and get v5 tickets with it
- try and use the tickets against the local srvtab
- if the password matches, always let them in
- if the ticket decrypts, let them in.
- */
-
- k_init (ttyn);
-
- for (cnt = 0;; username = NULL) {
-#ifdef KRB5_GET_TICKETS
- int kpass_ok, lpass_ok;
- char user_pwstring[MAXPWSIZE];
-#endif /* KRB5_GET_TICKETS */
-
- if (username == NULL) {
- fflag = 0;
- getloginname();
- }
-
- lookup_user(username); /* sets pwd */
-
- /* if user not super-user, check for disabled logins */
- if (pwd == NULL || pwd->pw_uid)
- checknologin();
-
- /*
- * Allows automatic login by root.
- * If not invoked by root, disallow if the uid's differ.
- */
-
- if (fflag && pwd) {
- int uid = (int) getuid();
- passwd_req = (uid && uid != pwd->pw_uid);
- }
-
- /*
- * If no remote login authentication and a password exists
- * for this user, prompt for one and verify it.
- */
- if (!passwd_req)
- break;
-
- if (!unix_needs_passwd())
- break;
-
-#ifdef KRB5_GET_TICKETS
- if (login_krb5_get_tickets) {
- /* rename these to something more verbose */
- kpass_ok = 0;
- lpass_ok = 0;
-
- setpriority(PRIO_PROCESS, 0, -4 + PRIO_OFFSET);
- if (! k5_get_password(user_pwstring, sizeof (user_pwstring))) {
- goto bad_login;
- }
-
- /* now that we have the password, we've obscured things
- sufficiently, and can avoid trying tickets */
- if (!pwd)
- goto bad_login;
-
- lpass_ok = unix_passwd_okay(user_pwstring);
-
- if (pwd->pw_uid != 0) { /* Don't get tickets for root */
- try_krb5(&me, user_pwstring);
-
- krbflag = got_v5_tickets;
- memset (user_pwstring, 0, sizeof(user_pwstring));
- /* password wiped, so we can relax */
- setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET);
- } else {
- memset(user_pwstring, 0, sizeof(user_pwstring));
- setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET);
- }
-
- /* Policy: If local password is good, user is good.
- We really can't trust the Kerberos password,
- because somebody on the net could spoof the
- Kerberos server (not easy, but possible).
- Some sites might want to use it anyways, in
- which case they should change this line
- to:
- if (kpass_ok)
- */
-
- if (lpass_ok)
- break;
-
- if (got_v5_tickets) {
- retval = krb5_verify_init_creds(kcontext, &my_creds, NULL,
- NULL, &xtra_creds,
- NULL);
- if (retval) {
- com_err("login", retval, "while verifying initial ticket");
-#ifndef SYSLOG42
- syslog(LOG_NOTICE|LOG_AUTH,
- "can't verify v5 ticket: %s\n",
- error_message(retval));
-#endif
- } else {
- break; /* we're ok */
- }
- }
-
- bad_login:
- setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET);
-
- if (krbflag)
- destroy_tickets(); /* clean up tickets if login fails */
- }
-#endif /* KRB5_GET_TICKETS */
-
-#ifdef OLD_PASSWD
- p = getpass ("Password:");
- /* conventional password only */
- if (unix_passwd_okay (p))
- break;
-#endif /* OLD_PASSWD */
- printf("Login incorrect\n");
- if (++cnt >= 5) {
- log_repeated_failures (tty, hostname);
- /* irix has no tichpcl */
-#ifdef TIOCHPCL
- (void)ioctl(0, TIOCHPCL, (char *)0);
-#endif
- sleepexit(1);
- }
- } /* end of password retry loop */
-
- /* committed to login -- turn off timeout */
- (void) alarm((u_int) 0);
-
- /*
- * If valid so far and root is logging in, see if root logins on
- * this terminal are permitted.
- *
- * We allow authenticated remote root logins (except -r style)
- */
-
- if (pwd->pw_uid == 0 && !rootterm(tty) && (passwd_req || rflag)) {
- if (hostname) {
-#ifdef UT_HOSTSIZE
- syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s FROM %.*s",
- tty, UT_HOSTSIZE, hostname);
-#else
- syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s FROM %s",
- tty, hostname);
-#endif
- } else {
- syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s", tty);
- }
- printf("Login incorrect\n");
- sleepexit(1);
- }
-
-#ifdef OQUOTA
- if (quota(Q_SETUID, pwd->pw_uid, 0, 0) < 0 && errno != EINVAL) {
- switch(errno) {
- case EUSERS:
- fprintf(stderr,
- "Too many users logged on already.\nTry again later.\n");
- break;
- case EPROCLIM:
- fprintf(stderr,
- "You have too many processes running.\n");
- break;
- default:
- perror("quota (Q_SETUID)");
- }
- sleepexit(0);
- }
-#endif
-
- if (chdir(pwd->pw_dir) < 0) {
- printf("No directory %s!\n", pwd->pw_dir);
- if (chdir("/"))
- exit(0);
- pwd->pw_dir = "/";
- printf("Logging in with home = \"/\".\n");
- }
-
- /* nothing else left to fail -- really log in */
- {
- struct utmp utmp;
-
- login_time = time(&utmp.ut_time);
- if ((retval = pty_update_utmp(PTY_USER_PROCESS, getpid(), username,
- ttyn, hostname,
- PTY_TTYSLOT_USABLE)) < 0)
- com_err (argv[0], retval, "while updating utmp");
- }
-
- quietlog = access(HUSHLOGIN, F_OK) == 0;
- dolastlog(hostname, quietlog, tty);
-
- (void)chown(ttyn, pwd->pw_uid,
- (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);
-
- (void)chmod(ttyn, 0620);
-
-#ifdef KRB5_GET_TICKETS
- /* Maybe telnetd got tickets for us? */
- if (!got_v5_tickets && have_v5_tickets (&me))
- forwarded_v5_tickets = 1;
-#endif /* KRB5_GET_TICKETS */
-
-#ifdef KRB5_GET_TICKETS
- if (login_krb5_get_tickets)
- dofork();
-#endif
-
-/* If the user's shell does not do job control we should put it in a
- different process group than than us, and set the tty process group
- to match, otherwise stray signals may be delivered to login.krb5 or
- telnetd or rlogind if they don't properly detach from their
- controlling tty, which is the case (under SunOS at least.) */
-
- {
- int pid = getpid();
- struct sigaction sa2, osa;
-
- /* this will set the PGID to the PID. */
-#ifdef HAVE_SETPGID
- if (setpgid(pid,pid) < 0)
- perror("login.krb5: setpgid");
-#elif defined(SETPGRP_TWOARG)
- if (setpgrp(pid,pid) < 0)
- perror("login.krb5: setpgrp");
-#else
- if (setpgrp() < 0)
- perror("login.krb5: setpgrp");
-#endif
-
- /* This will cause SIGTTOU to be ignored for the duration
- of the TIOCSPGRP. If this is not done, and the parent's
- process group is the foreground pgrp of the tty, then
- this will suspend the child, which is bad. */
-
- sa2.sa_flags = 0;
- sa2.sa_handler = SIG_IGN;
- sigemptyset(&(sa2.sa_mask));
-
- if (sigaction(SIGTTOU, &sa2, &osa))
- perror("login.krb5: sigaction(SIGTTOU, SIG_IGN)");
-
- /* This will set the foreground process group of the
- controlling terminal to this process group (containing
- only this process). */
-#ifdef HAVE_TCSETPGRP
- if (tcsetpgrp(0, pid) < 0)
- perror("login.krb5: tcsetpgrp");
-#else
- if (ioctl(0, TIOCSPGRP, &pid) < 0)
- perror("login.krb5: tiocspgrp");
-#endif
-
- /* This will reset the SIGTTOU handler */
-
- if (sigaction(SIGTTOU, &osa, NULL))
- perror("login.krb5: sigaction(SIGTTOU, [old handler])");
- }
-
- (void) setgid((gid_t) pwd->pw_gid);
- (void) initgroups(username, pwd->pw_gid);
-
- /*
- * The V5 ccache is created as root. It needs to be owned by the
- * user, and chown (a) assumes they are stored in a file and (b)
- * allows a race condition in which a user can delete the file (if
- * the directory sticky bit is not set) and make it a symlink to
- * somewhere else; on some platforms, chown() on a symlink
- * actually changes the owner of the pointed-to file. This is
- * Bad.
- *
- * So, we suck the V5 krbtgt into memory here, destroy the
- * ccache/ticket file, and recreate them later after the setuid.
- *
- * With the new v5 api, v5 tickets are kept in memory until written
- * out after the setuid. However, forwarded tickets still
- * need to be read in and recreated later
- */
-#ifdef KRB5_GET_TICKETS
- if (forwarded_v5_tickets) {
- krb5_creds mcreds;
-
- memset(&mcreds, 0, sizeof(mcreds));
- memset(&save_v5creds, 0, sizeof(save_v5creds));
-
- mcreds.client = me;
- retval =
- krb5_build_principal_ext(kcontext, &mcreds.server,
- krb5_princ_realm(kcontext, me)->length,
- krb5_princ_realm(kcontext, me)->data,
- tgtname.length, tgtname.data,
- krb5_princ_realm(kcontext, me)->length,
- krb5_princ_realm(kcontext, me)->data,
- 0);
- if (retval) {
- syslog(LOG_ERR,
- "%s while creating V5 krbtgt principal",
- error_message(retval));
- rewrite_ccache = 0;
- } else {
- mcreds.ticket_flags = 0;
-
- retval = krb5_cc_retrieve_cred(kcontext, ccache, 0,
- &mcreds, &save_v5creds);
- if (retval) {
- syslog(LOG_ERR,
- "%s while retrieiving V5 initial ticket for copy",
- error_message(retval));
- rewrite_ccache = 0;
- }
- }
-
- krb5_free_principal(kcontext, mcreds.server);
- }
-#endif /* KRB5_GET_TICKETS */
-
-#ifdef KRB5_GET_TICKETS
- if (forwarded_v5_tickets)
- destroy_tickets();
-#endif
-
-#ifdef OQUOTA
- quota(Q_DOWARN, pwd->pw_uid, (dev_t)-1, 0);
-#endif
-#ifdef HAVE_SETLOGIN
- if (setlogin(pwd->pw_name) < 0)
- syslog(LOG_ERR, "setlogin() failure %d",errno);
-#endif
-
-#ifdef HAVE_SETLUID
- /*
- * If we're on a system which keeps track of login uids, then
- * set the login uid. If this fails this opens up a problem on DEC OSF
- * with C2 enabled.
- */
- if (setluid((uid_t) pwd->pw_uid) < 0) {
- perror("setuid");
- sleepexit(1);
- }
-#endif /* HAVE_SETLUID */
-#ifdef _IBMR2
- if (setuidx(ID_LOGIN, pwd->pw_uid) < 0) {
- perror("setuidx");
- sleepexit(1);
- };
-#endif
-
- /* This call MUST succeed */
- if (setuid((uid_t) pwd->pw_uid) < 0) {
- perror("setuid");
- sleepexit(1);
- }
-
- /*
- * We are the user now. Re-create the destroyed ccache and
- * ticket file.
- */
-
-#ifdef KRB5_GET_TICKETS
- if (got_v5_tickets) {
- /* set up credential cache -- obeying KRB5_ENV_CCNAME
- set earlier */
- /* (KRB5_ENV_CCNAME == "KRB5CCNAME" via osconf.h) */
- if ((retval = krb5_cc_default(kcontext, &ccache))) {
- com_err(argv[0], retval, "while getting default ccache");
- } else if ((retval = krb5_cc_initialize(kcontext, ccache, me))) {
- com_err(argv[0], retval, "when initializing cache");
- } else if ((retval = krb5_cc_store_cred(kcontext, ccache,
- &my_creds))) {
- com_err(argv[0], retval, "while storing credentials");
- } else if (xtra_creds &&
- (retval = krb5_cc_copy_creds(kcontext, xtra_creds,
- ccache))) {
- com_err(argv[0], retval, "while storing credentials");
- }
-
- if (xtra_creds)
- krb5_cc_destroy(kcontext, xtra_creds);
- } else if (forwarded_v5_tickets && rewrite_ccache) {
- if ((retval = krb5_cc_initialize (kcontext, ccache, me))) {
- syslog(LOG_ERR,
- "%s while re-initializing V5 ccache as user",
- error_message(retval));
- } else if ((retval = krb5_cc_store_cred(kcontext, ccache,
- &save_v5creds))) {
- syslog(LOG_ERR,
- "%s while re-storing V5 credentials as user",
- error_message(retval));
-
- }
- krb5_free_cred_contents(kcontext, &save_v5creds);
- }
-#endif /* KRB5_GET_TICKETS */
-
- if (*pwd->pw_shell == '\0')
- pwd->pw_shell = BSHELL;
-
-#if defined(NTTYDISC) && defined(TIOCSETD)
- /* turn on new line discipline for all shells */
- ioctlval = NTTYDISC;
- (void)ioctl(0, TIOCSETD, (char *)&ioctlval);
-#endif
-
- ccname = getenv("KRB5CCNAME"); /* save cache */
- tz = getenv("TZ"); /* and time zone */
-
- /* destroy environment unless user has requested preservation */
- if (!pflag) {
- envinit = (char **) malloc(MAXENVIRON * sizeof(char *));
- if (envinit == 0) {
- fprintf(stderr, "Can't malloc empty environment.\n");
- sleepexit(1);
- }
- envinit[0] = NULL;
- environ = envinit;
- }
-
- setenv ("LOGNAME", pwd->pw_name, 1);
- setenv ("LOGIN", pwd->pw_name, 1);
-
- /* read the /etc/environment file on AIX */
-#ifdef HAVE_ETC_ENVIRONMENT
- read_env_vars_from_file ("/etc/environment");
-#endif
-
- /* Set login timezone for date information (sgi PDG) */
-#ifdef HAVE_ETC_TIMEZONE
- read_env_vars_from_file ("/etc/TIMEZONE");
-#else
- if (tz)
- setenv ("TZ", tz, 1);
-#endif
-
- if (ccname)
- setenv("KRB5CCNAME", ccname, 1);
-
- setenv("HOME", pwd->pw_dir, 1);
- setenv("PATH", LPATH, 0);
- setenv("USER", pwd->pw_name, 1);
- setenv("SHELL", pwd->pw_shell, 1);
-
- if (term[0] == '\0') {
- (void) strncpy(term, stypeof(tty), sizeof(term));
- term[sizeof(term) - 1] = '\0';
- }
- if (term[0])
- (void)setenv("TERM", term, 0);
-
-#ifdef KRB5_GET_TICKETS
- /* ccfile[0] is only set if we got tickets above */
- if (login_krb5_get_tickets && ccfile[0]) {
- (void) setenv(KRB5_ENV_CCNAME, ccfile, 1);
- krb5_cc_set_default_name(kcontext, ccfile);
- }
-#endif /* KRB5_GET_TICKETS */
-
- if (tty[sizeof("tty")-1] == 'd')
- syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
- if (pwd->pw_uid == 0)
- {
- if (hostname) {
-#ifdef UT_HOSTSIZE
- syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %.*s",
- tty, UT_HOSTSIZE, hostname);
-#else
- syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %s",
- tty, hostname);
-#endif
- } else {
- syslog(LOG_NOTICE, "ROOT LOGIN %s", tty);
- }
- }
-
- afs_login();
-
- if (!quietlog) {
- motd();
- check_mail();
- }
-
-#ifndef OQUOTA
- if (! access( QUOTAWARN, X_OK))
- (void) system(QUOTAWARN);
-#endif
-
- handler_init (sa, SIG_DFL);
- handler_set (SIGALRM, sa);
- handler_set (SIGQUIT, sa);
- handler_set (SIGINT, sa);
- handler_init (sa, SIG_IGN);
- handler_set (SIGTSTP, sa);
-
- tbuf[0] = '-';
- p = strrchr(pwd->pw_shell, '/');
- (void) strncpy(tbuf+1, p?(p+1):pwd->pw_shell, sizeof(tbuf) - 1);
- tbuf[sizeof(tbuf) - 1] = '\0';
-
- execlp(pwd->pw_shell, tbuf, (char *)NULL);
- fprintf(stderr, "login: no shell: ");
- perror(pwd->pw_shell);
- exit(0);
-}
-
-char *speeds[] = {
- "0", "50", "75", "110", "134", "150", "200", "300", "600",
- "1200", "1800", "2400", "4800", "9600", "19200", "38400",
-};
-#define NSPEEDS (sizeof(speeds) / sizeof(speeds[0]))
-
-#ifdef POSIX_TERMIOS
-/* this must be in sync with the list above */
-speed_t b_speeds[] = {
- B0, B50, B75, B110, B134, B150, B200, B300, B600,
- B1200, B1800, B2400, B4800, B9600, B19200, B38400,
-};
-#endif
-
-void
-term_init (do_rlogin)
-int do_rlogin;
-{
- int line_speed = -1;
-
- if (do_rlogin) {
- register char *cp = strchr(term, '/'), **cpp;
- char *speed;
-
- if (cp) {
- *cp++ = '\0';
- speed = cp;
- cp = strchr(speed, '/');
- if (cp)
- *cp++ = '\0';
- for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++)
- if (strcmp(*cpp, speed) == 0) {
- line_speed = cpp-speeds;
- break;
- }
- }
- }
-#ifdef POSIX_TERMIOS
- {
- struct termios tc;
-
- (void)tcgetattr(0, &tc);
- if (line_speed != -1) {
- cfsetispeed(&tc, b_speeds[line_speed]);
- cfsetospeed(&tc, b_speeds[line_speed]);
- }
- tc.c_cc[VMIN] = 1;
- tc.c_cc[VTIME] = 0;
-#ifndef NO_INIT_CC
- tc.c_cc[VERASE] = CERASE;
- tc.c_cc[VKILL] = CKILL;
- tc.c_cc[VEOF] = CEOF;
- tc.c_cc[VINTR] = CINTR;
- tc.c_cc[VQUIT] = CQUIT;
- tc.c_cc[VSTART] = CSTART;
- tc.c_cc[VSTOP] = CSTOP;
-#ifndef CNUL
-#define CNUL CEOL
-#endif
- tc.c_cc[VEOL] = CNUL;
- /* The following are common extensions to POSIX */
-#ifdef VEOL2
- tc.c_cc[VEOL2] = CNUL;
-#endif
-#ifdef VSUSP
-#if !defined(CSUSP) && defined(CSWTCH)
-#define CSUSP CSWTCH
-#endif
- tc.c_cc[VSUSP] = CSUSP;
-#endif
-#ifdef VDSUSP
- tc.c_cc[VDSUSP] = CDSUSP;
-#endif
-#ifdef VLNEXT
- tc.c_cc[VLNEXT] = CLNEXT;
-#endif
-#ifdef VREPRINT
- tc.c_cc[VREPRINT] = CRPRNT;
-#endif
-#ifdef VDISCRD
- tc.c_cc[VDISCRD] = CFLUSH;
-#endif
-#ifdef VDISCARD
-#ifndef CDISCARD
-#define CDISCARD CFLUSH
-#endif
- tc.c_cc[VDISCARD] = CDISCARD;
-#endif
-#ifdef VWERSE
- tc.c_cc[VWERSE] = CWERASE;
-#endif
-#ifdef VWERASE
- tc.c_cc[VWERASE] = CWERASE;
-#endif
-#if defined (VSTATUS) && defined (CSTATUS)
- tc.c_cc[VSTATUS] = CSTATUS;
-#endif /* VSTATUS && CSTATUS */
-#endif /* NO_INIT_CC */
- /* set all standard echo, edit, and job control options */
- /* but leave any extensions */
- tc.c_lflag |= ECHO|ECHOE|ECHOK|ICANON|ISIG|IEXTEN;
- tc.c_lflag &= ~(NOFLSH|TOSTOP);
-#ifdef ECHOCTL
- /* Not POSIX, but if we have it, we probably want it */
- tc.c_lflag |= ECHOCTL;
-#endif
-#ifdef ECHOKE
- /* Not POSIX, but if we have it, we probably want it */
- tc.c_lflag |= ECHOKE;
-#endif
- tc.c_iflag |= ICRNL|BRKINT;
- tc.c_oflag |= ONLCR|OPOST|TAB3;
- tcsetattr(0, TCSANOW, &tc);
- }
-
-#else /* not POSIX_TERMIOS */
-
- {
- struct sgttyb sgttyb;
- static struct tchars tc = {
- CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK
- };
- static struct ltchars ltc = {
- CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT
- };
-
- (void) ioctl(0, TIOCGETP, (char *)&sgttyb);
- if (line_speed != -1)
- sgttyb.sg_ispeed = sgttyb.sg_ospeed = line_speed;
- sgttyb.sg_flags = ECHO|CRMOD|ANYP|XTABS;
- sgttyb.sg_erase = CERASE;
- sgttyb.sg_kill = CKILL;
- (void)ioctl(0, TIOCSLTC, (char *)<c);
- (void)ioctl(0, TIOCSETC, (char *)&tc);
- (void)ioctl(0, TIOCSETP, (char *)&sgttyb);
-#if defined(TIOCSETD)
- {
- int ioctlval;
- ioctlval = 0;
- (void)ioctl(0, TIOCSETD, (char *)&ioctlval);
- }
-#endif
- }
-#endif
-}
-
-void getloginname()
-{
- register int ch;
- register char *p;
- static char nbuf[UT_NAMESIZE + 1];
-
- for (;;) {
- printf("login: ");
- for (p = nbuf; (ch = getchar()) != '\n'; ) {
- if (ch == EOF)
- exit(0);
- if (p < nbuf + UT_NAMESIZE)
- *p++ = ch;
- }
- if (p > nbuf) {
- if (nbuf[0] == '-')
- fprintf(stderr,
- "login names may not start with '-'.\n");
- else {
- *p = '\0';
- username = nbuf;
- break;
- }
- }
- }
-}
-
-sigtype
-timedout(signumber)
- int signumber;
-{
- fprintf(stderr, "Login timed out after %d seconds\n", timeout);
- exit(0);
-}
-
-#ifndef HAVE_TTYENT_H
-int root_tty_security = 1;
-#endif
-
-int rootterm(tty)
- char *tty;
-{
-#ifndef HAVE_TTYENT_H
- return(root_tty_security);
-#else
- struct ttyent *t;
-
- return((t = getttynam(tty)) && t->ty_status&TTY_SECURE);
-#endif /* HAVE_TTYENT_H */
-}
-
-#ifndef NO_MOTD
-sigjmp_buf motdinterrupt;
-
-static sigtype
-sigint(signum)
- int signum;
-{
- siglongjmp(motdinterrupt, 1);
-}
-
-void motd()
-{
- register int fd, nchars;
- char tbuf[8192];
- handler sa, osa;
-
- if ((fd = open(MOTDFILE, O_RDONLY, 0)) < 0)
- return;
- handler_init (sa, sigint);
- handler_swap (SIGINT, sa, osa);
- if (sigsetjmp(motdinterrupt, 1) == 0)
- while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
- (void)write(fileno(stdout), tbuf, nchars);
- handler_set (SIGINT, osa);
- (void)close(fd);
-}
-#else
-void motd()
-{
-}
-#endif
-
-#ifndef NO_MAILCHECK
-void check_mail()
-{
- char tbuf[MAXPATHLEN+2];
- struct stat st;
- (void)snprintf(tbuf, sizeof(tbuf), "%s/%s", MAILDIR, pwd->pw_name);
- if (stat(tbuf, &st) == 0 && st.st_size != 0)
- printf("You have %smail.\n",
- (st.st_mtime > st.st_atime) ? "new " : "");
-}
-#else
-void check_mail()
-{
-}
-#endif
-
-void checknologin()
-{
- register int fd, nchars;
- char tbuf[8192];
-
- if ((fd = open(NOLOGIN, O_RDONLY, 0)) >= 0) {
- while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
- (void)write(fileno(stdout), tbuf, (unsigned) nchars);
- sleepexit(0);
- }
-}
-
-void dolastlog(hostname, quiet, tty)
- char *hostname;
- int quiet;
- char *tty;
-{
-#if defined(HAVE_LASTLOG_H) || (defined(BSD) && (BSD >= 199103))
- struct lastlog ll;
- time_t lltime;
- int fd;
-
- if ((fd = open(LASTLOG, O_RDWR, 0)) >= 0) {
- (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET);
- if (!quiet) {
- if ((read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll)) &&
- (ll.ll_time != 0)) {
-
- /* .ll_time may not be a time_t. */
- lltime = ll.ll_time;
- printf("Last login: %.*s ", 24-5, (char *)ctime(&lltime));
-
- if (*ll.ll_host != '\0')
- printf("from %.*s\n", (int) sizeof(ll.ll_host),
- ll.ll_host);
- else
- printf("on %.*s\n", (int) sizeof(ll.ll_line), ll.ll_line);
- }
- (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET);
- }
- (void) time(&lltime);
- ll.ll_time = lltime;
-
- (void) strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
- ll.ll_line[sizeof(ll.ll_line) - 1] = '\0';
-
- if (hostname) {
- (void) strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
- ll.ll_host[sizeof(ll.ll_host) - 1] = '\0';
- } else {
- (void) memset(ll.ll_host, 0, sizeof(ll.ll_host));
- }
-
- (void)write(fd, (char *)&ll, sizeof(ll));
- (void)close(fd);
- }
-#endif
-}
-
-#undef UNKNOWN
-#ifdef __hpux
-#define UNKNOWN 0
-#else
-#define UNKNOWN "su"
-#endif
-
-char *
-stypeof(ttyid)
- char *ttyid;
-{
- char *cp = getenv("term");
-
-#ifndef HAVE_TTYENT_H
- if (cp)
- return cp;
- else
- return(UNKNOWN);
-#else
- struct ttyent *t;
- if (cp)
- return cp;
- else
- return(ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN);
-#endif
-}
-
-int doremotelogin(host)
- char *host;
-{
- static char lusername[UT_NAMESIZE+1];
- char rusername[UT_NAMESIZE+1];
-
- lgetstr(rusername, sizeof(rusername), "Remote user");
- lgetstr(lusername, sizeof(lusername), "Local user");
- lgetstr(term, sizeof(term), "Terminal type");
- username = lusername;
- pwd = getpwnam(username);
- if (pwd == NULL)
- return(-1);
- return(ruserok(host, (pwd->pw_uid == 0), rusername, username));
-}
-
-void lgetstr(buf, cnt, err)
- char *buf, *err;
- int cnt;
-{
- int ocnt = cnt;
- char *obuf = buf;
- char ch;
-
- do {
- if (read(0, &ch, sizeof(ch)) != sizeof(ch))
- exit(1);
- if (--cnt < 0) {
- fprintf(stderr,"%s '%.*s' too long, %d characters maximum.\r\n",
- err, ocnt, obuf, ocnt-1);
- sleepexit(1);
- }
- *buf++ = ch;
- } while (ch);
-}
-
-void sleepexit(eval)
- int eval;
-{
- sleep((u_int)5);
- exit(eval);
-}
-
-#ifdef KRB5_GET_TICKETS
-static int hungup = 0;
-
-static sigtype
-sighup() {
- hungup = 1;
-}
-
-/* call already conditionalized on login_krb5_get_tickets */
-/*
- * This routine handles cleanup stuff, and the like.
- * It exits only in the child process.
- */
-#include <sys/wait.h>
-void
-dofork()
-{
- int child,pid;
- handler sa;
- int syncpipe[2];
- char c;
- int n;
-
-#ifdef _IBMR2
- update_ref_count(1);
-#endif
- if (pipe(syncpipe) < 0) {
- perror("login: dofork: setting up syncpipe");
- exit(1);
- }
- if (!(child=fork())) {
- close(syncpipe[1]);
- while ((n = read(syncpipe[0], &c, 1)) < 0) {
- if (errno != EINTR) {
- perror("login: dofork: waiting for sync from parent");
- exit(1);
- }
- }
- if (n == 0) {
- fprintf(stderr, "login: dofork: unexpected EOF waiting for sync\n");
- exit(1);
- }
- close(syncpipe[0]);
- return; /* Child process returns */
- }
-
- /* The parent continues here */
-
- /* On receipt of SIGHUP, pass that along to child's process group. */
- handler_init (sa, sighup);
- handler_set (SIGHUP, sa);
- /* Tell child we're ready. */
- close(syncpipe[0]);
- write(syncpipe[1], "", 1);
- close(syncpipe[1]);
-
- /* Setup stuff? This would be things we could do in parallel with login */
- (void) chdir("/"); /* Let's not keep the fs busy... */
-
- /* If we're the parent, watch the child until it dies */
-
- while (1) {
-#ifdef HAVE_WAITPID
- pid = waitpid(child, 0, 0);
-#elif defined(WAIT_USES_INT)
- pid = wait((int *)0);
-#else
- pid = wait((union wait *)0);
-#endif
-
- if (hungup) {
-#ifdef HAVE_KILLPG
- killpg(child, SIGHUP);
-#else
- kill(-child, SIGHUP);
-#endif
- }
-
- if (pid == child)
- break;
- }
-
- /* Cleanup stuff */
- /* Run destroy_tickets to destroy tickets */
- (void) destroy_tickets(); /* If this fails, we lose quietly */
- afs_cleanup ();
-#ifdef _IBMR2
- update_ref_count(-1);
-#endif
-
- /* Leave */
- exit(0);
-}
-#endif /* KRB5_GET_TICKETS */
-
-
-#ifndef HAVE_STRSAVE
-/* Strsave was a routine in the version 4 krb library: we put it here
- for compatablilty with version 5 krb library, since kcmd.o is linked
- into all programs. */
-
-char *strsave(sp)
- char *sp;
-{
- register char *ret;
-
- if ((ret = strdup(sp)) == NULL) {
- fprintf(stderr, "no memory for saving args\n");
- exit(1);
- }
- return(ret);
-}
-#endif
-
-#ifdef _IBMR2
-update_ref_count(int adj)
-{
- struct passwd *save_pwd;
- static char *empty = "\0";
- char *grp;
- int i;
-
- /* save pwd before calling getuserattr() */
- save_pwd = (struct passwd *)malloc(sizeof(struct passwd));
- save_pwd->pw_name = strdup(pwd->pw_name);
- save_pwd->pw_passwd = strdup(pwd->pw_passwd);
- save_pwd->pw_uid = pwd->pw_uid;
- save_pwd->pw_gid = pwd->pw_gid;
- save_pwd->pw_gecos = strdup(pwd->pw_gecos);
- save_pwd->pw_dir = strdup(pwd->pw_dir);
- save_pwd->pw_shell = strdup(pwd->pw_shell);
- pwd = save_pwd;
-
- /* Update reference count on all user's temporary groups */
- setuserdb(S_READ|S_WRITE);
- if (getuserattr(username, S_GROUPS, (void *)&grp, SEC_LIST) == 0) {
- while (*grp) {
- if (getgroupattr(grp, "athena_temp", (void *)&i, SEC_INT) == 0) {
- i += adj;
- if (i > 0) {
- putgroupattr(grp, "athena_temp", (void *)i, SEC_INT);
- putgroupattr(grp, (char *)0, (void *)0, SEC_COMMIT);
- } else {
- putgroupattr(grp, S_USERS, (void *)empty, SEC_LIST);
-#ifdef HAVE_RMUFILE /* pre-4.3.0 AIX */
- putgroupattr(grp, (char *)0, (void *)0, SEC_COMMIT);
- rmufile(grp, 0, GROUP_TABLE);
-#else
- putgroupattr(grp, (char *)0, (void *)0, SEC_DELETE);
- putgroupattr(grp, (char *)0, (void *)0, SEC_COMMIT);
-#endif
- }
- }
- while (*grp) grp++;
- grp++;
- }
- }
- enduserdb();
-}
-#endif
+++ /dev/null
-/* here are actual path values from each operating system supported. */
-/* LPATH is from rlogin, for login.c; RPATH is from rsh, for rshd.c */
-#ifdef sun
-#ifdef __SVR4
-#define RPATH "/usr/bin"
-#define LPATH "/usr/bin"
-#else
-/* sun3 and sun4 */
-#define LPATH "/usr/ucb:/bin:/usr/bin"
-#define RPATH "/usr/ucb:/bin:/usr/bin"
-#endif
-#endif
-
-#ifdef __ultrix
-#define LPATH "/usr/ucb:/bin:/usr/bin"
-#define RPATH "/usr/ucb:/bin:/usr/bin"
-#endif
-
-#ifdef hpux
-/* hpux 8, both hppa and s300 */
-#define LPATH "/bin:/usr/bin:/usr/contrib/bin:/usr/local/bin"
-#define RPATH "/bin:/usr/bin:/usr/contrib/bin:/usr/local/bin"
-#else
-#ifdef __hpux /* 9.04 */
-#define LPATH_root ":/bin:/usr/bin:/etc"
-#define LPATH "/bin:/usr/bin"
-#define RPATH "/bin:/usr/bin:/usr/contrib/bin:/usr/local/bin"
-#endif
-#endif
-
-#ifdef NeXT
-#define LPATH "/usr/ucb:/bin:/usr/bin:/usr/local/bin"
-#define RPATH "/bin:/usr/ucb:/usr/bin"
-#endif
-
-#ifdef _IBMR2
-/* 3.2.0 */
-#define LPATH "/usr/bin:/usr/ucb:/usr/bin/X11"
-#define RPATH "/usr/bin:/usr/ucb:/usr/bin/X11"
-#endif
-
-#ifdef __SCO__
-#define LPATH "/bin:/usr/bin:/usr/dbin:/usr/ldbin"
-#define RPATH "/bin:/usr/bin:/usr/local/bin"
-#endif
-
-#ifdef sgi
-#define LPATH "/usr/sbin:/usr/bsd:/usr/bin:/bin:/usr/bin/X11"
-#define RPATH "/usr/sbin:/usr/bsd:/usr/bin:/bin:/usr/bin/X11"
-#endif
-
-#ifdef linux
-#define LPATH "/local/bin:/usr/bin:/bin:/usr/local/bin:/usr/bin/X11:."
-#define RPATH "/local/bin:/usr/bin:/bin:/usr/local/bin:/usr/bin/X11:."
-#endif
-
-#ifdef __386BSD__
-#define LPATH "/usr/bin:/bin"
-#define RPATH "/usr/bin:/bin"
-#endif
-
-#ifdef __alpha
-#ifdef __osf__
-#define LPATH "/usr/bin:."
-#define RPATH "/usr/bin:/bin"
-#endif
-#endif
-
-#ifdef __pyrsoft
-#ifdef MIPSEB
-#define RPATH "/bin:/usr/bin"
-#define LPATH "/usr/bin:/usr/ccs/bin:/usr/ucb:."
-#endif
-#endif
-
-#ifdef __DGUX
-#ifdef __m88k__
-#define RPATH "/usr/bin"
-#define LPATH "/usr/bin"
-#endif
-#endif
-
-#ifndef LPATH
-#ifdef __svr4__
-/* taken from unixware, sirius... */
-#define RPATH "/bin:/usr/bin:/usr/X/bin"
-#define LPATH "/usr/bin:/usr/dbin:/usr/dbin"
-#endif
-#endif
-
-#ifndef LPATH
-#ifdef __NetBSD__
-#define LPATH "/usr/bin:/bin"
-#define RPATH "/usr/bin:/bin"
-#endif
-#endif
-
-#ifdef _PATH_DEFPATH
-#undef LPATH
-#define LPATH _PATH_DEFPATH
-#undef RPATH
-#define RPATH _PATH_DEFPATH
-#endif
-
-/* catch-all entries for operating systems we haven't looked up
- hardcoded paths for */
-#ifndef LPATH
-#define LPATH "/usr/bin:/bin"
-#endif
-
-#ifndef RPATH
-#define RPATH "/usr/bin:/bin"
-#endif
+++ /dev/null
-.\" appl/bsd/rcp.M
-.\"
-.\" Copyright (c) 1983 The Regents of the University of California.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms are permitted
-.\" provided that the above copyright notice and this paragraph are
-.\" duplicated in all such forms and that any documentation,
-.\" advertising materials, and other materials related to such
-.\" distribution and use acknowledge that the software was developed
-.\" by the University of California, Berkeley. The name of the
-.\" University may not 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-.\"
-.\" @(#)rcp.1 6.6 (Berkeley) 9/20/88
-.\"
-.TH RCP 1
-.SH NAME
-rcp \- remote file copy
-.SH SYNOPSIS
-.B rcp
-[\fB\-p\fP] [\fB\-x\fP] [\fB\-k\fP \fIrealm\fP ] [\fB-c\fP \fIccachefile\fP] [\fB-C\fP \fIconfigfile\fP] [\fB\-D\fP \fIport\fP]
-[\fB\-N\fP]
-[\fB\-PN | \-PO\fP]
-.I file1 file2
-.sp
-.B rcp
-[\fB\-p\fB] [\fB\-x\fP] [\fP\-k\fP \fIrealm\fP] [\fB\-r\fP] [\fB\-D\fP
-\fIport\fP] [\fB\-N\fP]
-[\fB\-PN | \-PO\fP]
-.I file ... directory
-.sp
-.B rcp
-[\fB\-f | \-t\fP]
-.I ...
-.SH DESCRIPTION
-.B Rcp
-copies files between machines. Each
-.I file
-or
-.I directory
-argument is either a remote file name of the form ``rhost:path'', or a
-local file name (containing no `:' characters, or a `/' before any
-`:'s).
-.PP
-By default, the mode and owner of
-.I file2
-are preserved if it already existed; otherwise the mode of the source
-file modified by the
-.IR umask (2)
-on the destination host is used.
-.PP
-If
-.I path
-is not a full path name, it is interpreted relative to your login
-directory on
-.IR rhost .
-A
-.I path
-on a remote host may be quoted (using \e, ", or \(aa) so that the
-metacharacters are interpreted remotely.
-.PP
-.B Rcp
-does not prompt for passwords; it uses Kerberos authentication when
-connecting to
-.IR rhost .
-Each user may have a private authorization list in a file \&.k5login in
-his login directory. Each line in this file should contain a Kerberos
-principal name of the form
-.IR principal/instance@realm .
-If there is a ~/.k5login file, then access is granted to the account if
-and only if the originater user is authenticated to one of the
-principals named in the ~/.k5login file. Otherwise, the originating
-user will be granted access to the account if and only if the
-authenticated principal name of the user can be mapped to the local
-account name using the aname -> lname mapping rules (see
-.IR krb5_anadd (8)
-for more details).
-.SH OPTIONS
-.TP
-.B \-p
-attempt to preserve (duplicate) the modification times and modes of the
-source files in the copies, ignoring the
-.IR umask .
-.TP
-\fB\-x\fP
-encrypt all information transferring between hosts.
-.TP
-\fB\-k\fP \fIrealm\fP
-obtain tickets for the remote host in
-.I realm
-instead of the remote host's realm as determined by
-.IR krb_realmofhost (3).
-.TP
-\fB\-c\fP \fIccachefile\fP
-change the default credentials cache file to
-.I ccachefile
-.TP
-\fB\-C\fP \fIconfigfile\fP
-change the default configuation file to
-.I configfile
-.TP
-.B \-r
-if any of the source files are directories, copy each subtree rooted at
-that name; in this case the destination must be a directory.
-.TP
-\fB-PN\fP
-.TP
-\fB-PO\fP
-Explicitly request new or old version of the Kerberos ``rcmd''
-protocol. The new protocol avoids many security problems found in the
-old one, but is not interoperable with older servers. (An
-"input/output error" and a closed connection is the most likely result
-of attempting this combination.) If neither option is specified, some
-simple heuristics are used to guess which to try.
-.TP
-\fB\-D\fP \fIport\fP
-connect to port
-.I port
-on the remote machine.
-.TP
-.B \-N
-use a network connection, even when copying files on the local machine
-(used for testing purposes).
-.TP
-.B \-f \-t
-These options are for internal use only. They tell the
-remotely-running rcp process (started via the Kerberos remote shell
-daemon) which direction files are being sent. These options should
-not be used by the user. In particular, \fB-f\fP does \fBnot\fP mean
-that the user's Kerberos ticket should be forwarded!
-.PP
-.B Rcp
-handles third party copies, where neither source nor target files are on
-the current machine. Hostnames may also take the form ``rname@rhost''
-to use
-.I rname
-rather than the current user name on the remote host.
-.SH FILES
-.TP "\w'~/.k5login\ \ 'u"
-~/.k5login
-(on remote host) - file containing Kerberos principals that are allowed
-access.
-.SH SEE ALSO
-cp(1), ftp(1), rsh(1), rlogin(1), kerberos(3), krb_getrealm(3), kshd(8), rcp(1)
-[UCB version]
-.SH BUGS
-.B Rcp
-doesn't detect all cases where the target of a copy might be a file in
-cases where only a directory should be legal.
-.PP
-.B Rcp
-is confused by any output generated by commands in a \&.login,
-\&.profile, or \&.cshrc file on the remote host.
-.PP
-Kerberos is only used for the first connection of a third-party copy;
-the second connection uses the standard Berkeley rcp protocol.
+++ /dev/null
-.\" appl/bsd/rlogin.M
-.\"
-.\" Copyright (c) 1983 The Regents of the University of California.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms are permitted
-.\" provided that the above copyright notice and this paragraph are
-.\" duplicated in all such forms and that any documentation,
-.\" advertising materials, and other materials related to such
-.\" distribution and use acknowledge that the software was developed
-.\" by the University of California, Berkeley. The name of the
-.\" University may not 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-.\"
-.\" @(#)rlogin.1 6.9 (Berkeley) 9/19/88
-.\" "
-.TH RLOGIN 1
-.SH NAME
-rlogin \- remote login
-.SH SYNOPSIS
-.B rlogin
-.I rhost
-[\fB\-e\fP\fI\|c\fP] [\fB\-8\fP] [\fB\-c\fP] [ \fB\-a\fP] [\fB\-f\fP]
-[\fB\-F\fP] [\fB\-t\fP \fItermtype\fP] [\fB\-n\fP] [\fB\-7\fP]
-[\fB\-PN | \-PO\fP]
-[\fB\-d\fP] [\fB\-k\fP \fIrealm\fP] [\fB\-x\fP] [\fB\-L\fP] [\fB\-l\fP
-\fIusername\fP]
-.PP
-.SH DESCRIPTION
-.I Rlogin
-connects your terminal on the current local host system
-.I lhost
-to the remote host system
-.I rhost.
-.PP
-The version built to use Kerberos authentication is very similar to the
-standard Berkeley rlogin(1), except that instead of the \fIrhosts\fP
-mechanism, it uses Kerberos authentication to determine the
-authorization to use a remote account.
-.PP
-Each user may have a private authorization list in a file \&.k5login in
-his login directory. Each line in this file should contain a Kerberos
-principal name of the form
-.IR principal/instance@realm .
-If the originating user is authenticated to one of the principals named
-in \&.k5login, access is granted to the account. If there is no
-/.k5login file, the principal will be granted access to the account
-according to the aname\->lname mapping rules. (See
-.IR krb5_anadd(8)
-for more details.) Otherwise a login and password will be prompted for
-on the remote machine as in
-.IR login (1).
-To avoid some security problems, the \&.k5login file must be owned by
-the remote user.
-.PP
-If there is some problem in marshaling the Kerberos authentication
-information, an error message is printed and the standard UCB rlogin is
-executed in place of the Kerberos rlogin.
-.PP
-A line of the form ``~.'' disconnects from the remote host, where ``~''
-is the escape character. Similarly, the line ``~^Z'' (where ^Z,
-control-Z, is the suspend character) will suspend the rlogin session.
-Substitution of the delayed-suspend character (normally ^Y) for the
-suspend character suspends the send portion of the rlogin, but allows
-output from the remote system.
-.PP
-The remote terminal type is the same as your local terminal type (as
-given in your environment TERM variable), unless the
-.B \-t
-option is specified (see below). The terminal or window size is also
-copied to the remote system if the server supports the option, and
-changes in size are reflected as well.
-.PP
-All echoing takes place at the remote site, so that (except for delays)
-the rlogin is transparent. Flow control via ^S and ^Q and flushing of
-input and output on interrupts are handled properly.
-.SH OPTIONS
-.TP
-.B \-8
-allows an eight-bit input data path at all times; otherwise parity bits
-are stripped except when the remote side's stop and start characters are
-other than ^S/^Q. Eight-bit mode is the default.
-.TP
-.B \-L
-allows the rlogin session to be run in litout mode.
-.TP
-\fB\-e\fP\fIc\fP
-sets the escape character to
-.IR c .
-There is no space separating this option flag and the new escape
-character.
-.TP
-.B \-c
-require confirmation before disconnecting via ``~.''
-.TP
-.B \-a
-force the remote machine to ask for a password by sending a null local
-username. This option has no effect unless the standard UCB rlogin is
-executed in place of the Kerberos rlogin (see above).
-.TP
-\fB\-f\fP
-forward a copy of the local credentials to the remote system.
-.TP
-\fB\-F\fP
-forward a
-.I forwardable
-copy of the local credentials to the remote system.
-.TP
-\fB\-t\fP \fItermtype\fP
-replace the terminal type passed to the remote host with
-.IR termtype .
-.TP
-.B \-n
-prevent suspension of rlogin via ``~^Z'' or ``~^Y''.
-.TP
-.B \-7
-force seven-bit transmissions.
-.TP
-.B \-d
-turn on socket debugging (via
-.IR setsockopt (2))
-on the TCP sockets used for communication with the remote host.
-.TP
-.B \-k
-request rlogin to obtain tickets for the remote host in realm
-.I realm
-instead of the remote host's realm as determined by
-.IR krb_realmofhost (3).
-.TP
-\fB\-x\fP
-turn on DES encryption for data passed via the rlogin session. This
-applies only to input and output streams, so the username is sent
-unencrypted. This significantly reduces response time and
-significantly increases CPU utilization.
-.TP
-\fB-PN\fP
-.TP
-\fB-PO\fP
-Explicitly request new or old version of the Kerberos ``rcmd''
-protocol. The new protocol avoids many security problems found in the
-old one, but is not interoperable with older servers. (An
-"input/output error" and a closed connection is the most likely result
-of attempting this combination.) If neither option is specified, some
-simple heuristics are used to guess which to try.
-.SH SEE ALSO
-rsh(1), kerberos(1), krb_sendauth(3), krb_realmofhost(3), rlogin(1) [UCB
-version], klogind(8)
-.SH FILES
-.TP "\w'~/\&.k5login\ \ 'u"
-~/\&.k5login
-(on remote host) - file containing Kerberos principals that are allowed
-access.
-.SH BUGS
-More of the environment should be propagated.
+++ /dev/null
-/* fallback pathnames */
-
-#ifdef RPROGS_IN_USR_UCB
-#define UCB_RLOGIN "/usr/ucb/rlogin"
-#define UCB_RCP "/usr/ucb/rcp"
-#define UCB_RSH "/usr/ucb/rsh"
-/* all in /usr/ucb/, don't look for /bin/rcp */
-#endif
-
-#ifdef RPROGS_IN_USR_BIN
-#define UCB_RLOGIN "/usr/bin/rlogin"
-#define UCB_RCP "/usr/bin/rcp"
-#define UCB_RSH "/usr/bin/rsh"
-#endif
-
-#ifdef RPROGS_IN_USR_BSD
-#define UCB_RLOGIN "/usr/bsd/rlogin"
-#define UCB_RCP "/usr/bsd/rcp"
-#define UCB_RSH "/usr/bsd/rsh"
-#endif
-
-#ifdef RSH_IS_RCMD
-#undef UCB_RSH
-#define UCB_RSH "/usr/bin/rcmd"
-#endif
-
-#ifdef RSH_IS_REMSH
-#undef UCB_RSH
-#define UCB_RSH "/usr/bin/remsh"
-#endif
+++ /dev/null
-.\" appl/bsd/rsh.M
-.\"
-.\" Copyright (c) 1983 The Regents of the University of California.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms are permitted
-.\" provided that the above copyright notice and this paragraph are
-.\" duplicated in all such forms and that any documentation,
-.\" advertising materials, and other materials related to such
-.\" distribution and use acknowledge that the software was developed
-.\" by the University of California, Berkeley. The name of the
-.\" University may not 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-.\"
-.\" @(#)rsh.1 6.2 (Berkeley) 9/20/88
-.\" "
-.TH RSH 1
-.SH NAME
-rsh \- remote shell
-.SH SYNOPSIS
-.B rsh
-.I host
-[\fB\-l\fP \fIusername\fP] [\fB\-n\fP] [\fB\-d\fP] [\fB\-k\fP
-\fIrealm\fP] [\fB\-f\fP | \fB\-F\fP] [\fB\-x\fP]
-[\fB\-PN | \-PO\fP]
-.I command
-.SH DESCRIPTION
-.B Rsh
-connects to the specified
-.I host,
-and executes the specified \fIcommand\fR.
-.B Rsh
-copies its standard input to the remote command, the standard output of
-the remote command to its standard output, and the standard error of the
-remote command to its standard error. This implementation of
-.B rsh
-will accept any port for the standard error stream. Interrupt, quit and
-terminate signals are propagated to the remote command; \fIrsh\fP
-normally terminates when the remote command does.
-.PP
-Each user may have a private authorization list in a file \&.k5login in
-his login directory. Each line in this file should contain a Kerberos
-principal name of the form
-.IR principal/instance@realm .
-If there is a ~/.k5login file, then access is granted to the account if
-and only if the originater user is authenticated to one of the
-princiapls named in the ~/.k5login file. Otherwise, the originating
-user will be granted access to the account if and only if the
-authenticated principal name of the user can be mapped to the local
-account name using the aname -> lname mapping rules (see
-.IR krb5_anadd (8)
-for more details).
-.SH OPTIONS
-.TP
-\fB\-l\fP \fIusername\fP
-sets the remote username to
-.IR username .
-Otherwise, the remote username will be the same as the local username.
-.TP
-\fB\-x\fP
-causes the network session traffic to be encrypted. This applies only
-to the input and output streams, and not the command line.
-.TP
-\fB\-f\fP
-cause nonforwardable Kerberos credentials to be forwarded to the remote
-machine for use by the specified
-.IR command .
-They will be removed when
-.I command
-finishes. This option is mutually exclusive with the
-.B \-F
-option.
-.TP
-\fB\-F\fP
-cause
-.I forwardable
-Kerberos credentials to be forwarded to the remote machine for use by
-the specified
-.IR command .
-They will be removed when
-.I command
-finishes. This option is mutually exclusive with the
-.B \-f
-option.
-.TP
-\fB\-k\fP \fIrealm\fP
-causes
-.I rsh
-to obtain tickets for the remote host in
-.I realm
-instead of the remote host's realm as determined by
-.IR krb_realmofhost (3).
-.TP
-.B \-d
-turns on socket debugging (via
-.IR setsockopt (2))
-on the TCP sockets used for communication with the remote host.
-.TP
-.B \-n
-redirects input from the special device
-.I /dev/null
-(see the BUGS section below).
-.TP
-\fB-PN\fP
-.TP
-\fB-PO\fP
-Explicitly request new or old version of the Kerberos ``rcmd''
-protocol. The new protocol avoids many security problems found in the
-old one, but is not interoperable with older servers. (An
-"input/output error" and a closed connection is the most likely result
-of attempting this combination.) If neither option is specified, some
-simple heuristics are used to guess which to try.
-.PP
-If you omit
-.IR command ,
-then instead of executing a single command, you will be logged in on the
-remote host using
-.IR rlogin (1).
-.PP
-Shell metacharacters which are not quoted are interpreted on the local
-machine, while quoted metacharacters are interpreted on the remote
-machine. Thus the command
-.PP
-\ \ \ rsh otherhost cat remotefile >> localfile
-.PP
-appends the remote file
-.I remotefile
-to the local file
-.IR localfile ,
-while
-.PP
-\ \ \ rsh otherhost cat remotefile ">>" otherremotefile
-.PP
-appends
-.I remotefile
-to
-.IR otherremotefile .
-.SH FILES
-.TP "\w'~/.k5login\ \ 'u"
-/etc/hosts
-.sp -1v
-.TP
-~/\&.k5login
-(on remote host) - file containing Kerberos principals that are allowed
-access.
-.SH SEE ALSO
-rlogin(1), kerberos(3), krb_sendauth(3), krb_realmofhost(3), kshd(8)
-.SH BUGS
-If you are using
-.IR csh (1)
-and put a
-.IR rsh (1)
-in the background without redirecting its input away from the terminal,
-it will block even if no reads are posted by the remote command. If no
-input is desired you should redirect the input of
-.I rsh
-to /dev/null using the
-.B \-n
-option.
-.PP
-You cannot run an interactive command (like
-.IR rogue (6)
-or
-.IR vi (1));
-use
-.IR rlogin (1).
-.PP
-Stop signals stop the local \fIrsh\fP process only; this is arguably
-wrong, but currently hard to fix for reasons too complicated to explain
-here.
+++ /dev/null
-/*
- * Copyright (c) 1987 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/* based on @(#)setenv.c 5.2 (Berkeley) 6/27/88 */
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef NEED_SETENV
-extern int setenv(char *, char *, int);
-extern void unsetenv(char *);
-#endif
-
-static char *_findenv(char *, int*);
-/*
- * setenv --
- * Set the value of the environmental variable "name" to be
- * "value". If rewrite is set, replace any current value.
- */
-int
-setenv(name, value, rewrite)
- register char *name, *value;
- int rewrite;
-{
- extern char **environ;
- static int alloced; /* if allocated space before */
- register char *C;
- int l_value, offset;
-
- if (*value == '=') /* no `=' in value */
- ++value;
- l_value = strlen(value);
- if ((C = _findenv(name, &offset))) { /* find if already exists */
- if (!rewrite)
- return(0);
- if (strlen(C) >= l_value) { /* old larger; copy over */
- while ((*C++ = *value++));
- return(0);
- }
- }
- else { /* create new slot */
- register int cnt;
- register char **P;
-
- for (P = environ, cnt = 0; *P; ++P, ++cnt);
- if (alloced) { /* just increase size */
- environ = (char **)realloc((char *)environ,
- (u_int)(sizeof(char *) * (cnt + 2)));
- if (!environ)
- return(-1);
- }
- else { /* get new space */
- alloced = 1; /* copy old entries into it */
- P = (char **)malloc((u_int)(sizeof(char *) *
- (cnt + 2)));
- if (!P)
- return(-1);
- memcpy(P, environ, cnt * sizeof(char *));
- environ = P;
- }
- environ[cnt + 1] = NULL;
- offset = cnt;
- }
- for (C = name; *C && *C != '='; ++C); /* no `=' in name */
- if (!(environ[offset] = /* name + `=' + value */
- malloc((u_int)((int)(C - name) + l_value + 2))))
- return(-1);
- for (C = environ[offset]; (*C = *name++) &&( *C != '='); ++C);
- for (*C++ = '='; (*C++ = *value++););
- return(0);
-}
-
-/*
- * unsetenv(name) --
- * Delete environmental variable "name".
- */
-void
-unsetenv(name)
- char *name;
-{
- extern char **environ;
- register char **P;
- int offset;
-
- while (_findenv(name, &offset)) /* if set multiple times */
- for (P = &environ[offset];; ++P)
- if (!(*P = *(P + 1)))
- break;
-}
-/*
- * Copyright (c) 1987 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/* based on @(#)getenv.c 5.5 (Berkeley) 6/27/88 */
-
-#ifndef HAVE_GETENV
-/*
- * getenv --
- * Returns ptr to value associated with name, if any, else NULL.
- */
-char *
-getenv(name)
- char *name;
-{
- int offset;
-
- return(_findenv(name, &offset));
-}
-#endif
-
-/*
- * _findenv --
- * Returns pointer to value associated with name, if any, else NULL.
- * Sets offset to be the offset of the name/value combination in the
- * environmental array, for use by setenv(3) and unsetenv(3).
- * Explicitly removes '=' in argument name.
- *
- * This routine *should* be a static; don't use it.
- */
-static char *
-_findenv(name, offset)
- register char *name;
- int *offset;
-{
- extern char **environ;
- register unsigned int len;
- register char **P, *C;
-
- for (C = name, len = 0; *C && *C != '='; ++C, ++len);
- for (P = environ; *P; ++P)
- if (!strncmp(*P, name, len))
- if (*(C = *P + len) == '=') {
- *offset = P - environ;
- return(++C);
- }
- return(NULL);
-}
+++ /dev/null
-thisconfigdir=.
-myfulldir=appl/gssftp
-mydir=.
-BUILDTOP=$(REL)..$(S)..
-SUBDIRS=ftp ftpd
-LDFLAGS = -g
+++ /dev/null
-Notes on "Secure FTP" Implementation
-===============================================
-Mark Eichin <eichin@cygnus.com>, Cygnus Support
-last modified: 1995 Jan 14
-===============================================
-
-This implementation is supplied by Cygnus Support for inclusion in the MIT
-Kerberos V5 Release.
-
-Copyrights:
-The original BSD ftp implementation is:
- * Copyright (c) 1980, 1983, 1985, 1988, 1989, 1990, 1991 Regents of the
- University of California.
-
-History and Credits (as of 1995 Jan 14)
-================================================
-
-Steve Lunt at Bellcore developed the original V4 kerberized ftp. He
-also started writing the IETF ftpsec draft at the time. This was
-available to the public, and Cygnus eventually incorporated it into
-CNS V4.
-
-Steve Lunt left Bellcore, and dropped out of the computer security
-field altogether, after handing the draft off to Marc Horowitz at
-OpenVision, who was working on a commercial GSSAPI implementation.
-
-Marc Horowitz left OpenVision and is back at MIT currently; in the
-mean time, Cygnus took the V4 ftp and upgraded it to use GSSAPI and
-draft-08, as well as integrating it into the Kerberos V5 autoconf
-based configuration scheme.
-
-Bill Schoofs <wjs@cray.com> supplied corrections to the implementation
-to more correctly match draft 8, as well as correcting some of the
-remaining KERBEROS_V4 code.
-
-Karri Balk - Contractor <kbalk@cup.hp.com> supplied additional
-corrections based on interoperation testing with non-free
-implementations.
-
-Marc Horowitz has indicated that a draft 9 is forthcoming, with some
-clarifications based on experience with this implementation.
-
-No other free implementation of draft-8 is known at this time.
-
-
+++ /dev/null
-/*
- * Copyright (c) 1983, 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.
- *
- * @(#)ftp.h 5.6 (Berkeley) 4/3/91
- */
-
-#ifndef _FTP_H_
-#define _FTP_H_
-
-/* Definitions for FTP; see RFC-765. */
-
-/*
- * Reply codes.
- */
-#define PRELIM 1 /* positive preliminary */
-#define COMPLETE 2 /* positive completion */
-#define CONTINUE 3 /* positive intermediate */
-#define TRANSIENT 4 /* transient negative completion */
-#define ERROR 5 /* permanent negative completion */
-
-/*
- * Type codes
- */
-#define TYPE_A 1 /* ASCII */
-#define TYPE_E 2 /* EBCDIC */
-#define TYPE_I 3 /* image */
-#define TYPE_L 4 /* local byte size */
-
-#ifdef FTP_NAMES
-char *typenames[] = {"0", "ASCII", "EBCDIC", "Image", "Local" };
-#endif
-
-/*
- * Form codes
- */
-#define FORM_N 1 /* non-print */
-#define FORM_T 2 /* telnet format effectors */
-#define FORM_C 3 /* carriage control (ASA) */
-#ifdef FTP_NAMES
-char *formnames[] = {"0", "Nonprint", "Telnet", "Carriage-control" };
-#endif
-
-/*
- * Structure codes
- */
-#define STRU_F 1 /* file (no record structure) */
-#define STRU_R 2 /* record structure */
-#define STRU_P 3 /* page structure */
-#ifdef FTP_NAMES
-char *strunames[] = {"0", "File", "Record", "Page" };
-#endif
-
-/*
- * Mode types
- */
-#define MODE_S 1 /* stream */
-#define MODE_B 2 /* block */
-#define MODE_C 3 /* compressed */
-#ifdef FTP_NAMES
-char *modenames[] = {"0", "Stream", "Block", "Compressed" };
-#endif
-
-/*
- * Protection levels
- */
-#define PROT_C 1 /* clear */
-#define PROT_S 2 /* safe */
-#define PROT_P 3 /* private */
-#define PROT_E 4 /* confidential */
-
-#ifdef FTP_NAMES
-char *levelnames[] = {"0", "Clear", "Safe", "Private", "Confidential" };
-#endif
-
-#if defined(KERBEROS) && defined(NOENCRYPTION)
-/* define away krb_rd_priv and krb_mk_priv. Don't need them anyway. */
-/* This might not be the best place for this ... */
-#define krb_rd_priv(o,l,ses,s,h,c,m) krb_rd_safe(o,l,s,h,c,m)
-#define krb_mk_priv(i,o,l,ses,s,h,c) krb_mk_safe(i,o,l,s,h,c)
-#endif
-
-/*
- * Record Tokens
- */
-#define REC_ESC '\377' /* Record-mode Escape */
-#define REC_EOR '\001' /* Record-mode End-of-Record */
-#define REC_EOF '\002' /* Record-mode End-of-File */
-
-/*
- * Block Header
- */
-#define BLK_EOR 0x80 /* Block is End-of-Record */
-#define BLK_EOF 0x40 /* Block is End-of-File */
-#define BLK_ERRORS 0x20 /* Block is suspected of containing errors */
-#define BLK_RESTART 0x10 /* Block is Restart Marker */
-
-#define BLK_BYTECOUNT 2 /* Bytes in this block */
-
-#endif /* !_FTP_H_ */
+++ /dev/null
-/*
- * Copyright (c) 1983 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.
- *
- * @(#)telnet.h 5.14 (Berkeley) 4/3/91
- */
-
-#ifndef _TELNET_H_
-#define _TELNET_H_
-
-/*
- * Definitions for the TELNET protocol.
- */
-#define IAC 255 /* interpret as command: */
-#define DONT 254 /* you are not to use option */
-#define DO 253 /* please, you use option */
-#define WONT 252 /* I won't use option */
-#define WILL 251 /* I will use option */
-#define SB 250 /* interpret as subnegotiation */
-#define GA 249 /* you may reverse the line */
-#define EL 248 /* erase the current line */
-#define EC 247 /* erase the current character */
-#define AYT 246 /* are you there */
-#define AO 245 /* abort output--but let prog finish */
-#define IP 244 /* interrupt process--permanently */
-#define BREAK 243 /* break */
-#define DM 242 /* data mark--for connect. cleaning */
-#define NOP 241 /* nop */
-#define SE 240 /* end sub negotiation */
-#define EOR 239 /* end of record (transparent mode) */
-#define ABORT 238 /* Abort process */
-#define SUSP 237 /* Suspend process */
-#define xEOF 236 /* End of file: EOF is already used... */
-
-#define SYNCH 242 /* for telfunc calls */
-
-#ifdef TELCMDS
-char *telcmds[] = {
- "EOF", "SUSP", "ABORT", "EOR",
- "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC",
- "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0,
-};
-#else
-extern char *telcmds[];
-#endif
-
-#define TELCMD_FIRST xEOF
-#define TELCMD_LAST IAC
-#define TELCMD_OK(x) ((x) <= TELCMD_LAST && (x) >= TELCMD_FIRST)
-#define TELCMD(x) telcmds[(x)-TELCMD_FIRST]
-
-/* telnet options */
-#define TELOPT_BINARY 0 /* 8-bit data path */
-#define TELOPT_ECHO 1 /* echo */
-#define TELOPT_RCP 2 /* prepare to reconnect */
-#define TELOPT_SGA 3 /* suppress go ahead */
-#define TELOPT_NAMS 4 /* approximate message size */
-#define TELOPT_STATUS 5 /* give status */
-#define TELOPT_TM 6 /* timing mark */
-#define TELOPT_RCTE 7 /* remote controlled transmission and echo */
-#define TELOPT_NAOL 8 /* negotiate about output line width */
-#define TELOPT_NAOP 9 /* negotiate about output page size */
-#define TELOPT_NAOCRD 10 /* negotiate about CR disposition */
-#define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */
-#define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */
-#define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */
-#define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */
-#define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */
-#define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */
-#define TELOPT_XASCII 17 /* extended ascic character set */
-#define TELOPT_LOGOUT 18 /* force logout */
-#define TELOPT_BM 19 /* byte macro */
-#define TELOPT_DET 20 /* data entry terminal */
-#define TELOPT_SUPDUP 21 /* supdup protocol */
-#define TELOPT_SUPDUPOUTPUT 22 /* supdup output */
-#define TELOPT_SNDLOC 23 /* send location */
-#define TELOPT_TTYPE 24 /* terminal type */
-#define TELOPT_EOR 25 /* end or record */
-#define TELOPT_TUID 26 /* TACACS user identification */
-#define TELOPT_OUTMRK 27 /* output marking */
-#define TELOPT_TTYLOC 28 /* terminal location number */
-#define TELOPT_3270REGIME 29 /* 3270 regime */
-#define TELOPT_X3PAD 30 /* X.3 PAD */
-#define TELOPT_NAWS 31 /* window size */
-#define TELOPT_TSPEED 32 /* terminal speed */
-#define TELOPT_LFLOW 33 /* remote flow control */
-#define TELOPT_LINEMODE 34 /* Linemode option */
-#define TELOPT_XDISPLOC 35 /* X Display Location */
-#define TELOPT_ENVIRON 36 /* Environment variables */
-#define TELOPT_AUTHENTICATION 37/* Authenticate */
-#define TELOPT_ENCRYPT 38 /* Encryption option */
-#define TELOPT_EXOPL 255 /* extended-options-list */
-
-
-#define NTELOPTS (1+TELOPT_ENCRYPT)
-#ifdef TELOPTS
-char *telopts[NTELOPTS+1] = {
- "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME",
- "STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP",
- "NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS",
- "NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
- "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT",
- "SEND LOCATION", "TERMINAL TYPE", "END OF RECORD",
- "TACACS UID", "OUTPUT MARKING", "TTYLOC",
- "3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW",
- "LINEMODE", "XDISPLOC", "ENVIRON", "AUTHENTICATION",
- "ENCRYPT",
- 0,
-};
-#define TELOPT_FIRST TELOPT_BINARY
-#define TELOPT_LAST TELOPT_ENCRYPT
-#define TELOPT_OK(x) ((x) <= TELOPT_LAST && (x) >= TELOPT_FIRST)
-#define TELOPT(x) telopts[(x)-TELOPT_FIRST]
-#endif
-
-/* sub-option qualifiers */
-#define TELQUAL_IS 0 /* option is... */
-#define TELQUAL_SEND 1 /* send option */
-#define TELQUAL_INFO 2 /* ENVIRON: informational version of IS */
-#define TELQUAL_REPLY 2 /* AUTHENTICATION: client version of IS */
-#define TELQUAL_NAME 3 /* AUTHENTICATION: client version of IS */
-
-/*
- * LINEMODE suboptions
- */
-
-#define LM_MODE 1
-#define LM_FORWARDMASK 2
-#define LM_SLC 3
-
-#define MODE_EDIT 0x01
-#define MODE_TRAPSIG 0x02
-#define MODE_ACK 0x04
-#define MODE_SOFT_TAB 0x08
-#define MODE_LIT_ECHO 0x10
-
-#define MODE_MASK 0x1f
-
-/* Not part of protocol, but needed to simplify things... */
-#define MODE_FLOW 0x0100
-#define MODE_ECHO 0x0200
-#define MODE_INBIN 0x0400
-#define MODE_OUTBIN 0x0800
-#define MODE_FORCE 0x1000
-
-#define SLC_SYNCH 1
-#define SLC_BRK 2
-#define SLC_IP 3
-#define SLC_AO 4
-#define SLC_AYT 5
-#define SLC_EOR 6
-#define SLC_ABORT 7
-#define SLC_EOF 8
-#define SLC_SUSP 9
-#define SLC_EC 10
-#define SLC_EL 11
-#define SLC_EW 12
-#define SLC_RP 13
-#define SLC_LNEXT 14
-#define SLC_XON 15
-#define SLC_XOFF 16
-#define SLC_FORW1 17
-#define SLC_FORW2 18
-
-#define NSLC 18
-
-/*
- * For backwards compatability, we define SLC_NAMES to be the
- * list of names if SLC_NAMES is not defined.
- */
-#define SLC_NAMELIST "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \
- "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \
- "LNEXT", "XON", "XOFF", "FORW1", "FORW2", 0,
-#ifdef SLC_NAMES
-char *slc_names[] = {
- SLC_NAMELIST
-};
-#else
-extern char *slc_names[];
-#define SLC_NAMES SLC_NAMELIST
-#endif
-
-#define SLC_NAME_OK(x) ((x) >= 0 && (x) < NSLC)
-#define SLC_NAME(x) slc_names[x]
-
-#define SLC_NOSUPPORT 0
-#define SLC_CANTCHANGE 1
-#define SLC_VARIABLE 2
-#define SLC_DEFAULT 3
-#define SLC_LEVELBITS 0x03
-
-#define SLC_FUNC 0
-#define SLC_FLAGS 1
-#define SLC_VALUE 2
-
-#define SLC_ACK 0x80
-#define SLC_FLUSHIN 0x40
-#define SLC_FLUSHOUT 0x20
-
-#define ENV_VALUE 0
-#define ENV_VAR 1
-#define ENV_ESC 2
-
-/*
- * AUTHENTICATION suboptions
- */
-
-/*
- * Who is authenticating who ...
- */
-#define AUTH_WHO_CLIENT 0 /* Client authenticating server */
-#define AUTH_WHO_SERVER 1 /* Server authenticating client */
-#define AUTH_WHO_MASK 1
-
-/*
- * amount of authentication done
- */
-#define AUTH_HOW_ONE_WAY 0
-#define AUTH_HOW_MUTUAL 2
-#define AUTH_HOW_MASK 2
-
-#define AUTHTYPE_NULL 0
-#define AUTHTYPE_KERBEROS_V4 1
-#define AUTHTYPE_KERBEROS_V5 2
-#define AUTHTYPE_SPX 3
-#define AUTHTYPE_MINK 4
-#define AUTHTYPE_CNT 5
-
-#define AUTHTYPE_TEST 99
-
-#ifdef AUTH_NAMES
-char *authtype_names[] = {
- "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 0,
-};
-#else
-extern char *authtype_names[];
-#endif
-
-#define AUTHTYPE_NAME_OK(x) ((x) >= 0 && (x) < AUTHTYPE_CNT)
-#define AUTHTYPE_NAME(x) authtype_names[x]
-
-/*
- * ENCRYPTion suboptions
- */
-#define ENCRYPT_IS 0 /* I pick encryption type ... */
-#define ENCRYPT_SUPPORT 1 /* I support encryption types ... */
-#define ENCRYPT_REPLY 2 /* Initial setup response */
-#define ENCRYPT_START 3 /* Am starting to send encrypted */
-#define ENCRYPT_END 4 /* Am ending encrypted */
-#define ENCRYPT_REQSTART 5 /* Request you start encrypting */
-#define ENCRYPT_REQEND 6 /* Request you send encrypting */
-#define ENCRYPT_ENC_KEYID 7
-#define ENCRYPT_DEC_KEYID 8
-#define ENCRYPT_CNT 9
-
-#define ENCTYPE_ANY 0
-#define ENCTYPE_DES_CFB64 1
-#define ENCTYPE_DES_OFB64 2
-#define ENCTYPE_CNT 3
-
-#ifdef ENCRYPT_NAMES
-char *encrypt_names[] = {
- "IS", "SUPPORT", "REPLY", "START", "END",
- "REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID",
- 0,
-};
-char *enctype_names[] = {
- "ANY", "DES_CFB64", "DES_OFB64", 0,
-};
-#else
-extern char *encrypt_names[];
-extern char *enctype_names[];
-#endif
-
-
-#define ENCRYPT_NAME_OK(x) ((x) >= 0 && (x) < ENCRYPT_CNT)
-#define ENCRYPT_NAME(x) encrypt_names[x]
-
-#define ENCTYPE_NAME_OK(x) ((x) >= 0 && (x) < ENCTYPE_CNT)
-#define ENCTYPE_NAME(x) enctype_names[x]
-
-#endif /* !_TELNET_H_ */
+++ /dev/null
-K5_AC_INIT(README.gssftp)
-CONFIG_RULES
-AC_C_CONST
-AC_PROG_INSTALL
-AC_PROG_YACC
-KRB5_SIGTYPE
-CHECK_SIGNALS
-CHECK_SIGPROCMASK
-CHECK_SETJMP
-CHECK_WAIT_TYPE
-DECLARE_SYS_ERRLIST
-AC_HEADER_STDARG
-AC_CHECK_HEADER(termios.h,[AC_CHECK_FUNC(cfsetispeed,AC_DEFINE(POSIX_TERMIOS,1,[Define if POSIX termios interface found]))])
-AC_CHECK_HEADERS(unistd.h stdlib.h string.h sys/select.h sys/sockio.h paths.h)
-CHECK_UTMP
-DECLARE_SYS_ERRLIST
-AC_REPLACE_FUNCS(getdtablesize)
-AC_CHECK_FUNCS(getcwd getdtablesize getusershell seteuid setreuid setresuid strerror getenv)
-AC_CHECK_LIB(crypt,crypt) dnl
-KRB5_AC_LIBUTIL
-dnl
-dnl copied from appl/bsd/configure.in
-dnl
-AC_MSG_CHECKING([setenv])
-AC_CACHE_VAL(krb5_cv_setenv,
-[AC_TRY_LINK(
-[],[setenv("PATH","/bin",0);],
-krb5_cv_setenv=yes,krb5_cv_setenv=no)])
-AC_MSG_RESULT($krb5_cv_setenv)
-if test $krb5_cv_setenv = no; then
-SETENVSRC='$(srcdir)/../../bsd/setenv.c'
-SETENVOBJ=setenv.o
-AC_SUBST([SETENVSRC])
-AC_SUBST([SETENVOBJ])
-AC_DEFINE([NEED_SETENV],1,[Define if setenv needs to be defined])
-fi
-dnl
-dnl
-dnl
-AC_MSG_CHECKING([shadow password support])
-AC_CACHE_VAL(krb5_cv_shadow_pwd,
-[AC_TRY_LINK(
-[#include <sys/types.h>
-#include <pwd.h>
-#include <shadow.h>],
-[struct spwd *sp = getspnam("root")],
-krb5_cv_shadow_pwd=yes, krb5_cv_shadow_pwd=no)])
-AC_MSG_RESULT($krb5_cv_shadow_pwd)
-if test $krb5_cv_shadow_pwd = yes; then
-AC_DEFINE(HAVE_SHADOW,1,[Define if shadow password interface found])
-fi
-case $krb5_cv_host in
-alpha*-dec-osf*)
- AC_CHECK_LIB(security,setluid,
- AC_DEFINE(HAVE_SETLUID,1,[Define if setluid provided in OSF/1 security library])
- FTPD_LIBS="$FTPD_LIBS -lsecurity"
- )
- ;;
-esac
-dnl
-dnl
-dnl
-AC_SUBST(FTPD_LIBS)
-dnl
-dnl
-dnl
-KRB5_BUILD_PROGRAM
-V5_AC_OUTPUT_MAKEFILE(. ftp ftpd)
+++ /dev/null
-# No dependencies here.
+++ /dev/null
-thisconfigdir=./..
-myfulldir=appl/gssftp/ftp
-mydir=ftp
-BUILDTOP=$(REL)..$(S)..$(S)..
-#
-# appl/gssftp/ftp/Makefile.in
-#
-DEFINES = -DGSSAPI -DFTP_BUFSIZ=65535
-PROG_LIBPATH=-L$(TOPLIBD)
-PROG_RPATH=$(KRB5_LIBDIR)
-
-SRCS = $(srcdir)/cmds.c $(srcdir)/cmdtab.c $(srcdir)/domacro.c \
- $(srcdir)/ftp.c $(srcdir)/getpass.c $(srcdir)/glob.c \
- $(srcdir)/main.c $(srcdir)/radix.c \
- $(srcdir)/ruserpass.c $(srcdir)/secure.c
-
-
-OBJS = $(OUTPRE)cmds.$(OBJEXT) $(OUTPRE)cmdtab.$(OBJEXT) \
- $(OUTPRE)domacro.$(OBJEXT) $(OUTPRE)ftp.$(OBJEXT) \
- $(OUTPRE)getpass.$(OBJEXT) $(OUTPRE)glob.$(OBJEXT) \
- $(OUTPRE)main.$(OBJEXT) $(OUTPRE)radix.$(OBJEXT) \
- $(OUTPRE)ruserpass.$(OBJEXT) $(OUTPRE)secure.$(OBJEXT)
-
-LOCALINCLUDES = -I$(srcdir)/.. -I$(srcdir)
-
-all-unix:: ftp
-all-windows:: $(OUTPRE)ftp.exe
-
-ftp: $(OBJS) $(GSS_DEPLIBS) $(KRB5_BASE_DEPLIBS)
- $(CC_LINK) -o ftp $(OBJS) $(GSS_LIBS) $(KRB5_BASE_LIBS)
-
-$(OUTPRE)ftp.exe: $(OBJS) $(GLIB) $(KLIB)
- link $(EXE_LINKOPTS) -out:$@ $** ws2_32.lib advapi32.lib $(SCLIB)
- $(_VC_MANIFEST_EMBED_EXE)
-
-clean-unix::
- $(RM) ftp
-
-depend::
-
-install-unix::
- for f in ftp; do \
- $(INSTALL_PROGRAM) $$f \
- $(DESTDIR)$(CLIENT_BINDIR)/`echo $$f|sed '$(transform)'`; \
- $(INSTALL_DATA) $(srcdir)/$$f.M \
- $(DESTDIR)$(CLIENT_MANDIR)/`echo $$f|sed '$(transform)'`.1; \
- done
-
-ftp.o cmds.o main.o: $(srcdir)/../arpa/ftp.h
-ftp.o cmds.o cmdtab.o domacro.o main.o ruserpass.o: $(srcdir)/ftp_var.h
-secure.o: secure.h
-
-cmds.o: $(srcdir)/cmds.c
-cmdtab.o: $(srcdir)/cmdtab.c
-ftp.o: $(srcdir)/ftp.c
-getpass.o: $(srcdir)/getpass.c
-glob.o: $(srcdir)/glob.c
-main.o: $(srcdir)/main.c
-pclose.o: $(srcdir)/pclose.c
-ruserpass.o: $(srcdir)/ruserpass.c
-domacro.o: $(srcdir)/domacro.c
-radix.o: $(srcdir)/radix.c
-secure.o: $(srcdir)/secure.c
-
-# NOPOSTFIX
+++ /dev/null
-/*
- * Copyright (c) 1985, 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 lint
-static char sccsid[] = "@(#)cmds.c 5.26 (Berkeley) 3/5/91";
-#endif /* not lint */
-
-/*
- * FTP User Program -- Command Routines.
- */
-#ifdef _WIN32
-#include <win-mac.h>
-#endif
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include <port-sockets.h>
-
-#ifdef _WIN32
-#include <sys/stat.h>
-#include <direct.h>
-#include <mbstring.h>
-#undef ERROR
-#else
-#include <sys/wait.h>
-#include <sys/stat.h>
-#endif
-
-#include <arpa/ftp.h>
-
-#include <signal.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-#include <time.h>
-
-#include <k5-platform.h>
-
-#ifdef HAVE_GETCWD
-#define getwd(x) getcwd(x,MAXPATHLEN)
-#endif
-
-#include "ftp_var.h"
-#include "pathnames.h"
-
-extern char *globerr;
-extern char *home;
-extern char *remglob();
-#ifndef HAVE_STRERROR
-#define strerror(error) (sys_errlist[error])
-#ifdef NEED_SYS_ERRLIST
-extern char *sys_errlist[];
-#endif
-#endif
-
-extern off_t restart_point;
-extern char reply_string[];
-
-char *mname;
-jmp_buf jabort;
-
-extern char *auth_type;
-extern int do_auth();
-
-static int globulize (char **);
-static int confirm (char *, char *);
-static int getit (int, char **, int, char *);
-static sigtype mabort (int);
-static void quote1 (char *, int, char **);
-static char *dotrans (char *);
-static char *domap (char *);
-
-/*
- * `Another' gets another argument, and stores the new argc and argv.
- * It reverts to the top level (via main.c's intr()) on EOF/error.
- *
- * Returns false if no new arguments have been added.
- */
-int
-another(pargc, pargv, prompt)
- int *pargc;
- char ***pargv;
- char *prompt;
-{
- int len = strlen(line), ret;
- extern sig_t intr();
-
- if (len >= sizeof(line) - 3) {
- printf("sorry, arguments too long\n");
- intr();
- }
- printf("(%s) ", prompt);
- line[len++] = ' ';
- if (fgets(&line[len], (signed) sizeof(line) - len, stdin) == NULL)
- intr();
- len += strlen(&line[len]);
- if (len > 0 && line[len - 1] == '\n')
- line[len - 1] = '\0';
- makeargv();
- ret = margc > *pargc;
- *pargc = margc;
- *pargv = margv;
- return (ret);
-}
-
-/*
- * Connect to peer server and
- * auto-login, if possible.
- */
-void setpeer(argc, argv)
- int argc;
- char *argv[];
-{
- char *host, *hookup();
- unsigned short port;
-
- if (connected) {
- printf("Already connected to %s, use close first.\n",
- hostname);
- code = -1;
- return;
- }
- if (argc < 2)
- (void) another(&argc, &argv, "to");
- if (argc < 2 || argc > 3) {
- printf("usage: %s host-name [port]\n", argv[0]);
- code = -1;
- return;
- }
- port = sp->s_port;
- if (argc > 2) {
- int iport = atoi (argv[2]);
- if (iport <= 0 || iport >= 65536) {
- printf("%s: bad port number-- %s\n", argv[1], argv[2]);
- printf ("usage: %s host-name [port]\n", argv[0]);
- code = -1;
- return;
- }
- port = htons(iport);
- }
- host = hookup(argv[1], port);
- if (host) {
- int overbose;
-
- connected = 1;
- /*
- * Set up defaults for FTP.
- */
- clevel = dlevel = PROT_C;
- type = TYPE_A;
- curtype = TYPE_A;
- form = FORM_N;
- mode = MODE_S;
- stru = STRU_F;
- (void) strlcpy(bytename, "8", sizeof(bytename)), bytesize = 8;
- if (autoauth) {
- if (do_auth() && autoencrypt) {
- clevel = PROT_P;
- setpbsz(1<<20);
- if (command("PROT P") == COMPLETE)
- dlevel = PROT_P;
- else
- fprintf(stderr, "ftp: couldn't enable encryption\n");
- }
- if(auth_type && clevel == PROT_C)
- clevel = PROT_S;
- if(autologin)
- (void) login(argv[1]);
- }
-
-#ifndef unix
-/* sigh */
-#if defined(_AIX) || defined(__hpux) || defined(BSD)
-#define unix
-#endif
-#endif
-
-/* XXX - WIN32 - Is this really ok for Win32 (binary vs text mode)? */
-#if defined(unix) && (NBBY == 8 || defined(linux)) || defined(_WIN32)
-/*
- * this ifdef is to keep someone form "porting" this to an incompatible
- * system and not checking this out. This way they have to think about it.
- */
- overbose = verbose;
- if (debug == 0)
- verbose = -1;
- if (debug)
- printf("%s:%d: verbose=%d debug=%d overbose=%d\n",
- __FILE__, __LINE__, verbose, debug, overbose);
- if (command("SYST") == COMPLETE && overbose) {
- register char *cp, c=0;
- cp = strchr(reply_string+4, ' ');
- if (cp == NULL)
- cp = strchr(reply_string+4, '\r');
- if (cp) {
- if (cp[-1] == '.')
- cp--;
- c = *cp;
- *cp = '\0';
- }
-
- printf("Remote system type is %s.\n",
- reply_string+4);
- if (cp)
- *cp = c;
- }
- if (!strncmp(reply_string, "215 UNIX Type: L8", 17)) {
- if (proxy)
- unix_proxy = 1;
- else
- unix_server = 1;
- /*
- * Set type to 0 (not specified by user),
- * meaning binary by default, but don't bother
- * telling server. We can use binary
- * for text files unless changed by the user.
- */
- type = 0;
- if (overbose)
- printf("Using %s mode to transfer files.\n",
- "binary");
- } else {
- if (proxy)
- unix_proxy = 0;
- else
- unix_server = 0;
- if (overbose &&
- !strncmp(reply_string, "215 TOPS20", 10))
- printf(
-"Remember to set tenex mode when transfering binary files from this machine.\n");
- }
- verbose = overbose;
-#else
- if (debug)
- printf("(!defined(unix): not checking remote system type)\n");
-#endif /* unix */
- }
-}
-
-struct levels {
- char *p_name;
- char *p_mode;
- int p_level;
-} levels[] = {
- { "clear", "C", PROT_C },
- { "safe", "S", PROT_S },
-#ifndef NOENCRYPTION
- { "private", "P", PROT_P },
-#endif
- { 0, 0, 0}
-};
-
-static char *
-getclevel()
-{
- register struct levels *p;
-
- for (p = levels; p->p_level != clevel; p++);
- return(p->p_name);
-}
-
-static char *
-getdlevel()
-{
- register struct levels *p;
-
- for (p = levels; p->p_level != dlevel; p++);
- return(p->p_name);
-}
-
-char *plevel[] = {
- "protect",
- "",
- 0
-};
-
-/*
- * Set control channel protection level.
- */
-void setclevel(argc, argv)
- char *argv[];
-{
- register struct levels *p;
- int comret;
-
- if (argc > 2) {
- char *sep;
-
- printf("usage: %s [", argv[0]);
- sep = " ";
- for (p = levels; p->p_name; p++) {
- printf("%s%s", sep, p->p_name);
- if (*sep == ' ')
- sep = " | ";
- }
- printf(" ]\n");
- code = -1;
- return;
- }
- if (argc < 2) {
- printf("Using %s protection level for commands.\n",
- getclevel());
- code = 0;
- return;
- }
- for (p = levels; p->p_name; p++)
- if (strcmp(argv[1], p->p_name) == 0)
- break;
- if (p->p_name == 0) {
- printf("%s: unknown protection level\n", argv[1]);
- code = -1;
- return;
- }
- if (!auth_type) {
- if (strcmp(p->p_name, "clear"))
- printf("Cannot set protection level to %s\n", argv[1]);
- return;
- }
- if (!strcmp(p->p_name, "clear")) {
- comret = command("CCC");
- if (comret == COMPLETE)
- clevel = PROT_C;
- return;
- }
- clevel = p->p_level;
- printf("Control channel protection level set to %s.\n", p->p_name);
-}
-
-/*
- * Set data channel protection level.
- */
-void
-setdlevel(argc, argv)
- char *argv[];
-{
- register struct levels *p;
- int comret;
-
- if (argc > 2) {
- char *sep;
-
- printf("usage: %s [", argv[0]);
- sep = " ";
- for (p = levels; p->p_name; p++) {
- printf("%s%s", sep, p->p_name);
- if (*sep == ' ')
- sep = " | ";
- }
- printf(" ]\n");
- code = -1;
- return;
- }
- if (argc < 2) {
- printf("Using %s protection level to transfer files.\n",
- getdlevel());
- code = 0;
- return;
- }
- for (p = levels; p->p_name; p++)
- if (strcmp(argv[1], p->p_name) == 0)
- break;
- if (p->p_name == 0) {
- printf("%s: unknown protection level\n", argv[1]);
- code = -1;
- return;
- }
- if (!auth_type) {
- if (strcmp(p->p_name, "clear"))
- printf("Cannot set protection level to %s\n", argv[1]);
- return;
- }
- /* Start with a PBSZ of 1 meg */
- if (p->p_level != PROT_C) setpbsz(1<<20);
- comret = command("PROT %s", p->p_mode);
- if (comret == COMPLETE)
- dlevel = p->p_level;
-}
-
-
-/*
- * Set clear command protection level.
- */
-/*VARARGS*/
-void
-ccc()
-{
- plevel[1] = "clear";
- setclevel(2, plevel);
-}
-
-/*
- * Set clear data protection level.
- */
-/*VARARGS*/
-void
-setclear()
-{
- plevel[1] = "clear";
- setdlevel(2, plevel);
-}
-
-/*
- * Set safe data protection level.
- */
-/*VARARGS*/
-void
-setsafe()
-{
- plevel[1] = "safe";
- setdlevel(2, plevel);
-}
-
-#ifndef NOENCRYPTION
-/*
- * Set private data protection level.
- */
-/*VARARGS*/
-void
-setprivate()
-{
- plevel[1] = "private";
- setdlevel(2, plevel);
-}
-#endif
-
-struct types {
- char *t_name;
- char *t_mode;
- int t_type;
- char *t_arg;
-} types[] = {
- { "ascii", "A", TYPE_A, 0 },
- { "binary", "I", TYPE_I, 0 },
- { "image", "I", TYPE_I, 0 },
- { "ebcdic", "E", TYPE_E, 0 },
- { "tenex", "L", TYPE_L, bytename },
- { 0, 0 , 0, 0}
-};
-
-static char *
-gettype()
-{
- register struct types *p;
- int t;
-
- t = type;
- if (t == 0)
- t = TYPE_I;
- for (p = types; p->t_type != t; p++);
- return(p->t_name);
-}
-
-/*
- * Set transfer type.
- */
-void
-settype(argc, argv)
- int argc;
- char *argv[];
-{
- register struct types *p;
- int comret;
-
- if (argc > 2) {
- char *sep;
-
- printf("usage: %s [", argv[0]);
- sep = " ";
- for (p = types; p->t_name; p++) {
- printf("%s%s", sep, p->t_name);
- sep = " | ";
- }
- printf(" ]\n");
- code = -1;
- return;
- }
- if (argc < 2) {
- printf("Using %s mode to transfer files.\n", gettype());
- code = 0;
- return;
- }
- for (p = types; p->t_name; p++)
- if (strcmp(argv[1], p->t_name) == 0)
- break;
- if (p->t_name == 0) {
- printf("%s: unknown mode\n", argv[1]);
- code = -1;
- return;
- }
- if ((p->t_arg != NULL) && (*(p->t_arg) != '\0'))
- comret = command ("TYPE %s %s", p->t_mode, p->t_arg);
- else
- comret = command("TYPE %s", p->t_mode);
- if (comret == COMPLETE)
- curtype = type = p->t_type;
-}
-
-/*
- * Internal form of settype; changes current type in use with server
- * without changing our notion of the type for data transfers.
- * Used to change to and from ascii for listings.
- */
-void changetype(newtype, show)
- int newtype, show;
-{
- register struct types *p;
- int comret, oldverbose = verbose;
-
- if (newtype == 0)
- newtype = TYPE_I;
- if (newtype == curtype)
- return;
- if (debug == 0 && show == 0)
- verbose = 0;
- for (p = types; p->t_name; p++)
- if (newtype == p->t_type)
- break;
- if (p->t_name == 0) {
- printf("ftp: internal error: unknown type %d\n", newtype);
- return;
- }
- if (newtype == TYPE_L && bytename[0] != '\0')
- comret = command("TYPE %s %s", p->t_mode, bytename);
- else
- comret = command("TYPE %s", p->t_mode);
- if (comret == COMPLETE)
- curtype = newtype;
- verbose = oldverbose;
-}
-
-char *stype[] = {
- "type",
- "",
- 0
-};
-
-/*
- * Set binary transfer type.
- */
-/*VARARGS*/
-void setbinary()
-{
- stype[1] = "binary";
- settype(2, stype);
-}
-
-/*
- * Set ascii transfer type.
- */
-/*VARARGS*/
-void setascii()
-{
- stype[1] = "ascii";
- settype(2, stype);
-}
-
-/*
- * Set tenex transfer type.
- */
-/*VARARGS*/
-void settenex()
-{
- stype[1] = "tenex";
- settype(2, stype);
-}
-
-static char *
-get_mode()
-{
- return("stream");
-}
-
-/*
- * Set file transfer mode.
- */
-/*ARGSUSED*/
-void set_mode(argc, argv)
- int argc;
- char *argv[];
-{
-
- printf("We only support %s mode, sorry.\n", get_mode());
- code = -1;
-}
-
-static char *
-getform()
-{
- return("non-print");
-}
-
-/*
- * Set file transfer format.
- */
-/*ARGSUSED*/
-void setform(argc, argv)
- int argc;
- char *argv[];
-{
-
- printf("We only support %s format, sorry.\n", getform());
- code = -1;
-}
-
-static char *
-getstruct()
-{
- return("file");
-}
-
-/*
- * Set file transfer structure.
- */
-/*ARGSUSED*/
-void setstruct(argc, argv)
- int argc;
- char *argv[];
-{
-
- printf("We only support %s structure, sorry.\n", getstruct());
- code = -1;
-}
-
-/*
- * Send a single file.
- */
-void put(argc, argv)
- int argc;
- char *argv[];
-{
- char *cmd;
- int loc = 0;
- char *oldargv1, *oldargv2;
-
- if (argc == 2) {
- argc++;
- argv[2] = argv[1];
- loc++;
- }
- if (argc < 2 && !another(&argc, &argv, "local-file"))
- goto usage;
- if (argc < 3 && !another(&argc, &argv, "remote-file")) {
-usage:
- printf("usage: %s local-file remote-file\n", argv[0]);
- code = -1;
- return;
- }
- oldargv1 = argv[1];
- oldargv2 = argv[2];
- if (!globulize(&argv[1])) {
- code = -1;
- return;
- }
- /*
- * If "globulize" modifies argv[1], and argv[2] is a copy of
- * the old argv[1], make it a copy of the new argv[1].
- */
- if (argv[1] != oldargv1 && argv[2] == oldargv1) {
- argv[2] = argv[1];
- }
- cmd = (argv[0][0] == 'a') ? "APPE" : ((sunique) ? "STOU" : "STOR");
- if (loc && ntflag) {
- argv[2] = dotrans(argv[2]);
- }
- if (loc && mapflag) {
- argv[2] = domap(argv[2]);
- }
- sendrequest(cmd, argv[1], argv[2],
- argv[1] != oldargv1 || argv[2] != oldargv2);
-}
-
-/*
- * Send multiple files.
- */
-void mput(argc, argv)
- int argc;
- char **argv;
-{
- register int i;
- sig_t oldintr;
- int ointer;
- char *tp;
-
- if (argc < 2 && !another(&argc, &argv, "local-files")) {
- printf("usage: %s local-files\n", argv[0]);
- code = -1;
- return;
- }
- mname = argv[0];
- mflag = 1;
- oldintr = signal(SIGINT, mabort);
- (void) setjmp(jabort);
- if (proxy) {
- char *cp, *tp2, tmpbuf[MAXPATHLEN];
-
- while ((cp = remglob(argv,0)) != NULL) {
- if (*cp == 0) {
- mflag = 0;
- continue;
- }
- if (mflag && confirm(argv[0], cp)) {
- tp = cp;
- if (mcase) {
- while (*tp && !islower((unsigned char) (*tp))) {
- tp++;
- }
- if (!*tp) {
- tp = cp;
- tp2 = tmpbuf;
- while ((*tp2 = *tp) != 0) {
- if (isupper((unsigned char) *tp2)) {
- *tp2 = 'a' + *tp2 - 'A';
- }
- tp++;
- tp2++;
- }
- }
- tp = tmpbuf;
- }
- if (ntflag) {
- tp = dotrans(tp);
- }
- if (mapflag) {
- tp = domap(tp);
- }
- sendrequest((sunique) ? "STOU" : "STOR",
- cp, tp, cp != tp || !interactive);
- if (!mflag && fromatty) {
- ointer = interactive;
- interactive = 1;
- if (confirm("Continue with","mput")) {
- mflag++;
- }
- interactive = ointer;
- }
- }
- }
- (void) signal(SIGINT, oldintr);
- mflag = 0;
- return;
- }
- for (i = 1; i < argc; i++) {
- register char **cpp, **gargs;
-
- if (!doglob) {
- if (mflag && confirm(argv[0], argv[i])) {
- tp = (ntflag) ? dotrans(argv[i]) : argv[i];
- tp = (mapflag) ? domap(tp) : tp;
- sendrequest((sunique) ? "STOU" : "STOR",
- argv[i], tp, tp != argv[i] || !interactive);
- if (!mflag && fromatty) {
- ointer = interactive;
- interactive = 1;
- if (confirm("Continue with","mput")) {
- mflag++;
- }
- interactive = ointer;
- }
- }
- continue;
- }
- gargs = ftpglob(argv[i]);
- if (globerr != NULL) {
- printf("%s\n", globerr);
- if (gargs) {
- blkfree(gargs);
- free(gargs);
- }
- continue;
- }
- for (cpp = gargs; cpp && *cpp != NULL; cpp++) {
- if (mflag && confirm(argv[0], *cpp)) {
- tp = (ntflag) ? dotrans(*cpp) : *cpp;
- tp = (mapflag) ? domap(tp) : tp;
- sendrequest((sunique) ? "STOU" : "STOR",
- *cpp, tp, *cpp != tp || !interactive);
- if (!mflag && fromatty) {
- ointer = interactive;
- interactive = 1;
- if (confirm("Continue with","mput")) {
- mflag++;
- }
- interactive = ointer;
- }
- }
- }
- if (gargs != NULL) {
- blkfree(gargs);
- free(gargs);
- }
- }
- (void) signal(SIGINT, oldintr);
- mflag = 0;
-}
-
-void reget(argc, argv)
- int argc;
- char *argv[];
-{
- (void) getit(argc, argv, 1, "r+w");
-}
-
-void get(argc, argv)
- int argc;
- char *argv[];
-{
- (void) getit(argc, argv, 0, restart_point ? "r+w" : "w" );
-}
-
-/*
- * Receive one file.
- */
-static int getit(argc, argv, restartit, rmode)
- int argc;
- char *argv[];
- char *rmode;
-{
- int loc = 0;
- char *oldargv1, *oldargv2;
-
- if (argc == 2) {
- argc++;
- argv[2] = argv[1];
- loc++;
- }
- if (argc < 2 && !another(&argc, &argv, "remote-file"))
- goto usage;
- if (argc < 3 && !another(&argc, &argv, "local-file")) {
-usage:
- printf("usage: %s remote-file [ local-file ]\n", argv[0]);
- code = -1;
- return (0);
- }
- oldargv1 = argv[1];
- oldargv2 = argv[2];
- if (!globulize(&argv[2])) {
- code = -1;
- return (0);
- }
- if (loc && mcase) {
- char *tp = argv[1], *tp2, tmpbuf[MAXPATHLEN];
-
- while (*tp && !islower((unsigned char) *tp)) {
- tp++;
- }
- if (!*tp) {
- tp = argv[2];
- tp2 = tmpbuf;
- while ((*tp2 = *tp) != 0) {
- if (isupper((unsigned char) *tp2)) {
- *tp2 = 'a' + *tp2 - 'A';
- }
- tp++;
- tp2++;
- }
- argv[2] = tmpbuf;
- }
- }
- if (loc && ntflag)
- argv[2] = dotrans(argv[2]);
- if (loc && mapflag)
- argv[2] = domap(argv[2]);
- if (restartit) {
- struct stat stbuf;
- int ret;
-
- ret = stat(argv[2], &stbuf);
- if (restartit == 1) {
- if (ret < 0) {
- fprintf(stderr, "local: %s: %s\n", argv[2],
- strerror(errno));
- return (0);
- }
- restart_point = stbuf.st_size;
- } else {
- if (ret == 0) {
- int overbose;
-
- overbose = verbose;
- if (debug == 0)
- verbose = -1;
- if (command("MDTM %s", argv[1]) == COMPLETE) {
- int yy, mo, day, hour, min, sec;
- struct tm *tm;
- verbose = overbose;
- sscanf(reply_string,
- "%*s %04d%02d%02d%02d%02d%02d",
- &yy, &mo, &day, &hour, &min, &sec);
- tm = gmtime(&stbuf.st_mtime);
- tm->tm_mon++;
- if (tm->tm_year > yy-1900)
- return (1);
- else if (tm->tm_year == yy-1900) {
- if (tm->tm_mon > mo)
- return (1);
- } else if (tm->tm_mon == mo) {
- if (tm->tm_mday > day)
- return (1);
- } else if (tm->tm_mday == day) {
- if (tm->tm_hour > hour)
- return (1);
- } else if (tm->tm_hour == hour) {
- if (tm->tm_min > min)
- return (1);
- } else if (tm->tm_min == min) {
- if (tm->tm_sec > sec)
- return (1);
- }
- } else {
- printf("%s\n", reply_string);
- verbose = overbose;
- return (0);
- }
- }
- }
- }
-
- recvrequest("RETR", argv[2], argv[1], rmode,
- argv[1] != oldargv1 || argv[2] != oldargv2, loc);
- restart_point = 0;
- return (0);
-}
-
-static sigtype
-mabort(sig)
- int sig;
-{
- int ointer;
-
- printf("\n");
- (void) fflush(stdout);
- if (mflag && fromatty) {
- ointer = interactive;
- interactive = 1;
- if (confirm("Continue with", mname)) {
- interactive = ointer;
- longjmp(jabort,0);
- }
- interactive = ointer;
- }
- mflag = 0;
- longjmp(jabort,0);
-}
-
-/*
- * Get multiple files.
- */
-void mget(argc, argv)
- int argc;
- char **argv;
-{
- sig_t oldintr;
- int ointer;
- char *cp, *tp, *tp2, tmpbuf[MAXPATHLEN];
-
- if (argc < 2 && !another(&argc, &argv, "remote-files")) {
- printf("usage: %s remote-files\n", argv[0]);
- code = -1;
- return;
- }
- mname = argv[0];
- mflag = 1;
- oldintr = signal(SIGINT,mabort);
- (void) setjmp(jabort);
- while ((cp = remglob(argv,proxy)) != NULL) {
- if (*cp == '\0') {
- mflag = 0;
- continue;
- }
- if (mflag && confirm(argv[0], cp)) {
- tp = cp;
- if (mcase) {
- while (*tp && !islower((unsigned char) *tp)) {
- tp++;
- }
- if (!*tp) {
- tp = cp;
- tp2 = tmpbuf;
- while ((*tp2 = *tp) != 0) {
- if (isupper((unsigned char) *tp2)) {
- *tp2 = 'a' + *tp2 - 'A';
- }
- tp++;
- tp2++;
- }
- }
- tp = tmpbuf;
- }
- if (ntflag) {
- tp = dotrans(tp);
- }
- if (mapflag) {
- tp = domap(tp);
- }
- recvrequest("RETR", tp, cp, "w",
- tp != cp || !interactive, 1);
- if (!mflag && fromatty) {
- ointer = interactive;
- interactive = 1;
- if (confirm("Continue with","mget")) {
- mflag++;
- }
- interactive = ointer;
- }
- }
- }
- (void) signal(SIGINT,oldintr);
- mflag = 0;
-}
-
-char *
-remglob(argv,doswitch)
- char *argv[];
- int doswitch;
-{
-#ifdef _WIN32
- char *temp = NULL;
-#else
- char temp[16];
-#endif
- static char buf[MAXPATHLEN];
- static FILE *ftemp = NULL;
- static char **args;
- int oldverbose, oldhash;
- char *cp, *rmode;
-
- if (!mflag) {
- if (!doglob) {
- args = NULL;
- }
- else {
- if (ftemp) {
- (void) fclose(ftemp);
- ftemp = NULL;
- }
- }
- return(NULL);
- }
- if (!doglob) {
- if (args == NULL)
- args = argv;
- if ((cp = *++args) == NULL)
- args = NULL;
- return (cp);
- }
- if (ftemp == NULL) {
-#ifdef _WIN32
- temp = _tempnam(_PATH_TMP, "ftpglob");
- if (temp == NULL) {
- printf("can't get temporary file name\n");
- return (NULL);
- }
-#else
- (void) strncpy(temp, _PATH_TMP, sizeof(temp) - 1);
- temp[sizeof(temp) - 1] = '\0';
- (void) mktemp(temp);
-#endif /* !_WIN32 */
- oldverbose = verbose, verbose = 0;
- oldhash = hash, hash = 0;
- if (doswitch) {
- pswitch(!proxy);
- }
- for (rmode = "w"; *++argv != NULL; rmode = "a")
- recvrequest ("NLST", temp, *argv, rmode, 0, 0);
- if (doswitch) {
- pswitch(!proxy);
- }
- verbose = oldverbose; hash = oldhash;
- ftemp = fopen(temp, "r");
- (void) unlink(temp);
-#ifdef _WIN32
- free(temp);
- temp = NULL;
-#endif /* _WIN32 */
- if (ftemp == NULL) {
- printf("can't find list of remote files, oops\n");
- return (NULL);
- }
- }
- if (fgets(buf, sizeof (buf), ftemp) == NULL) {
- (void) fclose(ftemp), ftemp = NULL;
- return (NULL);
- }
- if ((cp = strchr(buf, '\n')) != NULL)
- *cp = '\0';
- return (buf);
-}
-
-static char *
-onoff(bool)
- int bool;
-{
-
- return (bool ? "on" : "off");
-}
-
-static void cstatus()
-{
- if (!connected) {
- printf(proxy ? "No proxy connection.\n" : "Not connected.\n");
- return;
- }
- printf("Connected %sto %s.\n",
- proxy ? "for proxy commands " : "", hostname);
- if (auth_type) printf("Authentication type: %s\n", auth_type);
- printf("Control Channel Protection Level: %s\n", getclevel());
- printf("Data Channel Protection Level: %s\n", getdlevel());
- printf("Passive mode %s\n", onoff(passivemode));
- printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n",
- get_mode(), gettype(), getform(), getstruct());
- printf("Store unique: %s; Receive unique: %s\n", onoff(sunique),
- onoff(runique));
- printf("Case: %s; CR stripping: %s\n",onoff(mcase),onoff(crflag));
- if (ntflag) {
- printf("Ntrans: (in) %s (out) %s\n", ntin,ntout);
- }
- else {
- printf("Ntrans: off\n");
- }
- if (mapflag) {
- printf("Nmap: (in) %s (out) %s\n", mapin, mapout);
- }
- else {
- printf("Nmap: off\n");
- }
-}
-
-/*
- * Show status.
- */
-/*ARGSUSED*/
-void status(argc, argv)
- char *argv[];
-{
- int i;
-
- cstatus();
- if (!proxy) {
- pswitch(1);
- if (connected) putchar('\n');
- cstatus();
- if (connected) putchar('\n');
- pswitch(0);
- }
- printf("Hash mark printing: %s; Use of PORT cmds: %s\n",
- onoff(hash), onoff(sendport));
- printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n",
- onoff(verbose), onoff(bell), onoff(interactive),
- onoff(doglob));
- if (macnum > 0) {
- printf("Macros:\n");
- for (i=0; i<macnum; i++) {
- printf("\t%s\n",macros[i].mac_name);
- }
- }
- code = 0;
-}
-
-/*
- * Set beep on cmd completed mode.
- */
-/*VARARGS*/
-void setbell()
-{
-
- bell = !bell;
- printf("Bell mode %s.\n", onoff(bell));
- code = bell;
-}
-
-/*
- * Turn on packet tracing.
- */
-/*VARARGS*/
-void settrace()
-{
-
- trace = !trace;
- printf("Packet tracing %s.\n", onoff(trace));
- code = trace;
-}
-
-/*
- * Toggle hash mark printing during transfers.
- */
-/*VARARGS*/
-void sethash()
-{
-
- hash = !hash;
- printf("Hash mark printing %s", onoff(hash));
- code = hash;
- if (hash)
- printf(" (%d bytes/hash mark)", 1024);
- printf(".\n");
-}
-
-/*
- * Turn on printing of server echo's.
- */
-/*VARARGS*/
-void setverbose()
-{
-
- verbose = !verbose;
- printf("Verbose mode %s.\n", onoff(verbose));
- code = verbose;
-}
-
-/*
- * Toggle PORT cmd use before each data connection.
- */
-/*VARARGS*/
-void setport()
-{
-
- sendport = !sendport;
- printf("Use of PORT cmds %s.\n", onoff(sendport));
- code = sendport;
-}
-
-/*
- * Turn on interactive prompting
- * during mget, mput, and mdelete.
- */
-/*VARARGS*/
-void setprompt()
-{
-
- interactive = !interactive;
- printf("Interactive mode %s.\n", onoff(interactive));
- code = interactive;
-}
-
-/*
- * Toggle metacharacter interpretation
- * on local file names.
- */
-/*VARARGS*/
-void setglob()
-{
-
- doglob = !doglob;
- printf("Globbing %s.\n", onoff(doglob));
- code = doglob;
-}
-
-/*
- * Set debugging mode on/off and/or
- * set level of debugging.
- */
-/*VARARGS*/
-void setdebug(argc, argv)
- int argc;
- char *argv[];
-{
- int val;
-
- if (argc > 1) {
- val = atoi(argv[1]);
- if (val < 0) {
- printf("%s: bad debugging value.\n", argv[1]);
- code = -1;
- return;
- }
- } else
- val = !debug;
- debug = val;
- if (debug)
- options |= SO_DEBUG;
- else
- options &= ~SO_DEBUG;
- printf("Debugging %s (debug=%d).\n", onoff(debug), debug);
- code = debug > 0;
-}
-
-/*
- * Set current working directory
- * on remote machine.
- */
-void cd(argc, argv)
- int argc;
- char *argv[];
-{
-
- if (argc < 2 && !another(&argc, &argv, "remote-directory")) {
- printf("usage: %s remote-directory\n", argv[0]);
- code = -1;
- return;
- }
- if (command("CWD %s", argv[1]) == ERROR && code == 500) {
- if (verbose)
- printf("CWD command not recognized, trying XCWD\n");
- (void) command("XCWD %s", argv[1]);
- }
-}
-
-/*
- * Set current working directory
- * on local machine.
- */
-void lcd(argc, argv)
- int argc;
- char *argv[];
-{
- char buf[MAXPATHLEN];
-
- if (argc < 2)
- argc++, argv[1] = home;
- if (argc != 2) {
- printf("usage: %s local-directory\n", argv[0]);
- code = -1;
- return;
- }
- if (!globulize(&argv[1])) {
- code = -1;
- return;
- }
- if (chdir(argv[1]) < 0) {
- fprintf(stderr, "local: %s: %s\n", argv[1], strerror(errno));
- code = -1;
- return;
- }
- printf("Local directory now %s\n", getcwd(buf, sizeof buf));
- code = 0;
-}
-
-/*
- * Delete a single file.
- */
-void delete_file(argc, argv)
- int argc;
- char *argv[];
-{
-
- if (argc < 2 && !another(&argc, &argv, "remote-file")) {
- printf("usage: %s remote-file\n", argv[0]);
- code = -1;
- return;
- }
- (void) command("DELE %s", argv[1]);
-}
-
-/*
- * Delete multiple files.
- */
-void mdelete(argc, argv)
- int argc;
- char **argv;
-{
- sig_t oldintr;
- int ointer;
- char *cp;
-
- if (argc < 2 && !another(&argc, &argv, "remote-files")) {
- printf("usage: %s remote-files\n", argv[0]);
- code = -1;
- return;
- }
- mname = argv[0];
- mflag = 1;
- oldintr = signal(SIGINT, mabort);
- (void) setjmp(jabort);
- while ((cp = remglob(argv,0)) != NULL) {
- if (*cp == '\0') {
- mflag = 0;
- continue;
- }
- if (mflag && confirm(argv[0], cp)) {
- (void) command("DELE %s", cp);
- if (!mflag && fromatty) {
- ointer = interactive;
- interactive = 1;
- if (confirm("Continue with", "mdelete")) {
- mflag++;
- }
- interactive = ointer;
- }
- }
- }
- (void) signal(SIGINT, oldintr);
- mflag = 0;
-}
-
-/*
- * Rename a remote file.
- */
-void renamefile(argc, argv)
- int argc;
- char *argv[];
-{
-
- if (argc < 2 && !another(&argc, &argv, "from-name"))
- goto usage;
- if (argc < 3 && !another(&argc, &argv, "to-name")) {
-usage:
- printf("%s from-name to-name\n", argv[0]);
- code = -1;
- return;
- }
- if (command("RNFR %s", argv[1]) == CONTINUE)
- (void) command("RNTO %s", argv[2]);
-}
-
-/*
- * Get a directory listing
- * of remote files.
- */
-void ls(argc, argv)
- int argc;
- char *argv[];
-{
- char *cmd;
-
- if (argc < 2)
- argc++, argv[1] = NULL;
- if (argc < 3)
- argc++, argv[2] = "-";
- if (argc > 3) {
- printf("usage: %s remote-directory local-file\n", argv[0]);
- code = -1;
- return;
- }
- cmd = argv[0][0] == 'n' ? "NLST" : "LIST";
- if (strcmp(argv[2], "-") && !globulize(&argv[2])) {
- code = -1;
- return;
- }
- if (strcmp(argv[2], "-") && *argv[2] != '|')
- if (!globulize(&argv[2]) || !confirm("output to local-file:", argv[2])) {
- code = -1;
- return;
- }
- recvrequest(cmd, argv[2], argv[1], "w", 0, 0);
-}
-
-/*
- * Get a directory listing
- * of multiple remote files.
- */
-void mls(argc, argv)
- int argc;
- char **argv;
-{
- sig_t oldintr;
- int ointer, i;
- char *volatile cmd, rmode[1], *dest;
-
- if (argc < 2 && !another(&argc, &argv, "remote-files"))
- goto usage;
- if (argc < 3 && !another(&argc, &argv, "local-file")) {
-usage:
- printf("usage: %s remote-files local-file\n", argv[0]);
- code = -1;
- return;
- }
- dest = argv[argc - 1];
- argv[argc - 1] = NULL;
- if (strcmp(dest, "-") && *dest != '|')
- if (!globulize(&dest) ||
- !confirm("output to local-file:", dest)) {
- code = -1;
- return;
- }
- cmd = argv[0][1] == 'l' ? "NLST" : "LIST";
- mname = argv[0];
- mflag = 1;
- oldintr = signal(SIGINT, mabort);
- (void) setjmp(jabort);
- for (i = 1; mflag && i < argc-1; ++i) {
- *rmode = (i == 1) ? 'w' : 'a';
- recvrequest(cmd, dest, argv[i], rmode, 0, 0);
- if (!mflag && fromatty) {
- ointer = interactive;
- interactive = 1;
- if (confirm("Continue with", argv[0])) {
- mflag ++;
- }
- interactive = ointer;
- }
- }
- (void) signal(SIGINT, oldintr);
- mflag = 0;
-}
-
-/*
- * Do a shell escape
- */
-/*ARGSUSED*/
-#ifdef _WIN32
-void shell(int argc, char **argv)
-{
- char *AppName;
- char ShellCmd[MAX_PATH];
- char CmdLine[MAX_PATH];
- int i;
- PROCESS_INFORMATION ProcessInformation;
- BOOL Result;
- STARTUPINFO StartupInfo;
- int NumBytes;
-
-#ifdef _DEBUG
- if (trace)
- {
- fprintf(stderr, "entered shell\n");
- fprintf(stderr, "arguments = \n");
- fprintf(stderr, " argc = %d\n", argc);
- for (i = 0; i < argc; i++)
- {
- fprintf(stderr, " argv %d = %s\n", i, argv[i]);
- }
- }
-#endif /* _DEBUG */
-
- NumBytes = GetEnvironmentVariable("COMSPEC", ShellCmd, sizeof(ShellCmd));
-
- if (NumBytes == 0)
- {
- code = -1;
- return;
- }
-
- AppName = ShellCmd;
- _mbscpy(CmdLine, ShellCmd);
-
- if (argc > 1)
- {
- _mbsncat(CmdLine, " /C", sizeof(CmdLine));
- }
-
- for (i = 1; i < argc; i++)
- {
- _mbsncat(CmdLine, " ", sizeof(CmdLine));
- _mbsncat(CmdLine, argv[i], sizeof(CmdLine));
- }
- CmdLine[sizeof(CmdLine)-1] = 0;
-
- memset(&StartupInfo, 0, sizeof(StartupInfo));
- StartupInfo.cb = sizeof(StartupInfo);
- Result = CreateProcess(AppName, /* command name */
- CmdLine, /* command line w/args */
- NULL, /* sec attr (app) */
- NULL, /* sec attr (thread) */
- FALSE, /* inherit flags */
- 0, /* creation flags */
- NULL, /* environment */
- NULL, /* working directory */
- &StartupInfo, /* startup info struct */
- &ProcessInformation); /* process info struct */
-
- if (Result)
- {
- WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
- CloseHandle(ProcessInformation.hProcess);
- code = 0;
- }
- else {
- code = -1;
- }
-}
-#else
-void shell(argc, argv)
- int argc;
- char **argv;
-{
- int pid;
- sig_t old1, old2;
- char shellnam[40], *shellprog, *namep;
-#ifdef WAIT_USES_INT
- int w_status;
-#else
- union wait w_status;
-#endif
-
- old1 = signal (SIGINT, SIG_IGN);
- old2 = signal (SIGQUIT, SIG_IGN);
- if ((pid = fork()) == 0) {
- for (pid = 3; pid < 20; pid++)
- (void) close(pid);
- (void) signal(SIGINT, SIG_DFL);
- (void) signal(SIGQUIT, SIG_DFL);
- shellprog = getenv("SHELL");
- if (shellprog == NULL)
- shellprog = "/bin/sh";
- namep = strrchr(shellprog,'/');
- if (namep == NULL)
- namep = shellprog;
- (void) snprintf(shellnam, sizeof(shellnam), "-%s", ++namep);
- if (strcmp(namep, "sh") != 0)
- shellnam[0] = '+';
- if (debug) {
- printf ("%s\n", shellprog);
- (void) fflush (stdout);
- }
- if (argc > 1) {
- execl(shellprog,shellnam,"-c",altarg,(char *)0);
- }
- else {
- execl(shellprog,shellnam,(char *)0);
- }
- perror(shellprog);
- code = -1;
- exit(1);
- }
- if (pid > 0)
- while (wait(&w_status) != pid)
- ;
- (void) signal(SIGINT, old1);
- (void) signal(SIGQUIT, old2);
- if (pid == -1) {
- perror("Try again later");
- code = -1;
- }
- else {
- code = 0;
- }
- return;
-}
-#endif
-
-/*
- * Send new user information (re-login)
- */
-void user(argc, argv)
- int argc;
- char **argv;
-{
- char macct[80];
- int n, aflag = 0;
-
- if (argc < 2)
- (void) another(&argc, &argv, "username");
- if (argc < 2 || argc > 4) {
- printf("usage: %s username [password] [account]\n", argv[0]);
- code = -1;
- return;
- }
- n = command("USER %s", argv[1]);
- if (n == COMPLETE)
- n = command("PASS dummy");
- else if (n == CONTINUE) {
-#ifndef NOENCRYPTION
- int oldclevel;
-#endif
- if (argc < 3)
- argv[2] = mygetpass("Password: "), argc++;
-#ifndef NOENCRYPTION
- if ((oldclevel = clevel) == PROT_S) clevel = PROT_P;
-#endif
- n = command("PASS %s", argv[2]);
-#ifndef NOENCRYPTION
- /* level may have changed */
- if (clevel == PROT_P) clevel = oldclevel;
-#endif
- }
- if (n == CONTINUE) {
- if (argc < 4) {
- printf("Account: "); (void) fflush(stdout);
- (void) fgets(macct, sizeof(macct) - 1, stdin);
- macct[strlen(macct) - 1] = '\0';
- argv[3] = macct; argc++;
- }
- n = command("ACCT %s", argv[3]);
- aflag++;
- }
- if (n != COMPLETE) {
- fprintf(stdout, "Login failed.\n");
- /* code = -1;*/
- return;
- }
- if (!aflag && argc == 4) {
- (void) command("ACCT %s", argv[3]);
- }
- return;
-}
-
-/*
- * Print working directory.
- */
-/*VARARGS*/
-void pwd()
-{
- int oldverbose = verbose;
-
- /*
- * If we aren't verbose, this doesn't do anything!
- */
- verbose = 1;
- if (command("PWD") == ERROR && code == 500) {
- printf("PWD command not recognized, trying XPWD\n");
- (void) command("XPWD");
- }
- verbose = oldverbose;
-}
-
-/*
- * Make a directory.
- */
-void makedir(argc, argv)
- int argc;
- char *argv[];
-{
-
- if (argc < 2 && !another(&argc, &argv, "directory-name")) {
- printf("usage: %s directory-name\n", argv[0]);
- code = -1;
- return;
- }
- if (command("MKD %s", argv[1]) == ERROR && code == 500) {
- if (verbose)
- printf("MKD command not recognized, trying XMKD\n");
- (void) command("XMKD %s", argv[1]);
- }
-}
-
-/*
- * Remove a directory.
- */
-void removedir(argc, argv)
- int argc;
- char *argv[];
-{
-
- if (argc < 2 && !another(&argc, &argv, "directory-name")) {
- printf("usage: %s directory-name\n", argv[0]);
- code = -1;
- return;
- }
- if (command("RMD %s", argv[1]) == ERROR && code == 500) {
- if (verbose)
- printf("RMD command not recognized, trying XRMD\n");
- (void) command("XRMD %s", argv[1]);
- }
-}
-
-/*
- * Send a line, verbatim, to the remote machine.
- */
-void quote(argc, argv)
- int argc;
- char *argv[];
-{
-
- if (argc < 2 && !another(&argc, &argv, "command line to send")) {
- printf("usage: %s line-to-send\n", argv[0]);
- code = -1;
- return;
- }
- quote1("", argc, argv);
-}
-
-/*
- * Send a SITE command to the remote machine. The line
- * is sent verbatim to the remote machine, except that the
- * word "SITE" is added at the front.
- */
-void site(argc, argv)
- int argc;
- char *argv[];
-{
-
- if (argc < 2 && !another(&argc, &argv, "arguments to SITE command")) {
- printf("usage: %s line-to-send\n", argv[0]);
- code = -1;
- return;
- }
- quote1("SITE ", argc, argv);
-}
-
-/*
- * Turn argv[1..argc) into a space-separated string, then prepend initial text.
- * Send the result as a one-line command and get response.
- */
-static void quote1(initial, argc, argv)
- char *initial;
- int argc;
- char **argv;
-{
- register int i, len;
- char buf[FTP_BUFSIZ]; /* must be >= sizeof(line) */
-
- (void) strncpy(buf, initial, sizeof(buf) - 1);
- buf[sizeof(buf) - 1] = '\0';
- if (argc > 1) {
- len = strlen(buf);
- len += strlen(strncpy(&buf[len], argv[1], sizeof(buf) - 1 - len));
- for (i = 2; i < argc; i++) {
- buf[len++] = ' ';
- len += strlen(strncpy(&buf[len], argv[i], sizeof(buf) - 1 - len));
- }
- }
- if (command(buf) == PRELIM) {
- while (getreply(0) == PRELIM);
- }
-}
-
-void do_chmod(argc, argv)
- int argc;
- char *argv[];
-{
-
- if (argc < 2 && !another(&argc, &argv, "mode"))
- goto usage;
- if (argc < 3 && !another(&argc, &argv, "file-name")) {
-usage:
- printf("usage: %s mode file-name\n", argv[0]);
- code = -1;
- return;
- }
- (void) command("SITE CHMOD %s %s", argv[1], argv[2]);
-}
-
-void do_umask(argc, argv)
- int argc;
- char *argv[];
-{
- int oldverbose = verbose;
-
- verbose = 1;
- (void) command(argc == 1 ? "SITE UMASK" : "SITE UMASK %s", argv[1]);
- verbose = oldverbose;
-}
-
-void siteidle(argc, argv)
- int argc;
- char *argv[];
-{
- int oldverbose = verbose;
-
- verbose = 1;
- (void) command(argc == 1 ? "SITE IDLE" : "SITE IDLE %s", argv[1]);
- verbose = oldverbose;
-}
-
-/*
- * Ask the other side for help.
- */
-void rmthelp(argc, argv)
- int argc;
- char *argv[];
-{
- int oldverbose = verbose;
-
- verbose = 1;
- (void) command(argc == 1 ? "HELP" : "HELP %s", argv[1]);
- verbose = oldverbose;
-}
-
-/*
- * Terminate session and exit.
- */
-/*VARARGS*/
-void quit()
-{
-
- if (connected)
- disconnect();
- pswitch(1);
- if (connected) {
- disconnect();
- }
- exit(0);
-}
-
-/*
- * Terminate session, but don't exit.
- */
-void disconnect()
-{
- extern FILE *cout;
- extern SOCKET data;
-
- if (!connected)
- return;
- (void) command("QUIT");
- if (cout) {
- (void) FCLOSE_SOCKET(cout);
- cout = NULL;
- }
- connected = 0;
- data = INVALID_SOCKET;
- if (!proxy) {
- macnum = 0;
- }
- auth_type = NULL;
- dlevel = PROT_C;
-}
-
-static int confirm(cmd, file)
- char *cmd, *file;
-{
- char mline[FTP_BUFSIZ];
-
- if (!interactive)
- return (1);
- printf("%s %s? ", cmd, file);
- (void) fflush(stdout);
- if (fgets(mline, sizeof mline, stdin) == NULL)
- return (0);
- return (*mline != 'n' && *mline != 'N');
-}
-
-void fatal(msg)
- char *msg;
-{
-
- fprintf(stderr, "ftp: %s\n", msg);
- exit(1);
-}
-
-/*
- * Glob a local file name specification with
- * the expectation of a single return value.
- * Can't control multiple values being expanded
- * from the expression, we return only the first.
- */
-static int globulize(cpp)
- char **cpp;
-{
- char **globbed;
- char **globbed1;
-
- if (!doglob)
- return (1);
- globbed = ftpglob(*cpp);
- if (globerr != NULL) {
- printf("%s: %s\n", *cpp, globerr);
- if (globbed) {
- blkfree(globbed);
- free(globbed);
- }
- return (0);
- }
- if (globbed) {
- globbed1 = globbed;
- *cpp = *globbed1++;
- /* don't waste too much memory */
- if (*globbed) {
- blkfree(globbed1);
- free(globbed);
- }
- }
- return (1);
-}
-
-void account(argc,argv)
- int argc;
- char **argv;
-{
- char macct[50], *ap;
-
- if (argc > 1) {
- ++argv;
- --argc;
- (void) strncpy(macct,*argv,49);
- macct[49] = '\0';
- while (argc > 1) {
- --argc;
- ++argv;
- (void) strncat(macct,*argv, 49-strlen(macct));
- }
- ap = macct;
- }
- else {
- ap = mygetpass("Account:");
- }
- (void) command("ACCT %s", ap);
-}
-
-jmp_buf abortprox;
-
-static sigtype
-proxabort(int sig)
-{
- extern int proxy;
-
- if (!proxy) {
- pswitch(1);
- }
- if (connected) {
- proxflag = 1;
- }
- else {
- proxflag = 0;
- }
- pswitch(0);
- longjmp(abortprox,1);
-}
-
-void doproxy(argc,argv)
- int argc;
- char *argv[];
-{
- register struct cmd *c;
- struct cmd *getcmd();
- sig_t oldintr;
-
- if (argc < 2 && !another(&argc, &argv, "command")) {
- printf("usage: %s command\n", argv[0]);
- code = -1;
- return;
- }
- c = getcmd(argv[1]);
- if (c == (struct cmd *) -1) {
- printf("?Ambiguous command\n");
- (void) fflush(stdout);
- code = -1;
- return;
- }
- if (c == 0) {
- printf("?Invalid command\n");
- (void) fflush(stdout);
- code = -1;
- return;
- }
- if (!c->c_proxy) {
- printf("?Invalid proxy command\n");
- (void) fflush(stdout);
- code = -1;
- return;
- }
- if (setjmp(abortprox)) {
- code = -1;
- return;
- }
- oldintr = signal(SIGINT, proxabort);
- pswitch(1);
- if (c->c_conn && !connected) {
- printf("Not connected\n");
- (void) fflush(stdout);
- pswitch(0);
- (void) signal(SIGINT, oldintr);
- code = -1;
- return;
- }
- (*c->c_handler)(argc-1, argv+1);
- if (connected) {
- proxflag = 1;
- }
- else {
- proxflag = 0;
- }
- pswitch(0);
- (void) signal(SIGINT, oldintr);
-}
-
-void setcase()
-{
- mcase = !mcase;
- printf("Case mapping %s.\n", onoff(mcase));
- code = mcase;
-}
-
-void setcr()
-{
- crflag = !crflag;
- printf("Carriage Return stripping %s.\n", onoff(crflag));
- code = crflag;
-}
-
-void setntrans(argc,argv)
- int argc;
- char *argv[];
-{
- if (argc == 1) {
- ntflag = 0;
- printf("Ntrans off.\n");
- code = ntflag;
- return;
- }
- ntflag++;
- code = ntflag;
- (void) strncpy(ntin, argv[1], 16);
- ntin[16] = '\0';
- if (argc == 2) {
- ntout[0] = '\0';
- return;
- }
- (void) strncpy(ntout, argv[2], 16);
- ntout[16] = '\0';
-}
-
-static char *
-dotrans(name)
- char *name;
-{
- static char new[MAXPATHLEN];
- char *cp1, *cp2 = new;
- register int i, ostop, found;
-
- for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++);
- for (cp1 = name; *cp1; cp1++) {
- found = 0;
- for (i = 0; *(ntin + i) && i < 16; i++) {
- if (*cp1 == *(ntin + i)) {
- found++;
- if (i < ostop) {
- *cp2++ = *(ntout + i);
- }
- break;
- }
- }
- if (!found) {
- *cp2++ = *cp1;
- }
- }
- *cp2 = '\0';
- return(new);
-}
-
-void setnmap(argc, argv)
- int argc;
- char *argv[];
-{
- char *cp;
-
- if (argc == 1) {
- mapflag = 0;
- printf("Nmap off.\n");
- code = mapflag;
- return;
- }
- if (argc < 3 && !another(&argc, &argv, "mapout")) {
- printf("Usage: %s [mapin mapout]\n",argv[0]);
- code = -1;
- return;
- }
- mapflag = 1;
- code = 1;
- cp = strchr(altarg, ' ');
- if (proxy) {
- while(*++cp == ' ');
- altarg = cp;
- cp = strchr(altarg, ' ');
- }
- *cp = '\0';
- (void) strncpy(mapin, altarg, MAXPATHLEN - 1);
- while (*++cp == ' ');
- (void) strncpy(mapout, cp, MAXPATHLEN - 1);
-}
-
-static char *
-domap(name)
- char *name;
-{
- static char new[MAXPATHLEN];
- register char *cp1 = name, *cp2 = mapin;
- char *tp[9], *te[9];
- int i, toks[9], toknum = 0, match = 1;
-
- for (i=0; i < 9; ++i) {
- toks[i] = 0;
- }
- while (match && *cp1 && *cp2) {
- switch (*cp2) {
- case '\\':
- if (*++cp2 != *cp1) {
- match = 0;
- }
- break;
- case '$':
- if (*(cp2+1) >= '1' && (*cp2+1) <= '9') {
- if (*cp1 != *(++cp2+1)) {
- toks[toknum = *cp2 - '1']++;
- tp[toknum] = cp1;
- while (*++cp1 && *(cp2+1)
- != *cp1);
- te[toknum] = cp1;
- }
- cp2++;
- break;
- }
- /* FALLTHROUGH */
- default:
- if (*cp2 != *cp1) {
- match = 0;
- }
- break;
- }
- if (match && *cp1) {
- cp1++;
- }
- if (match && *cp2) {
- cp2++;
- }
- }
- if (!match && *cp1) /* last token mismatch */
- {
- toks[toknum] = 0;
- }
- cp1 = new;
- *cp1 = '\0';
- cp2 = mapout;
- while (*cp2) {
- match = 0;
- switch (*cp2) {
- case '\\':
- if (*(cp2 + 1)) {
- *cp1++ = *++cp2;
- }
- break;
- case '[':
-LOOP:
- if (*++cp2 == '$' && isdigit((int) *(cp2+1))) {
- if (*++cp2 == '0') {
- char *cp3 = name;
-
- while (*cp3) {
- *cp1++ = *cp3++;
- }
- match = 1;
- }
- else if (toks[toknum = *cp2 - '1']) {
- char *cp3 = tp[toknum];
-
- while (cp3 != te[toknum]) {
- *cp1++ = *cp3++;
- }
- match = 1;
- }
- }
- else {
- while (*cp2 && *cp2 != ',' &&
- *cp2 != ']') {
- if (*cp2 == '\\') {
- cp2++;
- }
- else if (*cp2 == '$' &&
- isdigit((int) *(cp2+1))) {
- if (*++cp2 == '0') {
- char *cp3 = name;
-
- while (*cp3) {
- *cp1++ = *cp3++;
- }
- }
- else if (toks[toknum =
- *cp2 - '1']) {
- char *cp3=tp[toknum];
-
- while (cp3 !=
- te[toknum]) {
- *cp1++ = *cp3++;
- }
- }
- }
- else if (*cp2) {
- *cp1++ = *cp2++;
- }
- }
- if (!*cp2) {
- printf("nmap: unbalanced brackets\n");
- return(name);
- }
- match = 1;
- cp2--;
- }
- if (match) {
- while (*++cp2 && *cp2 != ']') {
- if (*cp2 == '\\' && *(cp2 + 1)) {
- cp2++;
- }
- }
- if (!*cp2) {
- printf("nmap: unbalanced brackets\n");
- return(name);
- }
- break;
- }
- switch (*++cp2) {
- case ',':
- goto LOOP;
- case ']':
- break;
- default:
- cp2--;
- goto LOOP;
- }
- break;
- case '$':
- if (isdigit((int) *(cp2 + 1))) {
- if (*++cp2 == '0') {
- char *cp3 = name;
-
- while (*cp3) {
- *cp1++ = *cp3++;
- }
- }
- else if (toks[toknum = *cp2 - '1']) {
- char *cp3 = tp[toknum];
-
- while (cp3 != te[toknum]) {
- *cp1++ = *cp3++;
- }
- }
- break;
- }
- /* intentional drop through */
- default:
- *cp1++ = *cp2;
- break;
- }
- cp2++;
- }
- *cp1 = '\0';
- if (!*new) {
- return(name);
- }
- return(new);
-}
-
-void setsunique()
-{
- sunique = !sunique;
- printf("Store unique %s.\n", onoff(sunique));
- code = sunique;
-}
-
-void setrunique()
-{
- runique = !runique;
- printf("Receive unique %s.\n", onoff(runique));
- code = runique;
-}
-
-/* change directory to perent directory */
-void cdup()
-{
- if (command("CDUP") == ERROR && code == 500) {
- if (verbose)
- printf("CDUP command not recognized, trying XCUP\n");
- (void) command("XCUP");
- }
-}
-
-/* restart transfer at specific point */
-void restart(argc, argv)
- int argc;
- char *argv[];
-{
- extern long atol();
- if (argc != 2)
- printf("restart: offset not specified\n");
- else {
- restart_point = atol(argv[1]);
- printf("restarting at %ld. %s\n", (long) restart_point,
- "execute get, put or append to initiate transfer");
- }
-}
-
-/* show remote system type */
-void syst()
-{
- (void) command("SYST");
-}
-
-void macdef(argc, argv)
- int argc;
- char *argv[];
-{
- char *tmp;
- int c;
-
- if (macnum == 16) {
- printf("Limit of 16 macros have already been defined\n");
- code = -1;
- return;
- }
- if (argc < 2 && !another(&argc, &argv, "macro name")) {
- printf("Usage: %s macro_name\n",argv[0]);
- code = -1;
- return;
- }
- if (interactive) {
- printf("Enter macro line by line, terminating it with a null line\n");
- }
- (void) strncpy(macros[macnum].mac_name, argv[1], 8);
- if (macnum == 0) {
- macros[macnum].mac_start = macbuf;
- }
- else {
- macros[macnum].mac_start = macros[macnum - 1].mac_end + 1;
- }
- tmp = macros[macnum].mac_start;
- while (tmp != macbuf+4096) {
- if ((c = getchar()) == EOF) {
- printf("macdef:end of file encountered\n");
- code = -1;
- return;
- }
- if ((*tmp = c) == '\n') {
- if (tmp == macros[macnum].mac_start) {
- macros[macnum++].mac_end = tmp;
- code = 0;
- return;
- }
- if (*(tmp-1) == '\0') {
- macros[macnum++].mac_end = tmp - 1;
- code = 0;
- return;
- }
- *tmp = '\0';
- }
- tmp++;
- }
- while (1) {
- while ((c = getchar()) != '\n' && c != EOF)
- /* LOOP */;
- if (c == EOF || getchar() == '\n') {
- printf("Macro not defined - 4k buffer exceeded\n");
- code = -1;
- return;
- }
- }
-}
-
-/*
- * get size of file on remote machine
- */
-void sizecmd(argc, argv)
- int argc;
- char *argv[];
-{
-
- if (argc < 2 && !another(&argc, &argv, "filename")) {
- printf("usage: %s filename\n", argv[0]);
- code = -1;
- return;
- }
- (void) command("SIZE %s", argv[1]);
-}
-
-/*
- * get last modification time of file on remote machine
- */
-void modtime(argc, argv)
- int argc;
- char *argv[];
-{
- int overbose;
-
- if (argc < 2 && !another(&argc, &argv, "filename")) {
- printf("usage: %s filename\n", argv[0]);
- code = -1;
- return;
- }
- overbose = verbose;
- if (debug == 0)
- verbose = -1;
- if (command("MDTM %s", argv[1]) == COMPLETE) {
- int yy, mo, day, hour, min, sec;
- sscanf(reply_string, "%*s %04d%02d%02d%02d%02d%02d", &yy, &mo,
- &day, &hour, &min, &sec);
- /* might want to print this in local time */
- printf("%s\t%02d/%02d/%04d %02d:%02d:%02d GMT\n", argv[1],
- mo, day, yy, hour, min, sec);
- } else
- printf("%s\n", reply_string);
- verbose = overbose;
-}
-
-/*
- * show status on remote machine
- */
-void rmtstatus(argc, argv)
- int argc;
- char *argv[];
-{
- (void) command(argc > 1 ? "STAT %s" : "STAT" , argv[1]);
-}
-
-/*
- * get file if modtime is more recent than current file
- */
-void newer(argc, argv)
- int argc;
- char *argv[];
-{
- if (getit(argc, argv, -1, "w"))
- printf("Local file \"%s\" is newer than remote file \"%s\"\n",
- argv[1], argv[2]);
-}
-
-#ifndef NO_PASSIVE_MODE
-/*
- * Start up passive mode interaction
- */
-
-/*VARARGS*/
-void setpassive()
-{
-
- passivemode = !passivemode;
- printf("Passive mode %s.\n", onoff(passivemode));
- code = passivemode;
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 1985, 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 lint
-static char sccsid[] = "@(#)cmdtab.c 5.10 (Berkeley) 6/1/90";
-#endif /* not lint */
-
-#include <stdio.h>
-#include "ftp_var.h"
-
-/*
- * User FTP -- Command Tables.
- */
-
-char accounthelp[] = "send account command to remote server";
-char appendhelp[] = "append to a file";
-char asciihelp[] = "set ascii transfer type";
-char beephelp[] = "beep when command completed";
-char binaryhelp[] = "set binary transfer type";
-char casehelp[] = "toggle mget upper/lower case id mapping";
-char ccchelp[] = "set clear protection level for commands";
-char cdhelp[] = "change remote working directory";
-char cduphelp[] = "change remote working directory to parent directory";
-char chmodhelp[] = "change file permissions of remote file";
-char clearhelp[] = "set clear protection level for file transfer";
-char connecthelp[] = "connect to remote ftp";
-char crhelp[] = "toggle carriage return stripping on ascii gets";
-char deletehelp[] = "delete remote file";
-char debughelp[] = "toggle/set debugging mode";
-char dirhelp[] = "list contents of remote directory";
-char disconhelp[] = "terminate ftp session";
-char domachelp[] = "execute macro";
-char formhelp[] = "set file transfer format";
-char globhelp[] = "toggle metacharacter expansion of local file names";
-char hashhelp[] = "toggle printing `#' for each buffer transferred";
-char helphelp[] = "print local help information";
-char idlehelp[] = "get (set) idle timer on remote side";
-char lcdhelp[] = "change local working directory";
-char levelhelp[] = "set protection level for file transfer";
-char clevelhelp[] = "set protection level for commands";
-char lshelp[] = "list contents of remote directory";
-char macdefhelp[] = "define a macro";
-char mdeletehelp[] = "delete multiple files";
-char mdirhelp[] = "list contents of multiple remote directories";
-char mgethelp[] = "get multiple files";
-char mkdirhelp[] = "make directory on the remote machine";
-char mlshelp[] = "list contents of multiple remote directories";
-char modtimehelp[] = "show last modification time of remote file";
-char modehelp[] = "set file transfer mode";
-char mputhelp[] = "send multiple files";
-char newerhelp[] = "get file if remote file is newer than local file ";
-char nlisthelp[] = "nlist contents of remote directory";
-char nmaphelp[] = "set templates for default file name mapping";
-char ntranshelp[] = "set translation table for default file name mapping";
-char porthelp[] = "toggle use of PORT cmd for each data connection";
-#ifndef NOENCRYPTION
-char privatehelp[] = "set private protection level for file transfer";
-#endif
-char prompthelp[] = "force interactive prompting on multiple commands";
-char proxyhelp[] = "issue command on alternate connection";
-char pwdhelp[] = "print working directory on remote machine";
-char quithelp[] = "terminate ftp session and exit";
-char quotehelp[] = "send arbitrary ftp command";
-char receivehelp[] = "receive file";
-char regethelp[] = "get file restarting at end of local file";
-char remotehelp[] = "get help from remote server";
-char renamehelp[] = "rename file";
-char restarthelp[]= "restart file transfer at bytecount";
-char rmdirhelp[] = "remove directory on the remote machine";
-char rmtstatushelp[]="show status of remote machine";
-char runiquehelp[] = "toggle store unique for local files";
-char resethelp[] = "clear queued command replies";
-char safehelp[] = "set safe protection level for file transfer";
-char sendhelp[] = "send one file";
-char sitehelp[] = "send site specific command to remote server\n\t\tTry \"rhelp site\" or \"site help\" for more information";
-char shellhelp[] = "escape to the shell";
-char sizecmdhelp[] = "show size of remote file";
-char statushelp[] = "show current status";
-char structhelp[] = "set file transfer structure";
-char suniquehelp[] = "toggle store unique on remote machine";
-char systemhelp[] = "show remote system type";
-char tenexhelp[] = "set tenex file transfer type";
-char tracehelp[] = "toggle packet tracing";
-char typehelp[] = "set file transfer type";
-char umaskhelp[] = "get (set) umask on remote side";
-char userhelp[] = "send new user information";
-char verbosehelp[] = "toggle verbose mode";
-#ifndef NO_PASSIVE_MODE
-char setpassivehelp[] = "toggle passive transfer mode";
-#endif
-
-struct cmd cmdtab[] = {
- { "!", shellhelp, 0, 0, 0, shell },
- { "$", domachelp, 1, 0, 0, domacro },
- { "account", accounthelp, 0, 1, 1, account},
- { "append", appendhelp, 1, 1, 1, put },
- { "ascii", asciihelp, 0, 1, 1, setascii },
- { "bell", beephelp, 0, 0, 0, setbell },
- { "binary", binaryhelp, 0, 1, 1, setbinary },
- { "bye", quithelp, 0, 0, 0, quit },
- { "case", casehelp, 0, 0, 1, setcase },
- { "ccc", ccchelp, 0, 1, 1, ccc },
- { "cd", cdhelp, 0, 1, 1, cd },
- { "cdup", cduphelp, 0, 1, 1, cdup },
- { "chmod", chmodhelp, 0, 1, 1, do_chmod },
- { "clear", clearhelp, 0, 1, 1, setclear },
- { "close", disconhelp, 0, 1, 1, disconnect },
- { "cprotect", clevelhelp, 0, 1, 1, setclevel },
- { "cr", crhelp, 0, 0, 0, setcr },
- { "delete", deletehelp, 0, 1, 1, delete_file },
- { "debug", debughelp, 0, 0, 0, setdebug },
- { "dir", dirhelp, 1, 1, 1, ls },
- { "disconnect", disconhelp, 0, 1, 1, disconnect },
- { "form", formhelp, 0, 1, 1, setform },
- { "get", receivehelp, 1, 1, 1, get },
- { "glob", globhelp, 0, 0, 0, setglob },
- { "hash", hashhelp, 0, 0, 0, sethash },
- { "help", helphelp, 0, 0, 1, help },
- { "idle", idlehelp, 0, 1, 1, siteidle },
- { "image", binaryhelp, 0, 1, 1, setbinary },
- { "lcd", lcdhelp, 0, 0, 0, lcd },
- { "ls", lshelp, 1, 1, 1, ls },
- { "macdef", macdefhelp, 0, 0, 0, macdef },
- { "mdelete", mdeletehelp, 1, 1, 1, mdelete },
- { "mdir", mdirhelp, 1, 1, 1, mls },
- { "mget", mgethelp, 1, 1, 1, mget },
- { "mkdir", mkdirhelp, 0, 1, 1, makedir },
- { "mls", mlshelp, 1, 1, 1, mls },
- { "mode", modehelp, 0, 1, 1, set_mode },
- { "modtime", modtimehelp, 0, 1, 1, modtime },
- { "mput", mputhelp, 1, 1, 1, mput },
- { "newer", newerhelp, 1, 1, 1, newer },
- { "nmap", nmaphelp, 0, 0, 1, setnmap },
- { "nlist", nlisthelp, 1, 1, 1, ls },
- { "ntrans", ntranshelp, 0, 0, 1, setntrans },
- { "open", connecthelp, 0, 0, 1, setpeer },
-#ifndef NO_PASSIVE_MODE
- { "passive", setpassivehelp, 0, 0, 0, setpassive },
-#endif
-#ifndef NOENCRYPTION
- { "private", privatehelp, 0, 1, 1, setprivate },
-#endif
- { "prompt", prompthelp, 0, 0, 0, setprompt },
- { "protect", levelhelp, 0, 1, 1, setdlevel },
- { "proxy", proxyhelp, 0, 0, 1, doproxy },
- { "sendport", porthelp, 0, 0, 0, setport },
- { "put", sendhelp, 1, 1, 1, put },
- { "pwd", pwdhelp, 0, 1, 1, pwd },
- { "quit", quithelp, 0, 0, 0, quit },
- { "quote", quotehelp, 1, 1, 1, quote },
- { "recv", receivehelp, 1, 1, 1, get },
- { "reget", regethelp, 1, 1, 1, reget },
- { "rstatus", rmtstatushelp, 0, 1, 1, rmtstatus },
- { "rhelp", remotehelp, 0, 1, 1, rmthelp },
- { "rename", renamehelp, 0, 1, 1, renamefile },
- { "reset", resethelp, 0, 1, 1, reset },
- { "restart", restarthelp, 1, 1, 1, restart },
- { "rmdir", rmdirhelp, 0, 1, 1, removedir },
- { "runique", runiquehelp, 0, 0, 1, setrunique },
- { "safe", safehelp, 0, 1, 1, setsafe },
- { "send", sendhelp, 1, 1, 1, put },
- { "site", sitehelp, 0, 1, 1, site },
- { "size", sizecmdhelp, 1, 1, 1, sizecmd },
- { "status", statushelp, 0, 0, 1, status },
- { "struct", structhelp, 0, 1, 1, setstruct },
- { "system", systemhelp, 0, 1, 1, syst },
- { "sunique", suniquehelp, 0, 0, 1, setsunique },
- { "tenex", tenexhelp, 0, 1, 1, settenex },
- { "trace", tracehelp, 0, 0, 0, settrace },
- { "type", typehelp, 0, 1, 1, settype },
- { "user", userhelp, 0, 1, 1, user },
- { "umask", umaskhelp, 0, 1, 1, do_umask },
- { "verbose", verbosehelp, 0, 0, 0, setverbose },
- { "?", helphelp, 0, 0, 1, help },
- { 0 },
-};
-
-int NCMDS = (sizeof (cmdtab) / sizeof (cmdtab[0])) - 1;
+++ /dev/null
-#
-# Generated makefile dependencies follow.
-#
-$(OUTPRE)cmds.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/port-sockets.h $(srcdir)/../arpa/ftp.h \
- cmds.c ftp_var.h pathnames.h
-$(OUTPRE)cmdtab.$(OBJEXT): cmdtab.c ftp_var.h
-$(OUTPRE)domacro.$(OBJEXT): domacro.c ftp_var.h
-$(OUTPRE)ftp.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
- $(BUILDTOP)/include/gssapi/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \
- $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-platform.h \
- $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \
- $(SRCTOP)/include/port-sockets.h $(srcdir)/../arpa/ftp.h \
- $(srcdir)/../arpa/telnet.h ftp.c ftp_var.h secure.h
-$(OUTPRE)getpass.$(OBJEXT): ftp_var.h getpass.c
-$(OUTPRE)glob.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \
- ftp_var.h glob.c
-$(OUTPRE)main.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(SRCTOP)/include/port-sockets.h $(srcdir)/../arpa/ftp.h \
- ftp_var.h main.c
-$(OUTPRE)radix.$(OBJEXT): ftp_var.h radix.c
-$(OUTPRE)ruserpass.$(OBJEXT): ftp_var.h ruserpass.c
-$(OUTPRE)secure.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_generic.h \
- $(srcdir)/../arpa/ftp.h secure.c secure.h
+++ /dev/null
-/*
- * Copyright (c) 1985 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 lint
-static char sccsid[] = "@(#)domacro.c 1.8 (Berkeley) 9/28/90";
-#endif /* not lint */
-
-#include <stdio.h>
-#include <signal.h>
-
-#include "ftp_var.h"
-
-#include <errno.h>
-#include <ctype.h>
-#include <string.h>
-
-void domacro(argc, argv)
- int argc;
- char *argv[];
-{
- register int i, j;
- register char *cp1, *cp2;
- int count = 2, loopflg = 0;
- char line2[200];
- extern char **glob();
- struct cmd *getcmd(), *c;
-
- if (argc < 2 && !another(&argc, &argv, "macro name")) {
- printf("Usage: %s macro_name.\n", argv[0]);
- code = -1;
- return;
- }
- for (i = 0; i < macnum; ++i) {
- if (!strncmp(argv[1], macros[i].mac_name, 9)) {
- break;
- }
- }
- if (i == macnum) {
- printf("'%s' macro not found.\n", argv[1]);
- code = -1;
- return;
- }
- (void) strncpy(line2, line, sizeof(line2) - 1);
- line2[sizeof(line2) - 1] = '\0';
-TOP:
- cp1 = macros[i].mac_start;
- while (cp1 != macros[i].mac_end) {
- while (isspace((int) *cp1)) {
- cp1++;
- }
- cp2 = line;
- while (*cp1 != '\0') {
- switch(*cp1) {
- case '\\':
- *cp2++ = *++cp1;
- break;
- case '$':
- if (isdigit((int) *(cp1+1))) {
- j = 0;
- while (isdigit((int) (*++cp1))) {
- j = 10*j + *cp1 - '0';
- }
- cp1--;
- if (argc - 2 >= j) {
- if(cp2 + strlen(argv[j+1]) - line < sizeof(line))
- (void) strncpy(cp2, argv[j+1],
- sizeof(line) - 1 -
- (cp2 - line));
- line[sizeof(line) - 1] = '\0';
- cp2 += strlen(argv[j+1]);
- }
- break;
- }
- if (*(cp1+1) == 'i') {
- loopflg = 1;
- cp1++;
- if (count < argc) {
- if(cp2 + strlen(argv[count]) - line < sizeof(line))
- (void) strncpy(cp2, argv[count],
- sizeof(line) - 1 -
- (cp2 - line));
- line[sizeof(line) - 1] = '\0';
- cp2 += strlen(argv[count]);
- }
- break;
- }
- /* intentional drop through */
- default:
- *cp2++ = *cp1;
- break;
- }
- if (*cp1 != '\0') {
- cp1++;
- }
- }
- *cp2 = '\0';
- makeargv();
- c = getcmd(margv[0]);
- if (c == (struct cmd *)-1) {
- printf("?Ambiguous command\n");
- code = -1;
- }
- else if (c == 0) {
- printf("?Invalid command\n");
- code = -1;
- }
- else if (c->c_conn && !connected) {
- printf("Not connected.\n");
- code = -1;
- }
- else {
- if (verbose) {
- printf("%s\n",line);
- }
- (*c->c_handler)(margc, margv);
- if (bell && c->c_bell) {
- (void) putchar('\007');
- }
- (void) strncpy(line, line2, sizeof(line) - 1);
- line[sizeof(line) - 1] = '\0';
- makeargv();
- argc = margc;
- argv = margv;
- }
- if (cp1 != macros[i].mac_end) {
- cp1++;
- }
- }
- if (loopflg && ++count < argc) {
- goto TOP;
- }
-}
+++ /dev/null
-.\" Copyright (c) 1985, 1989, 1990 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.
-.\"
-.\" @(#)ftp.1 6.18 (Berkeley) 7/30/91
-.\" "
-.TH FTP 1
-.SH NAME
-ftp \- ARPANET file transfer program
-.SH SYNOPSIS
-.B ftp
-[\fB\-v\fP] [\fB\-d\fP] [\fB\-i\fP] [\fB\-n\fP] [\fB\-g\fP] [\fB\-k\fP
-\fIrealm\fP] [\fB\-f\fP] [\fB\-x\fP] [\fB\-u\fP] [\fB\-t\fP] [\fIhost\fP]
-.SH DESCRIPTION
-.B FTP
-is the user interface to the
-.SM ARPANET
-standard File Transfer Protocol. The program allows a user to transfer
-files to and from a remote network site.
-.SH OPTIONS
-Options may be specified at the command line, or to the command
-interpreter.
-.TP
-.B \-v
-Verbose option forces
-.B ftp
-to show all responses from the remote server, as well as report on data
-transfer statistics.
-.TP
-.B \-n
-Restrains
-.B ftp
-from attempting ``auto-login'' upon initial connection. If auto-login
-is enabled,
-.B ftp
-will check the
-.I .netrc
-(see below) file in the user's home directory for an entry describing an
-account on the remote machine. If no entry exists,
-.B ftp
-will prompt for the remote machine login name (default is the user
-identity on the local machine), and, if necessary, prompt for a password
-and an account with which to login.
-.TP
-.B \-u
-Restrains
-.B ftp
-from attempting ``auto-authentication'' upon initial connection. If
-auto-authentication is enabled,
-.B ftp
-attempts to authenticate to the
-.SM FTP
-server by sending the
-.SM AUTH
-command, using whichever authentication types are locally supported.
-Once an authentication type is accepted, an authentication protocol
-will proceed by issuing
-.SM ADAT
-commands. This option also disables auto-login.
-.TP
-.B \-i
-Turns off interactive prompting during multiple file transfers.
-.TP
-.B \-d
-Enables debugging.
-.TP
-.B \-g
-Disables file name globbing.
-.TP
-.B \-f
-Causes credentials to be forwarded to the remote host.
-.TP
-.B \-x
-Causes the client to attempt to negotiate encryption (data and command
-protection levels ``private'') immediately after successfully
-authenticating.
-.TP
-.B \-t
-Enables packet tracing.
-.SH COMMANDS
-The client host with which
-.B ftp
-is to communicate may be specified on the command line. If this is
-done,
-.B ftp
-will immediately attempt to establish a connection to an
-.SM FTP
-server on that host; otherwise,
-.B ftp
-will enter its command interpreter and await instructions from the user.
-When
-.B ftp
-is awaiting commands from the user the prompt
-``ftp>''
-is provided to the user. The following commands are recognized by
-.BR ftp :
-.TP
-\fB\&!\fP [\fIcommand\fP] [\fIargs\fP]]
-Invoke an interactive shell on the local machine. If there are
-arguments, the first is taken to be a command to execute directly, with
-the rest of the arguments as its arguments.
-.TP
-\fB\&$\fP \fImacro-name\fP [\fIargs\fP]
-Execute the macro
-.I macro-name
-that was defined with the
-.B macdef
-command. Arguments are passed to the macro unglobbed.
-.TP
-\fBaccount\fP [\fIpasswd\fP]
-Supply a supplemental password required by a remote system for access to
-resources once a login has been successfully completed. If no argument
-is included, the user will be prompted for an account password in a
-non-echoing input mode.
-.TP
-\fBappend\fP \fIlocal-file\fP [\fIremote-file\fP]
-Append a local file to a file on the remote machine. If
-.I remote-file
-is left unspecified, the local file name is used in naming the remote
-file after being altered by any
-.B ntrans
-or
-.B nmap
-setting. File transfer uses the current settings for
-.BR type ,
-.BR format ,
-.BR mode ,
-and
-.BR structure .
-.TP
-.B ascii
-Set the file transfer
-.B type
-to network
-.SM ASCII .
-This is the default type.
-.TP
-.B bell
-Arrange that a bell be sounded after each file transfer command is
-completed.
-.TP
-.B binary
-Set the file transfer
-.B type
-to support binary file transfer.
-.TP
-.B bye
-Terminate the
-.SM FTP
-session with the remote server and exit
-.BR ftp .
-An end of file will also terminate the session and exit.
-.TP
-.B case
-Toggle remote computer file name case mapping during
-.B mget
-commands. When
-.B case
-is on (default is off), remote computer file names with all letters in
-upper case are written in the local directory with the letters mapped to
-lower case.
-.TP
-.B ccc
-Turn off integrity protection on the command channel. This command
-must be sent integrity protected, and must be proceeded by a successful
-.SM ADAT
-command. Since turning off integrity protection potentially
-allows an attacker to insert commands onto the command channel, some
-.SM FTP
-servers may refuse to honor this command.
-.TP
-\fBcd\fP \fIremote-directory\fP
-Change the working directory on the remote machine to
-.IR remote-directory .
-.TP
-.B cdup
-Change the remote machine working directory to the parent of the current
-remote machine working directory.
-.TP
-\fBchmod\fP \fImode\fP \fIfile-name\fP
-Change the permission modes of the file
-.I file-name
-on the remote system to
-.IR mode .
-.TP
-.B clear
-Set the protection level on data transfers to ``clear''. If no
-.SM ADAT
-command succeeded, then this is the default protection level.
-.TP
-.B close
-Terminate the
-.SM FTP
-session with the remote server, and return to the command interpreter.
-Any defined macros are erased.
-.TP
-\fBcprotect\fP [\fIprotection-level\fP]
-Set the protection level on commands to
-.IR protection-level .
-The valid protection levels are ``clear'' for unprotected commands,
-``safe'' for commands integrity protected by
-cryptographic checksum, and ``private'' for commands
-confidentiality and integrity protected by encryption. If an
-.SM ADAT
-command succeeded, then the default command protection level is
-``safe'', otherwise the only possible level is ``clear''. If no
-level is specified, the current level is printed.
-.B cprotect clear
-is equivalent to the
-.B ccc
-command.
-.TP
-.B cr
-Toggle carriage return stripping during ascii type file retrieval.
-Records are denoted by a carriage return/linefeed sequence during ascii
-type file transfer. When
-.B cr
-is on (the default), carriage returns are stripped from this sequence to
-conform with the
-.SM UNIX
-single linefeed record delimiter. Records on non-UNIX remote systems
-may contain single linefeeds; when an ascii type transfer is made, these
-linefeeds may be distinguished from a record delimiter only when
-.B cr
-is off.
-.TP
-\fBdelete\fP \fIremote-file\fP
-Delete the file
-.I remote-file
-on the remote machine.
-.TP
-\fBdebug\fP [\fIdebug-value\fP]
-Toggle debugging mode. If an optional
-.I debug-value
-is specified it is used to set the debugging level. When debugging is
-on,
-.B ftp
-prints each command sent to the remote machine, preceded by the string
-`\-\->'
-.TP
-\fBdir\fP [\fIremote-directory\fP] [\fIlocal-file\fP]
-Print a listing of the directory contents in the directory,
-.IR remote-directory ,
-and, optionally, placing the output in
-.IR local-file .
-If interactive prompting is on,
-.B ftp
-will prompt the user to verify that the last argument is indeed the
-target local file for receiving
-.B dir
-output. If no directory is specified, the current working directory on
-the remote machine is used. If no local file is specified, or
-.I local-file
-is
-`\fB\-\fP',
-output comes to the terminal.
-.TP
-.B disconnect
-A synonym for
-.IR close .
-.TP
-\fBform\fP \fIformat\fP
-Set the file transfer
-.B form
-to
-.IR format .
-The default format is ``file''.
-.TP
-\fBget\fP \fIremote-file\fP [\fIlocal-file\fP]
-Retrieve the file
-.I remote-file
-and store it on the local machine. If the local file name is not
-specified, it is given the same name it has on the remote machine,
-subject to alteration by the current
-.BR case ,
-.BR ntrans ,
-and
-.B nmap
-settings. The current settings for
-.BR type ,
-.BR form ,
-.BR mode ,
-and
-.B structure
-are used while transferring the file.
-.TP
-.B glob
-Toggle filename expansion for
-.BR mdelete ,
-.BR mget ,
-and
-.BR mput .
-If globbing is turned off with
-.BR glob ,
-the file name arguments are taken literally and not expanded. Globbing
-for
-.B mput
-is done as in
-.IR csh (1).
-For
-.B mdelete
-and
-.BR mget ,
-each remote file name is expanded separately on the remote machine and
-the lists are not merged. Expansion of a directory name is likely to be
-different from expansion of the name of an ordinary file: the exact
-result depends on the foreign operating system and ftp server, and can
-be previewed by doing
-`mls remote-files \-'
-Note:
-.B mget
-and
-.B mput
-are not meant to transfer entire directory subtrees of files. That can
-be done by transferring a
-.IR tar (1)
-archive of the subtree (in binary mode).
-.TP
-.B hash
-Toggle hash-sign (``#'') printing for each data block transferred. The
-size of a data block is 1024 bytes.
-.TP
-\fBhelp\fP [\fIcommand\fP]
-Print an informative message about the meaning of
-.IR command .
-If no argument is given,
-.B ftp
-prints a list of the known commands.
-.TP
-\fBidle\fP [\fIseconds\fP]
-Set the inactivity timer on the remote server to
-.I seconds
-seconds. If
-.I seconds
-is omitted, the current inactivity timer is printed.
-.TP
-\fBlcd\fP [\fIdirectory\fP]
-Change the working directory on the local machine. If no
-.I directory
-is specified, the user's home directory is used.
-.TP
-\fBls\fP [\fIremote-directory\fP] [\fIlocal-file\fP]
-Print a listing of the contents of a directory on the remote machine.
-The listing includes any system-dependent information that the server
-chooses to include; for example, most
-.SM UNIX
-systems will produce output from the command `ls \-l'. (See also
-.BR nlist .)
-If
-.I remote-directory
-is left unspecified, the current working directory is used. If
-interactive prompting is on,
-.B ftp
-will prompt the user to verify that the last argument is indeed the
-target local file for receiving
-.B ls
-output. If no local file is specified, or if
-.I local-file
-is
-`\fB\-\fP',
-the output is sent to the terminal.
-.TP
-\fBmacdef\fP\fImacro-name\fP
-Define a macro. Subsequent lines are stored as the macro
-.IR macro-name ;
-a null line (consecutive newline characters in a file or carriage
-returns from the terminal) terminates macro input mode. There is a
-limit of 16 macros and 4096 total characters in all defined macros.
-Macros remain defined until a
-.B close
-command is executed. The macro processor interprets `$' and `\e' as
-special characters. A `$' followed by a number (or numbers) is replaced
-by the corresponding argument on the macro invocation command line. A
-`$' followed by an `i' signals that macro processor that the executing
-macro is to be looped. On the first pass `$i' is replaced by the first
-argument on the macro invocation command line, on the second pass it is
-replaced by the second argument, and so on. A `\e' followed by any
-character is replaced by that character. Use the `\e' to prevent
-special treatment of the `$'.
-.TP
-\fBmdelete\fP [\fIremote-files\fP]
-Delete
-.I remote-files
-on the remote machine.
-.TP
-\fBmdir\fP \fIremote-files\fP \fIlocal-file\fP
-Like
-.BR dir ,
-except multiple remote files may be specified. If interactive prompting
-is on,
-.B ftp
-will prompt the user to verify that the last argument is indeed the
-target local file for receiving
-.B mdir
-output.
-.TP
-\fBmget\fP \fIremote-files\fP
-Expand the
-.I remote-files
-on the remote machine and do a
-.B get
-for each file name thus produced. See
-.B glob
-for details on the filename expansion. Resulting file names will then
-be processed according to
-.BR case ,
-.BR ntrans ,
-and
-.B nmap
-settings. Files are transferred into the local working directory, which
-can be changed with `lcd directory'; new local directories can be
-created with
-`\&! mkdir directory'.
-.TP
-\fBmkdir\fP \fIdirectory-name\fP
-Make a directory on the remote machine.
-.TP
-\fBmls\fP \fIremote-files\fP \fIlocal-file\fP
-Like
-.BR nlist ,
-except multiple remote files may be specified, and the
-.I local-file
-must be specified. If interactive prompting is on,
-.B ftp
-will prompt the user to verify that the last argument is indeed the
-target local file for receiving
-.B mls
-output.
-.TP
-\fBmode\fP [\fImode-name\fP]
-Set the file transfer
-.B mode
-to
-.IR mode-name .
-The default mode is ``stream'' mode.
-.TP
-\fBmodtime\fP \fIfile-name\fP
-Show the last modification time of the file on the remote machine.
-.TP
-\fBmput\fP \fIlocal-files\fP
-Expand wild cards in the list of local files given as arguments and do a
-.B put
-for each file in the resulting list. See
-.B glob
-for details of filename expansion. Resulting file names will then be
-processed according to
-.B ntrans
-and
-.B nmap
-settings.
-.TP
-\fBnewer\fP \fIfile-name\fP
-Get the file only if the modification time of the remote file is more
-recent that the file on the current system. If the file does not exist
-on the current system, the remote file is considered
-.BR newer .
-Otherwise, this command is identical to
-.BR get .
-.TP
-\fBnlist\fP [\fIremote-directory\fP] [\fIlocal-file\fP]
-Print a list of the files in a directory on the remote machine. If
-.I remote-directory
-is left unspecified, the current working directory is used. If
-interactive prompting is on,
-.B ftp
-will prompt the user to verify that the last argument is indeed the
-target local file for receiving
-.B nlist
-output. If no local file is specified, or if
-.I local-file
-is `\fB\-\fP', the output is sent to the terminal.
-.TP
-\fBnmap\fP [\fIinpattern\fP \fIoutpattern\fP]
-Set or unset the filename mapping mechanism. If no arguments are
-specified, the filename mapping mechanism is unset. If arguments are
-specified, remote filenames are mapped during
-.B mput
-commands and
-.B put
-commands issued without a specified remote target filename.
-If arguments are specified, local filenames are mapped during
-.B mget
-commands and
-.B get
-commands issued without a specified local target filename. This command
-is useful when connecting to non\-UNIX remote computer with different
-file naming conventions or practices. The mapping follows the pattern
-set by
-.I inpattern
-and
-.IR outpattern .
-[\fIInpattern\fP] is a template for incoming filenames (which may have
-already been processed according to the
-.B ntrans
-and
-.B case
-settings). Variable templating is accomplished by including the
-sequences `$1', `$2', ..., `$9' in
-.IR inpattern .
-Use `\e' to prevent this special treatment of the `$' character. All
-other characters are treated literally, and are used to determine the
-.B nmap
-[\fIinpattern\fP] variable values. For example, given
-.I inpattern
-$1.$2 and the remote file name "mydata.data", $1 would have the value
-"mydata", and $2 would have the value "data". The
-.I outpattern
-determines the resulting mapped filename. The sequences `$1', `$2',
-\&..., `$9' are replaced by any value resulting from the
-.I inpattern
-template. The sequence `$0' is replace by the original filename.
-Additionally, the sequence `[\fIseq1\fP, \fIseq2\fP]' is replaced by
-[\fIseq1\fP] if
-.I seq1
-is not a null string; otherwise it is replaced by
-.IR seq2 .
-For example, the command
-.sp
-.nf
- nmap $1.$2.$3 [$1,$2].[$2,file]
-.fi
-.sp
-would yield the output filename "myfile.data" for input filenames
-"myfile.data" and "myfile.data.old", "myfile.file" for the input
-filename "myfile", and "myfile.myfile" for the input filename ".myfile".
-Spaces may be included in
-.IR outpattern ,
-as in the example: `nmap $1 sed "s/ *$//" > $1'. Use the `\e' character
-to prevent special treatment of the `$','[',']', and `,' characters.
-.TP
-\fBntrans\fP [\fIinchars\fP [\fIoutchars\fP]]
-Set or unset the filename character translation mechanism. If no
-arguments are specified, the filename character translation mechanism is
-unset. If arguments are specified, characters in remote filenames are
-translated during
-.B mput
-commands and
-.B put
-commands issued without a specified remote target filename. If
-arguments are specified, characters in local filenames are translated
-during
-.B mget
-commands and
-.B get
-commands issued without a specified local target filename. This command
-is useful when connecting to a non-UNIX remote computer with different
-file naming conventions or practices. Characters in a filename matching
-a character in
-.I inchars
-are replaced with the corresponding character in
-.IR outchars .
-If the character's position in
-.I inchars
-is longer than the length of
-.IR outchars ,
-the character is deleted from the file name.
-.TP
-\fBopen\fP \fIhost\fP [\fIport\fP] [\fB\-forward\fP]
-Establish a connection to the specified
-.I host
-.SM FTP
-server. An optional port number may be supplied, in which case,
-.B ftp
-will attempt to contact an
-.SM FTP
-server at that port. If the
-.B auto-authenticate
-option is on (default),
-.B ftp
-will attempt to authenticate to the
-.SM FTP
-server by sending the
-.SM AUTH
-command, using whichever authentication types which are locally
-supported. Once an authentication type is accepted, an authentication
-protocol will proceed by issuing
-.SM ADAT
-commands. If the
-.B auto-login
-option is on (default),
-.B ftp
-will also attempt to automatically log the user in to the
-.SM FTP
-server (see below). If the
-.B \-forward
-option is specified,
-.B ftp
-will forward a copy of the user's Kerberos tickets to the remote host.
-.TP
-.B passive
-Toggle passive data transfer mode. In passive mode, the client initiates
-the data connection by listening on the data port. Passive mode may
-be necessary for operation from behind firewalls which do not permit
-incoming connections.
-.TP
-.B private
-Set the protection level on data transfers to ``private''. Data
-transmissions are confidentiality and integrity protected by encryption.
-If no
-.SM ADAT
-command succeeded, then the only possible level is ``clear''.
-.TP
-.B prompt
-Toggle interactive prompting. Interactive prompting occurs during
-multiple file transfers to allow the user to selectively retrieve or
-store files. If prompting is turned off (default is on), any
-.B mget
-or
-.B mput
-will transfer all files, and any
-.B mdelete
-will delete all files.
-.TP
-\fBprotect\fP [\fIprotection-level\fP]
-Set the protection level on data transfers to
-.IR protection-level .
-The valid protection levels are ``clear'' for unprotected data
-transmissions, ``safe'' for data transmissions integrity protected by
-cryptographic checksum, and ``private'' for data transmissions
-confidentiality and integrity protected by encryption. If no
-.SM ADAT
-command succeeded, then the only possible level is ``clear''. If no
-level is specified, the current level is printed. The default
-protection level is ``clear''.
-.TP
-\fBproxy\fP \fIftp-command\fP
-Execute an ftp command on a secondary control connection. This command
-allows simultaneous connection to two remote ftp servers for
-transferring files between the two servers. The first
-.B proxy
-command should be an
-.B open ,
-to establish the secondary control connection. Enter the command
-"proxy ?" to see other ftp commands executable on the secondary connection.
-The following commands behave differently when prefaced by
-.BR proxy :
-.B open
-will not define new macros during the auto-login process,
-.B close
-will not erase existing macro definitions,
-.B get
-and
-.B mget
-transfer files from the host on the primary control connection to the
-host on the secondary control connection, and
-.BR put ,
-.BR mput ,
-and
-.B append
-transfer files from the host on the secondary control connection to the
-host on the primary control connection. Third party file transfers
-depend upon support of the ftp protocol
-.SM PASV
-command by the server on the secondary control connection.
-.TP
-\fBput\fP \fIlocal-file\fP [\fIremote-file\fP]
-Store a local file on the remote machine. If
-.I remote-file
-is left unspecified, the local file name is used after processing
-according to any
-.B ntrans
-or
-.B nmap
-settings in naming the remote file. File transfer uses the current
-settings for
-.BR type ,
-.BR format ,
-.BR mode ,
-and
-.BR structure .
-.TP
-.B pwd
-Print the name of the current working directory on the remote machine.
-.TP
-.B quit
-A synonym for
-.BR bye .
-.TP
-\fBquote\fP \fIarg1\fP [\fIarg2\fP] [\fI...\fP]
-The arguments specified are sent, verbatim, to the remote
-.SM FTP
-server.
-.TP
-\fBrecv\fP \fIremote-file\fP [\fIlocal-file\fP]
-A synonym for get.
-.TP
-\fBreget\fP \fIremote-file\fP [\fIlocal-file\fP]
-Reget acts like get, except that if
-.I local-file
-exists and is smaller than
-.IR remote-file ,
-.I local-file
-is presumed to be a partially transferred copy of
-.I remote-file
-and the transfer is continued from the apparent point of failure. This
-command is useful when transferring very large files over networks that
-are prone to dropping connections.
-.TP
-\fBremotehelp\fP [\fIcommand-name\fP]
-Request help from the remote
-.SM FTP
-server. If a
-.I command-name
-is specified it is supplied to the server as well.
-.TP
-\fBremotestatus\fP [\fIfile-name\fP]
-With no arguments, show status of remote machine. If
-.I file-name
-is specified, show status of
-.I file-name
-on remote machine.
-.TP
-\fBrename\fP [\fIfrom\fP] [\fIto\fP]
-Rename the file
-.I from
-on the remote machine, to the file
-.IR to .
-.TP
-.B reset
-Clear reply queue. This command re-synchronizes command/reply
-sequencing with the remote ftp server. Resynchronization may be
-necessary following a violation of the ftp protocol by the remote
-server.
-.TP
-\fBrestart\fP \fImarker\fP
-Restart the immediately following
-.B get
-or
-.B put
-at the indicated
-.IR marker .
-On UNIX systems, marker is usually a byte offset into the file.
-.TP
-\fBrmdir\fP \fIdirectory-name\fP
-Delete a directory on the remote machine.
-.TP
-.B runique
-Toggle storing of files on the local system with unique filenames. If a
-file already exists with a name equal to the target local filename for a
-.B get
-or
-.B mget
-command, a ".1" is appended to the name. If the resulting name matches
-another existing file, a ".2" is appended to the original name. If this
-process continues up to ".99", an error message is printed, and the
-transfer does not take place. The generated unique filename will be
-reported. Note that
-.B runique
-will not affect local files generated from a shell command (see below).
-The default value is off.
-.TP
-.B safe
-Set the protection level on data transfers to ``safe''. Data
-transmissions are integrity-protected by cryptographic checksum. If no
-.SM ADAT
-command succeeded, then the only possible level is ``clear''.
-.TP
-\fBsend\fP \fIlocal-file\fP [\fIremote-file\fP]
-A synonym for put.
-.TP
-.B sendport
-Toggle the use of
-.SM PORT
-commands. By default,
-.B ftp
-will attempt to use a
-.SM PORT
-command when establishing a connection for each data transfer. The use
-of
-.SM PORT
-commands can prevent delays when performing multiple file transfers. If
-the
-.SM PORT
-command fails,
-.B ftp
-will use the default data port. When the use of
-.SM PORT
-commands is disabled, no attempt will be made to use
-.SM PORT
-commands for each data transfer. This is useful for certain
-.SM FTP
-implementations which do ignore
-.SM PORT
-commands but, incorrectly, indicate they've been accepted.
-.TP
-\fBsite\fP \fIarg1\fP [\fIarg2\fP] [\fI...\fP]
-The arguments specified are sent, verbatim, to the remote
-.SM FTP
-server as a
-.SM SITE
-command.
-.TP
-\fBsize\fP \fIfile-name\fP
-Return size of
-.I file-name
-on remote machine.
-.TP
-.B status
-Show the current status of
-.BR ftp .
-.TP
-\fBstruct\fP \fIstruct-name\fP
-Set the file transfer
-.I structure
-to
-.IR struct-name .
-By default ``stream'' structure is used.
-.TP
-.B sunique
-Toggle storing of files on remote machine under unique file names.
-Remote ftp server must support ftp protocol
-.SM STOU
-command for successful completion. The remote server will report unique
-name. Default value is off.
-.TP
-.B system
-Show the type of operating system running on the remote machine.
-.TP
-.B tenex
-Set the file transfer type to that needed to talk to
-.SM TENEX
-machines.
-.TP
-.B trace
-Toggle packet tracing.
-.TP
-\fBtype\fP [\fItype-name\fP]
-Set the file transfer
-.B type
-to
-.IR type-name .
-If no type is specified, the current type is printed. The default type
-is network
-.SM ASCII.
-.TP
-\fBumask\fP [\fInewmask\fP]
-Set the default umask on the remote server to
-.IR newmask .
-If
-.I newmask
-is omitted, the current umask is printed.
-.TP
-\fBuser\fP \fIuser-name\fP [\fIpassword\fP] [\fIaccount\fP]
-Identify yourself to the remote
-.SM FTP
-server. If the
-.I password
-is not specified and the server requires it,
-.B ftp
-will prompt the user for it (after disabling local echo). If an
-.I account
-field is not specified, and the
-.SM FTP
-server requires it, the user will be prompted for it. If an
-.I account
-field is specified, an account command will be relayed to the remote
-server after the login sequence is completed if the remote server did
-not require it for logging in. Unless
-.B ftp
-is invoked with ``auto-login'' disabled, this process is done
-automatically on initial connection to the
-.SM FTP
-server.
-.TP
-.B verbose
-Toggle verbose mode. In verbose mode, all responses from the
-.SM FTP
-server are displayed to the user. In addition, if verbose is on, when a
-file transfer completes, statistics regarding the efficiency of the
-transfer are reported. By default, verbose is on.
-.TP
-\fB \&? [\fIcommand\fP]
-A synonym for help.
-.PP
-Command arguments which have embedded spaces may be quoted with quote
-`"' marks.
-.SH ABORTING A FILE TRANSFER
-To abort a file transfer, use the terminal interrupt key (usually
-Ctrl-C). Sending transfers will be immediately halted. Receiving
-transfers will be halted by sending a
-.SM FTP
-protocol
-.SM ABOR
-command to the remote server, and discarding any further data received.
-The speed at which this is accomplished depends upon the remote server's
-support for
-.SM ABOR
-processing. If the remote server does not support the
-.SM ABOR
-command, an `ftp>' prompt will not appear until the remote server has
-completed sending the requested file.
-.PP
-The terminal interrupt key sequence will be ignored when
-.B ftp
-has completed any local processing and is awaiting a reply from the
-remote server. A long delay in this mode may result from the
-.SM ABOR
-processing described above, or from unexpected behavior by the remote
-server, including violations of the ftp protocol. If the delay results
-from unexpected remote server behavior, the local
-.B ftp
-program must be killed by hand.
-.SH FILE NAMING CONVENTIONS
-Files specified as arguments to
-.B ftp
-commands are processed according to the following rules.
-.TP
-1.
-If the file name `\fB-\fP' is specified,
-.I stdin
-(for reading) or
-.I stdout
-(for writing) is used.
-.TP
-2.
-If the first character of the file name is `\&|', the remainder of the
-argument is interpreted as a shell command.
-.B Ftp
-then forks a shell, using
-.IR popen (3)
-with the argument supplied, and reads from (writes to) stdout (stdin).
-If the shell command includes spaces, the argument must be quoted; e.g.
-``" ls -lt"''. A particularly useful example of this mechanism is:
-``dir more''.
-.TP
-3.
-Failing the above checks, if ``globbing'' is enabled, local file names
-are expanded according to the rules used in
-.IR csh (1);
-c.f. the
-.B glob
-command. If the
-.B ftp
-command expects a single local file (.e.g.
-.BR put ),
-only the first filename generated by the ``globbing'' operation is used.
-.TP
-4.
-For
-.B mget
-commands and
-.B get
-commands with unspecified local file names, the local filename is the
-remote filename, which may be altered by a
-.BR case ,
-.BR ntrans ,
-or
-.B nmap
-setting. The resulting filename may then be altered if
-.B runique
-is on.
-.TP
-5.
-For
-.B mput
-commands and
-.B put
-commands with unspecified remote file names, the remote filename is the
-local filename, which may be altered by a
-.B ntrans
-or
-.B nmap
-setting. The resulting filename may then be altered by the remote
-server if
-.B sunique
-is on.
-.SH FILE TRANSFER PARAMETERS
-The FTP specification specifies many parameters which may affect a file
-transfer. The
-.B type
-may be one of ``ascii'', ``image'' (binary), ``ebcdic'', and ``local
-byte size'' (mostly for PDP-10's and PDP-20's).
-.B Ftp
-supports the ascii and image types of file transfer, plus local byte
-size 8 for
-.B tenex
-mode transfers.
-.PP
-.B Ftp
-supports only the default values for the remaining file transfer
-parameters:
-.BR mode ,
-.BR form ,
-and
-.BR struct .
-.SH THE .netrc FILE
-The
-.I .netrc
-file contains login and initialization information used by the
-auto-login process. It resides in the user's home directory. The
-following tokens are recognized; they may be separated by spaces, tabs,
-or new-lines:
-.TP
-\fBmachine\fP \fIname\fP
-Identify a remote machine
-.IR name .
-The auto-login process searches the
-.I .netrc
-file for a
-.B machine
-token that matches the remote machine specified on the
-.B ftp
-command line or as an
-.B open
-command argument. Once a match is made, the subsequent
-.I .netrc
-tokens are processed, stopping when the end of file is reached or
-another
-.B machine
-or a
-.B default
-token is encountered.
-.TP
-.B default
-This is the same as
-.B machine
-.I name
-except that
-.B default
-matches any name. There can be only one
-.B default
-token, and it must be after all
-.B machine
-tokens. This is normally used as:
-.sp
- default login anonymous password user@site
-.sp
-thereby giving the user
-.I automatic
-anonymous ftp login to machines not specified in
-.IR .netrc .
-This can be overridden by using the
-.B \-n
-flag to disable auto-login.
-.TP
-\fBlogin\fP \fIname\fP
-Identify a user on the remote machine. If this token is present, the
-auto-login process will initiate a login using the specified
-.IR name .
-.TP
-\fBpassword\fP \fIstring\fP
-Supply a password. If this token is present, the auto-login process
-will supply the specified string if the remote server requires a
-password as part of the login process. Note that if this token is
-present in the
-.I .netrc
-file for any user other than
-.IR anonymous ,
-.B ftp
-will abort the auto-login process if the
-.I .netrc
-is readable by anyone besides the user.
-.TP
-\fBaccount\fP \fIstring\fP
-Supply an additional account password. If this token is present, the
-auto-login process will supply the specified string if the remote server
-requires an additional account password, or the auto-login process will
-initiate an
-.SM ACCT
-command if it does not.
-.TP
-\fBmacdef\fP \fIname\fP
-Define a macro. This token functions like the
-.B ftp
-.B macdef
-command functions. A macro is defined with the specified name; its
-contents begin with the next
-.I .netrc
-line and continue until a null line (consecutive new-line characters) is
-encountered. If a macro named
-.B init
-is defined, it is automatically executed as the last step in the
-auto-login process.
-.SH ENVIRONMENT
-.B Ftp
-utilizes the following environment variables.
-.TP
-.SM HOME
-For default location of a
-.I .netrc
-file, if one exists.
-.TP
-.SM SHELL
-For default shell.
-.SH SEE ALSO
-.IR ftpd (8)
-.PP
-Lunt, S. J., FTP Security Extensions, Internet Draft, November 1993.
-.SH HISTORY
-The
-.B ftp
-command appeared in 4.2BSD.
-.SH BUGS
-Correct execution of many commands depends upon proper behavior by the
-remote server.
-.PP
-An error in the treatment of carriage returns in the 4.2BSD ascii-mode
-transfer code has been corrected. This correction may result in
-incorrect transfers of binary files to and from 4.2BSD servers using the
-ascii type. Avoid this problem by using the binary image type.
+++ /dev/null
-/*
- * Copyright (c) 1985, 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.
- */
-
-/*
- * Copyright (C) 1998 by the FundsXpress, INC.
- *
- * All rights reserved.
- *
- * Export of this software from the United States of America may require
- * a specific license from the United States Government. It is the
- * responsibility of any person or organization contemplating export to
- * obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of FundsXpress. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. FundsXpress makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ftp.c 5.38 (Berkeley) 4/22/91";
-#endif /* not lint */
-
-#ifdef _WIN32
-#include <windows.h>
-#include <winsock2.h>
-#include <sys/timeb.h>
-#include <time.h>
-#include <crtdbg.h>
-#undef ERROR
-#define NOSTBLKSIZE
-
-#define popen _popen
-#define pclose _pclose
-#define sleep(secs) Sleep(secs * 1000)
-int gettimeofday(struct timeval *tv, void *tz);
-
-#endif
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#ifndef _WIN32
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <sys/time.h>
-#include <sys/file.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <pwd.h>
-#endif
-
-#include <arpa/ftp.h>
-#include <arpa/telnet.h>
-
-#include <stdio.h>
-#include <signal.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdarg.h>
-
-#include <port-sockets.h>
-
-#ifndef L_SET
-#define L_SET 0
-#endif
-#ifndef L_INCR
-#define L_INCR 1
-#endif
-
-#include <k5-platform.h>
-
-#ifdef GSSAPI
-#include <gssapi/gssapi.h>
-/* need to include the krb5 file, because we're doing manual fallback
- from the v2 mech to the v2 mech. Once there's real negotiation,
- we can be generic again. */
-#include <gssapi/gssapi_generic.h>
-#include <gssapi/gssapi_krb5.h>
-gss_ctx_id_t gcontext;
-#endif /* GSSAPI */
-
-static int kerror; /* XXX needed for all auth types */
-
-char *auth_type; /* Authentication succeeded? If so, what type? */
-
-unsigned int maxbuf, actualbuf;
-unsigned char *ucbuf;
-
-#define DEFINITIONS
-#include "ftp_var.h"
-#include "secure.h"
-
-#ifdef GSSAPI
-void user_gss_error (OM_uint32, OM_uint32, char *);
-#endif
-
-static void proxtrans (char *, char *, char *);
-static int initconn (void);
-static void ptransfer (char *, long, struct timeval *, struct timeval *);
-static void abort_remote (FILE *);
-static void tvsub (struct timeval *, struct timeval *, struct timeval *);
-static char *gunique (char *);
-
-struct sockaddr_in hisctladdr;
-struct sockaddr_in hisdataaddr;
-struct sockaddr_in data_addr;
-SOCKET data = -1;
-int abrtflag = 0;
-int ptflag = 0;
-struct sockaddr_in myctladdr;
-#ifndef _WIN32
-uid_t getuid();
-#endif
-sig_t lostpeer();
-off_t restart_point = 0;
-jmp_buf ptabort;
-
-#ifndef HAVE_STRERROR
-#define strerror(error) (sys_errlist[error])
-#ifdef NEED_SYS_ERRLIST
-extern char *sys_errlist[];
-#endif
-#endif
-
-extern int connected;
-
-#define herror() printf("unknown host\n")
-
-FILE *cin, *cout;
-FILE *dataconn (char *);
-
-char *
-hookup(char* host, int port)
-{
- register struct hostent *hp = 0;
- int s;
- socklen_t len;
-#ifdef IP_TOS
-#ifdef IPTOS_LOWDELAY
- int tos;
-#endif
-#endif
- static char hostnamebuf[80];
-
- memset(&hisctladdr, 0, sizeof (hisctladdr));
- hisctladdr.sin_addr.s_addr = inet_addr(host);
- if (hisctladdr.sin_addr.s_addr != -1) {
- hisctladdr.sin_family = AF_INET;
- (void) strncpy(hostnamebuf, host, sizeof(hostnamebuf));
- } else {
- hp = gethostbyname(host);
- if (hp == NULL) {
- fprintf(stderr, "ftp: %s: ", host);
- herror();
- code = -1;
- return((char *) 0);
- }
- hisctladdr.sin_family = hp->h_addrtype;
- memcpy(&hisctladdr.sin_addr, hp->h_addr_list[0],
- sizeof(hisctladdr.sin_addr));
- (void) strncpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf));
- }
- hostname = hostnamebuf;
- s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
- if (s == INVALID_SOCKET) {
- PERROR_SOCKET("ftp: socket");
- code = -1;
- return (0);
- }
- hisctladdr.sin_port = port;
- while (connect(s, (struct sockaddr *)&hisctladdr, sizeof (hisctladdr)) == SOCKET_ERROR) {
- if (hp && hp->h_addr_list[1]) {
- int oerrno = SOCKET_ERRNO;
-#ifndef _WIN32
- extern char *inet_ntoa();
-#endif
- fprintf(stderr, "ftp: connect to address %s: ",
- inet_ntoa(hisctladdr.sin_addr));
- SOCKET_SET_ERRNO(oerrno);
- PERROR_SOCKET((char *) 0);
- hp->h_addr_list++;
- memcpy(&hisctladdr.sin_addr,
- hp->h_addr_list[0],
- sizeof(hisctladdr.sin_addr));
- fprintf(stdout, "Trying %s...\n",
- inet_ntoa(hisctladdr.sin_addr));
- (void) closesocket(s);
- s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
- if (s == INVALID_SOCKET) {
- PERROR_SOCKET("ftp: socket");
- code = -1;
- return (0);
- }
- continue;
- }
- PERROR_SOCKET("ftp: connect");
- code = -1;
- goto bad;
- }
- len = sizeof (myctladdr);
- if (getsockname(s, (struct sockaddr *)&myctladdr, &len) == SOCKET_ERROR) {
- PERROR_SOCKET("ftp: getsockname");
- code = -1;
- goto bad;
- }
-#ifdef IP_TOS
-#ifdef IPTOS_LOWDELAY
- tos = IPTOS_LOWDELAY;
- if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) == SOCKET_ERROR) {
- PERROR_SOCKET("ftp: setsockopt TOS (ignored)");
- }
-#endif
-#endif
- cin = FDOPEN_SOCKET(s, "r");
- cout = FDOPEN_SOCKET(s, "w");
- if (cin == NULL || cout == NULL) {
- fprintf(stderr, "ftp: fdopen failed.\n");
- if (cin) {
- (void) FCLOSE_SOCKET(cin);
- cin = NULL;
- }
- if (cout) {
- (void) FCLOSE_SOCKET(cout);
- cout = NULL;
- }
- code = -1;
- goto bad;
- }
- if (verbose)
- printf("Connected to %s.\n", hostname);
- if (getreply(0) > 2) { /* read startup message from server */
- if (cin) {
- (void) FCLOSE_SOCKET(cin);
- cin = NULL;
- }
- if (cout) {
- (void) FCLOSE_SOCKET(cout);
- cout = NULL;
- }
- code = -1;
- goto bad;
- }
-#ifdef SO_OOBINLINE
- {
- int on = 1;
-
- if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on))
- == SOCKET_ERROR && debug) {
- PERROR_SOCKET("ftp: setsockopt");
- }
- }
-#endif /* SO_OOBINLINE */
-
- return (hostname);
-bad:
- (void) closesocket(s);
- return ((char *)0);
-}
-
-int login(char *host)
-{
- char tmp[80];
- char *l_user, *pass, *l_acct, *getenv(), *getlogin();
- int n, aflag = 0;
-
- l_user = pass = l_acct = 0;
- if (ruserpass(host, &l_user, &pass, &l_acct) < 0) {
- code = -1;
- return(0);
- }
- while (l_user == NULL) {
- char *myname;
-
- myname = getenv("LOGNAME");
- if (myname == NULL)
- myname = getenv("USER");
-#ifndef _WIN32
- if (myname == NULL)
- myname = getlogin();
- if (myname == NULL) {
- struct passwd *pp = getpwuid(getuid());
-
- if (pp != NULL)
- myname = pp->pw_name;
- }
-#else
- if (myname == NULL) {
- static char buffer[200];
- int len = sizeof(buffer);
- if (GetUserName(buffer, &len))
- myname = buffer;
- else
- myname = "<Unknown>";
- }
-#endif
- if (myname)
- printf("Name (%s:%s): ", host, myname);
- else
- printf("Name (%s): ", host);
- (void) fgets(tmp, sizeof(tmp) - 1, stdin);
- tmp[strlen(tmp) - 1] = '\0';
- if (*tmp == '\0')
- l_user = myname;
- else
- l_user = tmp;
- }
- n = command("USER %s", l_user);
- if (n == COMPLETE) {
- /* determine if we need to send a dummy password */
- int oldverbose = verbose;
-
- verbose = 0;
- if (command("PWD") != COMPLETE) {
- verbose = oldverbose;
- command("PASS dummy");
- } else {
- verbose = oldverbose;
- }
- }
- else if (n == CONTINUE) {
-#ifndef NOENCRYPTION
- int oldclevel;
-#endif
- if (pass == NULL)
- pass = mygetpass("Password:");
-#ifndef NOENCRYPTION
- oldclevel = clevel;
- clevel = PROT_P;
-#endif
- n = command("PASS %s", pass);
-#ifndef NOENCRYPTION
- /* level may have changed */
- if (clevel == PROT_P) clevel = oldclevel;
-#endif
- }
- if (n == CONTINUE) {
- aflag++;
- l_acct = mygetpass("Account:");
- n = command("ACCT %s", l_acct);
- }
- if (n != COMPLETE) {
- fprintf(stderr, "Login failed.\n");
- return (0);
- }
- if (!aflag && l_acct != NULL)
- (void) command("ACCT %s", l_acct);
- if (proxy)
- return(1);
- for (n = 0; n < macnum; ++n) {
- if (!strcmp("init", macros[n].mac_name)) {
- (void) strlcpy(line, "$init", sizeof(line));
- makeargv();
- domacro(margc, margv);
- break;
- }
- }
- return (1);
-}
-
-static sigtype
-cmdabort(int sig)
-{
- printf("\n");
- (void) fflush(stdout);
- abrtflag++;
- if (ptflag)
- longjmp(ptabort,1);
-}
-
-static int secure_command(char* cmd)
-{
- unsigned char in[FTP_BUFSIZ], out[FTP_BUFSIZ];
- int length;
-
- if (auth_type && clevel != PROT_C) {
-#ifdef GSSAPI
- /* secure_command (based on level) */
- if (strcmp(auth_type, "GSSAPI") == 0) {
- gss_buffer_desc in_buf, out_buf;
- OM_uint32 maj_stat, min_stat;
- int conf_state;
-/* clevel = PROT_P; */
- in_buf.value = cmd;
- in_buf.length = strlen(cmd) + 1;
- maj_stat = gss_seal(&min_stat, gcontext,
- (clevel==PROT_P), /* private */
- GSS_C_QOP_DEFAULT,
- &in_buf, &conf_state,
- &out_buf);
- if (maj_stat != GSS_S_COMPLETE) {
- /* generally need to deal */
- user_gss_error(maj_stat, min_stat,
- (clevel==PROT_P)?
- "gss_seal ENC didn't complete":
- "gss_seal MIC didn't complete");
- } else if ((clevel == PROT_P) && !conf_state) {
- fprintf(stderr,
- "GSSAPI didn't encrypt message");
- } else {
- if (debug)
- fprintf(stderr, "sealed (%s) %lu bytes\n",
- clevel==PROT_P?"ENC":"MIC",
- (unsigned long) out_buf.length);
- length=out_buf.length;
- memcpy(out, out_buf.value, out_buf.length);
- gss_release_buffer(&min_stat, &out_buf);
- }
- }
-#endif /* GSSAPI */
- /* Other auth types go here ... */
- kerror = radix_encode(out, in, &length, 0);
- if (kerror) {
- fprintf(stderr,"Couldn't base 64 encode command (%s)\n",
- radix_error(kerror));
- return(0);
- }
- fprintf(cout, "%s %s", clevel == PROT_P ? "ENC" : "MIC", in);
- if(debug)
- fprintf(stderr, "secure_command(%s)\nencoding %d bytes %s %s\n",
- cmd, length, clevel==PROT_P ? "ENC" : "MIC", in);
- } else fputs(cmd, cout);
- fprintf(cout, "\r\n");
- (void) fflush(cout);
- return(1);
-}
-
-int command(char *fmt, ...)
-{
- char in[FTP_BUFSIZ];
- va_list ap;
- int r;
- sig_t oldintr;
-
- abrtflag = 0;
- if (debug) {
- if (proxflag) printf("%s ", hostname);
- printf("---> ");
- va_start(ap, fmt);
- if (strncmp("PASS ", fmt, 5) == 0)
- printf("PASS XXXX");
- else
- vfprintf(stdout, fmt, ap);
- va_end(ap);
- printf("\n");
- (void) fflush(stdout);
- }
- if (cout == NULL) {
- perror ("No control connection for command");
- code = -1;
- return (0);
- }
- oldintr = signal(SIGINT, cmdabort);
- va_start(ap, fmt);
- vsnprintf(in, FTP_BUFSIZ, fmt, ap);
- va_end(ap);
-again: if (secure_command(in) == 0)
- return(0);
- cpend = 1;
- r = getreply(!strcmp(fmt, "QUIT"));
-#ifndef NOENCRYPTION
- if (r == 533 && clevel == PROT_P) {
- fprintf(stderr,
- "ENC command not supported at server; retrying under MIC...\n");
- clevel = PROT_S;
- goto again;
- }
-#endif
- if (abrtflag && oldintr && oldintr != SIG_IGN)
- (*oldintr)(SIGINT);
- (void) signal(SIGINT, oldintr);
- return(r);
-}
-
-char reply_string[FTP_BUFSIZ]; /* last line of previous reply */
-
-/* for parsing replies to the ADAT command */
-char *reply_parse, reply_buf[FTP_BUFSIZ], *reply_ptr;
-
-#include <ctype.h>
-
-int getreply(int expecteof)
-{
- register int i, c, n;
- register int dig;
- register char *cp;
- int originalcode = 0, continuation = 0;
- sig_t oldintr;
- int pflag = 0;
- char *pt = pasv;
- char ibuf[FTP_BUFSIZ], obuf[FTP_BUFSIZ];
- int safe = 0;
-#ifndef strpbrk
- extern char *strpbrk();
-#endif
-#ifndef strstr
- extern char *strstr();
-#endif
-
- ibuf[0] = '\0';
- if (reply_parse) reply_ptr = reply_buf;
- oldintr = signal(SIGINT, cmdabort);
- for (;;) {
- obuf[0] = '\0';
- dig = n = code = i = 0;
- cp = reply_string;
- while ((c = ibuf[0] ? ibuf[i++] : getc(cin)) != '\n') {
- if (c == IAC) { /* handle telnet commands */
- switch (c = getc(cin)) {
- case WILL:
- case WONT:
- c = getc(cin);
- fprintf(cout, "%c%c%c", IAC, DONT, c);
- (void) fflush(cout);
- break;
- case DO:
- case DONT:
- c = getc(cin);
- fprintf(cout, "%c%c%c", IAC, WONT, c);
- (void) fflush(cout);
- break;
- default:
- break;
- }
- continue;
- }
- dig++;
- if (c == EOF) {
- if (expecteof) {
- (void) signal(SIGINT,oldintr);
- code = 221;
- return (0);
- }
- lostpeer();
- if (verbose) {
- printf("421 Service not available, remote server has closed connection\n");
- (void) fflush(stdout);
- }
- code = 421;
- return(4);
- }
- if (n == 0)
- n = c;
- if (auth_type && !ibuf[0] &&
- (n == '6' || continuation)) {
- if (c != '\r' && dig > 4)
- obuf[i++] = c;
- } else {
- if (auth_type && !ibuf[0] && dig == 1 && verbose)
- printf("Unauthenticated reply received from server:\n");
- if (reply_parse) *reply_ptr++ = c;
- if (c != '\r' && (verbose > 0 ||
- (verbose > -1 && n == '5' && dig > 4))) {
- if (proxflag &&
- (dig == 1 || (dig == 5 && verbose == 0)))
- printf("%s:",hostname);
- (void) putchar(c);
- }
- }
- if (auth_type && !ibuf[0] && n != '6') continue;
- if (dig < 4 && isdigit(c))
- code = code * 10 + (c - '0');
- if (!pflag && code == 227)
- pflag = 1;
- if (dig > 4 && pflag == 1 && isdigit(c))
- pflag = 2;
- if (pflag == 2) {
- if (c != '\r' && c != ')')
- *pt++ = c;
- else {
- *pt = '\0';
- pflag = 3;
- }
- }
- if (dig == 4 && c == '-' && n != '6') {
- if (continuation)
- code = 0;
- continuation++;
- }
- if (cp < &reply_string[sizeof(reply_string) - 1])
- *cp++ = c;
- }
- if (auth_type && !ibuf[0] && n != '6')
- return(getreply(expecteof));
- ibuf[0] = obuf[i] = '\0';
- if (code && n == '6') {
- if (code != 631 && code != 632 && code != 633) {
- printf("Unknown reply: %d %s\n", code, obuf);
- n = '5';
- } else safe = (code == 631);
- }
- if (obuf[0]) /* if there is a string to decode */
- if (!auth_type) {
- printf("Cannot decode reply:\n%d %s\n", code, obuf);
- n = '5';
- }
-#ifdef NOENCRYPTION
- else if (code == 632) {
- printf("Cannot decrypt %d reply: %s\n", code, obuf);
- n = '5';
- }
-#endif
-#ifdef NOCONFIDENTIAL
- else if (code == 633) {
- printf("Cannot decrypt %d reply: %s\n", code, obuf);
- n = '5';
- }
-#endif
- else {
- int len;
- kerror = radix_encode((unsigned char *)obuf,
- (unsigned char *)ibuf,
- &len, 1);
- if (kerror) {
- printf("Can't base 64 decode reply %d (%s)\n\"%s\"\n",
- code, radix_error(kerror), obuf);
- n = '5';
- }
-#ifdef GSSAPI
- else if (strcmp(auth_type, "GSSAPI") == 0) {
- gss_buffer_desc xmit_buf, msg_buf;
- OM_uint32 maj_stat, min_stat;
- int conf_state;
- xmit_buf.value = ibuf;
- xmit_buf.length = len;
- /* decrypt/verify the message */
- conf_state = safe;
- maj_stat = gss_unseal(&min_stat, gcontext,
- &xmit_buf, &msg_buf,
- &conf_state, NULL);
- if (maj_stat != GSS_S_COMPLETE) {
- user_gss_error(maj_stat, min_stat,
- "failed unsealing reply");
- n = '5';
- } else {
- if(msg_buf.length < sizeof(ibuf) - 2 - 1) {
- memcpy(ibuf, msg_buf.value,
- msg_buf.length);
- memcpy(&ibuf[msg_buf.length], "\r\n", 3);
- } else {
- user_gss_error(maj_stat, min_stat,
- "reply was too long");
- }
- gss_release_buffer(&min_stat,&msg_buf);
- continue;
- }
- }
-#endif
- /* Other auth types go here... */
- }
- else
- if (verbose > 0 || (verbose > -1 && n == '5')) {
- (void) putchar(c);
- (void) fflush (stdout);
- }
- if (continuation && code != originalcode) {
- if (originalcode == 0)
- originalcode = code;
- continue;
- }
- *cp = '\0';
- if (n != '1')
- cpend = 0;
- (void) signal(SIGINT,oldintr);
- if (code == 421 || originalcode == 421)
- lostpeer();
- if (abrtflag && oldintr && oldintr != cmdabort && oldintr != SIG_IGN)
- (*oldintr)(SIGINT);
- if (reply_parse) {
- *reply_ptr = '\0';
- reply_ptr = strstr(reply_buf, reply_parse);
- if (reply_ptr) {
- reply_parse = reply_ptr + strlen(reply_parse);
- reply_ptr = strpbrk(reply_parse, " \r");
- if (reply_ptr)
- *reply_ptr = '\0';
- } else reply_parse = reply_ptr;
- }
- return (n - '0');
- }
-}
-
-static int empty(fd_set *mask, int sec)
-{
- struct timeval t;
-
- t.tv_sec = (long) sec;
- t.tv_usec = 0;
- return(select(32, mask, (fd_set *) 0, (fd_set *) 0, &t));
-}
-
-jmp_buf sendabort;
-
-static sigtype
-abortsend(int sig)
-{
-
- mflag = 0;
- abrtflag = 0;
- printf("\nsend aborted\nwaiting for remote to finish abort\n");
- (void) fflush(stdout);
- longjmp(sendabort, 1);
-}
-
-void secure_error(char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- putc('\n', stderr);
-}
-
-#define HASHBYTES 1024
-
-void sendrequest(char *cmd, char *local, char *remote, int printnames)
-{
- struct stat st;
- struct timeval start, stop;
- register int c, d;
- FILE *volatile fin, *volatile dout = 0;
- int (*volatile closefunc)();
- volatile sig_t oldintr, oldintp;
- volatile long bytes = 0, hashbytes = HASHBYTES;
- char *volatile lmode;
- unsigned char buf[FTP_BUFSIZ], *bufp;
-
- if (verbose && printnames) {
- if (local && *local != '-')
- printf("local: %s ", local);
- if (remote)
- printf("remote: %s\n", remote);
- }
- if (proxy) {
- proxtrans(cmd, local, remote);
- return;
- }
- if (curtype != type)
- changetype(type, 0);
- closefunc = NULL;
- oldintr = NULL;
- oldintp = NULL;
- lmode = "w";
- if (setjmp(sendabort)) {
- while (cpend) {
- (void) getreply(0);
- }
- if (data != INVALID_SOCKET) {
- (void) closesocket(data);
- data = INVALID_SOCKET;
- }
- if (oldintr)
- (void) signal(SIGINT,oldintr);
-#ifdef SIGPIPE
- if (oldintp)
- (void) signal(SIGPIPE,oldintp);
-#endif
- code = -1;
- return;
- }
- oldintr = signal(SIGINT, abortsend);
- if (strcmp(local, "-") == 0)
- fin = stdin;
- else if (*local == '|') {
-#ifdef SIGPIPE
- oldintp = signal(SIGPIPE,SIG_IGN);
-#endif
- fin = popen(local + 1, "r");
- if (fin == NULL) {
- perror(local + 1);
- (void) signal(SIGINT, oldintr);
-#ifdef SIGPIPE
- (void) signal(SIGPIPE, oldintp);
-#endif
- code = -1;
- return;
- }
- closefunc = pclose;
- } else {
-#ifdef _WIN32
- if ((curtype == TYPE_I) || (curtype == TYPE_L))
- fin = fopen(local, "rb");
- else
- fin = fopen(local, "rt");
-#else /* !_WIN32 */
- fin = fopen(local, "r");
-#endif /* !_WIN32 */
- if (fin == NULL) {
- fprintf(stderr, "local: %s: %s\n", local,
- strerror(errno));
- (void) signal(SIGINT, oldintr);
- code = -1;
- return;
- }
- closefunc = fclose;
- if (fstat(fileno(fin), &st) < 0 ||
- (st.st_mode&S_IFMT) != S_IFREG) {
- fprintf(stdout, "%s: not a plain file.\n", local);
- (void) signal(SIGINT, oldintr);
- fclose(fin);
- code = -1;
- return;
- }
- }
- if (initconn()) {
- (void) signal(SIGINT, oldintr);
-#ifdef SIGPIPE
- if (oldintp)
- (void) signal(SIGPIPE, oldintp);
-#endif
- code = -1;
- if (closefunc != NULL)
- (*closefunc)(fin);
- return;
- }
- if (setjmp(sendabort))
- goto die;
-
- if (restart_point &&
- (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "APPE") == 0)) {
- if (fseek(fin, (long) restart_point, 0) < 0) {
- fprintf(stderr, "local: %s: %s\n", local,
- strerror(errno));
- restart_point = 0;
- if (closefunc != NULL)
- (*closefunc)(fin);
- return;
- }
- if (command("REST %ld", (long) restart_point)
- != CONTINUE) {
- restart_point = 0;
- if (closefunc != NULL)
- (*closefunc)(fin);
- return;
- }
- restart_point = 0;
- lmode = "r+w";
- }
- if (remote) {
- if (command("%s %s", cmd, remote) != PRELIM) {
- (void) signal(SIGINT, oldintr);
-#ifdef SIGPIPE
- if (oldintp)
- (void) signal(SIGPIPE, oldintp);
-#endif
- if (closefunc != NULL)
- (*closefunc)(fin);
- return;
- }
- } else
- if (command("%s", cmd) != PRELIM) {
- (void) signal(SIGINT, oldintr);
-#ifdef SIGPIPE
- if (oldintp)
- (void) signal(SIGPIPE, oldintp);
-#endif
- if (closefunc != NULL)
- (*closefunc)(fin);
- return;
- }
- dout = dataconn(lmode);
- if (dout == NULL)
- goto die;
- (void) gettimeofday(&start, (struct timezone *)0);
-#ifdef SIGPIPE
- oldintp = signal(SIGPIPE, SIG_IGN);
-#endif
- switch (curtype) {
-
- case TYPE_I:
- case TYPE_L:
- errno = d = 0;
- while ((c = read(fileno(fin), buf, sizeof (buf))) > 0) {
- bytes += c;
- for (bufp = buf; c > 0; c -= d, bufp += d)
- if ((d = secure_write(fileno(dout), bufp,
- (unsigned int) c)) <= 0)
- break;
- if (hash) {
- while (bytes >= hashbytes) {
- (void) putchar('#');
- hashbytes += HASHBYTES;
- }
- (void) fflush(stdout);
- }
- if (d <= 0 )
- break;
- }
- if (hash && bytes > 0) {
- if (bytes < HASHBYTES)
- (void) putchar('#');
- (void) putchar('\n');
- (void) fflush(stdout);
- }
- if (c < 0)
- fprintf(stderr, "local: %s: %s\n", local,
- strerror(errno));
- if (d < 0 || (d = secure_flush(fileno(dout))) < 0) {
- if (d == -1 && errno != EPIPE)
- perror("netout");
- bytes = -1;
- }
- break;
-
- case TYPE_A:
- while ((c = getc(fin)) != EOF) {
- if (c == '\n') {
- while (hash && (bytes >= hashbytes)) {
- (void) putchar('#');
- (void) fflush(stdout);
- hashbytes += HASHBYTES;
- }
- if (ferror(dout) ||
- secure_putc('\r', dout) < 0)
- break;
- bytes++;
- }
- if (secure_putc(c, dout) < 0)
- break;
- bytes++;
- /* if (c == '\r') { */
- /* (void) putc('\0', dout); this violates rfc */
- /* bytes++; */
- /* } */
- }
- if (hash) {
- if (bytes < hashbytes)
- (void) putchar('#');
- (void) putchar('\n');
- (void) fflush(stdout);
- }
- if (ferror(fin))
- fprintf(stderr, "local: %s: %s\n", local,
- strerror(errno));
- d = 0;
- if (ferror(dout) || (d = secure_flush(fileno(dout))) < 0) {
- if ((ferror(dout) || d == -1) && errno != EPIPE)
- perror("netout");
- bytes = -1;
- }
- break;
- }
- (void) gettimeofday(&stop, (struct timezone *)0);
- if (closefunc != NULL)
- (*closefunc)(fin);
- (void) FCLOSE_SOCKET(dout);
- dout = NULL;
- (void) getreply(0);
- (void) signal(SIGINT, oldintr);
-#ifdef SIGPIPE
- if (oldintp)
- (void) signal(SIGPIPE, oldintp);
-#endif
- if (bytes > 0)
- ptransfer("sent", bytes, &start, &stop);
- return;
-die:
- (void) gettimeofday(&stop, (struct timezone *)0);
- (void) signal(SIGINT, oldintr);
-#ifdef SIGPIPE
- if (oldintp)
- (void) signal(SIGPIPE, oldintp);
-#endif
- if (!cpend) {
- code = -1;
- return;
- }
- if (data != INVALID_SOCKET) {
- (void) closesocket(data);
- data = INVALID_SOCKET;
- }
- if (dout) {
- (void) FCLOSE_SOCKET(dout);
- dout = NULL;
- }
- (void) getreply(0);
- code = -1;
- if (closefunc != NULL && fin != NULL)
- (*closefunc)(fin);
- if (bytes > 0)
- ptransfer("sent", bytes, &start, &stop);
-}
-
-jmp_buf recvabort;
-
-static sigtype
-abortrecv(int sig)
-{
-
- mflag = 0;
- abrtflag = 0;
- printf("\nreceive aborted\nwaiting for remote to finish abort\n");
- (void) fflush(stdout);
- longjmp(recvabort, 1);
-}
-
-void recvrequest(char *cmd, char *volatile local, char *remote, char *lmode,
- int printnames, int fnameonly)
-{
- FILE *volatile fout, *volatile din = 0, *popen();
- int (*volatile closefunc)(), pclose(), fclose();
- volatile sig_t oldintr, oldintp;
- volatile int is_retr, tcrflag, bare_lfs = 0;
- static unsigned int bufsize;
- static char *buf;
- unsigned int blksize;
- volatile long bytes = 0, hashbytes = HASHBYTES;
- register int c, d;
- struct timeval start, stop;
-#ifndef NOSTBLKSIZE
- struct stat st;
-#endif
- off_t lseek();
-
- is_retr = strcmp(cmd, "RETR") == 0;
- if (is_retr && verbose && printnames) {
- if (local && *local != '-')
- printf("local: %s ", local);
- if (remote)
- printf("remote: %s\n", remote);
- }
- if (proxy && is_retr) {
- proxtrans(cmd, local, remote);
- return;
- }
- closefunc = NULL;
- oldintr = NULL;
- oldintp = NULL;
- tcrflag = !crflag && is_retr;
- if (setjmp(recvabort)) {
- while (cpend) {
- (void) getreply(0);
- }
- if (data != INVALID_SOCKET) {
- (void) closesocket(data);
- data = INVALID_SOCKET;
- }
- if (oldintr)
- (void) signal(SIGINT, oldintr);
- code = -1;
- return;
- }
- oldintr = signal(SIGINT, abortrecv);
- if (fnameonly || (strcmp(local, "-") && *local != '|')) {
- if (access(local, 2) < 0) {
- char *dir = strrchr(local, '/');
-
- if (errno != ENOENT && errno != EACCES) {
- fprintf(stderr, "local: %s: %s\n", local,
- strerror(errno));
- (void) signal(SIGINT, oldintr);
- code = -1;
- return;
- }
- if (dir != NULL)
- *dir = 0;
- d = access(dir ? local : ".", 2);
- if (dir != NULL)
- *dir = '/';
- if (d < 0) {
- fprintf(stderr, "local: %s: %s\n", local,
- strerror(errno));
- (void) signal(SIGINT, oldintr);
- code = -1;
- return;
- }
- if (!runique && errno == EACCES &&
- chmod(local, 0600) < 0) {
- fprintf(stderr, "local: %s: %s\n", local,
- strerror(errno));
- (void) signal(SIGINT, oldintr);
- (void) signal(SIGINT, oldintr);
- code = -1;
- return;
- }
- if (runique && errno == EACCES &&
- (local = gunique(local)) == NULL) {
- (void) signal(SIGINT, oldintr);
- code = -1;
- return;
- }
- }
- else if (runique && (local = gunique(local)) == NULL) {
- (void) signal(SIGINT, oldintr);
- code = -1;
- return;
- }
- }
- if (!is_retr) {
- if (curtype != TYPE_A)
- changetype(TYPE_A, 0);
- } else if (curtype != type)
- changetype(type, 0);
- if (initconn()) {
- (void) signal(SIGINT, oldintr);
- code = -1;
- return;
- }
- if (setjmp(recvabort))
- goto die;
- if (is_retr && restart_point &&
- command("REST %ld", (long) restart_point) != CONTINUE)
- return;
- if (remote) {
- if (command("%s %s", cmd, remote) != PRELIM) {
- (void) signal(SIGINT, oldintr);
- return;
- }
- } else {
- if (command("%s", cmd) != PRELIM) {
- (void) signal(SIGINT, oldintr);
- return;
- }
- }
- din = dataconn("r");
- if (din == NULL)
- goto die;
- if (strcmp(local, "-") == 0 && !fnameonly)
- fout = stdout;
- else if (*local == '|' && !fnameonly) {
-#ifdef SIGPIPE
- oldintp = signal(SIGPIPE, SIG_IGN);
-#endif
- fout = popen(local + 1, "w");
- if (fout == NULL) {
- perror(local+1);
- goto die;
- }
- closefunc = pclose;
- } else {
-#ifdef _WIN32
- int old_fmode = _fmode;
-
- if ((curtype == TYPE_I) || (curtype == TYPE_L))
- _fmode = _O_BINARY;
-#endif /* _WIN32 */
- fout = fopen(local, lmode);
-#ifdef _WIN32
- _fmode = old_fmode;
-#endif
- if (fout == NULL) {
- fprintf(stderr, "local: %s: %s\n", local,
- strerror(errno));
- goto die;
- }
- closefunc = fclose;
- }
- blksize = FTP_BUFSIZ;
-#ifndef NOSTBLKSIZE
- if (fstat(fileno(fout), &st) == 0 && st.st_blksize != 0)
- blksize = st.st_blksize;
-#endif
- if (blksize > bufsize) {
- if (buf)
- (void) free(buf);
- buf = (char *)malloc((unsigned)blksize);
- if (buf == NULL) {
- perror("malloc");
- bufsize = 0;
- goto die;
- }
- bufsize = blksize;
- }
- (void) gettimeofday(&start, (struct timezone *)0);
- switch (curtype) {
-
- case TYPE_I:
- case TYPE_L:
- if (restart_point &&
- lseek(fileno(fout), (long) restart_point, L_SET) < 0) {
- fprintf(stderr, "local: %s: %s\n", local,
- strerror(errno));
- if (closefunc != NULL)
- (*closefunc)(fout);
- return;
- }
- errno = d = 0;
- while ((c = secure_read(fileno(din), buf, bufsize)) > 0) {
- d = write(fileno(fout), buf,(unsigned int) c);
- if (d != c)
- break;
- bytes += c;
- if (hash) {
- while (bytes >= hashbytes) {
- (void) putchar('#');
- hashbytes += HASHBYTES;
- }
- (void) fflush(stdout);
- }
- }
- if (hash && bytes > 0) {
- if (bytes < HASHBYTES)
- (void) putchar('#');
- (void) putchar('\n');
- (void) fflush(stdout);
- }
- if (c < 0) {
- if (c == -1 && errno != EPIPE)
- perror("netin");
- bytes = -1;
- }
- if (d < c) {
- if (d < 0)
- fprintf(stderr, "local: %s: %s\n", local,
- strerror(errno));
- else
- fprintf(stderr, "%s: short write\n", local);
- }
- break;
-
- case TYPE_A:
- if (restart_point) {
- register int i, n, ch;
-
- if (fseek(fout, 0L, L_SET) < 0)
- goto done;
- n = restart_point;
- for (i = 0; i++ < n;) {
- if ((ch = getc(fout)) == EOF)
- goto done;
- if (ch == '\n')
- i++;
- }
- if (fseek(fout, 0L, L_INCR) < 0) {
-done:
- fprintf(stderr, "local: %s: %s\n", local,
- strerror(errno));
- if (closefunc != NULL)
- (*closefunc)(fout);
- return;
- }
- }
- while ((c = secure_getc(din)) >= 0) {
- if (c == '\n')
- bare_lfs++;
- while (c == '\r') {
- while (hash && (bytes >= hashbytes)) {
- (void) putchar('#');
- (void) fflush(stdout);
- hashbytes += HASHBYTES;
- }
- bytes++;
- if ((c = secure_getc(din)) != '\n' || tcrflag) {
- if (ferror(fout))
- goto break2;
- (void) putc('\r', fout);
- if (c == '\0') {
- bytes++;
- goto contin2;
- }
- }
- }
- if (c < 0) break;
- (void) putc(c, fout);
- bytes++;
- contin2: ;
- }
-break2:
- if (bare_lfs) {
- printf("WARNING! %d bare linefeeds received in ASCII mode\n", bare_lfs);
- printf("File may not have transferred correctly.\n");
- }
- if (hash) {
- if (bytes < hashbytes)
- (void) putchar('#');
- (void) putchar('\n');
- (void) fflush(stdout);
- }
- if (ferror(din)) {
- if (errno != EPIPE)
- perror("netin");
- bytes = -1;
- }
- if (ferror(fout) || c == -2) {
- if (c != -2)
- fprintf(stderr, "local: %s: %s\n", local,
- strerror(errno));
- bytes = -1;
- }
- break;
- }
- if (closefunc != NULL)
- (*closefunc)(fout);
- (void) signal(SIGINT, oldintr);
-#ifdef SIGPIPE
- if (oldintp)
- (void) signal(SIGPIPE, oldintp);
-#endif
- (void) gettimeofday(&stop, (struct timezone *)0);
- (void) FCLOSE_SOCKET(din);
- din = NULL;
- (void) getreply(0);
- if (bytes > 0 && is_retr)
- ptransfer("received", bytes, &start, &stop);
- return;
-die:
-
-/* abort using RFC959 recommended IP,SYNC sequence */
-
- (void) gettimeofday(&stop, (struct timezone *)0);
-#ifdef SIGPIPE
- if (oldintp)
- (void) signal(SIGPIPE, oldintr);
-#endif
- (void) signal(SIGINT, SIG_IGN);
- if (!cpend) {
- code = -1;
- (void) signal(SIGINT, oldintr);
- return;
- }
-
- abort_remote(din);
- code = -1;
- if (data != INVALID_SOCKET) {
- (void) closesocket(data);
- data = INVALID_SOCKET;
- }
- if (closefunc != NULL && fout != NULL)
- (*closefunc)(fout);
- if (din) {
- (void) FCLOSE_SOCKET(din);
- din = NULL;
- }
- if (bytes > 0)
- ptransfer("received", bytes, &start, &stop);
- (void) signal(SIGINT, oldintr);
-}
-
-/*
- * Need to start a listen on the data channel before we send the command,
- * otherwise the server's connect may fail.
- */
-static int initconn()
-{
- register char *p, *a;
- int result, tmpno = 0;
- socklen_t len;
- int on = 1;
-#ifndef NO_PASSIVE_MODE
- int a1,a2,a3,a4,p1,p2;
-
- if (passivemode) {
- data = socket(AF_INET, SOCK_STREAM, 0);
- if (data == INVALID_SOCKET) {
- PERROR_SOCKET("ftp: socket");
- return(1);
- }
- if (options & SO_DEBUG &&
- setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) == SOCKET_ERROR)
- PERROR_SOCKET("ftp: setsockopt (ignored)");
- if (command("PASV") != COMPLETE) {
- printf("Passive mode refused. Turning off passive mode.\n");
- passivemode = 0;
- return initconn();
- }
-
-/*
- * What we've got at this point is a string of comma separated
- * one-byte unsigned integer values, separated by commas.
- * The first four are the an IP address. The fifth is the MSB
- * of the port number, the sixth is the LSB. From that we'll
- * prepare a sockaddr_in.
- */
-
- if (sscanf(pasv,"%d,%d,%d,%d,%d,%d",&a1,&a2,&a3,&a4,&p1,&p2) != 6) {
- printf("Passive mode address scan failure. Shouldn't happen!\n");
- return(1);
- };
-
- data_addr.sin_family = AF_INET;
- data_addr.sin_addr.s_addr = htonl((a1<<24)|(a2<<16)|(a3<<8)|a4);
- data_addr.sin_port = htons((p1<<8)|p2);
-
- if (connect(data, (struct sockaddr *) &data_addr, sizeof(data_addr)) == SOCKET_ERROR) {
- PERROR_SOCKET("ftp: connect");
- return(1);
- }
-#ifdef IP_TOS
-#ifdef IPTOS_THROUGHPUT
- on = IPTOS_THROUGHPUT;
- if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) == SOCKET_ERROR)
- PERROR_SOCKET("ftp: setsockopt TOS (ignored)");
-#endif
-#endif
- hisdataaddr = data_addr;
- return(0);
- }
-#endif
-
-noport:
- data_addr = myctladdr;
- if (sendport)
- data_addr.sin_port = 0; /* let system pick one */
- if (data != INVALID_SOCKET)
- (void) closesocket(data);
- data = socket(AF_INET, SOCK_STREAM, 0);
- if (data == INVALID_SOCKET) {
- PERROR_SOCKET("ftp: socket");
- if (tmpno)
- sendport = 1;
- return (1);
- }
- if (!sendport)
- if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) == SOCKET_ERROR) {
- PERROR_SOCKET("ftp: setsockopt (reuse address)");
- goto bad;
- }
- if (bind(data, (struct sockaddr *)&data_addr, sizeof (data_addr)) == SOCKET_ERROR) {
- PERROR_SOCKET("ftp: bind");
- goto bad;
- }
- if (options & SO_DEBUG &&
- setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) == SOCKET_ERROR)
- PERROR_SOCKET("ftp: setsockopt (ignored)");
- len = sizeof (data_addr);
- if (getsockname(data, (struct sockaddr *)&data_addr, &len) == SOCKET_ERROR) {
- PERROR_SOCKET("ftp: getsockname");
- goto bad;
- }
- if (listen(data, 1) == SOCKET_ERROR)
- PERROR_SOCKET("ftp: listen");
- if (sendport) {
- a = (char *)&data_addr.sin_addr;
- p = (char *)&data_addr.sin_port;
-#define UC(b) (((int)b)&0xff)
- result =
- command("PORT %d,%d,%d,%d,%d,%d",
- UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
- UC(p[0]), UC(p[1]));
- if (result == ERROR && sendport == -1) {
- sendport = 0;
- tmpno = 1;
- goto noport;
- }
- return (result != COMPLETE);
- }
- if (tmpno)
- sendport = 1;
-#ifdef IP_TOS
-#ifdef IPTOS_THROUGHPUT
- on = IPTOS_THROUGHPUT;
- if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) == SOCKET_ERROR)
- PERROR_SOCKET("ftp: setsockopt TOS (ignored)");
-#endif
-#endif
- return (0);
-bad:
- (void) closesocket(data), data = INVALID_SOCKET;
- if (tmpno)
- sendport = 1;
- return (1);
-}
-
-FILE *
-dataconn(char *lmode)
-{
- int s;
- socklen_t fromlen = sizeof (hisdataaddr);
-#ifdef IP_TOS
-#ifdef IPTOS_LOWDELAY
- int tos;
-#endif
-#endif
-
-#ifndef NO_PASSIVE_MODE
- if (passivemode)
- return (FDOPEN_SOCKET(data, lmode));
-#endif
- s = accept(data, (struct sockaddr *) &hisdataaddr, &fromlen);
- if (s == INVALID_SOCKET) {
- PERROR_SOCKET("ftp: accept");
- (void) closesocket(data), data = INVALID_SOCKET;
- return (NULL);
- }
- (void) closesocket(data);
- data = s;
-#ifdef IP_TOS
-#ifdef IPTOS_THROUGHPUT
- tos = IPTOS_THROUGHPUT;
- if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) == SOCKET_ERROR)
- PERROR_SOCKET("ftp: setsockopt TOS (ignored)");
-#endif
-#endif
- return (FDOPEN_SOCKET(data, lmode));
-}
-
-static void ptransfer(char *direction, long bytes,
- struct timeval *t0, struct timeval *t1)
-{
- struct timeval td;
- float s, kbs;
-
- if (verbose) {
- tvsub(&td, t1, t0);
- s = td.tv_sec + (td.tv_usec / 1000000.);
-#define nz(x) ((x) == 0 ? 1 : (x))
- kbs = (bytes / nz(s))/1024.0;
- printf("%ld bytes %s in %.2g seconds (%.2g Kbytes/s)\n",
- bytes, direction, s, kbs);
- }
-}
-
-/*tvadd(tsum, t0)
- struct timeval *tsum, *t0;
-{
-
- tsum->tv_sec += t0->tv_sec;
- tsum->tv_usec += t0->tv_usec;
- if (tsum->tv_usec > 1000000)
- tsum->tv_sec++, tsum->tv_usec -= 1000000;
-} */
-
-static void tvsub(struct timeval *tdiff, struct timeval *t1,
- struct timeval *t0)
-{
-
- tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
- tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
- if (tdiff->tv_usec < 0)
- tdiff->tv_sec--, tdiff->tv_usec += 1000000;
-}
-
-static sigtype
-psabort(int sig)
-{
- abrtflag++;
-}
-
-void pswitch(int flag)
-{
- sig_t oldintr;
- static struct comvars {
- int connect;
- char name[MAXHOSTNAMELEN];
- struct sockaddr_in mctl;
- struct sockaddr_in hctl;
- FILE *in;
- FILE *out;
- int tpe;
- int curtpe;
- int cpnd;
- int sunqe;
- int runqe;
- int mcse;
- int ntflg;
- char nti[17];
- char nto[17];
- int mapflg;
- char mi[MAXPATHLEN];
- char mo[MAXPATHLEN];
- char *authtype;
- int clvl;
- int dlvl;
- } proxstruct, tmpstruct;
- struct comvars *ip, *op;
-
- abrtflag = 0;
- oldintr = signal(SIGINT, psabort);
- if (flag) {
- if (proxy)
- return;
- ip = &tmpstruct;
- op = &proxstruct;
- proxy++;
- } else {
- if (!proxy)
- return;
- ip = &proxstruct;
- op = &tmpstruct;
- proxy = 0;
- }
- ip->connect = connected;
- connected = op->connect;
- if (hostname) {
- if (ip->name != hostname)
- (void) strncpy(ip->name, hostname, sizeof(ip->name) - 1);
- ip->name[strlen(ip->name)] = '\0';
- } else
- ip->name[0] = 0;
- hostname = op->name;
- ip->hctl = hisctladdr;
- hisctladdr = op->hctl;
- ip->mctl = myctladdr;
- myctladdr = op->mctl;
- ip->in = cin;
- cin = op->in;
- ip->out = cout;
- cout = op->out;
- ip->tpe = type;
- type = op->tpe;
- ip->curtpe = curtype;
- curtype = op->curtpe;
- ip->cpnd = cpend;
- cpend = op->cpnd;
- ip->sunqe = sunique;
- sunique = op->sunqe;
- ip->runqe = runique;
- runique = op->runqe;
- ip->mcse = mcase;
- mcase = op->mcse;
- ip->ntflg = ntflag;
- ntflag = op->ntflg;
- (void) strncpy(ip->nti, ntin, sizeof(ip->nti) - 1);
- (ip->nti)[strlen(ip->nti)] = '\0';
- (void) strncpy(ntin, op->nti, sizeof(ntin) - 1);
- ntin[sizeof(ntin) - 1] = '\0';
- (void) strncpy(ip->nto, ntout, sizeof(ip->nto) - 1);
- (ip->nto)[strlen(ip->nto)] = '\0';
- (void) strncpy(ntout, op->nto, sizeof(ntout) - 1);
- ntout[sizeof(ntout) - 1] = '\0';
- ip->mapflg = mapflag;
- mapflag = op->mapflg;
- (void) strncpy(ip->mi, mapin, MAXPATHLEN - 1);
- (ip->mi)[strlen(ip->mi)] = '\0';
- (void) strncpy(mapin, op->mi, sizeof(mapin) - 1);
- mapin[sizeof(mapin) - 1] = '\0';
- (void) strncpy(ip->mo, mapout, MAXPATHLEN - 1);
- (ip->mo)[strlen(ip->mo)] = '\0';
- (void) strncpy(mapout, op->mo, sizeof(mapout) - 1);
- mapout[sizeof(mapout) - 1] = '\0';
- ip->authtype = auth_type;
- auth_type = op->authtype;
- ip->clvl = clevel;
- clevel = op->clvl;
- ip->dlvl = dlevel;
- dlevel = op->dlvl;
- if (!clevel)
- clevel = PROT_C;
- if (!dlevel)
- dlevel = PROT_C;
- (void) signal(SIGINT, oldintr);
- if (abrtflag) {
- abrtflag = 0;
- if (oldintr)
- (*oldintr)(SIGINT);
- }
-}
-
-int ptabflg;
-
-static sigtype
-abortpt(int sig)
-{
- printf("\n");
- (void) fflush(stdout);
- ptabflg++;
- mflag = 0;
- abrtflag = 0;
- longjmp(ptabort, 1);
-}
-
-static void
-proxtrans(char *cmd, char *local, char *remote)
-{
- volatile sig_t oldintr;
- volatile int secndflag = 0;
- int prox_type, nfnd;
- char *volatile cmd2;
- fd_set mask;
-
- if (strcmp(cmd, "RETR"))
- cmd2 = "RETR";
- else
- cmd2 = runique ? "STOU" : "STOR";
- if ((prox_type = type) == 0) {
- if (unix_server && unix_proxy)
- prox_type = TYPE_I;
- else
- prox_type = TYPE_A;
- }
- if (curtype != prox_type)
- changetype(prox_type, 1);
- if (command("PASV") != COMPLETE) {
- printf("proxy server does not support third party transfers.\n");
- return;
- }
- pswitch(0);
- if (!connected) {
- printf("No primary connection\n");
- pswitch(1);
- code = -1;
- return;
- }
- if (curtype != prox_type)
- changetype(prox_type, 1);
- if (command("PORT %s", pasv) != COMPLETE) {
- pswitch(1);
- return;
- }
- if (setjmp(ptabort))
- goto die;
- oldintr = signal(SIGINT, abortpt);
- if (command("%s %s", cmd, remote) != PRELIM) {
- (void) signal(SIGINT, oldintr);
- pswitch(1);
- return;
- }
- sleep(2);
- pswitch(1);
- secndflag++;
- if (command("%s %s", cmd2, local) != PRELIM)
- goto die;
- ptflag++;
- (void) getreply(0);
- pswitch(0);
- (void) getreply(0);
- (void) signal(SIGINT, oldintr);
- pswitch(1);
- ptflag = 0;
- printf("local: %s remote: %s\n", local, remote);
- return;
-die:
- (void) signal(SIGINT, SIG_IGN);
- ptflag = 0;
- if (strcmp(cmd, "RETR") && !proxy)
- pswitch(1);
- else if (!strcmp(cmd, "RETR") && proxy)
- pswitch(0);
- if (!cpend && !secndflag) { /* only here if cmd = "STOR" (proxy=1) */
- if (command("%s %s", cmd2, local) != PRELIM) {
- pswitch(0);
- if (cpend)
- abort_remote((FILE *) NULL);
- }
- pswitch(1);
- if (ptabflg)
- code = -1;
- (void) signal(SIGINT, oldintr);
- return;
- }
- if (cpend)
- abort_remote((FILE *) NULL);
- pswitch(!proxy);
- if (!cpend && !secndflag) { /* only if cmd = "RETR" (proxy=1) */
- if (command("%s %s", cmd2, local) != PRELIM) {
- pswitch(0);
- if (cpend)
- abort_remote((FILE *) NULL);
- pswitch(1);
- if (ptabflg)
- code = -1;
- (void) signal(SIGINT, oldintr);
- return;
- }
- }
- if (cpend)
- abort_remote((FILE *) NULL);
- pswitch(!proxy);
- if (cpend) {
- FD_ZERO(&mask);
- FD_SET(SOCKETNO(fileno(cin)), &mask);
- if ((nfnd = empty(&mask, 10)) <= 0) {
- if (nfnd < 0) {
- perror("abort");
- }
- if (ptabflg)
- code = -1;
- lostpeer();
- }
- (void) getreply(0);
- (void) getreply(0);
- }
- if (proxy)
- pswitch(0);
- pswitch(1);
- if (ptabflg)
- code = -1;
- (void) signal(SIGINT, oldintr);
-}
-
-void reset()
-{
- fd_set mask;
- int nfnd = 1;
-
- FD_ZERO(&mask);
- while (nfnd > 0) {
- FD_SET(SOCKETNO(fileno(cin)), &mask);
- if ((nfnd = empty(&mask,0)) < 0) {
- perror("reset");
- code = -1;
- lostpeer();
- }
- else if (nfnd) {
- (void) getreply(0);
- }
- }
-}
-
-static char *
-gunique(char *local)
-{
- static char new[MAXPATHLEN];
- char *cp = strrchr(local, '/');
- int d, count=0;
- char ext = '1';
-
- if (cp)
- *cp = '\0';
- d = access(cp ? local : ".", 2);
- if (cp)
- *cp = '/';
- if (d < 0) {
- fprintf(stderr, "local: %s: %s\n", local, strerror(errno));
- return((char *) 0);
- }
- (void) strncpy(new, local, sizeof(new) - 3);
- new[sizeof(new) - 1] = '\0';
- cp = new + strlen(new);
- *cp++ = '.';
- while (!d) {
- if (++count == 100) {
- printf("runique: can't find unique file name.\n");
- return((char *) 0);
- }
- *cp++ = ext;
- *cp = '\0';
- if (ext == '9')
- ext = '0';
- else
- ext++;
- if ((d = access(new, 0)) < 0)
- break;
- if (ext != '0')
- cp--;
- else if (*(cp - 2) == '.')
- *(cp - 1) = '1';
- else {
- *(cp - 2) = *(cp - 2) + 1;
- cp--;
- }
- }
- return(new);
-}
-
-#ifdef GSSAPI
-static const struct {
- gss_OID mech_type;
- char *service_name;
-} gss_trials[] = {
- { GSS_C_NO_OID, "ftp" },
- { GSS_C_NO_OID, "host" },
-};
-static const int n_gss_trials = sizeof(gss_trials)/sizeof(gss_trials[0]);
-#endif /* GSSAPI */
-
-int do_auth()
-{
- int oldverbose = verbose;
-#ifdef GSSAPI
- u_char out_buf[FTP_BUFSIZ];
- int i;
-#endif /* GSSAPI */
-
- if (auth_type) return(1); /* auth already succeeded */
-
- /* Other auth types go here ... */
-
-#ifdef GSSAPI
- if (command("AUTH %s", "GSSAPI") == CONTINUE) {
- OM_uint32 maj_stat, min_stat, dummy_stat;
- gss_name_t target_name;
- gss_buffer_desc send_tok, recv_tok, *token_ptr;
- char stbuf[FTP_BUFSIZ];
- int comcode, trial;
- struct gss_channel_bindings_struct chan;
- chan.initiator_addrtype = GSS_C_AF_INET; /* OM_uint32 */
- chan.initiator_address.length = 4;
- chan.initiator_address.value = &myctladdr.sin_addr.s_addr;
- chan.acceptor_addrtype = GSS_C_AF_INET; /* OM_uint32 */
- chan.acceptor_address.length = 4;
- chan.acceptor_address.value = &hisctladdr.sin_addr.s_addr;
- chan.application_data.length = 0;
- chan.application_data.value = 0;
-
- if (verbose)
- printf("GSSAPI accepted as authentication type\n");
-
- /* blob from gss-client */
-
- for (trial = 0; trial < n_gss_trials; trial++) {
- /* ftp@hostname first, the host@hostname */
- /* the V5 GSSAPI binding canonicalizes this for us... */
- snprintf(stbuf, sizeof(stbuf), "%s@%s",
- gss_trials[trial].service_name, hostname);
- if (debug)
- fprintf(stderr, "Trying to authenticate to <%s>\n", stbuf);
-
- send_tok.value = stbuf;
- send_tok.length = strlen(stbuf) + 1;
- maj_stat = gss_import_name(&min_stat, &send_tok,
- gss_nt_service_name, &target_name);
-
- if (maj_stat != GSS_S_COMPLETE) {
- user_gss_error(maj_stat, min_stat, "parsing name");
- secure_error("name parsed <%s>\n", stbuf);
- continue;
- }
-
- token_ptr = GSS_C_NO_BUFFER;
- gcontext = GSS_C_NO_CONTEXT; /* structure copy */
-
- do {
- if (debug)
- fprintf(stderr, "calling gss_init_sec_context\n");
- maj_stat =
- gss_init_sec_context(&min_stat,
- GSS_C_NO_CREDENTIAL,
- &gcontext,
- target_name,
- (gss_OID_desc *)gss_trials[trial].mech_type,
- GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG |
- (forward ? GSS_C_DELEG_FLAG :
- (unsigned) 0),
- 0,
- &chan, /* channel bindings */
- token_ptr,
- NULL, /* ignore mech type */
- &send_tok,
- NULL, /* ignore ret_flags */
- NULL); /* ignore time_rec */
-
-
- if (maj_stat!=GSS_S_COMPLETE && maj_stat!=GSS_S_CONTINUE_NEEDED){
- if (trial == n_gss_trials-1)
- user_gss_error(maj_stat, min_stat, "initializing context");
- /* could just be that we missed on the service name */
- goto outer_loop;
- }
-
- if (send_tok.length != 0) {
- int len = send_tok.length;
- reply_parse = "ADAT="; /* for command() later */
- oldverbose = verbose;
- verbose = (trial == n_gss_trials-1)?0:-1;
- kerror = radix_encode(send_tok.value, out_buf, &len, 0);
- gss_release_buffer(&dummy_stat, &send_tok);
- if (kerror) {
- fprintf(stderr, "Base 64 encoding failed: %s\n",
- radix_error(kerror));
- } else if ((comcode = command("ADAT %s", out_buf))!=COMPLETE
- && comcode != 3 /* (335) */) {
- if (trial == n_gss_trials-1) {
- fprintf(stderr, "GSSAPI ADAT failed\n");
- /* force out of loop */
- maj_stat = GSS_S_FAILURE;
- }
- /* backoff to the v1 gssapi is still possible. Send
- a new AUTH command. If that fails, terminate the
- loop */
- if (command("AUTH %s", "GSSAPI") != CONTINUE) {
- fprintf(stderr,
- "GSSAPI ADAT failed, AUTH restart failed\n");
- /* force out of loop */
- maj_stat = GSS_S_FAILURE;
- }
- goto outer_loop;
- } else if (!reply_parse) {
- fprintf(stderr,
- "No authentication data received from server\n");
- if (maj_stat == GSS_S_COMPLETE) {
- fprintf(stderr, "...but no more was needed\n");
- goto gss_complete_loop;
- } else {
- user_gss_error(maj_stat, min_stat, "no reply, huh?");
- goto gss_complete_loop;
- }
- } else if ((kerror = radix_encode((unsigned char *)reply_parse,
- out_buf,&i,1))) {
- fprintf(stderr, "Base 64 decoding failed: %s\n",
- radix_error(kerror));
- } else {
- /* everything worked */
- token_ptr = &recv_tok;
- recv_tok.value = out_buf;
- recv_tok.length = i;
- continue;
- }
-
- /* get out of loop clean */
- gss_complete_loop:
- trial = n_gss_trials-1;
- goto outer_loop;
- }
- } while (maj_stat == GSS_S_CONTINUE_NEEDED);
- outer_loop:
- gss_release_name(&dummy_stat, &target_name);
- if (maj_stat == GSS_S_COMPLETE)
- break;
- }
- verbose = oldverbose;
- if (maj_stat == GSS_S_COMPLETE) {
- printf("GSSAPI authentication succeeded\n");
- reply_parse = NULL;
- auth_type = "GSSAPI";
- return(1);
- } else {
- fprintf(stderr, "GSSAPI authentication failed\n");
- verbose = oldverbose;
- reply_parse = NULL;
- }
- }
-#endif /* GSSAPI */
-
- /* Other auth types go here ... */
-
- return(0);
-}
-
-void
-setpbsz(unsigned int size)
-{
- int oldverbose;
-
- if (ucbuf) (void) free(ucbuf);
- actualbuf = size;
- while ((ucbuf = (unsigned char *)malloc(actualbuf)) == NULL)
- if (actualbuf)
- actualbuf >>= 2;
- else {
- perror("Error while trying to malloc PROT buffer:");
- exit(1);
- }
- oldverbose = verbose;
- verbose = 0;
- reply_parse = "PBSZ=";
- if (command("PBSZ %u", actualbuf) != COMPLETE)
- fatal("Cannot set PROT buffer size");
- if (reply_parse) {
- if ((maxbuf = (unsigned int) atol(reply_parse)) > actualbuf)
- maxbuf = actualbuf;
- } else maxbuf = actualbuf;
- reply_parse = NULL;
- verbose = oldverbose;
-}
-
-static void abort_remote(FILE *din)
-{
- char buf[FTP_BUFSIZ];
- int nfnd;
- fd_set mask;
-
- /*
- * send IAC in urgent mode instead of DM because 4.3BSD places oob mark
- * after urgent byte rather than before as is protocol now
- */
- snprintf(buf, sizeof(buf), "%c%c%c", IAC, IP, IAC);
- if (send(SOCKETNO(fileno(cout)), buf, 3, MSG_OOB) != 3)
- PERROR_SOCKET("abort");
- putc(DM, cout);
- (void) secure_command("ABOR");
- FD_ZERO(&mask);
- FD_SET(SOCKETNO(fileno(cin)), &mask);
- if (din) {
- FD_SET(SOCKETNO(fileno(din)), &mask);
- }
- if ((nfnd = empty(&mask, 10)) <= 0) {
- if (nfnd < 0) {
- perror("abort");
- }
- if (ptabflg)
- code = -1;
- lostpeer();
- }
- if (din && FD_ISSET(SOCKETNO(fileno(din)), &mask)) {
- /* Security: No threat associated with this read. */
- while (read(fileno(din), buf, FTP_BUFSIZ) > 0)
- /* LOOP */;
- }
- if (getreply(0) == ERROR && code == 552) {
- /* 552 needed for nic style abort */
- (void) getreply(0);
- }
- (void) getreply(0);
-}
-
-#ifdef GSSAPI
-void user_gss_error(OM_uint32 maj_stat, OM_uint32 min_stat, char *s)
-{
- /* a lot of work just to report the error */
- OM_uint32 gmaj_stat, gmin_stat, msg_ctx;
- gss_buffer_desc msg;
- msg_ctx = 0;
- while (!msg_ctx) {
- gmaj_stat = gss_display_status(&gmin_stat, maj_stat,
- GSS_C_GSS_CODE,
- GSS_C_NULL_OID,
- &msg_ctx, &msg);
- if ((gmaj_stat == GSS_S_COMPLETE)||
- (gmaj_stat == GSS_S_CONTINUE_NEEDED)) {
- fprintf(stderr, "GSSAPI error major: %s\n",
- (char*)msg.value);
- (void) gss_release_buffer(&gmin_stat, &msg);
- }
- if (gmaj_stat != GSS_S_CONTINUE_NEEDED)
- break;
- }
- msg_ctx = 0;
- while (!msg_ctx) {
- gmaj_stat = gss_display_status(&gmin_stat, min_stat,
- GSS_C_MECH_CODE,
- GSS_C_NULL_OID,
- &msg_ctx, &msg);
- if ((gmaj_stat == GSS_S_COMPLETE)||
- (gmaj_stat == GSS_S_CONTINUE_NEEDED)) {
- fprintf(stderr, "GSSAPI error minor: %s\n",
- (char*)msg.value);
- (void) gss_release_buffer(&gmin_stat, &msg);
- }
- if (gmaj_stat != GSS_S_CONTINUE_NEEDED)
- break;
- }
- fprintf(stderr, "GSSAPI error: %s\n", s);
-}
-
-void secure_gss_error(OM_uint32 maj_stat, OM_uint32 min_stat, char *s)
-{
- user_gss_error(maj_stat, min_stat, s);
- return;
-}
-#endif /* GSSAPI */
-
-#ifdef _WIN32
-
-int gettimeofday(struct timeval *tv, void *tz)
-{
- struct _timeb tb;
- _tzset();
- _ftime(&tb);
- if (tv) {
- tv->tv_sec = tb.time;
- tv->tv_usec = tb.millitm * 1000;
- }
-#if 0
- if (tz) {
- tz->tz_minuteswest = tb.timezone;
- tz->tz_dsttime = tb.dstflag;
- }
-#else
- _ASSERTE(!tz);
-#endif
- return 0;
-}
-
-int fclose_socket(FILE* f)
-{
- int rc = 0;
- SOCKET _s = _get_osfhandle(_fileno(f));
-
- rc = fclose(f);
- if (rc)
- return rc;
- if (closesocket(_s) == SOCKET_ERROR)
- return SOCKET_ERRNO;
- return 0;
-}
-
-FILE* fdopen_socket(SOCKET s, char* mode)
-{
- int o_mode = 0;
- int old_fmode = _fmode;
- FILE* f = 0;
-
- if (strstr(mode, "a+")) o_mode |= _O_RDWR | _O_APPEND;
- if (strstr(mode, "r+")) o_mode |= _O_RDWR;
- if (strstr(mode, "w+")) o_mode |= _O_RDWR;
- if (strchr(mode, 'a')) o_mode |= _O_WRONLY | _O_APPEND;
- if (strchr(mode, 'r')) o_mode |= _O_RDONLY;
- if (strchr(mode, 'w')) o_mode |= _O_WRONLY;
-
- /* In theory, _open_osfhandle only takes: _O_APPEND, _O_RDONLY, _O_TEXT */
-
- _fmode = _O_BINARY;
- f = fdopen(_open_osfhandle(s, o_mode), mode);
- _fmode = old_fmode;
-
- return f;
-}
-#endif /* _WIN32 */
+++ /dev/null
-/*
- * Copyright (c) 1985, 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.
- *
- * @(#)ftp_var.h 5.9 (Berkeley) 6/1/90
- */
-
-#ifdef _WIN32
-#include <windows.h>
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#endif
-
-#ifdef _WIN32
-int fclose_socket(FILE* f);
-FILE* fdopen_socket(SOCKET s, char* mode);
-#define FCLOSE_SOCKET(f) fclose_socket(f)
-#define FDOPEN_SOCKET(s, mode) fdopen_socket(s, mode)
-#define SOCKETNO(fd) _get_osfhandle(fd)
-#define PERROR_SOCKET(str) do { errno = SOCKET_ERRNO; perror(str); } while(0)
-#else
-#define FCLOSE_SOCKET(f) fclose(f)
-#define FDOPEN_SOCKET(s, mode) fdopen(s, mode)
-#define SOCKETNO(fd) (fd)
-#define PERROR_SOCKET(str) perror(str)
-#endif
-
-#ifdef _WIN32
-typedef void (*sig_t)(int);
-typedef void sigtype;
-#else
-#define sig_t my_sig_t
-#define sigtype krb5_sigtype
-typedef sigtype (*sig_t)();
-#endif
-
-/*
- * FTP global variables.
- */
-
-#ifdef DEFINITIONS
-#define extern
-#endif
-
-/*
- * Options and other state info.
- */
-extern int trace; /* trace packets exchanged */
-extern int hash; /* print # for each buffer transferred */
-extern int sendport; /* use PORT cmd for each data connection */
-extern int verbose; /* print messages coming back from server */
-extern int connected; /* connected to server */
-extern int fromatty; /* input is from a terminal */
-extern int interactive; /* interactively prompt on m* cmds */
-extern int debug; /* debugging level */
-extern int bell; /* ring bell on cmd completion */
-extern int doglob; /* glob local file names */
-extern int autoauth; /* Do authentication on connect */
-extern int autologin; /* establish user account on connection */
-extern int autoencrypt; /* negotiate encryption on connection */
-extern int forward; /* forward credentials */
-extern int proxy; /* proxy server connection active */
-extern int proxflag; /* proxy connection exists */
-extern int sunique; /* store files on server with unique name */
-extern int runique; /* store local files with unique name */
-extern int mcase; /* map upper to lower case for mget names */
-extern int ntflag; /* use ntin ntout tables for name translation */
-extern int mapflag; /* use mapin mapout templates on file names */
-extern int code; /* return/reply code for ftp command */
-extern int crflag; /* if 1, strip car. rets. on ascii gets */
-extern char pasv[64]; /* passive port for proxy data connection */
-#ifndef NO_PASSIVE_MODE
-extern int passivemode; /* passive mode enabled */
-#endif
-extern char *altarg; /* argv[1] with no shell-like preprocessing */
-extern char ntin[17]; /* input translation table */
-extern char ntout[17]; /* output translation table */
-#ifdef _WIN32
-#ifndef MAXPATHLEN
-#define MAXPATHLEN MAX_PATH
-#endif
-#else
-#include <sys/param.h>
-#endif
-extern char mapin[MAXPATHLEN]; /* input map template */
-extern char mapout[MAXPATHLEN]; /* output map template */
-extern int clevel; /* command channel protection level */
-extern int dlevel; /* data channel protection level */
-extern int type; /* requested file transfer type */
-extern int curtype; /* current file transfer type */
-extern int stru; /* file transfer structure */
-extern int form; /* file transfer format */
-extern int mode; /* file transfer mode */
-extern char bytename[32]; /* local byte size in ascii */
-extern int bytesize; /* local byte size in binary */
-
-extern char *hostname; /* name of host connected to */
-extern int unix_server; /* server is unix, can use binary for ascii */
-extern int unix_proxy; /* proxy is unix, can use binary for ascii */
-
-extern struct servent *sp; /* service spec for tcp/ftp */
-
-#include <setjmp.h>
-extern jmp_buf toplevel; /* non-local goto stuff for cmd scanner */
-
-extern char line[500]; /* input line buffer */
-extern char *stringbase; /* current scan point in line buffer */
-extern char argbuf[500]; /* argument storage buffer */
-extern char *argbase; /* current storage point in arg buffer */
-extern int margc; /* count of arguments on input line */
-extern char *margv[20]; /* args parsed from input line */
-extern int cpend; /* flag: if != 0, then pending server reply */
-extern int mflag; /* flag: if != 0, then active multi command */
-
-extern int options; /* used during socket creation */
-
-/*
- * Format of command table.
- */
-struct cmd {
- char *c_name; /* name of command */
- char *c_help; /* help string */
- char c_bell; /* give bell when command completes */
- char c_conn; /* must be connected to use command */
- char c_proxy; /* proxy server may execute */
- void (*c_handler)(); /* function to call */
-};
-
-struct macel {
- char mac_name[9]; /* macro name */
- char *mac_start; /* start of macro in macbuf */
- char *mac_end; /* end of macro in macbuf */
-};
-
-extern int macnum; /* number of defined macros */
-extern struct macel macros[16];
-extern char macbuf[4096];
-
-#ifdef DEFINITIONS
-#undef extern
-#endif
-
-extern char *tail();
-#ifndef _WIN32
-extern char *mktemp();
-#endif
-
-extern int command(char *, ...)
-#if !defined(__cplusplus) && (__GNUC__ > 2)
- __attribute__((__format__(__printf__, 1, 2)))
-#endif
- ;
-
-char *remglob (char **, int);
-int another (int *, char ***, char *);
-void makeargv (void);
-void setpeer (int, char **);
-void setclevel (int, char **);
-void setdlevel (int, char **);
-void ccc (void);
-void setclear (void);
-void setsafe (void);
-void setprivate (void);
-void settype (int, char **);
-void changetype (int, int);
-void setbinary (void);
-void setascii (void);
-void settenex (void);
-void set_mode (int, char **);
-void setform (int, char **);
-void setstruct (int, char **);
-void siteidle (int, char **);
-void put (int, char **);
-void mput (int, char **);
-void reget (int, char **);
-void get (int, char **);
-void mget (int, char **);
-void status (int, char **);
-void setbell (void);
-void settrace (void);
-void sethash (void);
-void setverbose (void);
-void setport (void);
-void setprompt (void);
-void setglob (void);
-void setdebug (int, char **);
-void cd (int, char **);
-void lcd (int, char **);
-void delete_file (int, char **);
-void mdelete (int, char **);
-void renamefile (int, char **);
-void ls (int, char **);
-void mls (int, char **);
-void shell (int, char **);
-void user (int, char **);
-void pwd (void);
-void makedir (int, char **);
-void removedir (int, char **);
-void quote (int, char **);
-void site (int, char **);
-void do_chmod (int, char **);
-void do_umask (int, char **);
-void setidle (int, char **);
-void rmthelp (int, char **);
-void quit (void);
-void disconnect (void);
-void fatal (char *);
-void account (int, char **);
-void doproxy (int, char **);
-void setcase (void);
-void setcr (void);
-void setntrans (int, char **);
-void setnmap (int, char **);
-void setsunique (void);
-void setrunique (void);
-void cdup (void);
-void restart (int, char **);
-void syst (void);
-void macdef (int, char **);
-void sizecmd (int, char **);
-void modtime (int, char **);
-void rmtstatus (int, char **);
-void newer (int, char **);
-void setpassive (void);
-
-/* ftp.c */
-void sendrequest (char *, char *, char *, int);
-void recvrequest (char *, char *volatile, char *, char *, int, int);
-int login (char *);
-void setpbsz (unsigned int);
-void pswitch (int);
-int getreply (int);
-void reset (void);
-char *hookup (char *, int);
-int do_auth (void);
-
-/* glob.c */
-void blkfree (char **);
-
-/* domacro.c */
-void domacro (int, char **);
-
-
-/* main.c */
-void help (int, char **);
-struct cmd *getcmd (char *);
-
-
-/* ruserpass.c */
-int ruserpass (char *, char **, char **, char **);
-
-/* radix.h */
-int radix_encode (unsigned char *, unsigned char *, int *, int);
-char *radix_error (int);
-
-/* getpass.c */
-char *mygetpass (char *);
-
-/* glob.c */
-char **ftpglob (char *);
+++ /dev/null
-/*
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)getpass.c 1.1 90/04/28 SMI"; /* from UCB 5.4 3/7/86 */
-#endif /* not lint */
-
-#ifdef _WIN32
-#include <io.h>
-#include <windows.h>
-#include <stdio.h>
-
-static DWORD old_mode;
-static HANDLE cons_handle;
-
-BOOL WINAPI
-GetPassConsoleControlHandler(DWORD dwCtrlType)
-{
- switch(dwCtrlType){
- case CTRL_BREAK_EVENT:
- case CTRL_C_EVENT:
- printf("Interrupt\n");
- fflush(stdout);
- (void) SetConsoleMode(cons_handle, old_mode);
- ExitProcess(-1);
- break;
- default:
- break;
- }
- return TRUE;
-}
-
-char *
-mygetpass(char *prompt)
-{
- DWORD new_mode;
- char *ptr;
- int scratchchar;
- static char password[50+1];
- int pwsize = sizeof(password);
-
- cons_handle = GetStdHandle(STD_INPUT_HANDLE);
- if (cons_handle == INVALID_HANDLE_VALUE)
- return NULL;
- if (!GetConsoleMode(cons_handle, &old_mode))
- return NULL;
-
- new_mode = old_mode;
- new_mode |= ( ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT );
- new_mode &= ~( ENABLE_ECHO_INPUT );
-
- if (!SetConsoleMode(cons_handle, new_mode))
- return NULL;
-
- SetConsoleCtrlHandler(&GetPassConsoleControlHandler, TRUE);
-
- (void) fputs(prompt, stdout);
- (void) fflush(stdout);
- (void) memset(password, 0, pwsize);
-
- if (fgets(password, pwsize, stdin) == NULL) {
- if (ferror(stdin))
- goto out;
- (void) putchar('\n');
- }
- else {
- (void) putchar('\n');
-
- if ((ptr = strchr(password, '\n')))
- *ptr = '\0';
- else /* need to flush */
- do {
- scratchchar = getchar();
- } while (scratchchar != EOF && scratchchar != '\n');
- }
-
-out:
- (void) SetConsoleMode(cons_handle, old_mode);
- SetConsoleCtrlHandler(&GetPassConsoleControlHandler, FALSE);
-
- return password;
-}
-
-#else /* !_WIN32 */
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#include <stdio.h>
-#include <signal.h>
-
-#if defined (POSIX) || defined (POSIX_TERMIOS)
-#include <termios.h>
-static struct termios ttyo, ttyb;
-#define stty(f, t) tcsetattr(f, TCSANOW, t)
-#define gtty(f, t) tcgetattr(f, t)
-#else
-#include <sgtty.h>
-static struct sgttyb ttyo, ttyb;
-#endif
-
-#include "ftp_var.h"
-
-static FILE *fi;
-
-static sigtype
-intfix(sig)
- int sig;
-{
- if (fi != NULL)
- (void) stty(fileno(fi), &ttyo);
- exit(SIGINT);
-}
-
-char *
-mygetpass(prompt)
-char *prompt;
-{
- register char *p;
- register int c;
- static char pbuf[50+1];
- sigtype (*sig)();
-
- if ((fi = fopen("/dev/tty", "r")) == NULL)
- fi = stdin;
- else
- setbuf(fi, (char *)NULL);
- sig = signal(SIGINT, intfix);
- (void) gtty(fileno(fi), &ttyb);
- ttyo = ttyb;
-#if defined (POSIX) || defined (POSIX_TERMIOS)
- ttyb.c_lflag &= ~ECHO;
-#else
- ttyb.sg_flags &= ~ECHO;
-#endif
- (void) stty(fileno(fi), &ttyb);
- fprintf(stderr, "%s", prompt); (void) fflush(stderr);
- for (p=pbuf; (c = getc(fi))!='\n' && c!=EOF;) {
- if (p < &pbuf[sizeof(pbuf)-1])
- *p++ = c;
- }
- *p = '\0';
- fprintf(stderr, "\n"); (void) fflush(stderr);
- (void) stty(fileno(fi), &ttyo);
- (void) signal(SIGINT, sig);
- if (fi != stdin)
- (void) fclose(fi);
- return(pbuf);
-}
-
-#endif /* !_WIN32 */
+++ /dev/null
-/*
- * Copyright (c) 1980 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 lint
-static char sccsid[] = "@(#)glob.c 5.9 (Berkeley) 2/25/91";
-#endif /* not lint */
-
-/*
- * C-shell glob for random programs.
- */
-
-#include <sys/stat.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#ifndef _WIN32
-#include <sys/param.h>
-#include <dirent.h>
-#include <pwd.h>
-#endif
-
-#ifdef POSIX
-#include <limits.h>
-#endif
-
-#include <k5-platform.h>
-
-#include "ftp_var.h"
-
-#ifdef ARG_MAX
-#undef NCARGS
-#define NCARGS ARG_MAX
-#endif
-
-#ifndef NCARGS
-#define NCARGS 4096
-#endif
-
-#define QUOTE 0200
-#define TRIM 0177
-#define eq(a,b) (strcmp(a, b)==0)
-#define GAVSIZ (NCARGS/6)
-#define isdir(d) ((d.st_mode & S_IFMT) == S_IFDIR)
-
-static char **gargv; /* Pointer to the (stack) arglist */
-static int gargc; /* Number args in gargv */
-static int gnleft;
-static short gflag;
-char **ftpglob();
-char *globerr;
-char *home;
-static char *strspl (char *, char *), *strend (char *);
-char **copyblk (char **);
-
-static void acollect (char *), addpath (int),
- collect (char *), expand (char *),
- Gcat (char *, char *);
-static void ginit (char **), matchdir (char *),
- rscan (char **, int (*f)()), sort (void);
-static int amatch (char *, char *),
- execbrc (char *, char *), match (char *, char *);
-static int digit (int), letter (int),
- any (int, char *);
-#ifndef _WIN32
-static int gethdir (char *);
-#endif
-static int tglob (int );
-
-static int globcnt;
-
-char *globchars = "`{[*?";
-
-static char *gpath, *gpathp, *lastgpathp;
-static int globbed;
-static char *entp;
-static char **sortbas;
-
-char **
-ftpglob(v)
- register char *v;
-{
- char agpath[FTP_BUFSIZ];
- char *agargv[GAVSIZ];
- char *vv[2];
- vv[0] = v;
- vv[1] = 0;
- gflag = 0;
- rscan(vv, tglob);
- if (gflag == 0) {
- /* Caller will always free the contents, so make a copy. */
- size_t len = strlen (v) + 1;
- vv[0] = malloc (len);
- if (vv[0] == 0) {
- globerr = "Can't allocate memory";
- return 0;
- }
- memcpy (vv[0], v, len);
- return (copyblk(vv));
- }
-
- globerr = 0;
- gpath = agpath; gpathp = gpath; *gpathp = 0;
- lastgpathp = &gpath[sizeof(agpath) - 1];
- ginit(agargv); globcnt = 0;
- collect(v);
- if (globcnt == 0 && (gflag&1)) {
- blkfree(gargv), gargv = 0;
- return (0);
- } else
- return (gargv = copyblk(gargv));
-}
-
-static void
-ginit(agargv)
- char **agargv;
-{
-
- agargv[0] = 0; gargv = agargv; sortbas = agargv; gargc = 0;
- gnleft = NCARGS - 4;
-}
-
-static void
-collect(as)
- register char *as;
-{
- if (eq(as, "{") || eq(as, "{}")) {
- Gcat(as, "");
- sort();
- } else
- acollect(as);
-}
-
-static void
-acollect(as)
- register char *as;
-{
- register int ogargc = gargc;
-
- gpathp = gpath; *gpathp = 0; globbed = 0;
- expand(as);
- if (gargc != ogargc)
- sort();
-}
-
-static void
-sort()
-{
- register char **p1, **p2, *c;
- char **Gvp = &gargv[gargc];
-
- p1 = sortbas;
- while (p1 < Gvp-1) {
- p2 = p1;
- while (++p2 < Gvp)
- if (strcmp(*p1, *p2) > 0)
- c = *p1, *p1 = *p2, *p2 = c;
- p1++;
- }
- sortbas = Gvp;
-}
-
-static void
-expand(as)
- char *as;
-{
- register char *cs;
- register char *sgpathp, *oldcs;
- struct stat stb;
-
- sgpathp = gpathp;
- cs = as;
-#ifndef _WIN32
- if (*cs == '~' && gpathp == gpath) {
- addpath('~');
- for (cs++; letter(*cs) || digit(*cs) || *cs == '-';)
- addpath(*cs++);
- if (!*cs || *cs == '/') {
- if (gpathp != gpath + 1) {
- *gpathp = 0;
- if (gethdir(gpath + 1))
- globerr = "Unknown user name after ~";
- (void) memmove(gpath, gpath + 1,
- strlen(gpath));
- } else
- (void) strncpy(gpath, home, FTP_BUFSIZ - 1);
- gpath[FTP_BUFSIZ - 1] = '\0';
- gpathp = strend(gpath);
- }
- }
-#endif
- while (!any(*cs, globchars)) {
- if (*cs == 0) {
- if (!globbed)
- Gcat(gpath, "");
- else if (stat(gpath, &stb) >= 0) {
- Gcat(gpath, "");
- globcnt++;
- }
- goto endit;
- }
- addpath(*cs++);
- }
- oldcs = cs;
- while (cs > as && *cs != '/')
- cs--, gpathp--;
- if (*cs == '/')
- cs++, gpathp++;
- *gpathp = 0;
- if (*oldcs == '{') {
- (void) execbrc(cs, ((char *)0));
- return;
- }
- matchdir(cs);
-endit:
- gpathp = sgpathp;
- *gpathp = 0;
-}
-
-#ifdef _WIN32
-
-static void
-matchdir(pattern)
- char *pattern;
-{
- HANDLE hFile = INVALID_HANDLE_VALUE;
- WIN32_FIND_DATA file_data;
- char *base = *gpath ? gpath : ".";
- char *buffer = 0;
-
- if (asprintf(&buffer, "%s\\*", base) < 0) return;
- hFile = FindFirstFile(buffer, &file_data);
- if (hFile == INVALID_HANDLE_VALUE) {
- if (!globbed)
- globerr = "Bad directory components";
- return;
- }
- do {
- if (match(file_data.cFileName, pattern)) {
- Gcat(gpath, file_data.cFileName);
- globcnt++;
- }
- } while (FindNextFile(hFile, &file_data));
- FindClose(hFile);
-}
-
-#else /* !_WIN32 */
-
-static void
-matchdir(pattern)
- char *pattern;
-{
-#if 0
- struct stat stb;
-#endif
- register struct dirent *dp;
- DIR *dirp;
-
- dirp = opendir(*gpath?gpath:".");
- if (dirp == NULL) {
- if (globbed)
- return;
- goto patherr2;
- }
- /* This fails on systems where you can't inspect the contents of
- the DIR structure. If there are systems whose opendir does
- not check for a directory, then use stat, not fstat. */
-#if 0
- if (fstat(dirp->dd_fd, &stb) < 0)
- goto patherr1;
- if (!isdir(stb)) {
- errno = ENOTDIR;
- goto patherr1;
- }
-#endif
- while ((dp = readdir(dirp)) != NULL) {
- if (dp->d_ino == 0)
- continue;
- if (match(dp->d_name, pattern)) {
- Gcat(gpath, dp->d_name);
- globcnt++;
- }
- }
- closedir(dirp);
- return;
-
-#if 0
-patherr1:
-#endif
- closedir(dirp);
-patherr2:
- globerr = "Bad directory components";
-}
-
-#endif /* !_WIN32 */
-
-static int
-execbrc(p, s)
- char *p, *s;
-{
- char restbuf[FTP_BUFSIZ + 2];
- register char *pe, *pm, *pl;
- int brclev = 0;
- char *lm, savec, *sgpathp;
-
- for (lm = restbuf; *p != '{'; *lm++ = *p++)
- continue;
- /* pe starts pointing to one past the first '{'. */
- for (pe = ++p; *pe; pe++)
- switch (*pe) {
-
- case '{':
- brclev++;
- continue;
-
- case '}':
- if (brclev == 0)
- goto pend;
- brclev--;
- continue;
-
- case '[':
- for (pe++; *pe && *pe != ']'; pe++)
- continue;
- if (!*pe)
- pe--;
- continue;
- }
-pend:
- brclev = 0;
- for (pl = pm = p; pm <= pe; pm++)
- switch (*pm & (QUOTE|TRIM)) {
-
- case '{':
- brclev++;
- continue;
-
- case '}':
- if (brclev) { /* brclev = 0 is outermost brace set */
- brclev--;
- continue;
- }
- goto doit;
-
- case ','|QUOTE:
- case ',':
- if (brclev)
- continue;
-doit:
- savec = *pm;
- *pm = 0;
- (void) strncpy(lm, pl, sizeof(restbuf) - 1 - (lm - restbuf));
- restbuf[sizeof(restbuf) - 1] = '\0';
- if (*pe) {
- (void) strncat(restbuf, pe + 1,
- sizeof(restbuf) - 1 - strlen(restbuf));
- }
- *pm = savec;
- if (s == 0) {
- sgpathp = gpathp;
- expand(restbuf);
- gpathp = sgpathp;
- *gpathp = 0;
- } else if (amatch(s, restbuf))
- return (1);
- sort();
- pl = pm + 1;
- if (brclev)
- return (0);
- continue;
-
- case '[':
- for (pm++; *pm && *pm != ']'; pm++)
- continue;
- if (!*pm)
- pm--;
- continue;
- }
- if (brclev)
- goto doit;
- return (0);
-}
-
-static int
-match(s, p)
- char *s, *p;
-{
- register int c;
- register char *sentp;
- char sglobbed = globbed;
-
- if (*s == '.' && *p != '.')
- return (0);
- sentp = entp;
- entp = s;
- c = amatch(s, p);
- entp = sentp;
- globbed = sglobbed;
- return (c);
-}
-
-static int
-amatch(s, p)
- register char *s, *p;
-{
- register int scc;
- int ok, lc;
- char *sgpathp;
- struct stat stb;
- int c, cc;
-
- globbed = 1;
- for (;;) {
- scc = *s++ & TRIM;
- switch (c = *p++) {
-
- case '{':
- return (execbrc(p - 1, s - 1));
-
- case '[':
- ok = 0;
- lc = 077777;
- while ((cc = *p++)) {
- if (cc == ']') {
- if (ok)
- break;
- return (0);
- }
- if (cc == '-') {
- if (lc <= scc && scc <= *p++)
- ok++;
- } else
- if (scc == (lc = cc))
- ok++;
- }
- if (cc == 0) {
- if (ok)
- p--;
- else
- return 0;
- }
- continue;
-
- case '*':
- /* Multiple stars are equivalent to one.
- Don't chew up cpu time with O(n**2)
- recursion if a long string of them is
- given. */
- while (*p == '*')
- p++;
- if (!*p)
- return (1);
- if (*p == '/') {
- p++;
- goto slash;
- }
- s--;
- do {
- if (amatch(s, p))
- return (1);
- } while (*s++);
- return (0);
-
- case 0:
- return (scc == 0);
-
- default:
- if (c != scc)
- return (0);
- continue;
-
- case '?':
- if (scc == 0)
- return (0);
- continue;
-
- case '/':
- if (scc)
- return (0);
-slash:
- s = entp;
- sgpathp = gpathp;
- while (*s)
- addpath(*s++);
- addpath('/');
- if (stat(gpath, &stb) == 0 && isdir(stb)) {
- if (*p == 0) {
- Gcat(gpath, "");
- globcnt++;
- } else
- expand(p);
- }
- gpathp = sgpathp;
- *gpathp = 0;
- return (0);
- }
- }
-}
-
-static int
-Gmatch(s, p)
- register char *s, *p;
-{
- register int scc;
- int ok, lc;
- int c, cc;
-
- for (;;) {
- scc = *s++ & TRIM;
- switch (c = *p++) {
-
- case '[':
- ok = 0;
- lc = 077777;
- while ((cc = *p++)) {
- if (cc == ']') {
- if (ok)
- break;
- return (0);
- }
- if (cc == '-') {
- if (lc <= scc && scc <= *p++)
- ok++;
- } else
- if (scc == (lc = cc))
- ok++;
- }
- if (cc == 0) {
- if (ok)
- p--;
- else
- return 0;
- }
- continue;
-
- case '*':
- if (!*p)
- return (1);
- for (s--; *s; s++)
- if (Gmatch(s, p))
- return (1);
- return (0);
-
- case 0:
- return (scc == 0);
-
- default:
- if ((c & TRIM) != scc)
- return (0);
- continue;
-
- case '?':
- if (scc == 0)
- return (0);
- continue;
-
- }
- }
-}
-
-static void
-Gcat(s1, s2)
- register char *s1, *s2;
-{
- register int len = strlen(s1) + strlen(s2) + 1;
-
- if (len >= gnleft || gargc >= GAVSIZ - 1)
- globerr = "Arguments too long";
- else {
- gargc++;
- gnleft -= len;
- gargv[gargc] = 0;
- gargv[gargc - 1] = strspl(s1, s2);
- }
-}
-
-static void
-addpath(c)
- int c;
-{
-
- if (gpathp >= lastgpathp)
- globerr = "Pathname too long";
- else {
- *gpathp++ = c & 0xff;
- *gpathp = 0;
- }
-}
-
-static void
-rscan(t, f)
- register char **t;
- int (*f)();
-{
- register char *p, c;
-
- while ((p = *t++)) {
- if (f == tglob) {
- if (*p == '~')
- gflag |= 2;
- else if (eq(p, "{") || eq(p, "{}"))
- continue;
- }
- while ((c = *p++))
- (*f)(c);
- }
-}
-/*
-static
-scan(t, f)
- register char **t;
- int (*f)();
-{
- register char *p, c;
-
- while (p = *t++)
- while (c = *p)
- *p++ = (*f)(c);
-} */
-
-static int
-tglob(c)
- register int c;
-{
-
- if (any(c, globchars))
- gflag |= c == '{' ? 2 : 1;
- return (c);
-}
-/*
-static
-trim(c)
- char c;
-{
-
- return (c & TRIM);
-} */
-
-
-static int
-letter(c)
- register int c;
-{
-
- return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_');
-}
-
-static int
-digit(c)
- register int c;
-{
-
- return (c >= '0' && c <= '9');
-}
-
-static int any(c, s)
- register int c;
- register char *s;
-{
-
- while (*s)
- if (*s++ == c)
- return(1);
- return(0);
-}
-static int blklen(av)
- register char **av;
-{
- register int i = 0;
-
- while (*av++)
- i++;
- return (i);
-}
-
-static char **
-blkcpy(oav, bv)
- char **oav;
- register char **bv;
-{
- register char **av = oav;
-
- while ((*av++ = *bv++))
- continue;
- return (oav);
-}
-
-void blkfree(av0)
- char **av0;
-{
- register char **av = av0;
-
- while (*av)
- free(*av++);
-}
-
-static
-char *
-strspl(cp, dp)
- register char *cp, *dp;
-{
- char *ep;
-
- if (asprintf(&ep, "%s%s", cp, dp) < 0)
- fatal("Out of memory");
- return (ep);
-}
-
-char **
-copyblk(v)
- register char **v;
-{
- register char **nv = (char **)malloc((unsigned)((blklen(v) + 1) *
- sizeof(char **)));
- if (nv == (char **)0)
- fatal("Out of memory");
-
- return (blkcpy(nv, v));
-}
-
-static
-char *
-strend(cp)
- register char *cp;
-{
-
- while (*cp)
- cp++;
- return (cp);
-}
-
-#ifndef _WIN32
-/*
- * Extract a home directory from the password file
- * The argument points to a buffer where the name of the
- * user whose home directory is sought is currently.
- * We write the home directory of the user back there.
- */
-static int gethdir(mhome)
- char *mhome;
-{
- register struct passwd *pp = getpwnam(mhome);
- size_t bufsize = lastgpathp - mhome;
-
- if (!pp)
- return (1);
- if (strlcpy(mhome, pp->pw_dir, bufsize) >= bufsize)
- return (1);
- return (0);
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 1985, 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 lint
-char copyright[] =
-"@(#) Copyright (c) 1985, 1989 Regents of the University of California.\n\
- All rights reserved.\n";
-#endif /* not lint */
-
-#ifndef lint
-static char sccsid[] = "@(#)main.c 5.18 (Berkeley) 3/1/91";
-#endif /* not lint */
-
-/*
- * FTP User Program -- Command Interface.
- */
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include <stdio.h>
-#include <signal.h>
-#include "ftp_var.h"
-#ifndef _WIN32
-#include <sys/socket.h>
-#include <netdb.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <pwd.h>
-#endif /* !_WIN32 */
-
-#ifdef _WIN32
-#include <io.h>
-#undef ERROR
-#endif
-
-#include <arpa/ftp.h>
-
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-
-#include <port-sockets.h>
-
-#ifdef _WIN32
-/* For SO_SYNCHRONOUS_NONALERT and SO_OPENTYPE: */
-#include <mswsock.h>
-#endif
-
-#ifndef _WIN32
-uid_t getuid();
-#endif
-
-sigtype intr (int), lostpeer (int);
-extern char *home;
-char *getlogin();
-
-static void cmdscanner (int);
-static char *slurpstring (void);
-
-
-int
-main(argc, argv)
- volatile int argc;
- char **volatile argv;
-{
- register char *cp;
- int top;
-#ifndef _WIN32
- struct passwd *pw = NULL;
-#endif
- char homedir[MAXPATHLEN];
- char *progname = argv[0];
-
-#ifdef _WIN32
- DWORD optionValue = SO_SYNCHRONOUS_NONALERT;
- if (setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *)&optionValue, sizeof(optionValue)) == SOCKET_ERROR) {
- fprintf(stderr, "ftp: cannot enable synchronous sockets\n");
- exit(1);
- }
-#endif
-
- sp = getservbyname("ftp", "tcp");
- if (sp == 0) {
- fprintf(stderr, "ftp: ftp/tcp: unknown service\n");
- exit(1);
- }
- doglob = 1;
- interactive = 1;
- autoauth = 1;
- autologin = 1;
- forward = 0;
- autoencrypt = 0;
- argc--, argv++;
- while (argc > 0 && **argv == '-') {
- for (cp = *argv + 1; *cp; cp++)
- switch (*cp) {
-
- case 'd':
- options |= SO_DEBUG;
- debug++;
- break;
-
- case 'v':
- verbose++;
- break;
-
- case 't':
- trace++;
- break;
-
- case 'i':
- interactive = 0;
- break;
-
- case 'n':
- autologin = 0;
- break;
-
- case 'g':
- doglob = 0;
- break;
-
- case 'u':
- autoauth = 0;
- break;
-
- case 'f':
- forward = 1;
- break;
-
- case 'x':
- autoencrypt = 1;
- break;
-
- default:
- fprintf(stderr,
- "ftp: %c: unknown option\n", *cp);
- fprintf(stderr, "Usage: %s [-v] [-d] [-i] [-n] [-g] "
- "[-k realm] [-f] [-x] [-u] [-t] [host]\n",
- progname);
- exit(1);
- }
- nextopt:
- argc--, argv++;
- }
- fromatty = isatty(fileno(stdin));
- if (fromatty)
- verbose++;
- cpend = 0; /* no pending replies */
- proxy = 0; /* proxy not active */
-#ifndef NO_PASSIVE_MODE
- passivemode = 0; /* passive mode not active */
-#endif
- crflag = 1; /* strip c.r. on ascii gets */
- sendport = -1; /* not using ports */
- /*
- * Set up the home directory in case we're globbing.
- */
-#ifdef _WIN32
- cp = getenv("HOME");
- if (cp != NULL) {
- home = homedir;
- (void) strncpy(home, cp, sizeof(homedir) - 1);
- homedir[sizeof(homedir) - 1] = '\0';
- }
-#else /* !_WIN32 */
- cp = getlogin();
- if (cp != NULL) {
- pw = getpwnam(cp);
- }
- if (pw == NULL)
- pw = getpwuid(getuid());
- if (pw != NULL) {
- home = homedir;
- (void) strncpy(home, pw->pw_dir, sizeof(homedir) - 1);
- homedir[sizeof(homedir) - 1] = '\0';
- }
-#endif /* !_WIN32 */
- if (argc > 0) {
- if (setjmp(toplevel))
- exit(0);
- (void) signal(SIGINT, intr);
-#ifdef SIGPIPE
- (void) signal(SIGPIPE, lostpeer);
-#endif
- setpeer(argc + 1, argv - 1);
- }
- top = setjmp(toplevel) == 0;
- if (top) {
- (void) signal(SIGINT, intr);
-#ifdef SIGPIPE
- (void) signal(SIGPIPE, lostpeer);
-#endif
- }
- for (;;) {
- cmdscanner(top);
- top = 1;
- }
-}
-
-sigtype
-intr(sig)
- int sig;
-{
-
- longjmp(toplevel, 1);
-}
-
-sigtype
-lostpeer(sig)
- int sig;
-{
- extern FILE *cout;
- extern SOCKET data;
- extern char *auth_type;
- extern int clevel;
- extern int dlevel;
-
- if (connected) {
- if (cout != NULL) {
- (void) shutdown(SOCKETNO(fileno(cout)), 1+1);
- (void) FCLOSE_SOCKET(cout);
- cout = NULL;
- }
- if (data != INVALID_SOCKET) {
- (void) shutdown(data, 1+1);
- (void) closesocket(data);
- data = INVALID_SOCKET;
- }
- connected = 0;
- auth_type = NULL;
- clevel = dlevel = PROT_C;
- }
- pswitch(1);
- if (connected) {
- if (cout != NULL) {
- (void) shutdown(SOCKETNO(fileno(cout)), 1+1);
- (void) FCLOSE_SOCKET(cout);
- cout = NULL;
- }
- connected = 0;
- auth_type = NULL;
- clevel = dlevel = PROT_C;
- }
- proxflag = 0;
- pswitch(0);
-}
-
-/*char *
-tail(filename)
- char *filename;
-{
- register char *s;
-
- while (*filename) {
- s = strrchr(filename, '/');
- if (s == NULL)
- break;
- if (s[1])
- return (s + 1);
- *s = '\0';
- }
- return (filename);
-}
-*/
-/*
- * Command parser.
- */
-static void
-cmdscanner(top)
- int top;
-{
- register struct cmd *c;
- register int l;
-
- if (!top)
- (void) putchar('\n');
- for (;;) {
- if (fromatty) {
- printf("ftp> ");
- (void) fflush(stdout);
- }
- if (fgets(line, sizeof line, stdin) == NULL)
- quit();
- l = strlen(line);
- if (l == 0)
- break;
- if (line[--l] == '\n') {
- if (l == 0)
- break;
- line[l] = '\0';
- } else if (l == sizeof(line) - 2) {
- printf("sorry, input line too long\n");
- while ((l = getchar()) != '\n' && l != EOF)
- /* void */;
- break;
- } /* else it was a line without a newline */
- makeargv();
- if (margc == 0) {
- continue;
- }
- c = getcmd(margv[0]);
- if (c == (struct cmd *)-1) {
- printf("?Ambiguous command\n");
- continue;
- }
- if (c == 0) {
- printf("?Invalid command\n");
- continue;
- }
- if (c->c_conn && !connected) {
- printf("Not connected.\n");
- continue;
- }
- (*c->c_handler)(margc, margv);
- if (bell && c->c_bell)
- (void) putchar('\007');
- if (c->c_handler != help)
- break;
- }
- (void) signal(SIGINT, intr);
-#ifdef SIGPIPE
- (void) signal(SIGPIPE, lostpeer);
-#endif
-}
-
-struct cmd *
-getcmd(name)
- register char *name;
-{
- extern struct cmd cmdtab[];
- register char *p, *q;
- register struct cmd *c, *found;
- register int nmatches, longest;
-
- longest = 0;
- nmatches = 0;
- found = 0;
- for (c = cmdtab; (p = c->c_name) != NULL; c++) {
- for (q = name; *q == *p++; q++)
- if (*q == 0) /* exact match? */
- return (c);
- if (!*q) { /* the name was a prefix */
- if (q - name > longest) {
- longest = q - name;
- nmatches = 1;
- found = c;
- } else if (q - name == longest)
- nmatches++;
- }
- }
- if (nmatches > 1)
- return ((struct cmd *)-1);
- return (found);
-}
-
-/*
- * Slice a string up into argc/argv.
- */
-
-int slrflag;
-
-void makeargv()
-{
- char **argp;
-
- margc = 0;
- argp = margv;
- stringbase = line; /* scan from first of buffer */
- argbase = argbuf; /* store from first of buffer */
- slrflag = 0;
- while ((*argp++ = slurpstring())) {
- margc++;
- if (margc == sizeof(margv)/sizeof(margv[0])) {
- printf("sorry, too many arguments in input line\n");
- margc = 0;
- margv[0] = 0;
- return;
- }
- }
-}
-
-/*
- * Parse string into argbuf;
- * implemented with FSM to
- * handle quoting and strings
- */
-static char *
-slurpstring()
-{
- int got_one = 0;
- register char *sb = stringbase;
- register char *ap = argbase;
- char *tmp = argbase; /* will return this if token found */
-
- if (*sb == '!' || *sb == '$') { /* recognize ! as a token for shell */
- switch (slrflag) { /* and $ as token for macro invoke */
- case 0:
- slrflag++;
- stringbase++;
- return ((*sb == '!') ? "!" : "$");
- /* NOTREACHED */
- case 1:
- slrflag++;
- altarg = stringbase;
- break;
- default:
- break;
- }
- }
-
-S0:
- switch (*sb) {
-
- case '\0':
- goto EXIT;
-
- case ' ':
- case '\t':
- sb++; goto S0;
-
- default:
- switch (slrflag) {
- case 0:
- slrflag++;
- break;
- case 1:
- slrflag++;
- altarg = sb;
- break;
- default:
- break;
- }
- goto S1;
- }
-
-S1:
- switch (*sb) {
-
- case ' ':
- case '\t':
- case '\0':
- goto EXIT; /* end of token */
-
- case '\\':
- sb++; goto S2; /* slurp next character */
-
- case '"':
- sb++; goto S3; /* slurp quoted string */
-
- default:
- *ap++ = *sb++; /* add character to token */
- got_one = 1;
- goto S1;
- }
-
-S2:
- switch (*sb) {
-
- case '\0':
- goto EXIT;
-
- default:
- *ap++ = *sb++;
- got_one = 1;
- goto S1;
- }
-
-S3:
- switch (*sb) {
-
- case '\0':
- goto EXIT;
-
- case '"':
- sb++; goto S1;
-
- default:
- *ap++ = *sb++;
- got_one = 1;
- goto S3;
- }
-
-EXIT:
- if (got_one)
- *ap++ = '\0';
- argbase = ap; /* update storage pointer */
- stringbase = sb; /* update scan pointer */
- if (got_one) {
- return(tmp);
- }
- switch (slrflag) {
- case 0:
- slrflag++;
- break;
- case 1:
- slrflag++;
- altarg = (char *) 0;
- break;
- default:
- break;
- }
- return((char *)0);
-}
-
-#define HELPINDENT ((int) sizeof("disconnect"))
-
-/*
- * Help command.
- * Call each command handler with argc == 0 and argv[0] == name.
- */
-void help(argc, argv)
- int argc;
- char *argv[];
-{
- extern struct cmd cmdtab[];
- register struct cmd *c;
-
- if (argc == 1) {
- register int i, j, w, k;
- int columns, width = 0, lines;
- extern int NCMDS;
-
- printf("Commands may be abbreviated. Commands are:\n\n");
- for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
- int len = strlen(c->c_name);
-
- if (len > width)
- width = len;
- }
- width = (width + 8) &~ 7;
- columns = 80 / width;
- if (columns == 0)
- columns = 1;
- lines = (NCMDS + columns - 1) / columns;
- for (i = 0; i < lines; i++) {
- for (j = 0; j < columns; j++) {
- c = cmdtab + j * lines + i;
- if (c->c_name && (!proxy || c->c_proxy)) {
- printf("%s", c->c_name);
- }
- else if (c->c_name) {
- for (k=0; k < strlen(c->c_name); k++) {
- (void) putchar(' ');
- }
- }
- if (c + lines >= &cmdtab[NCMDS]) {
- printf("\n");
- break;
- }
- w = strlen(c->c_name);
- while (w < width) {
- w = (w + 8) &~ 7;
- (void) putchar('\t');
- }
- }
- }
- return;
- }
- while (--argc > 0) {
- register char *arg;
- arg = *++argv;
- c = getcmd(arg);
- if (c == (struct cmd *)-1)
- printf("?Ambiguous help command %s\n", arg);
- else if (c == (struct cmd *)0)
- printf("?Invalid help command %s\n", arg);
- else
- printf("%-*s\t%s\n", HELPINDENT,
- c->c_name, c->c_help);
- }
-}
+++ /dev/null
-/*
- * 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.
- *
- * @(#)pathnames.h 5.2 (Berkeley) 6/1/90
- */
-
-#undef _PATH_TMP
-#define _PATH_TMP "/tmp/ftpXXXXXX"
+++ /dev/null
-/*
- * Copyright (c) 1980 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)pclose.c 1.1 90/04/28 SMI"; /* from UCB 1.2 3/7/86 */
-#endif /* not lint */
-
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#include <signal.h>
-#include <sys/param.h>
-#include <sys/wait.h>
-#define sig_t my_sig_t
-#define sigtype krb5_sigtype
-typedef sigtype (*sig_t)();
-
-#define tst(a,b) (*mode == 'r'? (b) : (a))
-#define RDR 0
-#define WTR 1
-
-static int *popen_pid;
-static int nfiles;
-
-#ifndef HAVE_GETDTABLESIZE
-#include <sys/resource.h>
-int getdtablesize() {
- struct rlimit rl;
- getrlimit(RLIMIT_NOFILE, &rl);
- return rl.rlim_cur;
-}
-#endif
-
-FILE *
-mypopen(cmd,mode)
- char *cmd;
- char *mode;
-{
- int p[2];
- volatile int myside, hisside;
- int pid;
-
- if (nfiles <= 0)
- nfiles = getdtablesize();
- if (popen_pid == NULL) {
- popen_pid = (int *)malloc((unsigned) nfiles * sizeof *popen_pid);
- if (popen_pid == NULL)
- return (NULL);
- for (pid = 0; pid < nfiles; pid++)
- popen_pid[pid] = -1;
- }
- if (pipe(p) < 0)
- return (NULL);
- myside = tst(p[WTR], p[RDR]);
- hisside = tst(p[RDR], p[WTR]);
- if ((pid = fork()) == 0) {
- /* myside and hisside reverse roles in child */
- (void) close(myside);
- if (hisside != tst(0, 1)) {
- (void) dup2(hisside, tst(0, 1));
- (void) close(hisside);
- }
- execl("/bin/sh", "sh", "-c", cmd, (char *)NULL);
- _exit(127);
- }
- if (pid == -1) {
- (void) close(myside);
- (void) close(hisside);
- return (NULL);
- }
- popen_pid[myside] = pid;
- (void) close(hisside);
- return (fdopen(myside, mode));
-}
-
-sigtype
-pabort(sig)
- int sig;
-{
- extern int mflag;
-
- mflag = 0;
-}
-
-mypclose(ptr)
- FILE *ptr;
-{
- int child, pid;
-#ifdef USE_SIGPROCMASK
- sigset_t old, new;
-#else
- int omask;
-#endif
- sigtype pabort(), (*istat)();
-#ifdef WAIT_USES_INT
- int status;
-#else
- union wait status;
-#endif
-
- child = popen_pid[fileno(ptr)];
- popen_pid[fileno(ptr)] = -1;
- (void) fclose(ptr);
- if (child == -1)
- return (-1);
- istat = signal(SIGINT, pabort);
-#ifdef USE_SIGPROCMASK
- sigemptyset(&old);
- sigemptyset(&new);
- sigaddset(&new,SIGQUIT);
- sigaddset(&new,SIGHUP);
- sigprocmask(SIG_BLOCK, &new, &old);
- while ((pid = wait(&status)) != child && pid != -1)
- ;
- sigprocmask(SIG_SETMASK, &old, NULL);
-#else
- omask = sigblock(sigmask(SIGQUIT)|sigmask(SIGHUP));
- while ((pid = wait(&status)) != child && pid != -1)
- ;
- sigsetmask(omask);
-#endif
- (void) signal(SIGINT, istat);
- return (pid == -1 ? -1 : 0);
-}
+++ /dev/null
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-
-#include "ftp_var.h"
-
-static char *radixN =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-static char pad = '=';
-
-int radix_encode(inbuf, outbuf, len, decode)
-unsigned char inbuf[], outbuf[];
-int *len, decode;
-{
- int i,j,D = 0;
- char *p;
- unsigned char c = 0;
-
- if (decode) {
- for (i=0,j=0; inbuf[i] && inbuf[i] != pad; i++) {
- if ((p = strchr(radixN, inbuf[i])) == NULL) return(1);
- D = p - radixN;
- switch (i&3) {
- case 0:
- c = D<<2;
- break;
- case 1:
- outbuf[j++] = c | D>>4;
- c = (D&15)<<4;
- break;
- case 2:
- outbuf[j++] = c | D>>2;
- c = (D&3)<<6;
- break;
- case 3:
- outbuf[j++] = c | D;
- }
- }
- switch (i&3) {
- case 1: return(3);
- case 2: if (D&15) return(3);
- if (strcmp((char *)&inbuf[i], "==")) return(2);
- break;
- case 3: if (D&3) return(3);
- if (strcmp((char *)&inbuf[i], "=")) return(2);
- }
- *len = j;
- } else {
- for (i=0,j=0; i < *len; i++)
- switch (i%3) {
- case 0:
- outbuf[j++] = radixN[inbuf[i]>>2];
- c = (inbuf[i]&3)<<4;
- break;
- case 1:
- outbuf[j++] = radixN[c|inbuf[i]>>4];
- c = (inbuf[i]&15)<<2;
- break;
- case 2:
- outbuf[j++] = radixN[c|inbuf[i]>>6];
- outbuf[j++] = radixN[inbuf[i]&63];
- c = 0;
- }
- if (i%3) outbuf[j++] = radixN[c];
- switch (i%3) {
- case 1: outbuf[j++] = pad;
- case 2: outbuf[j++] = pad;
- }
- outbuf[*len = j] = '\0';
- }
- return(0);
-}
-
-char *
-radix_error(e)
-int e;
-{
- switch (e) {
- case 0: return("Success");
- case 1: return("Bad character in encoding");
- case 2: return("Encoding not properly padded");
- case 3: return("Decoded # of bits not a multiple of 8");
- default: return("Unknown error");
- }
-}
-
-#ifdef STANDALONE
-usage(s)
-char *s;
-{
- fprintf(stderr, "Usage: %s [ -d ] [ string ]\n", s);
- exit(2);
-}
-
-static int n;
-
-putbuf(inbuf, outbuf, len, decode)
-unsigned char inbuf[], outbuf[];
-int len, decode;
-{
- int c;
-
- if (c = radix_encode(inbuf, outbuf, &len, decode)) {
- fprintf(stderr, "Couldn't %scode input: %s\n",
- decode ? "de" : "en", radix_error(c));
- exit(1);
- }
- if (decode)
- write(1, outbuf, len);
- else
- for (c = 0; c < len;) {
- putchar(outbuf[c++]);
- if (++n%76 == 0) putchar('\n');
- }
-}
-
-main(argc,argv)
-int argc;
-char *argv[];
-{
- unsigned char *inbuf, *outbuf;
- int c, len = 0, decode = 0;
- extern int optind;
-
- while ((c = getopt(argc, argv, "d")) != -1)
- switch(c) {
- default:
- usage(argv[0]);
- case 'd':
- decode++;
- }
-
- switch (argc - optind) {
- case 0:
- inbuf = (unsigned char *) malloc(5);
- outbuf = (unsigned char *) malloc(5);
- while ((c = getchar()) != EOF)
- if (c != '\n') {
- inbuf[len++] = c;
- if (len == (decode ? 4 : 3)) {
- inbuf[len] = '\0';
- putbuf(inbuf, outbuf, len, decode);
- len=0;
- }
- }
- if (len) {
- inbuf[len] = '\0';
- putbuf(inbuf, outbuf, len, decode);
- }
- break;
- case 1:
- inbuf = (unsigned char *)argv[optind];
- len = strlen(inbuf);
- outbuf = (unsigned char *)
- malloc((len * (decode?3:4)) / (decode?4:3) + 1);
- putbuf(inbuf, outbuf, len, decode);
- break;
- default:
- fprintf(stderr, "Only one argument allowed\n");
- usage(argv[0]);
- }
- if (n%76) putchar('\n');
- exit(0);
-}
-#endif /* STANDALONE */
+++ /dev/null
-/*
- * Copyright (c) 1985 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 lint
-static char sccsid[] = "@(#)ruserpass.c 5.3 (Berkeley) 3/1/91";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <ctype.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include "ftp_var.h"
-
-#ifdef _WIN32
-#include <win-mac.h>
-#endif
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
-#endif
-
-static int token (void);
-static FILE *cfile;
-
-#define DEFAULT 1
-#define LOGIN 2
-#define PASSWD 3
-#define ACCOUNT 4
-#define MACDEF 5
-#define ID 10
-#define MACH 11
-
-static char tokval[100];
-
-static struct toktab {
- char *tokstr;
- int tval;
-} toktab[]= {
- { "default", DEFAULT },
- { "login", LOGIN },
- { "password", PASSWD },
- { "passwd", PASSWD },
- { "account", ACCOUNT },
- { "machine", MACH },
- { "macdef", MACDEF },
- { NULL, 0 }
-};
-
-
-static int
-token()
-{
- char *cp;
- int c;
- struct toktab *t;
-
- if (feof(cfile))
- return (0);
- while ((c = getc(cfile)) != EOF &&
- (c == '\n' || c == '\t' || c == ' ' || c == ','))
- continue;
- if (c == EOF)
- return (0);
- cp = tokval;
- if (c == '"') {
- while ((c = getc(cfile)) != EOF && c != '"') {
- if (c == '\\')
- c = getc(cfile);
- *cp++ = c;
- }
- } else {
- *cp++ = c;
- while ((c = getc(cfile)) != EOF
- && c != '\n' && c != '\t' && c != ' ' && c != ',') {
- if (c == '\\')
- c = getc(cfile);
- *cp++ = c;
- }
- }
- *cp = 0;
- if (tokval[0] == 0)
- return (0);
- for (t = toktab; t->tokstr; t++)
- if (!strcmp(t->tokstr, tokval))
- return (t->tval);
- return (ID);
-}
-
-int
-ruserpass(host, aname, apass, aacct)
- char *host, **aname, **apass, **aacct;
-{
- char *hdir, buf[FTP_BUFSIZ], *tmp;
- char myname[MAXHOSTNAMELEN + 1], *mydomain;
- int t, i, c, usedefault = 0;
- struct stat stb;
-
- hdir = getenv("HOME");
- if (hdir == NULL)
- hdir = ".";
- (void) snprintf(buf, sizeof(buf), "%s/.netrc", hdir);
- cfile = fopen(buf, "r");
- if (cfile == NULL) {
- if (errno != ENOENT)
- perror(buf);
- return(0);
- }
- if (gethostname(myname, sizeof(myname)) < 0)
- myname[0] = '\0';
- if ((mydomain = strchr(myname, '.')) == NULL)
- mydomain = "";
-next:
- while ((t = token())) switch(t) {
-
- case DEFAULT:
- usedefault = 1;
- /* FALL THROUGH */
-
- case MACH:
- if (!usedefault) {
- if (token() != ID)
- continue;
- /*
- * Allow match either for user's input host name
- * or official hostname. Also allow match of
- * incompletely-specified host in local domain.
- */
- if (strcasecmp(host, tokval) == 0)
- goto match;
- if (strcasecmp(hostname, tokval) == 0)
- goto match;
- if ((tmp = strchr(hostname, '.')) != NULL &&
- strcasecmp(tmp, mydomain) == 0 &&
- strncasecmp(hostname, tokval,
- (unsigned) (tmp-hostname)) == 0 &&
- tokval[tmp - hostname] == '\0')
- goto match;
- if ((tmp = strchr(host, '.')) != NULL &&
- strcasecmp(tmp, mydomain) == 0 &&
- strncasecmp(host, tokval,
- (unsigned ) (tmp - host)) == 0 &&
- tokval[tmp - host] == '\0')
- goto match;
- continue;
- }
- match:
- while ((t = token()) && t != MACH && t != DEFAULT) switch(t) {
-
- case LOGIN:
- if (token()) {
- if (*aname == 0) {
- *aname = strdup(tokval);
- } else {
- if (strcmp(*aname, tokval))
- goto next;
- }
- }
- break;
- case PASSWD:
- if (strcmp(*aname, "anonymous") &&
- fstat(fileno(cfile), &stb) >= 0 &&
- (stb.st_mode & 077) != 0) {
- fprintf(stderr, "Error - .netrc file not correct mode.\n");
- fprintf(stderr, "Remove password or correct mode.\n");
- goto bad;
- }
- if (token() && *apass == 0) {
- *apass = strdup(tokval);
- }
- break;
- case ACCOUNT:
- if (fstat(fileno(cfile), &stb) >= 0
- && (stb.st_mode & 077) != 0) {
- fprintf(stderr, "Error - .netrc file not correct mode.\n");
- fprintf(stderr, "Remove account or correct mode.\n");
- goto bad;
- }
- if (token() && *aacct == 0) {
- *aacct = strdup(tokval);
- }
- break;
- case MACDEF:
- if (proxy) {
- (void) fclose(cfile);
- return(0);
- }
- while ((c = getc(cfile)) != EOF)
- if (c != ' ' && c != '\t')
- break;
- if (c == EOF || c == '\n') {
- printf("Missing macdef name argument.\n");
- goto bad;
- }
- if (macnum == 16) {
- printf("Limit of 16 macros have already been defined\n");
- goto bad;
- }
- tmp = macros[macnum].mac_name;
- *tmp++ = c;
- for (i=0; i < 8 && (c=getc(cfile)) != EOF &&
- !isspace(c); ++i) {
- *tmp++ = c;
- }
- if (c == EOF) {
- printf("Macro definition missing null line terminator.\n");
- goto bad;
- }
- *tmp = '\0';
- if (c != '\n') {
- while ((c=getc(cfile)) != EOF && c != '\n');
- }
- if (c == EOF) {
- printf("Macro definition missing null line terminator.\n");
- goto bad;
- }
- if (macnum == 0) {
- macros[macnum].mac_start = macbuf;
- }
- else {
- macros[macnum].mac_start = macros[macnum-1].mac_end + 1;
- }
- tmp = macros[macnum].mac_start;
- while (tmp != macbuf + 4096) {
- if ((c=getc(cfile)) == EOF) {
- printf("Macro definition missing null line terminator.\n");
- goto bad;
- }
- *tmp = c;
- if (*tmp == '\n') {
- if (*(tmp-1) == '\0') {
- macros[macnum++].mac_end = tmp - 1;
- break;
- }
- *tmp = '\0';
- }
- tmp++;
- }
- if (tmp == macbuf + 4096) {
- printf("4K macro buffer exceeded\n");
- goto bad;
- }
- break;
- default:
- fprintf(stderr, "Unknown .netrc keyword %s\n", tokval);
- break;
- }
- goto done;
- }
-done:
- (void) fclose(cfile);
- return(0);
-bad:
- (void) fclose(cfile);
- return(-1);
-}
+++ /dev/null
-/*
- * Shared routines for client and server for
- * secure read(), write(), getc(), and putc().
- * Only one security context, thus only work on one fd at a time!
- */
-#include "autoconf.h"
-
-#ifdef GSSAPI
-#include <gssapi/gssapi.h>
-#include <gssapi/gssapi_generic.h>
-extern gss_ctx_id_t gcontext;
-#endif /* GSSAPI */
-
-#include <secure.h> /* stuff which is specific to client or server */
-
-#ifdef _WIN32
-#undef ERROR
-#endif
-
-#include <arpa/ftp.h>
-
-#include <stdio.h>
-#include <string.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <sys/types.h>
-#ifdef _WIN32
-#include <port-sockets.h>
-#else
-#include <netinet/in.h>
-#endif
-#include <errno.h>
-
-#ifndef HAVE_STRERROR
-#define strerror(error) (sys_errlist[error])
-#ifdef NEED_SYS_ERRLIST
-extern char *sys_errlist[];
-#endif
-#endif
-
-#ifdef HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#ifdef HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-typedef uint32_t ftp_uint32;
-typedef int32_t ftp_int32;
-
-static int secure_putbuf (int, unsigned char *, unsigned int);
-
-extern struct sockaddr_in hisaddr;
-extern struct sockaddr_in myaddr;
-extern int dlevel;
-extern char *auth_type;
-
-/* Some libc's (GNU libc, at least) define MAX as a macro. Forget that. */
-#ifdef MAX
-#undef MAX
-#endif
-
-#define MAX maxbuf
-extern unsigned int maxbuf; /* maximum output buffer size */
-extern unsigned char *ucbuf; /* cleartext buffer */
-static unsigned int nout; /* number of chars in ucbuf,
- * pointer into ucbuf */
-static unsigned int smaxbuf; /* Internal saved value of maxbuf
- in case changes on us */
-static unsigned int smaxqueue; /* Maximum allowed to queue before
- flush buffer. < smaxbuf by fudgefactor */
-
-/* perhaps use these in general, certainly use them for GSSAPI */
-
-#ifndef looping_write
-static int
-looping_write(fd, buf, len)
- int fd;
- register const char *buf;
- int len;
-{
- int cc;
- register int wrlen = len;
- do {
- cc = write(fd, buf, wrlen);
- if (cc < 0) {
- if (errno == EINTR)
- continue;
- return(cc);
- }
- else {
- buf += cc;
- wrlen -= cc;
- }
- } while (wrlen > 0);
- return(len);
-}
-#endif
-#ifndef looping_read
-static int
-looping_read(fd, buf, len)
- int fd;
- register char *buf;
- register int len;
-{
- int cc, len2 = 0;
-
- do {
- cc = read(fd, buf, len);
- if (cc < 0) {
- if (errno == EINTR)
- continue;
- return(cc); /* errno is already set */
- }
- else if (cc == 0) {
- return(len2);
- } else {
- buf += cc;
- len2 += cc;
- len -= cc;
- }
- } while (len > 0);
- return(len2);
-}
-#endif
-
-
-
-#define ERR -2
-
-/*
- * Given maxbuf as a buffer size, determine how much can we
- * really transfer given the overhead of different algorithms
- *
- * Sets smaxbuf and smaxqueue
- */
-
-static int secure_determine_constants()
-{
- smaxbuf = maxbuf;
- smaxqueue = maxbuf;
-
-#ifdef GSSAPI
- if (strcmp(auth_type, "GSSAPI") == 0) {
- OM_uint32 maj_stat, min_stat, mlen;
- OM_uint32 msize = maxbuf;
- maj_stat = gss_wrap_size_limit(&min_stat, gcontext,
- (dlevel == PROT_P),
- GSS_C_QOP_DEFAULT,
- msize, &mlen);
- if (maj_stat != GSS_S_COMPLETE) {
- secure_gss_error(maj_stat, min_stat,
- "GSSAPI fudge determination");
- /* Return error how? */
- return ERR;
- }
- smaxqueue = mlen;
- }
-#endif
-
- return 0;
-}
-
-static int
-secure_putbyte(fd, c)
-int fd;
-unsigned char c;
-{
- int ret;
-
- if ((smaxbuf == 0) || (smaxqueue == 0) || (smaxbuf != maxbuf)) {
- ret = secure_determine_constants();
- if (ret) return ret;
- }
- ucbuf[nout++] = c;
- if (nout == smaxqueue) {
- nout = 0;
- ret = secure_putbuf(fd, ucbuf, smaxqueue);
- return(ret?ret:c);
- }
- return (c);
-}
-
-/* returns:
- * 0 on success
- * -1 on error (errno set)
- * -2 on security error
- */
-int secure_flush(fd)
-int fd;
-{
- int ret;
-
- if (dlevel == PROT_C)
- return(0);
- if (nout) {
- ret = secure_putbuf(fd, ucbuf, nout);
- if (ret)
- return(ret);
- }
- return(secure_putbuf(fd, (unsigned char *) "", nout = 0));
-}
-
-/* returns:
- * c>=0 on success
- * -1 on error
- * -2 on security error
- */
-int secure_putc(c, stream)
-int c;
-FILE *stream;
-{
- if (dlevel == PROT_C)
- return(putc(c,stream));
- return(secure_putbyte(fileno(stream), (unsigned char) c));
-}
-
-/* returns:
- * nbyte on success
- * -1 on error (errno set)
- * -2 on security error
- */
-int
-secure_write(fd, buf, nbyte)
-int fd;
-unsigned char *buf;
-unsigned int nbyte;
-{
- unsigned int i;
- int c;
-
- if (dlevel == PROT_C)
- return(write(fd,buf,nbyte));
- for (i=0; nbyte>0; nbyte--)
- if ((c = secure_putbyte(fd, buf[i++])) < 0)
- return(c);
- return(i);
-}
-
-/* returns:
- * 0 on success
- * -1 on error (errno set)
- * -2 on security error
- */
-static int
-secure_putbuf(fd, buf, nbyte)
- int fd;
-unsigned char *buf;
-unsigned int nbyte;
-{
- static char *outbuf; /* output ciphertext */
- static unsigned int bufsize; /* size of outbuf */
- ftp_int32 length = 0;
- ftp_uint32 net_len;
- unsigned int fudge = smaxbuf - smaxqueue; /* Difference in length
- buffer lengths required */
-
- /* Other auth types go here ... */
-#ifdef GSSAPI
- if (strcmp(auth_type, "GSSAPI") == 0) {
- gss_buffer_desc in_buf, out_buf;
- OM_uint32 maj_stat, min_stat;
- int conf_state;
-
- in_buf.value = buf;
- in_buf.length = nbyte;
- maj_stat = gss_seal(&min_stat, gcontext,
- (dlevel == PROT_P), /* confidential */
- GSS_C_QOP_DEFAULT,
- &in_buf, &conf_state,
- &out_buf);
- if (maj_stat != GSS_S_COMPLETE) {
- /* generally need to deal */
- /* ie. should loop, but for now just fail */
- secure_gss_error(maj_stat, min_stat,
- dlevel == PROT_P?
- "GSSAPI seal failed":
- "GSSAPI sign failed");
- return(ERR);
- }
-
- if (bufsize < out_buf.length) {
- if (outbuf?
- (outbuf = realloc(outbuf, (unsigned) out_buf.length)):
- (outbuf = malloc((unsigned) out_buf.length))) {
- bufsize = out_buf.length;
- } else {
- bufsize = 0;
- secure_error("%s (in malloc of PROT buffer)",
- strerror(errno));
- return(ERR);
- }
- }
-
- length=out_buf.length;
- memcpy(outbuf, out_buf.value, out_buf.length);
- gss_release_buffer(&min_stat, &out_buf);
- }
-#endif /* GSSAPI */
- net_len = htonl((u_long) length);
- if (looping_write(fd, (char *) &net_len, 4) == -1) return(-1);
- if (looping_write(fd, outbuf, length) != length) return(-1);
- return(0);
-}
-
-static int
-secure_getbyte(fd)
-int fd;
-{
- /* number of chars in ucbuf, pointer into ucbuf */
- static unsigned int nin, bufp;
- int kerror;
- ftp_uint32 length;
-
- if (nin == 0) {
- if ((kerror = looping_read(fd, (char *) &length,
- sizeof(length)))
- != sizeof(length)) {
- secure_error("Couldn't read PROT buffer length: %d/%s",
- kerror,
- kerror == -1 ? strerror(errno)
- : "premature EOF");
- return(ERR);
- }
- if ((length = (u_long) ntohl(length)) > MAX) {
- secure_error("Length (%d) of PROT buffer > PBSZ=%u",
- length, MAX);
- return(ERR);
- }
- if ((kerror = looping_read(fd, (char *) ucbuf, (int) length)) != length) {
- secure_error("Couldn't read %u byte PROT buffer: %s",
- length, kerror == -1 ?
- strerror(errno) : "premature EOF");
- return(ERR);
- }
- /* Other auth types go here ... */
-#ifdef GSSAPI
- if (strcmp(auth_type, "GSSAPI") == 0) {
- gss_buffer_desc xmit_buf, msg_buf;
- OM_uint32 maj_stat, min_stat;
- int conf_state;
-
- xmit_buf.value = ucbuf;
- xmit_buf.length = length;
- conf_state = (dlevel == PROT_P);
- /* decrypt/verify the message */
- maj_stat = gss_unseal(&min_stat, gcontext, &xmit_buf,
- &msg_buf, &conf_state, NULL);
- if (maj_stat != GSS_S_COMPLETE) {
- secure_gss_error(maj_stat, min_stat,
- (dlevel == PROT_P)?
- "failed unsealing ENC message":
- "failed unsealing MIC message");
- return ERR;
- }
-
- memcpy(ucbuf, msg_buf.value, nin = bufp = msg_buf.length);
- gss_release_buffer(&min_stat, &msg_buf);
- }
-#endif /* GSSAPI */
- /* Other auth types go here ... */
- }
- if (nin == 0)
- return(EOF);
- else return(ucbuf[bufp - nin--]);
-}
-
-/* returns:
- * c>=0 on success
- * -1 on EOF
- * -2 on security error
- */
-int secure_getc(stream)
-FILE *stream;
-{
- if (dlevel == PROT_C)
- return(getc(stream));
- return(secure_getbyte(fileno(stream)));
-}
-
-/* returns:
- * n>0 on success (n == # of bytes read)
- * 0 on EOF
- * -1 on error (errno set), only for PROT_C
- * -2 on security error
- */
-int secure_read(fd, buf, nbyte)
-int fd;
-char *buf;
-unsigned int nbyte;
-{
- static int c;
- int i;
-
- if (dlevel == PROT_C)
- return(read(fd,buf,nbyte));
- if (c == EOF)
- return(c = 0);
- for (i=0; nbyte>0; nbyte--)
- switch (c = secure_getbyte(fd)) {
- case ERR: return(c);
- case EOF: if (!i) c = 0;
- return(i);
- default: buf[i++] = c;
- }
- return(i);
-}
+++ /dev/null
-#include <stdio.h>
-
-#define CRED_DECL extern CREDENTIALS cred;
-#define SESSION &cred.session
-#define myaddr data_addr
-#define hisaddr hisdataaddr
-
-int secure_flush (int);
-int secure_putc (int, FILE *);
-int secure_getc (FILE *);
-int secure_write (int, unsigned char *, unsigned int);
-int secure_read (int, char *, unsigned int);
-void secure_gss_error (OM_uint32 maj_stat, OM_uint32 min_stat, char *s);
-
-void secure_error(char *, ...)
-#if !defined(__cplusplus) && (__GNUC__ > 2)
- __attribute__((__format__(__printf__, 1, 2)))
-#endif
- ;
+++ /dev/null
-This version of ftpd has been fixed to conform to RFC959.
-
-Unfortunately, this conformance introduces a user visible change. While
-technically, this is the fault of the client (ftp) instead of the server
-(ftpd), the change will be seen whenever an old ftp client calls a new ftpd
-server.
-
-The problem is that the old ftpd implemented the NLST command by execing
-/bin/ls. This produced non-conformant output in some cases. The new
-ftpd no longer executes /bin/ls for the NLST command as it has it's own
-built-in code.
-
-The user visible change in the ftp behavior is caused by the ftp client
-"knowing" that the daemon will exec /bin/ls. This assumption should not
-have been made.
-
-When the old ftp client is used, one of the options is the "ls" command
-which sends the command NLST to the ftpd server. The client should really
-be sending the LIST command. The new ftp client has been corrected to do
-this.
-
-NLST should not normally be used directly by humans. It is intended to
-interface with commands like mget or mput.
-
-Users who are not able to upgrade their ftp client may obtain the previous
-behavior, by using the command "dir" instead of "ls".
-
-These changes only apply to those sites using code derived from the Berkeley
-software releases (which means almost every UNIX based implementation will
-see this problem).
-
+++ /dev/null
-thisconfigdir=./..
-myfulldir=appl/gssftp/ftpd
-mydir=ftpd
-BUILDTOP=$(REL)..$(S)..$(S)..
-#
-# appl/gssftp/ftpd/Makefile.in
-#
-DEFINES = -DGSSAPI -DFTP_BUFSIZ=10240 #-DNOCONFIDENTIAL
-PROG_LIBPATH=-L$(TOPLIBD)
-PROG_RPATH=$(KRB5_LIBDIR)
-
-SETENVSRC=@SETENVSRC@
-SETENVOBJ=@SETENVOBJ@
-LIBOBJS=@LIBOBJS@
-COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
-FTPD_LIBS=@FTPD_LIBS@
-
-SRCS = $(srcdir)/ftpd.c ftpcmd.c $(srcdir)/popen.c \
- $(srcdir)/vers.c \
- $(srcdir)/../ftp/glob.c \
- $(srcdir)/../ftp/radix.c \
- $(srcdir)/../ftp/secure.c \
- $(srcdir)/../../bsd/getdtablesize.c $(SETENVSRC)
-
-OBJS = ftpd.o ftpcmd.o glob.o popen.o vers.o radix.o \
- secure.o $(LIBOBJS) $(SETENVOBJ)
-
-LOCALINCLUDES = -I$(srcdir)/.. -I$(srcdir)
-
-all:: ftpd
-
-ftpd: $(OBJS) $(PTY_DEPLIB) $(GSS_DEPLIBS) $(KRB5_BASE_DEPLIBS)
- $(CC_LINK) -o $@ $(OBJS) $(FTPD_LIBS) $(PTY_LIB) $(UTIL_LIB) $(GSS_LIBS) $(KRB5_BASE_LIBS)
-
-generate-files-mac: ftpcmd.c
-
-clean::
- $(RM) ftpd ftpcmd.c
-
-depend::
-
-install::
- for f in ftpd; do \
- $(INSTALL_PROGRAM) $$f \
- $(DESTDIR)$(SERVER_BINDIR)/`echo $$f|sed '$(transform)'`; \
- $(INSTALL_DATA) $(srcdir)/$$f.M \
- ${DESTDIR}$(SERVER_MANDIR)/`echo $$f|sed '$(transform)'`.8; \
- done
-
-
-ftpcmd.c: $(srcdir)/ftpcmd.y
- $(RM) ftpcmd.c y.tab.c
- $(YACC) $(srcdir)/ftpcmd.y
- $(MV) y.tab.c ftpcmd.c
-
-glob.o: $(srcdir)/../ftp/glob.c
- $(CC) -c $(ALL_CFLAGS) $(srcdir)/../ftp/glob.c
-radix.o: $(srcdir)/../ftp/radix.c
- $(CC) -c $(ALL_CFLAGS) $(srcdir)/../ftp/radix.c
-secure.o: $(srcdir)/../ftp/secure.c
- $(CC) -c $(ALL_CFLAGS) $(srcdir)/../ftp/secure.c
-
-getdtablesize.o: $(srcdir)/../../bsd/getdtablesize.c
- $(CC) -c $(ALL_CFLAGS) $(srcdir)/../../bsd/getdtablesize.c
-
-setenv.o: $(srcdir)/../../bsd/setenv.c
- $(CC) -c $(ALL_CFLAGS) $(srcdir)/../../bsd/setenv.c
-
-
-ftpd.o: $(srcdir)/pathnames.h
-secure.o: $(srcdir)/secure.h
-
-ftpd.o: $(srcdir)/ftpd.c
-ftpcmd.o: ftpcmd.c
-popen.o: $(srcdir)/popen.c
-vers.o: $(srcdir)/vers.c
-
-# NOPOSTFIX
+++ /dev/null
-#
-# Generated makefile dependencies follow.
-#
-$(OUTPRE)ftpd.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \
- $(BUILDTOP)/include/gssapi/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \
- $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/libpty.h \
- $(COM_ERR_DEPS) $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/k5-util.h $(SRCTOP)/include/krb5.h \
- $(SRCTOP)/include/port-sockets.h $(srcdir)/../arpa/ftp.h \
- $(srcdir)/../arpa/telnet.h ftpd.c ftpd_var.h pathnames.h \
- secure.h
-$(OUTPRE)ftpcmd.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \
- $(BUILDTOP)/include/gssapi/gssapi_generic.h $(SRCTOP)/include/k5-buf.h \
- $(srcdir)/../arpa/ftp.h $(srcdir)/../arpa/telnet.h \
- ftpcmd.c ftpd_var.h
-$(OUTPRE)popen.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \
- $(BUILDTOP)/include/gssapi/gssapi_generic.h ftpd_var.h \
- popen.c
-$(OUTPRE)vers.$(OBJEXT): vers.c
-$(OUTPRE)glob.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \
- $(srcdir)/../ftp/ftp_var.h $(srcdir)/../ftp/glob.c
-$(OUTPRE)radix.$(OBJEXT): $(srcdir)/../ftp/ftp_var.h \
- $(srcdir)/../ftp/radix.c
-$(OUTPRE)secure.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_generic.h \
- $(srcdir)/../arpa/ftp.h $(srcdir)/../ftp/secure.c secure.h
-$(OUTPRE)getdtablesize.$(OBJEXT): $(srcdir)/../../bsd/getdtablesize.c
+++ /dev/null
-/* -*- fundamental -*-
- * Copyright (c) 1985, 1988 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.
- *
- * @(#)ftpcmd.y 5.24 (Berkeley) 2/25/91
- */
-
-/*
- * Grammar for FTP commands.
- * See RFC 959.
- * See Also draft-ietf-cat-ftpsec-08.txt.
- */
-
-%{
-
-#ifndef lint
-static char sccsid[] = "@(#)ftpcmd.y 5.24 (Berkeley) 2/25/91";
-#endif /* not lint */
-
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#ifdef HAVE_SYS_SOCKIO_H
-#include <sys/sockio.h>
-#endif
-#include <sys/stat.h>
-#include <netinet/in.h>
-#include <arpa/ftp.h>
-#include <signal.h>
-#include <setjmp.h>
-#include <syslog.h>
-#include <time.h>
-#include <pwd.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-#include <k5-buf.h>
-
-#include "ftpd_var.h"
-
-extern char *auth_type;
-
-unsigned int maxbuf, actualbuf;
-unsigned char *ucbuf;
-
-static int kerror; /* XXX needed for all auth types */
-#ifdef GSSAPI
-#include <gssapi/gssapi.h>
-#include <gssapi/gssapi_generic.h>
-extern gss_ctx_id_t gcontext;
-#endif
-
-#ifndef unix
-/* sigh */
-#if defined(_AIX) || defined(__hpux) || defined(BSD)
-#define unix
-#endif
-#endif
-
-#ifndef NBBY
-#define NBBY 8
-#endif
-
-static struct sockaddr_in host_port;
-
-extern struct sockaddr_in data_dest;
-extern int logged_in;
-extern struct passwd *pw;
-extern int guest;
-extern int logging;
-extern int type;
-extern int form;
-extern int clevel;
-extern int debug;
-
-
-extern int allow_ccc;
-extern int ccc_ok;
-extern int timeout;
-extern int maxtimeout;
-extern int pdata;
-extern int authlevel;
-extern char hostname[], remotehost[];
-extern char proctitle[];
-extern char *globerr;
-extern int usedefault;
-extern int transflag;
-extern char tmpline[];
-
-char **ftpglob();
-
-off_t restart_point;
-
-static int cmd_type;
-static int cmd_form;
-static int cmd_bytesz;
-char cbuf[FTP_BUFSIZ]; /* was 512 */
-char *fromname;
-
-/* bison needs these decls up front */
-extern jmp_buf errcatch;
-
-#define CMD 0 /* beginning of command */
-#define ARGS 1 /* expect miscellaneous arguments */
-#define STR1 2 /* expect SP followed by STRING */
-#define STR2 3 /* expect STRING */
-#define OSTR 4 /* optional SP then STRING */
-#define ZSTR1 5 /* SP then optional STRING */
-#define ZSTR2 6 /* optional STRING after SP */
-#define SITECMD 7 /* SITE command */
-#define NSTR 8 /* Number followed by a string */
-
-struct tab {
- char *name;
- short token;
- short state;
- short implemented; /* 1 if command is implemented */
- char *help;
-};
-struct tab cmdtab[];
-struct tab sitetab[];
-
-void sizecmd(char *);
-void help(struct tab *, char *);
-static int yylex(void);
-static char *copy(char *);
-%}
-
-%union { int num; char *str; }
-
-%token
- SP CRLF COMMA STRING NUMBER
-
- USER PASS ACCT REIN QUIT PORT
- PASV TYPE STRU MODE RETR STOR
- APPE MLFL MAIL MSND MSOM MSAM
- MRSQ MRCP ALLO REST RNFR RNTO
- ABOR DELE CWD LIST NLST SITE
- STAT HELP NOOP MKD RMD PWD
- CDUP STOU SMNT SYST SIZE MDTM
- AUTH ADAT PROT PBSZ
- CCC
-
- UMASK IDLE CHMOD
-
- LEXERR
-
-%type <num> NUMBER
-%type <num> form_code prot_code struct_code mode_code octal_number
-%type <num> check_login byte_size nonguest
-
-%type <str> STRING
-%type <str> password pathname username pathstring
-
-%start cmd_list
-
-%%
-
-cmd_list: /* empty */
- | cmd_list cmd
- {
- fromname = (char *) 0;
- restart_point = (off_t) 0;
- }
- | cmd_list rcmd
- ;
-
-cmd: USER SP username CRLF
- {
- user((char *) $3);
- free($3);
- }
- | PASS SP password CRLF
- {
- pass((char *) $3);
- free($3);
- }
- | PORT SP host_port CRLF
- {
- /*
- * Don't allow a port < 1024 if we're not
- * connecting back to the original source address
- * This prevents nastier forms of the bounce attack.
- */
- if (ntohs(host_port.sin_port) < 1024)
- reply(504, "Port number too low");
- else {
- data_dest = host_port;
- usedefault = 0;
- if (pdata >= 0) {
- (void) close(pdata);
- pdata = -1;
- }
- reply(200, "PORT command successful.");
- }
- }
- | PASV check_login CRLF
- {
- if ($2)
- passive();
- }
- | PROT SP prot_code CRLF
- {
- if (maxbuf)
- setdlevel ($3);
- else
- reply(503, "Must first set PBSZ");
- }
- | CCC CRLF
- {
- if (!allow_ccc) {
- reply(534, "CCC not supported");
- }
- else {
- if(clevel == PROT_C && !ccc_ok) {
- reply(533, "CCC command must be integrity protected");
- } else {
- reply(200, "CCC command successful.");
- ccc_ok = 1;
- }
- }
- }
- | PBSZ SP STRING CRLF
- {
- /* Others may want to do something more fancy here */
- if (!auth_type)
- reply(503, "Must first perform authentication");
- else if (strlen($3) > 10 ||
- (strlen($3) == 10 &&
- strcmp($3,"4294967296") >= 0))
- reply(501, "Bad value for PBSZ: %s", $3);
- else {
- if (ucbuf) (void) free(ucbuf);
- actualbuf = (unsigned int) atol($3);
- /* I attempt what is asked for first, and if that
- fails, I try dividing by 4 */
- while ((ucbuf = (unsigned char *)malloc(actualbuf)) == NULL)
- if (actualbuf)
- lreply(200, "Trying %u", actualbuf >>= 2);
- else {
- perror_reply(421,
- "Local resource failure: malloc");
- dologout(1);
- }
- reply(200, "PBSZ=%u", maxbuf = actualbuf);
- }
- }
- | TYPE SP type_code CRLF
- {
- switch (cmd_type) {
-
- case TYPE_A:
- if (cmd_form == FORM_N) {
- reply(200, "Type set to A.");
- type = cmd_type;
- form = cmd_form;
- } else
- reply(504, "Form must be N.");
- break;
-
- case TYPE_E:
- reply(504, "Type E not implemented.");
- break;
-
- case TYPE_I:
- reply(200, "Type set to I.");
- type = cmd_type;
- break;
-
- case TYPE_L:
-#if NBBY == 8
- if (cmd_bytesz == 8) {
- reply(200,
- "Type set to L (byte size 8).");
- type = cmd_type;
- } else
- reply(504, "Byte size must be 8.");
-#else /* NBBY == 8 */
- UNIMPLEMENTED for NBBY != 8
-#endif /* NBBY == 8 */
- }
- }
- | STRU SP struct_code CRLF
- {
- switch ($3) {
-
- case STRU_F:
- reply(200, "STRU F ok.");
- break;
-
- default:
- reply(504, "Unimplemented STRU type.");
- }
- }
- | MODE SP mode_code CRLF
- {
- switch ($3) {
-
- case MODE_S:
- reply(200, "MODE S ok.");
- break;
-
- default:
- reply(502, "Unimplemented MODE type.");
- }
- }
- | ALLO SP NUMBER CRLF
- {
- reply(202, "ALLO command ignored.");
- }
- | ALLO SP NUMBER SP 'R' SP NUMBER CRLF
- {
- reply(202, "ALLO command ignored.");
- }
- | RETR check_login SP pathname CRLF
- {
- if ($2 && $4 != NULL)
- retrieve((char *) 0, (char *) $4);
- if ($4 != NULL)
- free($4);
- }
- | STOR check_login SP pathname CRLF
- {
- if ($2 && $4 != NULL)
- store_file((char *) $4, "w", 0);
- if ($4 != NULL)
- free($4);
- }
- | APPE check_login SP pathname CRLF
- {
- if ($2 && $4 != NULL)
- store_file((char *) $4, "a", 0);
- if ($4 != NULL)
- free($4);
- }
- | NLST check_login CRLF
- {
- if ($2)
- send_file_list(".");
- }
- | NLST check_login SP STRING CRLF
- {
- if ($2 && $4 != NULL)
- send_file_list((char *) $4);
- if ($4 != NULL)
- free($4);
- }
- | LIST check_login CRLF
- {
- if ($2)
- retrieve("/bin/ls -lgA", "");
- }
- | LIST check_login SP pathname CRLF
- {
- if ($2 && $4 != NULL)
- retrieve("/bin/ls -lgA %s", (char *) $4);
- if ($4 != NULL)
- free($4);
- }
- | STAT check_login SP pathname CRLF
- {
- if ($2 && $4 != NULL)
- statfilecmd((char *) $4);
- if ($4 != NULL)
- free($4);
- }
- | STAT CRLF
- {
- statcmd();
- }
- | DELE check_login SP pathname CRLF
- {
- if ($2 && $4 != NULL)
- delete_file((char *) $4);
- if ($4 != NULL)
- free($4);
- }
- | RNTO SP pathname CRLF
- {
- if (fromname) {
- renamecmd(fromname, (char *) $3);
- free(fromname);
- fromname = (char *) 0;
- } else {
- reply(503, "Bad sequence of commands.");
- }
- free($3);
- }
- | ABOR CRLF
- {
- reply(225, "ABOR command successful.");
- }
- | CWD check_login CRLF
- {
- if ($2)
- cwd(pw->pw_dir);
- }
- | CWD check_login SP pathname CRLF
- {
- if ($2 && $4 != NULL)
- cwd((char *) $4);
- if ($4 != NULL)
- free($4);
- }
- | HELP CRLF
- {
- help(cmdtab, (char *) 0);
- }
- | HELP SP STRING CRLF
- {
- register char *cp = (char *)$3;
-
- if (strncasecmp(cp, "SITE", 4) == 0) {
- cp = (char *)$3 + 4;
- if (*cp == ' ')
- cp++;
- if (*cp)
- help(sitetab, cp);
- else
- help(sitetab, (char *) 0);
- } else
- help(cmdtab, (char *) $3);
- }
- | NOOP CRLF
- {
- reply(200, "NOOP command successful.");
- }
- | MKD nonguest SP pathname CRLF
- {
- if ($2 && $4 != NULL)
- makedir((char *) $4);
- if ($4 != NULL)
- free($4);
- }
- | RMD nonguest SP pathname CRLF
- {
- if ($2 && $4 != NULL)
- removedir((char *) $4);
- if ($4 != NULL)
- free($4);
- }
- | PWD check_login CRLF
- {
- if ($2)
- pwd();
- }
- | CDUP check_login CRLF
- {
- if ($2)
- cwd("..");
- }
- | SITE SP HELP CRLF
- {
- help(sitetab, (char *) 0);
- }
- | SITE SP HELP SP STRING CRLF
- {
- help(sitetab, (char *) $5);
- }
- | SITE SP UMASK check_login CRLF
- {
- int oldmask;
-
- if ($4) {
- oldmask = umask(0);
- (void) umask(oldmask);
- reply(200, "Current UMASK is %03o", oldmask);
- }
- }
- | SITE SP UMASK nonguest SP octal_number CRLF
- {
- int oldmask;
-
- if ($4) {
- if (($6 == -1) || ($6 > 0777)) {
- reply(501, "Bad UMASK value");
- } else {
- oldmask = umask($6);
- reply(200,
- "UMASK set to %03o (was %03o)",
- $6, oldmask);
- }
- }
- }
- | SITE SP CHMOD nonguest SP octal_number SP pathname CRLF
- {
- if ($4 && ($8 != NULL)) {
- if ($6 > 0777)
- reply(501,
- "CHMOD: Mode value must be between 0 and 0777");
- else if (chmod((char *) $8, $6) < 0)
- perror_reply(550, (char *) $8);
- else
- reply(200, "CHMOD command successful.");
- }
- if ($8 != NULL)
- free($8);
- }
- | SITE SP IDLE CRLF
- {
- reply(200,
- "Current IDLE time limit is %d seconds; max %d",
- timeout, maxtimeout);
- }
- | SITE SP IDLE SP NUMBER CRLF
- {
- if ($5 < 30 || $5 > maxtimeout) {
- reply(501,
- "Maximum IDLE time must be between 30 and %d seconds",
- maxtimeout);
- } else {
- timeout = $5;
- (void) alarm((unsigned) timeout);
- reply(200,
- "Maximum IDLE time set to %d seconds",
- timeout);
- }
- }
- | STOU check_login SP pathname CRLF
- {
- if ($2 && $4 != NULL)
- store_file((char *) $4, "w", 1);
- if ($4 != NULL)
- free($4);
- }
- | SYST CRLF
- {
-#ifdef unix
-#ifdef __svr4__
-#undef BSD
-#endif
-#ifdef BSD
- reply(215, "UNIX Type: L%d Version: BSD-%d",
- NBBY, BSD);
-#else /* BSD */
- reply(215, "UNIX Type: L%d", NBBY);
-#endif /* BSD */
-#else /* unix */
- reply(215, "UNKNOWN Type: L%d", NBBY);
-#endif /* unix */
- }
-
- /*
- * SIZE is not in RFC959, but Postel has blessed it and
- * it will be in the updated RFC.
- *
- * Return size of file in a format suitable for
- * using with RESTART (we just count bytes).
- */
- | SIZE check_login SP pathname CRLF
- {
- if ($2 && $4 != NULL)
- sizecmd((char *) $4);
- if ($4 != NULL)
- free($4);
- }
-
- /*
- * MDTM is not in RFC959, but Postel has blessed it and
- * it will be in the updated RFC.
- *
- * Return modification time of file as an ISO 3307
- * style time. E.g. YYYYMMDDHHMMSS or YYYYMMDDHHMMSS.xxx
- * where xxx is the fractional second (of any precision,
- * not necessarily 3 digits)
- */
- | MDTM check_login SP pathname CRLF
- {
- if ($2 && $4 != NULL) {
- struct stat stbuf;
- if (stat($4, &stbuf) < 0)
- perror_reply(550, $4);
- else if ((stbuf.st_mode&S_IFMT) != S_IFREG) {
- reply(550, "%s: not a plain file.",
- (char *) $4);
- } else {
- register struct tm *t;
- struct tm *gmtime();
- t = gmtime(&stbuf.st_mtime);
- reply(213,
- "%4d%02d%02d%02d%02d%02d",
- 1900+t->tm_year, t->tm_mon+1,
- t->tm_mday, t->tm_hour,
- t->tm_min, t->tm_sec);
- }
- }
- if ($4 != NULL)
- free($4);
- }
- | AUTH SP STRING CRLF
- {
- auth((char *) $3);
- }
- | ADAT SP STRING CRLF
- {
- auth_data((char *) $3);
- free($3);
- }
- | QUIT CRLF
- {
- reply(221, "Goodbye.");
- dologout(0);
- }
- | error CRLF
- {
- yyerrok;
- }
- ;
-rcmd: RNFR check_login SP pathname CRLF
- {
- restart_point = (off_t) 0;
- if ($2 && $4) {
- fromname = renamefrom((char *) $4);
- if (fromname == (char *) 0 && $4) {
- free($4);
- }
- }
- }
- | REST SP byte_size CRLF
- {
- fromname = (char *) 0;
- restart_point = $3;
- reply(350, "Restarting at %ld. %s",
- (long) restart_point,
- "Send STORE or RETRIEVE to initiate transfer.");
- }
- ;
-
-username: STRING
- ;
-
-password: /* empty */
- {
- *(char **)&($$) = (char *)calloc(1, sizeof(char));
- }
- | STRING
- ;
-
-byte_size: NUMBER
- ;
-
-host_port: NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA
- NUMBER COMMA NUMBER
- {
- register char *a, *p;
-
- a = (char *)&host_port.sin_addr;
- a[0] = $1; a[1] = $3; a[2] = $5; a[3] = $7;
- p = (char *)&host_port.sin_port;
- p[0] = $9; p[1] = $11;
- host_port.sin_family = AF_INET;
- }
- ;
-
-form_code: 'N'
- {
- $$ = FORM_N;
- }
- | 'T'
- {
- $$ = FORM_T;
- }
- | 'C'
- {
- $$ = FORM_C;
- }
- ;
-
-prot_code: 'C'
- {
- $$ = PROT_C;
- }
- | 'S'
- {
- $$ = PROT_S;
- }
- | 'P'
- {
- $$ = PROT_P;
- }
- | 'E'
- {
- $$ = PROT_E;
- }
- ;
-
-type_code: 'A'
- {
- cmd_type = TYPE_A;
- cmd_form = FORM_N;
- }
- | 'A' SP form_code
- {
- cmd_type = TYPE_A;
- cmd_form = $3;
- }
- | 'E'
- {
- cmd_type = TYPE_E;
- cmd_form = FORM_N;
- }
- | 'E' SP form_code
- {
- cmd_type = TYPE_E;
- cmd_form = $3;
- }
- | 'I'
- {
- cmd_type = TYPE_I;
- }
- | 'L'
- {
- cmd_type = TYPE_L;
- cmd_bytesz = NBBY;
- }
- | 'L' SP byte_size
- {
- cmd_type = TYPE_L;
- cmd_bytesz = $3;
- }
- /* this is for a bug in the BBN ftp */
- | 'L' byte_size
- {
- cmd_type = TYPE_L;
- cmd_bytesz = $2;
- }
- ;
-
-struct_code: 'F'
- {
- $$ = STRU_F;
- }
- | 'R'
- {
- $$ = STRU_R;
- }
- | 'P'
- {
- $$ = STRU_P;
- }
- ;
-
-mode_code: 'S'
- {
- $$ = MODE_S;
- }
- | 'B'
- {
- $$ = MODE_B;
- }
- | 'C'
- {
- $$ = MODE_C;
- }
- ;
-
-pathname: pathstring
- {
- /*
- * Problem: this production is used for all pathname
- * processing, but only gives a 550 error reply.
- * This is a valid reply in some cases but not in others.
- */
- if (logged_in && $1 && strncmp((char *) $1, "~", 1) == 0) {
- char **vv;
-
- vv = ftpglob((char *) $1);
- $$ = (vv != NULL) ? *vv : NULL;
- if ($$ == NULL) {
- if (globerr == NULL)
- $$ = $1;
- else {
- reply(550, "%s", globerr);
- free($1);
- }
- } else
- free($1);
- } else
- $$ = $1;
- }
- ;
-
-pathstring: STRING
- ;
-
-octal_number: NUMBER
- {
- register int ret, dec, multby, digit;
-
- /*
- * Convert a number that was read as decimal number
- * to what it would be if it had been read as octal.
- */
- dec = $1;
- multby = 1;
- ret = 0;
- while (dec) {
- digit = dec%10;
- if (digit > 7) {
- ret = -1;
- break;
- }
- ret += digit * multby;
- multby *= 8;
- dec /= 10;
- }
- $$ = ret;
- }
- ;
-
-check_login: /* empty */
- {
- if (logged_in)
- $$ = 1;
- else {
- reply(530, "Please login with USER and PASS.");
- $$ = 0;
- }
- }
- ;
-
-nonguest: check_login
- {
- if (guest) {
- reply(550, "Operation prohibited for anonymous users.");
- $$ = 0;
- }
- else
- $$ = $1;
- }
- ;
-%%
-
-struct tab cmdtab[] = { /* In order defined in RFC 765 */
- { "USER", USER, STR1, 1, "<sp> username" },
- { "PASS", PASS, ZSTR1, 1, "<sp> password" },
- { "ACCT", ACCT, STR1, 0, "(specify account)" },
- { "SMNT", SMNT, ARGS, 0, "(structure mount)" },
- { "REIN", REIN, ARGS, 0, "(reinitialize server state)" },
- { "QUIT", QUIT, ARGS, 1, "(terminate service)", },
- { "PORT", PORT, ARGS, 1, "<sp> b0, b1, b2, b3, b4" },
- { "PASV", PASV, ARGS, 1, "(set server in passive mode)" },
- { "TYPE", TYPE, ARGS, 1, "<sp> [ A | E | I | L ]" },
- { "STRU", STRU, ARGS, 1, "(specify file structure)" },
- { "MODE", MODE, ARGS, 1, "(specify transfer mode)" },
- { "RETR", RETR, STR1, 1, "<sp> file-name" },
- { "STOR", STOR, STR1, 1, "<sp> file-name" },
- { "APPE", APPE, STR1, 1, "<sp> file-name" },
- { "MLFL", MLFL, OSTR, 0, "(mail file)" },
- { "MAIL", MAIL, OSTR, 0, "(mail to user)" },
- { "MSND", MSND, OSTR, 0, "(mail send to terminal)" },
- { "MSOM", MSOM, OSTR, 0, "(mail send to terminal or mailbox)" },
- { "MSAM", MSAM, OSTR, 0, "(mail send to terminal and mailbox)" },
- { "MRSQ", MRSQ, OSTR, 0, "(mail recipient scheme question)" },
- { "MRCP", MRCP, STR1, 0, "(mail recipient)" },
- { "ALLO", ALLO, ARGS, 1, "allocate storage (vacuously)" },
- { "REST", REST, ARGS, 1, "(restart command)" },
- { "RNFR", RNFR, STR1, 1, "<sp> file-name" },
- { "RNTO", RNTO, STR1, 1, "<sp> file-name" },
- { "ABOR", ABOR, ARGS, 1, "(abort operation)" },
- { "DELE", DELE, STR1, 1, "<sp> file-name" },
- { "CWD", CWD, OSTR, 1, "[ <sp> directory-name ]" },
- { "XCWD", CWD, OSTR, 1, "[ <sp> directory-name ]" },
- { "LIST", LIST, OSTR, 1, "[ <sp> path-name ]" },
- { "NLST", NLST, OSTR, 1, "[ <sp> path-name ]" },
- { "SITE", SITE, SITECMD, 1, "site-cmd [ <sp> arguments ]" },
- { "SYST", SYST, ARGS, 1, "(get type of operating system)" },
- { "STAT", STAT, OSTR, 1, "[ <sp> path-name ]" },
- { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]" },
- { "NOOP", NOOP, ARGS, 1, "" },
- { "MKD", MKD, STR1, 1, "<sp> path-name" },
- { "XMKD", MKD, STR1, 1, "<sp> path-name" },
- { "RMD", RMD, STR1, 1, "<sp> path-name" },
- { "XRMD", RMD, STR1, 1, "<sp> path-name" },
- { "PWD", PWD, ARGS, 1, "(return current directory)" },
- { "XPWD", PWD, ARGS, 1, "(return current directory)" },
- { "CDUP", CDUP, ARGS, 1, "(change to parent directory)" },
- { "XCUP", CDUP, ARGS, 1, "(change to parent directory)" },
- { "STOU", STOU, STR1, 1, "<sp> file-name" },
- { "AUTH", AUTH, STR1, 1, "<sp> auth-type" },
- { "ADAT", ADAT, STR1, 1, "<sp> auth-data" },
- { "PROT", PROT, ARGS, 1, "<sp> protection-level" },
- { "PBSZ", PBSZ, STR1, 1, "<sp> buffer-size" },
- { "CCC", CCC, ARGS, 1, "(clear command channel)" },
- { "SIZE", SIZE, OSTR, 1, "<sp> path-name" },
- { "MDTM", MDTM, OSTR, 1, "<sp> path-name" },
- { NULL, 0, 0, 0, 0 }
-};
-
-struct tab sitetab[] = {
- { "UMASK", UMASK, ARGS, 1, "[ <sp> umask ]" },
- { "IDLE", IDLE, ARGS, 1, "[ <sp> maximum-idle-time ]" },
- { "CHMOD", CHMOD, NSTR, 1, "<sp> mode <sp> file-name" },
- { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]" },
- { NULL, 0, 0, 0, 0 }
-};
-
-static struct tab *
-lookup(p, cmd)
- register struct tab *p;
- char *cmd;
-{
-
- for (; p->name != NULL; p++)
- if (strcmp(cmd, p->name) == 0)
- return (p);
- return (0);
-}
-
-/*
- * urgsafe_getc - hacked up getc to ignore EOF if SIOCATMARK returns TRUE
- */
-static int
-urgsafe_getc(f)
- FILE *f;
-{
- register int c;
- int atmark;
-
- c = getc(f);
- if (c == EOF) {
- if (ioctl(fileno(f), SIOCATMARK, &atmark) != -1) {
- c = getc(f);
- syslog(LOG_DEBUG, "atmark: c=%d", c);
- }
- }
- return c;
-}
-
-#include <arpa/telnet.h>
-
-/*
- * getline - a hacked up version of fgets to ignore TELNET escape codes.
- */
-char *
-ftpd_getline(s, n, iop)
- char *s;
- int n;
- register FILE *iop;
-{
- register int c;
- register char *cs;
-
- cs = s;
-/* tmpline may contain saved command from urgent mode interruption */
- for (c = 0; tmpline[c] != '\0' && --n > 0; ++c) {
- *cs++ = tmpline[c];
- if (tmpline[c] == '\n') {
- *cs++ = '\0';
- if (debug)
- syslog(LOG_DEBUG, "command: %s", s);
- tmpline[0] = '\0';
- return(s);
- }
- if (c == 0)
- tmpline[0] = '\0';
- }
- while ((c = urgsafe_getc(iop)) != EOF) {
- c &= 0377;
- if (c == IAC) {
- if (debug) syslog(LOG_DEBUG, "got IAC");
- if ((c = urgsafe_getc(iop)) != EOF) {
- c &= 0377;
- if (debug) syslog(LOG_DEBUG, "got IAC %d", c);
- switch (c) {
- case WILL:
- case WONT:
- c = urgsafe_getc(iop);
- printf("%c%c%c", IAC, DONT, 0377&c);
- (void) fflush(stdout);
- continue;
- case DO:
- case DONT:
- c = urgsafe_getc(iop);
- printf("%c%c%c", IAC, WONT, 0377&c);
- (void) fflush(stdout);
- continue;
- case IAC:
- break;
- default:
- continue; /* ignore command */
- }
- }
- }
- *cs++ = c;
- if (--n <= 0 || c == '\n')
- break;
- }
- if (c == EOF && cs == s)
- return (NULL);
- *cs++ = '\0';
- if (auth_type) {
- char out[sizeof(cbuf)], *cp;
- int len, mic;
-
-
- /* Check to see if we have a protected command. */
- if (!((mic = strncmp(s, "ENC", 3)) && strncmp(s, "MIC", 3)
- && strncmp(s, "AUTH", 4)
-#ifndef NOCONFIDENTIAL
- && strncmp(s, "CONF", 4)
-#endif
- ) && (cs = strpbrk(s, " \r\n"))) {
- *cs++ = '\0'; /* If so, split it into s and cs. */
- } else { /* If not, check if unprotected commands are allowed. */
- if(ccc_ok) {
- clevel = PROT_C;
- upper(s);
- return(s);
- } else {
- reply(533, "All commands must be protected.");
- syslog(LOG_ERR, "Unprotected command received");
- *s = '\0';
- return(s);
- }
- }
- upper(s);
- if (debug)
- syslog(LOG_INFO, "command %s received (mic=%d)", s, mic);
-#ifdef NOCONFIDENTIAL
- if (!strcmp(s, "CONF")) {
- reply(537, "CONF protected commands not supported.");
- *s = '\0';
- return(s);
- }
-#endif
-/* Some paranoid sites may want to require that commands be encrypted. */
-#ifdef PARANOID
- if (mic) {
- reply(533, "All commands must be ENC protected. Retry command under ENC.");
- *s = '\0';
- return(s);
- }
-#endif /* PARANOID */
-#ifdef NOENCRYPTION
- if (!mic) {
- reply(533, "ENC protection not supported. Retry command under MIC.");
- *s = '\0';
- return(s);
- }
-#endif /* NOENCRYPTION */
- if ((cp = strpbrk(cs, " \r\n")))
- *cp = '\0';
- kerror = radix_encode(cs, out, &len, 1);
- if (kerror) {
- reply(501, "Can't base 64 decode argument to %s command (%s)",
- mic ? "MIC" : "ENC", radix_error(kerror));
- *s = '\0';
- return(s);
- }
- if (debug) syslog(LOG_DEBUG, "getline got %d from %s <%s>\n",
- len, cs, mic?"MIC":"ENC");
- clevel = mic ? PROT_S : PROT_P;
-#ifdef GSSAPI
-/* we know this is a MIC or ENC already, and out/len already has the bits */
- if (strcmp(auth_type, "GSSAPI") == 0) {
- gss_buffer_desc xmit_buf, msg_buf;
- OM_uint32 maj_stat, min_stat;
- int conf_state;
-
- xmit_buf.value = out;
- xmit_buf.length = len;
- /* decrypt the message */
- conf_state = !mic;
- maj_stat = gss_unseal(&min_stat, gcontext, &xmit_buf,
- &msg_buf, &conf_state, NULL);
- if (maj_stat == GSS_S_CONTINUE_NEEDED) {
- if (debug) syslog(LOG_DEBUG, "%s-unseal continued",
- mic?"MIC":"ENC");
- reply(535, "%s-unseal continued, oops",
- mic?"MIC":"ENC");
- *s = 0; return s;
- }
- if (maj_stat != GSS_S_COMPLETE) {
- reply_gss_error(535, maj_stat, min_stat,
- mic? "failed unsealing MIC message":
- "failed unsealing ENC message");
- *s = 0;
- return s;
- }
-
- memcpy(s, msg_buf.value, msg_buf.length);
- memcpy(s+msg_buf.length-(s[msg_buf.length-1]?0:1), "\r\n", 3);
- gss_release_buffer(&min_stat, &msg_buf);
- }
-#endif /* GSSAPI */
- /* Other auth types go here ... */
-
- /* A password should never be MICed, but the CNS ftp
- * client and the pre-6/98 Krb5 client did this if you
- * authenticated but didn't encrypt.
- */
- if (authlevel && mic && !strncmp(s, "PASS", 4)) {
- lreply(530, "There is a problem with your ftp client. Password refused.");
- reply(530, "Enable encryption before logging in, or update your ftp program.");
- *s = 0;
- return s;
- }
-
- }
-#ifdef GSSAPI /* or other auth types */
- else { /* !auth_type */
- if ( (!(strncmp(s, "ENC", 3))) || (!(strncmp(s, "MIC", 3)))
-#ifndef NOCONFIDENTIAL
- || (!(strncmp(s, "CONF", 4)))
-#endif
- ) {
- reply(503, "Must perform authentication before sending protected commands");
- *s = '\0';
- return(s);
- }
- }
-#endif GSSAPI
-
- if (debug) {
- if (!strncmp(s, "PASS ", 5) && !guest)
- syslog(LOG_DEBUG, "command: <PASS XXX>");
- else
- syslog(LOG_DEBUG, "command: <%.*s>(%d)",
- strlen(s) - 2, s, strlen(s));
- }
- return (s);
-}
-
-static krb5_sigtype
-toolong(sig)
- int sig;
-{
- time_t now;
-
- reply(421,
- "Timeout (%d seconds): closing control connection.", timeout);
- (void) time(&now);
- if (logging) {
- syslog(LOG_INFO,
- "User %s timed out after %d seconds at %s",
- (pw ? pw -> pw_name : "unknown"), timeout, ctime(&now));
- }
- dologout(1);
-}
-
-static int
-yylex()
-{
- static int cpos, state;
- register char *cp, *cp2;
- register struct tab *p;
- int n;
- char c;
-
- for (;;) {
- switch (state) {
-
- case CMD:
- (void) signal(SIGALRM, toolong);
- (void) alarm((unsigned) timeout);
- if (ftpd_getline(cbuf, sizeof(cbuf)-1, stdin) == NULL) {
- reply(221, "You could at least say goodbye.");
- dologout(0);
- }
- (void) alarm(0);
-
- /* If getline() finds an error, the string is null */
- if (*cbuf == '\0')
- continue;
-
-#ifdef SETPROCTITLE
- if (strncasecmp(cbuf, "PASS", 4) != NULL)
- setproctitle("%s: %s", proctitle, cbuf);
-#endif /* SETPROCTITLE */
- if ((cp = strchr(cbuf, '\r'))) {
- *cp++ = '\n';
- *cp = '\0';
- }
- if ((cp = strpbrk(cbuf, " \n")))
- cpos = cp - cbuf;
- if (cpos == 0)
- cpos = 4;
- c = cbuf[cpos];
- cbuf[cpos] = '\0';
- upper(cbuf);
- p = lookup(cmdtab, cbuf);
- cbuf[cpos] = c;
- if (p != 0) {
- if (p->implemented == 0) {
- nack(p->name);
- longjmp(errcatch,0);
- /* NOTREACHED */
- }
- state = p->state;
- yylval.str = p->name;
- return (p->token);
- }
- break;
-
- case SITECMD:
- if (cbuf[cpos] == ' ') {
- cpos++;
- return (SP);
- }
- cp = &cbuf[cpos];
- if ((cp2 = strpbrk(cp, " \n")))
- cpos = cp2 - cbuf;
- c = cbuf[cpos];
- cbuf[cpos] = '\0';
- upper(cp);
- p = lookup(sitetab, cp);
- cbuf[cpos] = c;
- if (p != 0) {
- if (p->implemented == 0) {
- state = CMD;
- nack(p->name);
- longjmp(errcatch,0);
- /* NOTREACHED */
- }
- state = p->state;
- yylval.str = p->name;
- return (p->token);
- }
- state = CMD;
- break;
-
- case OSTR:
- if (cbuf[cpos] == '\n') {
- state = CMD;
- return (CRLF);
- }
- /* FALLTHROUGH */
-
- case STR1:
- case ZSTR1:
- dostr1:
- if (cbuf[cpos] == ' ') {
- cpos++;
- state = state == OSTR ? STR2 : state+1;
- return (SP);
- }
- break;
-
- case ZSTR2:
- if (cbuf[cpos] == '\n') {
- state = CMD;
- return (CRLF);
- }
- /* FALLTHROUGH */
-
- case STR2:
- cp = &cbuf[cpos];
- n = strlen(cp);
- cpos += n - 1;
- /*
- * Make sure the string is nonempty and \n terminated.
- */
- if (n > 1 && cbuf[cpos] == '\n') {
- cbuf[cpos] = '\0';
- yylval.str = copy(cp);
- cbuf[cpos] = '\n';
- state = ARGS;
- return (STRING);
- }
- break;
-
- case NSTR:
- if (cbuf[cpos] == ' ') {
- cpos++;
- return (SP);
- }
- if (isdigit((int) cbuf[cpos])) {
- cp = &cbuf[cpos];
- while (isdigit((int) cbuf[++cpos]))
- ;
- c = cbuf[cpos];
- cbuf[cpos] = '\0';
- yylval.num = atoi(cp);
- cbuf[cpos] = c;
- state = STR1;
- return (NUMBER);
- }
- state = STR1;
- goto dostr1;
-
- case ARGS:
- if (isdigit((int) cbuf[cpos])) {
- cp = &cbuf[cpos];
- while (isdigit((int) cbuf[++cpos]))
- ;
- c = cbuf[cpos];
- cbuf[cpos] = '\0';
- yylval.num = atoi(cp);
- cbuf[cpos] = c;
- return (NUMBER);
- }
- switch (cbuf[cpos++]) {
-
- case '\n':
- state = CMD;
- return (CRLF);
-
- case ' ':
- return (SP);
-
- case ',':
- return (COMMA);
-
- case 'A':
- case 'a':
- return ('A');
-
- case 'B':
- case 'b':
- return ('B');
-
- case 'C':
- case 'c':
- return ('C');
-
- case 'E':
- case 'e':
- return ('E');
-
- case 'F':
- case 'f':
- return ('F');
-
- case 'I':
- case 'i':
- return ('I');
-
- case 'L':
- case 'l':
- return ('L');
-
- case 'N':
- case 'n':
- return ('N');
-
- case 'P':
- case 'p':
- return ('P');
-
- case 'R':
- case 'r':
- return ('R');
-
- case 'S':
- case 's':
- return ('S');
-
- case 'T':
- case 't':
- return ('T');
-
- }
- break;
-
- default:
- fatal("Unknown state in scanner.");
- }
- yyerror((char *) 0);
- state = CMD;
- longjmp(errcatch,0);
- }
-}
-
-void
-upper(s)
- register char *s;
-{
- while (*s != '\0') {
- if (islower((int) (*s)))
- *s = toupper((int) (*s));
- s++;
- }
-}
-
-static char *
-copy(s)
- char *s;
-{
- char *p;
-
- p = strdup(s);
- if (p == NULL)
- fatal("Ran out of memory.");
- return (p);
-}
-
-void
-help(ctab, s)
- struct tab *ctab;
- char *s;
-{
- register struct tab *c;
- register int width, NCMDS;
- char str[80];
- char *ftype;
-
- if (ctab == sitetab)
- ftype = "SITE ";
- else
- ftype = "";
- width = 0, NCMDS = 0;
- for (c = ctab; c->name != NULL; c++) {
- int len = strlen(c->name);
-
- if (len > width)
- width = len;
- NCMDS++;
- }
- width = (width + 8) &~ 7;
- if (s == 0) {
- register int i, j, w;
- int columns, lines;
- struct k5buf buf;
-
- lreply(214, "The following %scommands are recognized %s.",
- ftype, "(* =>'s unimplemented)");
- columns = 76 / width;
- if (columns == 0)
- columns = 1;
- lines = (NCMDS + columns - 1) / columns;
- for (i = 0; i < lines; i++) {
- krb5int_buf_init_fixed(&buf, str, sizeof(str));
- krb5int_buf_add(&buf, " ");
- for (j = 0; j < columns; j++) {
- c = ctab + j * lines + i;
- krb5int_buf_add_fmt(&buf, "%s%c", c->name,
- c->implemented ? ' '
- : '*');
- if (c + lines >= &ctab[NCMDS])
- break;
- w = strlen(c->name) + 1;
- while (w < width) {
- krb5int_buf_add(&buf, " ");
- w++;
- }
- }
- reply(0, "%s", str);
- }
- reply(214, "Direct comments to ftp-bugs@%s.", hostname);
- return;
- }
- upper(s);
- c = lookup(ctab, s);
- if (c == (struct tab *)0) {
- reply(502, "Unknown command %s.", s);
- return;
- }
- if (c->implemented)
- reply(214, "Syntax: %s%s %s", ftype, c->name, c->help);
- else
- reply(214, "%s%-*s\t%s; unimplemented.", ftype, width,
- c->name, c->help);
-}
-
-void
-sizecmd(filename)
-char *filename;
-{
- switch (type) {
- case TYPE_L:
- case TYPE_I: {
- struct stat stbuf;
- if (stat(filename, &stbuf) < 0 ||
- (stbuf.st_mode&S_IFMT) != S_IFREG)
- reply(550, "%s: not a plain file.", filename);
- else
- reply(213, "%lu", (long) stbuf.st_size);
- break;}
- case TYPE_A: {
- FILE *fin;
- register int c;
- register long count;
- struct stat stbuf;
- fin = fopen(filename, "r");
- if (fin == NULL) {
- perror_reply(550, filename);
- return;
- }
- if (fstat(fileno(fin), &stbuf) < 0 ||
- (stbuf.st_mode&S_IFMT) != S_IFREG) {
- reply(550, "%s: not a plain file.", filename);
- (void) fclose(fin);
- return;
- }
-
- count = 0;
- while((c=getc(fin)) != EOF) {
- if (c == '\n') /* will get expanded to \r\n */
- count++;
- count++;
- }
- (void) fclose(fin);
-
- reply(213, "%ld", count);
- break;}
- default:
- reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]);
- }
-}
+++ /dev/null
-.\" Copyright (c) 1985, 1988, 1991 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.
-.\"
-.\" @(#)ftpd.8 6.9 (Berkeley) 3/16/91
-.\" "
-.TH FTPD 8
-.SH NAME
-ftpd \- DARPA Internet File Transfer Protocol server
-.SH SYNOPSIS
-.B ftpd
-[\fB\-A \fP|\fB -a\fP] [\fB\-C\fP] [\fB\-c\fP] [\fB\-d\fP] [\fB-E\fP]
-[\fB\-l\fP] [\fB\-v\fP] [\fB\-T\fP \fImaxtimeout\fP] [\fB\-t\fP \fItimeout\fP]
-[\fB\-p\fP \fIport\fP] [\fB\-U\fP \fIftpusers-file\fP] [\fB\-u\fP \fIumask\fP]
-[\fB\-r\fP \fIrealm-file\fP] [\fB\-s\fP \fIsrvtab\fP]
-[\fB\-w\fP{\fBip\fP|\fImaxhostlen\fP[\fB,\fP{\fBstriplocal\fP|\fBnostriplocal\fP}]}]
-.SH DESCRIPTION
-.B Ftpd
-is the
-.SM DARPA
-Internet File Transfer Protocol server process. The server uses the
-.SM TCP
-protocol and listens at the port specified in the ``ftp'' service
-specification; see
-.IR services (5).
-.PP
-Available options:
-.TP
-.B \-A
-Connections are only allowed for users who can authenticate via the
-ftp AUTH mechanism. (Anonymous ftp may also be allowed if it is
-configured.) Ftpd will ask the user for a password if one is
-required.
-.TP
-.B \-a
-Connections are only allowed for users who can authenticate (via the
-ftp AUTH mechanism) and who are authorized to connect to the named
-account without a password. (Anonymous ftp may also be allowed if it is
-configured.)
-.TP
-.B \-C
-Non-anonymous users need local credentials (for example, to authenticate
-to remote fileservers), and so they should be prompted for a password
-unless they forwarded credentials as part of authentication.
-.TP
-.B \-c
-Allow the CCC (Clear Command Channel) command to be used. This allows
-less secure connections, and should probably only be used when debugging.
-.TP
-.B \-d
-Debugging information is written to the syslog. (Identical to -v)
-.TP
-.B \-E
-Don't allow passwords to be typed across unencrypted connections.
-.TP
-.B \-l
-Each
-.IR ftp (1)
-session is logged in the syslog. If this flag appears twice, additional
-information about operations performed (such as files retrieved, directories
-created, etc.) will be logged via syslog. If it appears three times, some
-other statistics such as the number of bytes transferred will be logged via
-syslog as well.
-.TP
-.B \-v
-Debugging information is written to the syslog. (Identical to -d)
-.TP
-\fB\-T\fP \fImaxtimeout\fP
-A client may request a maximum timeout period allowed set to
-.I timeout
-seconds with the
-.B \-T
-option. The default limit is 2 hours. This is different from the normal
-inactivity timeout specified by the
-.B \-t
-option (see below).
-.TP
-\fB\-t\fP \fItimeout\fP
-The inactivity timeout period is set to
-.I timeout
-seconds (the default is 15 minutes).
-.TP
-\fB\-p\fP \fIport\fP
-Run as a server and accept a connection on
-.IR port .
-Normally the ftp server is invoked by
-.IR inetd (8).
-.TP
-\fB\-U\fP \fIftpusers-file\fP
-Sets the full path and name of the
-.I ftpusers
-file to use. The default value is normally
-.IR /etc/ftpusers .
-.TP
-\fB\-u\fP \fIumask\fP
-Sets the umask for the ftpd process. The default value is normally 027.
-.TP
-\fB\-w \fP{\fBip\fP|\fImaxhostlen\fP[\fB,\fP{\fBstriplocal\fP|\fBnostriplocal\fP}]}
-Controls the form of the remote hostname passed to login(1).
-Specifying \fBip\fP results in the numeric IP address always being
-passed to login(1). Specifying a number, \fImaxhostlen\fP, sets the
-maximum length of the hostname passed to login(1) before it will be
-passed as a numeric IP address. If \fImaxhostlen\fP is 0, then the
-system default, as determined by the utmp or utmpx structures, is
-used. The \fBnostriplocal\fP and \fBstriplocal\fP options, which must
-be preceded by a comma, control whether or not the local host domain
-is stripped from the remote hostname. By default, the equivalent of
-\fBstriplocal\fP is in effect.
-.PP
-The ftp server currently supports the following ftp requests; case is
-not distinguished.
-.TP "\w'Request\ \ 'u"
-.B Request
-.B Description
-.sp -1
-.TP
-ABOR
-abort previous command
-.sp -1
-.TP
-ACCT
-specify account (ignored)
-.sp -1
-.TP
-ADAT
-send an authentication protocol message
-.sp -1
-.TP
-ALLO
-allocate storage (vacuously)
-.sp -1
-.TP
-APPE
-append to a file
-.sp -1
-.TP
-AUTH
-specify an authentication protocol to be performed
-.sp -1
-.TP
-CCC
-set the command channel protection mode to "Clear" (no protection).
-Only available if the \fB-c\fP command-line option was given.
-.sp -1
-.TP
-CDUP
-change to parent of current working directory
-.sp -1
-.TP
-CWD
-change working directory
-.sp -1
-.TP
-DELE
-delete a file
-.sp -1
-.TP
-ENC
-send a privacy and integrity protected command (given in argument)
-.sp -1
-.TP
-HELP
-give help information
-.sp -1
-.TP
-LIST
-give list files in a directory (``ls -lgA'')
-.sp -1
-.TP
-MIC
-send an integrity protected command (given in argument)
-.sp -1
-.TP
-MKD
-make a directory
-.sp -1
-.TP
-MDTM
-show last modification time of file
-.sp -1
-.TP
-MODE
-specify data transfer
-.I mode
-.sp -1
-.TP
-NLST
-give name list of files in directory
-.sp -1
-.TP
-NOOP
-do nothing
-.sp -1
-.TP
-PASS
-specify password
-.sp -1
-.TP
-PASV
-prepare for server-to-server transfer
-.sp -1
-.TP
-PBSZ
-specify a protection buffer size
-.sp -1
-.TP
-PORT
-specify data connection port
-.sp -1
-.TP
-PROT
-specify a protection level under which to protect data transfers
-.sp -1
-.TP
-PWD
-print the current working directory
-.sp -1
-.TP
-QUIT
-terminate session
-.sp -1
-.TP
-REST
-restart incomplete transfer
-.sp -1
-.TP
-RETR
-retrieve a file
-.sp -1
-.TP
-RMD
-remove a directory
-.sp -1
-.TP
-RNFR
-specify rename-from file name
-.sp -1
-.TP
-RNTO
-specify rename-to file name
-.sp -1
-.TP
-SITE
-non-standard commands (see next section)
-.sp -1
-.TP
-SIZE
-return size of file
-.sp -1
-.TP
-STAT
-return status of server
-.sp -1
-.TP
-STOR
-store a file
-.sp -1
-.TP
-STOU
-store a file with a unique name
-.sp -1
-.TP
-STRU
-specify data transfer
-.I structure
-.sp -1
-.TP
-SYST
-show operating system type of server system
-.sp -1
-.TP
-TYPE
-specify data transfer
-.I type
-.sp -1
-.TP
-USER
-specify user name
-.sp -1
-.TP
-XCUP
-change to parent of current working directory (deprecated)
-.sp -1
-.TP
-XCWD
-change working directory (deprecated)
-.sp -1
-.TP
-XMKD
-make a directory (deprecated)
-.sp -1
-.TP
-XPWD
-print the current working directory (deprecated)
-.sp -1
-.TP
-XRMD
-remove a directory (deprecated)
-.PP
-The following non-standard or
-.SM UNIX
-specific commands are supported by the SITE request.
-.TP "\w'Request\ \ 'u"
-.B Request
-.B Description
-.sp -1
-.TP
-UMASK
-change umask.
-.IR E.g. ,
-SITE UMASK 002
-.sp -1
-.TP
-IDLE
-set idle-timer.
-.IR E.g. ,
-SITE IDLE 60
-.sp -1
-.TP
-CHMOD
-change mode of a file.
-.IR E.g. ,
-SITE CHMOD 755 filename
-.sp -1
-.TP
-HELP
-give help information.
-.IR E.g. ,
-SITE HELP
-.PP
-The remaining ftp requests specified in Internet
-.I RFC 959
-are recognized, but not implemented. MDTM and SIZE are not specified in
-.I RFC
-.IR 959 ,
-but will appear in the next updated FTP RFC.
-.PP
-The ftp server will abort an active file transfer only when the ABOR
-command is preceded by a Telnet "Interrupt Process" (IP) signal and a
-Telnet "Synch" signal in the command Telnet stream, as described in
-Internet
-.I RFC
-.IR 959 .
-If a STAT command is received during a data transfer, preceded by a
-Telnet IP and Synch, transfer status will be returned.
-.PP
-.B Ftpd
-interprets file names according to the
-``globbing''
-conventions used by
-.IR csh (1).
-This allows users to utilize the metacharacters ``\&*?[]{}~''.
-.PP
-.B Ftpd
-authenticates users according to the following rules:
-.sp
-.TP
- 1.
-The user name must be in the password data base,
-.IR /etc/passwd .
-.TP
- 2.
-An
-.SM AUTH
-command must be accepted, the ensuing authentication protocol (conducted
-via
-.SM ADAT
-commands and replies) must successfully complete, and the authenticated
-user must permitted access. Otherwise, a valid password which is not
-null must be provided by the client.
-.TP
- 3.
-The user name must not appear in the file
-.IR /etc/ftpusers .
-.TP
- 4.
-The user must have a standard shell returned by
-.IR getusershell (3).
-.TP
- 5.
-If the user name is ``anonymous'' or ``ftp'', an anonymous ftp account
-must be present in the password file (user ``ftp''). In this case the
-user is allowed to log in by specifying any password (by convention this
-is given as the client host's name).
-.PP
-In the last case,
-.B ftpd
-takes special measures to restrict the client's access privileges. The
-server performs a
-.IR chroot (2)
-command to the home directory of the ``ftp'' user. In order that system
-security is not breached, it is recommended that the ``ftp'' subtree be
-constructed with care; the following rules are recommended.
-.TP
-.I ~ftp
-Make the home directory owned by ``ftp'' and unwritable by anyone.
-.TP
-.I ~ftp/bin
-Make this directory owned by the super-user and unwritable by anyone.
-The program
-.IR ls (1)
-must be present to support the list command. This program should have
-mode 111.
-.TP
-.I ~ftp/etc
-Make this directory owned by the super-user and unwritable by anyone.
-The files
-.IR passwd (5)
-and
-.IR group (5)
-must be present for the
-.I ls
-command to be able to produce owner names rather than numbers. The
-password field in
-.I passwd
-is not used, and should not contain real encrypted passwords. These
-files should be mode 444.
-.TP
-.I ~ftp/pub
-Make this directory mode 777 and owned by ``ftp''. Users should then
-place files which are to be accessible via the anonymous account in this
-directory.
-.PP
-If an
-.SM ADAT
-command succeeds, the control channel must be either integrity or
-privacy protected. In this case, the
-.SM MIC
-and
-.SM ENC
-commands are the only commands allowed over the control channel. The
-argument to the
-.SM MIC
-command is a base 64 encoded string which, when decoded, is an ftp
-command integrity protected with a cryptographic checksum. The argument
-to the
-.SM ENC
-command is a base 64 encoded string which, when decoded, is an ftp
-command privacy and integrity protected with encryption.
-.PP
-If an
-.SM ADAT
-command succeeds, ftp replies will also be either integrity or privacy
-protected.
-.PP
-If an
-.SM ADAT
-command succeeds, the data channel can also be integrity or privacy
-protected. The
-.SM PROT
-command accepts S for integrity and P for privacy protection. Unless an
-.SM ADAT
-command succeeds, the only protection level accepted by the
-.SM PROT
-command is C (clear).
-.SH SEE ALSO
-.IR ftp (1),
-.IR getusershell (3),
-.IR syslogd (8)
-.PP
-Lunt, S. J., FTP Security Extensions, Internet Draft, November 1993.
-.SH BUGS
-The anonymous account is inherently dangerous and should avoided when
-possible.
-.PP
-The server must run as the super-user to create sockets with privileged
-port numbers. It maintains an effective user id of the logged in user,
-reverting to the super-user only when binding addresses to sockets. The
-possible security holes have been extensively scrutinized, but are
-possibly incomplete.
-.SH HISTORY
-The
-.B ftpd
-command appeared in 4.2BSD.
+++ /dev/null
-/*
- * Copyright (c) 1985, 1988, 1990 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 lint
-char copyright[] =
-"@(#) Copyright (c) 1985, 1988, 1990 Regents of the University of California.\n\
- All rights reserved.\n";
-#endif /* not lint */
-
-#ifndef lint
-static char sccsid[] = "@(#)ftpd.c 5.40 (Berkeley) 7/2/91";
-#endif /* not lint */
-
-/*
- * FTP server.
- */
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/wait.h>
-#include <sys/file.h>
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-
-#define FTP_NAMES
-#include <arpa/ftp.h>
-#include <arpa/inet.h>
-#include <arpa/telnet.h>
-
-#include <signal.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <time.h>
-#include <pwd.h>
-#ifdef HAVE_SHADOW
-#include <shadow.h>
-#endif
-#include <grp.h>
-#include <setjmp.h>
-#ifndef POSIX_SETJMP
-#undef sigjmp_buf
-#undef sigsetjmp
-#undef siglongjmp
-#define sigjmp_buf jmp_buf
-#define sigsetjmp(j,s) setjmp(j)
-#define siglongjmp longjmp
-#endif
-#include <netdb.h>
-#include <errno.h>
-#include <syslog.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-#ifndef STDARG
-#if (defined(__STDC__) && ! defined(VARARGS)) || defined(HAVE_STDARG_H)
-#define STDARG
-#endif
-#endif
-#ifdef STDARG
-#include <stdarg.h>
-#endif
-#include "pathnames.h"
-#include <libpty.h>
-
-#include <k5-platform.h>
-
-#ifdef NEED_SETENV
-extern int setenv(char *, char *, int);
-#endif
-
-#ifndef L_SET
-#define L_SET 0
-#endif
-#ifndef L_INCR
-#define L_INCR 1
-#endif
-
-#ifndef HAVE_STRERROR
-#define strerror(error) (sys_errlist[error])
-#ifdef NEED_SYS_ERRLIST
-extern char *sys_errlist[];
-#endif
-#endif
-
-extern char *mktemp ();
-char *ftpusers;
-extern int yyparse(void);
-
-#include <k5-util.h>
-#include "port-sockets.h"
-
-#ifdef GSSAPI
-#include <gssapi/gssapi.h>
-#include <gssapi/gssapi_generic.h>
-#include <gssapi/gssapi_krb5.h>
-gss_ctx_id_t gcontext;
-gss_buffer_desc client_name;
-static char *gss_services[] = { "ftp", "host", NULL };
-
-#include <krb5.h>
-krb5_context kcontext;
-krb5_ccache ccache;
-
-static void ftpd_gss_convert_creds(char *name, gss_cred_id_t);
-static int ftpd_gss_userok(gss_buffer_t, char *name);
-
-static void log_gss_error(int, OM_uint32, OM_uint32, const char *);
-
-#endif /* GSSAPI */
-
-char *auth_type; /* Authentication succeeded? If so, what type? */
-static char *temp_auth_type;
-int authorized; /* Auth succeeded and was accepted by gssapi */
-int have_creds; /* User has credentials on disk */
-
-/*
- * File containing login names
- * NOT to be used on this machine.
- * Commonly used to disallow uucp.
- */
-#include "ftpd_var.h"
-#include "secure.h"
-
-extern char *crypt();
-extern char version[];
-extern char *home; /* pointer to home directory for glob */
-extern FILE *ftpd_popen(), *fopen(), *freopen();
-extern int ftpd_pclose(), fclose();
-extern char cbuf[];
-extern off_t restart_point;
-
-struct sockaddr_in ctrl_addr;
-struct sockaddr_in data_source;
-struct sockaddr_in data_dest;
-struct sockaddr_in his_addr;
-struct sockaddr_in pasv_addr;
-
-int data;
-jmp_buf errcatch;
-sigjmp_buf urgcatch;
-int logged_in;
-struct passwd *pw;
-int debug;
-int allow_ccc = 0; /* whether or not the CCC command is allowed */
-int ccc_ok = 0; /* whether or not to accept cleartext commands */
-int timeout = 900; /* timeout after 15 minutes of inactivity */
-int maxtimeout = 7200;/* don't allow idle time to be set beyond 2 hours */
-int logging;
-int authlevel;
-int want_creds;
-int guest;
-int restricted;
-int type;
-int clevel; /* control protection level */
-int dlevel; /* data protection level */
-int form;
-int stru; /* avoid C keyword */
-int mode;
-int usedefault = 1; /* for data transfers */
-int pdata = -1; /* for passive mode */
-int transflag;
-off_t file_size;
-off_t byte_count;
-#if !defined(CMASK) || CMASK == 0
-#undef CMASK
-#define CMASK 027
-#endif
-int defumask = CMASK; /* default umask value */
-char tmpline[FTP_BUFSIZ];
-char pathbuf[MAXPATHLEN + 1];
-char hostname[MAXHOSTNAMELEN];
-char remotehost[MAXHOSTNAMELEN];
-char rhost_addra[16];
-char *rhost_sane;
-
-/* Defines for authlevel */
-#define AUTHLEVEL_NONE 0
-#define AUTHLEVEL_AUTHENTICATE 1
-#define AUTHLEVEL_AUTHORIZE 2
-
-/*
- * Timeout intervals for retrying connections
- * to hosts that don't accept PORT cmds. This
- * is a kludge, but given the problems with TCP...
- */
-#define SWAITMAX 90 /* wait at most 90 seconds */
-#define SWAITINT 5 /* interval between retries */
-
-int swaitmax = SWAITMAX;
-int swaitint = SWAITINT;
-
-void lostconn(int), myoob(int);
-FILE *getdatasock(char *);
-#if defined(__STDC__)
-/*
- * The following prototypes must be ANSI for systems for which
- * sizeof(off_t) > sizeof(int) to prevent stack overflow problems
- */
-FILE *dataconn(char *name, off_t size, char *mymode);
-void send_data(FILE *instr, FILE *outstr, off_t blksize);
-#else
-void send_data();
-FILE *dataconn();
-#endif
-static void dolog(struct sockaddr_in *);
-static int receive_data(FILE *, FILE *);
-static void login(char *passwd, int logincode);
-static void end_login(void);
-static int disallowed_user(char *);
-static int restricted_user(char *);
-static int checkuser(char *);
-static char *gunique(char *);
-
-#ifdef SETPROCTITLE
-char **Argv = NULL; /* pointer to argument vector */
-char *LastArgv = NULL; /* end of argv */
-char proctitle[FTP_BUFSIZ]; /* initial part of title */
-#endif /* SETPROCTITLE */
-
-#ifdef __SCO__
-/* sco has getgroups and setgroups but no initgroups */
-int initgroups(char* name, gid_t basegid) {
- gid_t others[NGROUPS_MAX+1];
- int ngrps;
-
- others[0] = basegid;
- ngrps = getgroups(NGROUPS_MAX, others+1);
- return setgroups(ngrps+1, others);
-}
-#endif
-
-int stripdomain = 1;
-int maxhostlen = 0;
-int always_ip = 0;
-
-int
-main(argc, argv, envp)
- int argc;
- char *argv[];
- char **envp;
-{
- int addrlen, c, on = 1, tos, port = -1;
- extern char *optarg;
- extern int optopt;
- char *option_string = "AaCcdElp:T:t:U:u:vw:";
- ftpusers = _PATH_FTPUSERS_DEFAULT;
-
- debug = 0;
-#ifdef SETPROCTITLE
- /*
- * Save start and extent of argv for setproctitle.
- */
- Argv = argv;
- while (*envp)
- envp++;
- LastArgv = envp[-1] + strlen(envp[-1]);
-#endif /* SETPROCTITLE */
-
-#ifdef GSSAPI
- krb5_init_context(&kcontext);
-#endif
-
- while ((c = getopt(argc, argv, option_string)) != -1) {
- switch (c) {
-
- case 'v':
- debug = 1;
- break;
-
- case 'd':
- debug = 1;
- break;
-
- case 'E':
- if (!authlevel)
- authlevel = AUTHLEVEL_AUTHENTICATE;
- break;
-
- case 'l':
- logging ++;
- break;
-
- case 'a':
- authlevel = AUTHLEVEL_AUTHORIZE;
- break;
-
- case 'A':
- authlevel = AUTHLEVEL_AUTHENTICATE;
- break;
-
- case 'C':
- want_creds = 1;
- break;
-
- case 'c':
- allow_ccc = 1;
- break;
-
- case 'p':
- port = atoi(optarg);
- break;
-
- case 't':
- timeout = atoi(optarg);
- if (maxtimeout < timeout)
- maxtimeout = timeout;
- break;
-
- case 'T':
- maxtimeout = atoi(optarg);
- if (timeout > maxtimeout)
- timeout = maxtimeout;
- break;
-
- case 'u':
- {
- int val = 0;
- char *umask_val = optarg;
-
- while (*umask_val >= '0' && *umask_val <= '9') {
- val = val*8 + *umask_val - '0';
- umask_val++;
- }
- if (*umask_val != ' ' && *umask_val != '\0')
- fprintf(stderr, "ftpd: Bad value for -u\n");
- else
- defumask = val;
- break;
- }
-
- case 'U':
- ftpusers = optarg;
- break;
-
- case 'w':
- {
- char *foptarg;
- foptarg = optarg;
-
- if (!strcmp(foptarg, "ip"))
- always_ip = 1;
- else {
- char *cp2;
- cp2 = strchr(foptarg, ',');
- if (cp2 == NULL)
- maxhostlen = atoi(foptarg);
- else if (*(++cp2)) {
- if (!strcmp(cp2, "striplocal"))
- stripdomain = 1;
- else if (!strcmp(cp2, "nostriplocal"))
- stripdomain = 0;
- else {
- fprintf(stderr,
- "ftpd: bad arg to -w\n");
- exit(1);
- }
- *(--cp2) = '\0';
- maxhostlen = atoi(foptarg);
- }
- }
- break;
- }
- default:
- fprintf(stderr, "ftpd: Unknown flag -%c ignored.\n",
- (char)optopt);
- break;
- }
- }
-
- if (port != -1) {
- struct sockaddr_in sin4;
- int s, ns;
- socklen_t sz;
-
- /* Accept an incoming connection on port. */
- sin4.sin_family = AF_INET;
- sin4.sin_addr.s_addr = INADDR_ANY;
- sin4.sin_port = htons(port);
- s = socket(AF_INET, SOCK_STREAM, 0);
- if (s < 0) {
- perror("socket");
- exit(1);
- }
- (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
- (char *)&on, sizeof(on));
- if (bind(s, (struct sockaddr *)&sin4, sizeof sin4) < 0) {
- perror("bind");
- exit(1);
- }
- if (listen(s, 1) < 0) {
- perror("listen");
- exit(1);
- }
- sz = sizeof sin4;
- ns = accept(s, (struct sockaddr *)&sin4, &sz);
- if (ns < 0) {
- perror("accept");
- exit(1);
- }
- (void) close(s);
- (void) dup2(ns, 0);
- (void) dup2(ns, 1);
- (void) dup2(ns, 2);
- if (ns > 2)
- (void) close(ns);
- }
-
- /*
- * LOG_NDELAY sets up the logging connection immediately,
- * necessary for anonymous ftp's that chroot and can't do it later.
- */
-#ifndef LOG_NDELAY
-/* Ultrix syslog does not support NDELAY. */
-#define LOG_NDELAY 0
-#endif
-#ifndef LOG_DAEMON
-#define LOG_DAEMON 0
-#endif
- openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_DAEMON);
-
- addrlen = sizeof (his_addr);
- if (getpeername(0, (struct sockaddr *)&his_addr, &addrlen) < 0) {
- syslog(LOG_ERR, "getpeername (%s): %m",argv[0]);
- exit(1);
- }
- addrlen = sizeof (ctrl_addr);
- if (getsockname(0, (struct sockaddr *)&ctrl_addr, &addrlen) < 0) {
- syslog(LOG_ERR, "getsockname (%s): %m",argv[0]);
- exit(1);
- }
-#ifdef IP_TOS
-#ifdef IPTOS_LOWDELAY
- tos = IPTOS_LOWDELAY;
- if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
- syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
-#endif
-#endif
- port = ntohs(ctrl_addr.sin_port);
- data_source.sin_port = htons(port - 1);
-
- (void) freopen("/dev/null", "w", stderr);
- (void) signal(SIGPIPE, lostconn);
- (void) signal(SIGCHLD, SIG_IGN);
-#ifdef SIGURG
-#ifdef POSIX_SIGNALS
- {
- struct sigaction sa;
-
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = myoob;
- if (sigaction(SIGURG, &sa, NULL) < 0)
- syslog(LOG_ERR, "signal: %m");
- }
-#else
- if ((long)signal(SIGURG, myoob) < 0)
- syslog(LOG_ERR, "signal: %m");
-#endif /* POSIX_SIGNALS */
-#endif /* SIGURG */
-
- /* Try to handle urgent data inline */
-#ifdef SO_OOBINLINE
- if (setsockopt(0, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on)) < 0)
- syslog(LOG_ERR, "setsockopt: %m");
-#endif
-
-#ifdef F_SETOWN
- if (fcntl(fileno(stdin), F_SETOWN, getpid()) == -1)
- syslog(LOG_ERR, "fcntl F_SETOWN: %m");
-#endif
- dolog(&his_addr);
- /*
- * Set up default state
- */
- data = -1;
- clevel = dlevel = PROT_C;
- type = TYPE_A;
- form = FORM_N;
- stru = STRU_F;
- mode = MODE_S;
- tmpline[0] = '\0';
- (void) gethostname(hostname, sizeof (hostname));
- reply(220, "%s FTP server (%s) ready.", hostname, version);
- (void) setjmp(errcatch);
- for (;;)
- (void) yyparse();
- /* NOTREACHED */
-}
-
-void
-lostconn(sig)
-int sig;
-{
- if (debug)
- syslog(LOG_DEBUG, "lost connection");
- dologout(-1);
-}
-
-static char ttyline[20];
-
-/*
- * Helper function for sgetpwnam().
- */
-static char *
-sgetsave(s)
- char *s;
-{
- char *new = strdup(s);
-
- if (new == NULL) {
- perror_reply(421, "Local resource failure: malloc");
- dologout(1);
- /* NOTREACHED */
- }
- return (new);
-}
-
-/*
- * Save the result of a getpwnam. Used for USER command, since
- * the data returned must not be clobbered by any other command
- * (e.g., globbing).
- */
-static struct passwd *
-sgetpwnam(name)
- char *name;
-{
- static struct passwd save;
- register struct passwd *p;
-#ifdef HAVE_SHADOW
- register struct spwd *sp;
-#endif
- if ((p = getpwnam(name)) == NULL)
- return (p);
- if (save.pw_name) {
- free(save.pw_name);
- free(save.pw_passwd);
- free(save.pw_gecos);
- free(save.pw_dir);
- free(save.pw_shell);
- }
- save = *p;
- save.pw_name = sgetsave(p->pw_name);
-#ifdef HAVE_SHADOW
- if ((sp = getspnam(name)) == NULL)
- save.pw_passwd = sgetsave(p->pw_passwd);
- else
- save.pw_passwd = sgetsave(sp->sp_pwdp);
-#else
- save.pw_passwd = sgetsave(p->pw_passwd);
-#endif
- save.pw_gecos = sgetsave(p->pw_gecos);
- save.pw_dir = sgetsave(p->pw_dir);
- save.pw_shell = sgetsave(p->pw_shell);
- return (&save);
-}
-
-/*
- * Expand the given pathname relative to the current working directory.
- */
-static char *
-path_expand(path)
- char *path;
-{
- pathbuf[0] = '\x0';
- if (!path) return pathbuf;
- /* Don't bother with getcwd() if the path is absolute */
- if (path[0] != '/') {
- if (!getcwd(pathbuf, sizeof pathbuf)) {
- pathbuf[0] = '\x0';
- syslog(LOG_ERR, "getcwd() failed");
- }
- else {
- int len = strlen(pathbuf);
- if (pathbuf[len-1] != '/') {
- pathbuf[len++] = '/';
- pathbuf[len] = '\x0';
- }
- }
- }
- return strncat(pathbuf, path,
- sizeof (pathbuf) - strlen(pathbuf) - 1);
-}
-
-/*
- * Set data channel protection level
- */
-void
-setdlevel(prot_level)
-int prot_level;
-{
- switch (prot_level) {
- case PROT_S:
-#ifndef NOENCRYPTION
- case PROT_P:
-#endif
- if (auth_type)
- case PROT_C:
- reply(200, "Data channel protection level set to %s.",
- (dlevel = prot_level) == PROT_S ?
- "safe" : dlevel == PROT_P ?
- "private" : "clear");
- else
- default: reply(536, "%s protection level not supported.",
- levelnames[prot_level]);
- }
-}
-
-int login_attempts; /* number of failed login attempts */
-int askpasswd; /* had user command, ask for passwd */
-
-/*
- * USER command.
- * Sets global passwd pointer pw if named account exists and is acceptable;
- * sets askpasswd if a PASS command is expected. If logged in previously,
- * need to reset state. If name is "ftp" or "anonymous", the name is not in
- * ftpusers, and ftp account exists, set guest and pw, then just return.
- * If account doesn't exist, ask for passwd anyway. Otherwise, check user
- * requesting login privileges. Disallow anyone who does not have a standard
- * shell as returned by getusershell(). Disallow anyone mentioned in the file
- * ftpusers to allow people such as root and uucp to be avoided, except
- * for users whose names are followed by whitespace and then the keyword
- * "restrict." Restricted users are allowed to login, but a chroot() is
- * done to their home directory.
- */
-void
-user(name)
- char *name;
-{
- register char *cp;
- char *shell;
- char buf[FTP_BUFSIZ];
-#ifdef HAVE_GETUSERSHELL
- char *getusershell();
-#endif
-
- if (logged_in) {
- if (guest) {
- reply(530, "Can't change user from guest login.");
- return;
- }
- end_login();
- }
-
- authorized = guest = 0;
- if (strcmp(name, "ftp") == 0 || strcmp(name, "anonymous") == 0) {
- if (disallowed_user("ftp") || disallowed_user("anonymous"))
- reply(530, "User %s access denied.", name);
- else if ((pw = sgetpwnam("ftp")) != NULL) {
- guest = 1;
- askpasswd = 1;
- reply(331, "Guest login ok, send ident as password.");
- } else
- reply(530, "User %s unknown.", name);
- return;
- }
-
- /*
- * If authentication is required, check that before anything
- * else to avoid leaking information.
- */
- if (authlevel && !auth_type) {
- reply(530,
- "Must perform authentication before identifying USER.");
- return;
- }
-
- pw = sgetpwnam(name);
- if (pw) {
- if ((shell = pw->pw_shell) == NULL || *shell == 0)
- shell = "/bin/sh";
-#ifdef HAVE_GETUSERSHELL
- setusershell();
- while ((cp = getusershell()) != NULL)
- if (strcmp(cp, shell) == 0)
- break;
- endusershell();
-#else
- cp = shell;
-#endif
- if (cp == NULL || disallowed_user(name)) {
- reply(530, "User %s access denied.", name);
- if (logging)
- syslog(LOG_NOTICE,
- "FTP LOGIN REFUSED FROM %s, %s (%s)",
- rhost_addra, remotehost, name);
- pw = (struct passwd *) NULL;
- return;
- }
- restricted = restricted_user(name);
- }
-
- if (auth_type) {
- int result;
-#ifdef GSSAPI
- if (auth_type && strcmp(auth_type, "GSSAPI") == 0) {
- int len;
-
- authorized = ftpd_gss_userok(&client_name, name) == 0;
- len = sizeof("GSSAPI user is not authorized as "
- "; Password required.")
- + strlen(client_name.value)
- + strlen(name);
- if (len >= sizeof(buf)) {
- syslog(LOG_ERR, "user: username too long");
- name = "[username too long]";
- }
- snprintf(buf, sizeof(buf),
- "GSSAPI user %s is%s authorized as %s",
- (char *) client_name.value,
- authorized ? "" : " not",
- name);
- }
-#endif /* GSSAPI */
-
- if (!authorized && authlevel == AUTHLEVEL_AUTHORIZE) {
- strncat(buf, "; Access denied.",
- sizeof(buf) - strlen(buf) - 1);
- result = 530;
- pw = NULL;
- } else if (!authorized || (want_creds && !have_creds)) {
- strncat(buf, "; Password required.",
- sizeof(buf) - strlen(buf) - 1);
- askpasswd = 1;
- result = 331;
- } else
- result = 232;
- if (result == 232)
- login(NULL, result);
- reply(result, "%s", buf);
- syslog(authorized ? LOG_INFO : LOG_ERR, "%s", buf);
- return;
- }
-
- /* User didn't authenticate and authentication wasn't required. */
- reply(331, "Password required for %s.", name);
- askpasswd = 1;
-
- /*
- * Delay before reading passwd after first failed
- * attempt to slow down passwd-guessing programs.
- */
- if (login_attempts)
- sleep((unsigned) login_attempts);
-}
-
-/*
- * Check if a user is in the file ftpusers.
- * Return 1 if they are (a disallowed user), -1 if their username
- * is followed by "restrict." (a restricted user). Otherwise return 0.
- */
-static int
-checkuser(name)
- char *name;
-{
- register FILE *fd;
- register char *p;
- char line[FTP_BUFSIZ];
-
- if ((fd = fopen(ftpusers, "r")) != NULL) {
- while (fgets(line, sizeof(line), fd) != NULL) {
- if ((p = strchr(line, '\n')) != NULL) {
- *p = '\0';
- if (line[0] == '#')
- continue;
- if (strcmp(line, name) == 0)
- return (1);
- if (strncmp(line, name, strlen(name)) == 0) {
- int i = strlen(name) + 1;
-
- /* Make sure foo doesn't match foobar */
- if (line[i] == '\0' || !isspace((int) line[i]))
- continue;
- /* Ignore whitespace */
- while (isspace((int) line[++i]));
-
- if (strcmp(&line[i], "restrict") == 0)
- return (-1);
- else
- return (1);
- }
- }
- }
- (void) fclose(fd);
- }
-
- return (0);
-}
-
-static int
-disallowed_user(name)
- char *name;
-{
- return(checkuser(name) == 1);
-}
-
-static int
-restricted_user(name)
- char *name;
-{
- return(checkuser(name) == -1);
-}
-
-/*
- * Terminate login as previous user, if any, resetting state;
- * used when USER command is given or login fails.
- */
-static void
-end_login()
-{
-
- (void) krb5_seteuid((uid_t)0);
- if (logged_in)
- pty_logwtmp(ttyline, "", "");
- if (have_creds) {
-#ifdef GSSAPI
- krb5_cc_destroy(kcontext, ccache);
-#endif
- have_creds = 0;
- }
- pw = NULL;
- logged_in = 0;
- guest = 0;
-}
-
-static int
-kpass(name, passwd)
-char *name, *passwd;
-{
-#ifdef GSSAPI
- krb5_principal server, me;
- krb5_creds my_creds;
- krb5_timestamp now;
-#endif /* GSSAPI */
- char ccname[MAXPATHLEN];
-
-#ifdef GSSAPI
- memset(&my_creds, 0, sizeof(my_creds));
- if (krb5_parse_name(kcontext, name, &me))
- return 0;
- my_creds.client = me;
-
- snprintf(ccname, sizeof(ccname), "FILE:/tmp/krb5cc_ftpd%ld",
- (long) getpid());
- if (krb5_cc_resolve(kcontext, ccname, &ccache))
- return(0);
- if (krb5_cc_initialize(kcontext, ccache, me))
- return(0);
- if (krb5_build_principal_ext(kcontext, &server,
- krb5_princ_realm(kcontext, me)->length,
- krb5_princ_realm(kcontext, me)->data,
- KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME,
- krb5_princ_realm(kcontext, me)->length,
- krb5_princ_realm(kcontext, me)->data,
- 0))
- goto nuke_ccache;
-
- my_creds.server = server;
- if (krb5_timeofday(kcontext, &now))
- goto nuke_ccache;
- my_creds.times.starttime = 0; /* start timer when
- request gets to KDC */
- my_creds.times.endtime = now + 60 * 60 * 10;
- my_creds.times.renew_till = 0;
-
- if (krb5_get_init_creds_password(kcontext, &my_creds, me,
- passwd, NULL, NULL, 0, NULL, NULL))
- goto nuke_ccache;
-
- if (krb5_cc_store_cred(kcontext, ccache, &my_creds))
- goto nuke_ccache;
-
- if (!want_creds) {
- krb5_cc_destroy(kcontext, ccache);
- return(1);
- }
-
- have_creds = 1;
- return(1);
-#endif /* GSSAPI */
-
-nuke_ccache:
-#ifdef GSSAPI
- krb5_cc_destroy(kcontext, ccache);
-#endif /* GSSAPI */
- return(0);
-}
-
-void
-pass(passwd)
- char *passwd;
-{
- char *xpasswd, *salt;
-
- if (authorized && !want_creds) {
- reply(202, "PASS command superfluous.");
- return;
- }
-
- if (logged_in || askpasswd == 0) {
- reply(503, "Login with USER first.");
- return;
- }
-
- if (!guest) {
- /* "ftp" is only account allowed no password */
- if (pw == NULL)
- salt = "xx";
- else
- salt = pw->pw_passwd;
-#ifdef __SCO__
- /* SCO does not provide crypt. */
- xpasswd = "";
-#else
- xpasswd = crypt(passwd, salt);
-#endif
- /* Fail if:
- * pw is NULL
- * kpass fails and we want_creds
- * kpass fails and the user has no local password
- * kpass fails and the provided password doesn't match pw
- */
- if (pw == NULL || (!kpass(pw->pw_name, passwd) &&
- (want_creds || !*pw->pw_passwd ||
- strcmp(xpasswd, pw->pw_passwd)))) {
- pw = NULL;
- sleep(5);
- if (++login_attempts >= 3) {
- reply(421,
- "Login incorrect, closing connection.");
- syslog(LOG_NOTICE,
- "repeated login failures from %s (%s)",
- rhost_addra, remotehost);
- dologout(0);
- }
- reply(530, "Login incorrect.");
- return;
- }
- }
- login_attempts = 0; /* this time successful */
-
- login(passwd, 0);
- return;
-}
-
-static void
-login(passwd, logincode)
- char *passwd;
- int logincode;
-{
- if (have_creds) {
-#ifdef GSSAPI
- const char *ccname = krb5_cc_get_name(kcontext, ccache);
- chown(ccname, pw->pw_uid, pw->pw_gid);
-#endif
- }
-
- (void) krb5_setegid((gid_t)pw->pw_gid);
- (void) initgroups(pw->pw_name, pw->pw_gid);
-
- /* open wtmp before chroot */
- (void) snprintf(ttyline, sizeof(ttyline), "ftp%ld", (long) getpid());
- pty_logwtmp(ttyline, pw->pw_name, rhost_sane);
- logged_in = 1;
-
- if (guest || restricted) {
- if (chroot(pw->pw_dir) < 0) {
- reply(550, "Can't set privileges.");
- goto bad;
- }
- }
-#ifdef HAVE_SETLUID
- /*
- * If we're on a system which keeps track of login uids, then
- * set the login uid. If this fails this opens up a problem on DEC OSF
- * with C2 enabled.
- */
- if (((uid_t)getluid() != pw->pw_uid)
- && setluid((uid_t)pw->pw_uid) < 0) {
- reply(550, "Can't set luid.");
- goto bad;
- }
-#endif
- if (krb5_seteuid((uid_t)pw->pw_uid) < 0) {
- reply(550, "Can't set uid.");
- goto bad;
- }
- if (guest) {
- /*
- * We MUST do a chdir() after the chroot. Otherwise
- * the old current directory will be accessible as "."
- * outside the new root!
- */
- if (chdir("/") < 0) {
- reply(550, "Can't set guest privileges.");
- goto bad;
- }
- } else {
- if (chdir(restricted ? "/" : pw->pw_dir) < 0) {
- if (chdir("/") < 0) {
- reply(530, "User %s: can't change directory to %s.",
- pw->pw_name, pw->pw_dir);
- goto bad;
- } else {
- if (!logincode)
- logincode = 230;
- lreply(logincode, "No directory! Logging in with home=/");
- }
- }
- }
- if (guest) {
- reply(230, "Guest login ok, access restrictions apply.");
-#ifdef SETPROCTITLE
- snprintf(proctitle, sizeof(proctitle), "%s: anonymous/%.*s",
- rhost_sane, passwd);
- setproctitle(proctitle);
-#endif /* SETPROCTITLE */
- if (logging)
- syslog(LOG_INFO,
- "ANONYMOUS FTP LOGIN FROM %s, %s (%s)",
- rhost_addra, remotehost, passwd);
- } else {
- if (askpasswd) {
- askpasswd = 0;
- reply(230, "User %s logged in.", pw->pw_name);
- }
-#ifdef SETPROCTITLE
- snprintf(proctitle, sizeof(proctitle), "%s: %s",
- rhost_sane, pw->pw_name);
- setproctitle(proctitle);
-#endif /* SETPROCTITLE */
- if (logging)
- syslog(LOG_INFO, "FTP LOGIN FROM %s, %s (%s)",
- rhost_addra, remotehost, pw->pw_name);
- }
- home = pw->pw_dir; /* home dir for globbing */
- (void) umask(defumask);
- return;
-bad:
- /* Forget all about it... */
- end_login();
-}
-
-void
-retrieve(cmd, name)
- char *cmd, *name;
-{
- FILE *fin, *dout;
- struct stat st;
- int (*closefunc)();
-
- if (logging > 1 && !cmd)
- syslog(LOG_NOTICE, "get %s", path_expand(name));
- if (cmd == 0) {
- fin = fopen(name, "r"), closefunc = fclose;
- st.st_size = 0;
- } else {
- char line[FTP_BUFSIZ];
-
- if (strlen(cmd) + strlen(name) + 1 >= sizeof(line)) {
- syslog(LOG_ERR, "retrieve: filename too long");
- reply(501, "filename too long");
- return;
- }
- (void) snprintf(line, sizeof(line), cmd, name), name = line;
- fin = ftpd_popen(line, "r"), closefunc = ftpd_pclose;
- st.st_size = -1;
-#ifndef NOSTBLKSIZE
- st.st_blksize = FTP_BUFSIZ;
-#endif
- }
- if (fin == NULL) {
- if (errno != 0)
- perror_reply(550, name);
- return;
- }
- if (cmd == 0 &&
- (fstat(fileno(fin), &st) < 0 || (st.st_mode&S_IFMT) != S_IFREG)) {
- reply(550, "%s: not a plain file.", name);
- goto done;
- }
- if (restart_point) {
- if (type == TYPE_A) {
- register int i, n, c;
-
- n = restart_point;
- i = 0;
- while (i++ < n) {
- if ((c=getc(fin)) == EOF) {
- perror_reply(550, name);
- goto done;
- }
- if (c == '\n')
- i++;
- }
- } else if (lseek(fileno(fin), restart_point, L_SET) < 0) {
- perror_reply(550, name);
- goto done;
- }
- }
- dout = dataconn(name, st.st_size, "w");
- if (dout == NULL)
- goto done;
-#ifndef NOSTBLKSIZE
- send_data(fin, dout, st.st_blksize);
-#else
- send_data(fin, dout, FTP_BUFSIZ);
-#endif
- (void) fclose(dout);
- data = -1;
- pdata = -1;
-done:
- (*closefunc)(fin);
- if (logging > 2 && !cmd)
- syslog(LOG_NOTICE, "get: %i bytes transferred", byte_count);
-}
-
-void
-store_file(name, fmode, unique)
- char *name, *fmode;
- int unique;
-{
- FILE *fout, *din;
- struct stat st;
- int (*closefunc)();
-
- if (logging > 1) syslog(LOG_NOTICE, "put %s", path_expand(name));
-
- if (unique && stat(name, &st) == 0 &&
- (name = gunique(name)) == NULL)
- return;
-
- if (restart_point)
- fmode = "r+w";
- fout = fopen(name, fmode);
- closefunc = fclose;
- if (fout == NULL) {
- perror_reply(553, name);
- return;
- }
- if (restart_point) {
- if (type == TYPE_A) {
- register int i, n, c;
-
- n = restart_point;
- i = 0;
- while (i++ < n) {
- if ((c=getc(fout)) == EOF) {
- perror_reply(550, name);
- goto done;
- }
- if (c == '\n')
- i++;
- }
- /*
- * We must do this seek to "current" position
- * because we are changing from reading to
- * writing.
- */
- if (fseek(fout, 0L, L_INCR) < 0) {
- perror_reply(550, name);
- goto done;
- }
- } else if (lseek(fileno(fout), restart_point, L_SET) < 0) {
- perror_reply(550, name);
- goto done;
- }
- }
- din = dataconn(name, (off_t)-1, "r");
- if (din == NULL)
- goto done;
- if (receive_data(din, fout) == 0) {
- if (unique)
- reply(226, "Transfer complete (unique file name:%s).",
- name);
- else
- reply(226, "Transfer complete.");
- }
- (void) fclose(din);
- data = -1;
- pdata = -1;
-done:
- (*closefunc)(fout);
- if (logging > 2)
- syslog(LOG_NOTICE, "put: %i bytes transferred", byte_count);
-}
-
-FILE *
-getdatasock(fmode)
- char *fmode;
-{
- int s, on = 1, tries;
-
- if (data >= 0)
- return (fdopen(data, fmode));
- (void) krb5_seteuid((uid_t)0);
- s = socket(AF_INET, SOCK_STREAM, 0);
- if (s < 0)
- goto bad;
- if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
- (char *) &on, sizeof (on)) < 0)
- goto bad;
- /* anchor socket to avoid multi-homing problems */
- data_source.sin_family = AF_INET;
- data_source.sin_addr = ctrl_addr.sin_addr;
- for (tries = 1; ; tries++) {
- if (bind(s, (struct sockaddr *)&data_source,
- sizeof (data_source)) >= 0)
- break;
- if (errno != EADDRINUSE || tries > 10)
- goto bad;
- sleep(tries);
- }
- if (krb5_seteuid((uid_t)pw->pw_uid)) {
- fatal("seteuid user");
- }
-#ifdef IP_TOS
-#ifdef IPTOS_THROUGHPUT
- on = IPTOS_THROUGHPUT;
- if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
- syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
-#endif
-#endif
- return (fdopen(s, fmode));
-bad:
- if (krb5_seteuid((uid_t)pw->pw_uid)) {
- fatal("seteuid user");
- }
- (void) close(s);
- return (NULL);
-}
-
-FILE *
-dataconn(name, size, fmode)
- char *name;
- off_t size;
- char *fmode;
-{
- char sizebuf[32];
- FILE *file;
- int retry = 0, tos;
-
- file_size = size;
- byte_count = 0;
- if (size != (off_t) -1)
- /* cast size to long in case sizeof(off_t) > sizeof(long) */
- (void) snprintf (sizebuf, sizeof(sizebuf), " (%ld bytes)",
- (long)size);
- else
- sizebuf[0] = '\0';
- if (pdata >= 0) {
- int s, fromlen = sizeof(data_dest);
-
- s = accept(pdata, (struct sockaddr *)&data_dest, &fromlen);
- if (s < 0) {
- reply(425, "Can't open data connection.");
- (void) close(pdata);
- pdata = -1;
- return(NULL);
- }
- (void) close(pdata);
- pdata = s;
-#ifdef IP_TOS
-#ifdef IPTOS_LOWDELAY
- tos = IPTOS_LOWDELAY;
- (void) setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos,
- sizeof(int));
-#endif
-#endif
- reply(150, "Opening %s mode data connection for %s%s.",
- type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
- return(fdopen(pdata, fmode));
- }
- if (data >= 0) {
- reply(125, "Using existing data connection for %s%s.",
- name, sizebuf);
- usedefault = 1;
- return (fdopen(data, fmode));
- }
- if (usedefault)
- data_dest = his_addr;
- usedefault = 1;
- file = getdatasock(fmode);
- if (file == NULL) {
- reply(425, "Can't create data socket (%s,%d): %s.",
- inet_ntoa(data_source.sin_addr),
- ntohs(data_source.sin_port), strerror(errno));
- return (NULL);
- }
- data = fileno(file);
- while (connect(data, (struct sockaddr *)&data_dest,
- sizeof (data_dest)) < 0) {
- if (errno == EADDRINUSE && retry < swaitmax) {
- sleep((unsigned) swaitint);
- retry += swaitint;
- continue;
- }
- perror_reply(425, "Can't build data connection");
- (void) fclose(file);
- data = -1;
- return (NULL);
- }
- reply(150, "Opening %s mode data connection for %s%s.",
- type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
- return (file);
-}
-
-/*
- * XXX callers need to limit total length of output string to
- * FTP_BUFSIZ
- */
-void
-secure_error(char *fmt, ...)
-{
- char buf[FTP_BUFSIZ];
- va_list ap;
-
- va_start(ap, fmt);
- vsnprintf(buf, sizeof(buf), fmt, ap);
- va_end(ap);
- reply(535, "%s", buf);
- syslog(LOG_ERR, "%s", buf);
-}
-
-/*
- * Tranfer the contents of "instr" to
- * "outstr" peer using the appropriate
- * encapsulation of the data subject
- * to Mode, Structure, and Type.
- *
- * NB: Form isn't handled.
- */
-void send_data(instr, outstr, blksize)
- FILE *instr, *outstr;
- off_t blksize;
-{
- register int c, cnt;
- register char *buf;
- int netfd, filefd;
- volatile int ret = 0;
-
- transflag++;
- if (sigsetjmp(urgcatch, 1)) {
- transflag = 0;
- (void)secure_flush(fileno(outstr));
- return;
- }
- switch (type) {
-
- case TYPE_A:
- while ((c = getc(instr)) != EOF) {
- byte_count++;
- if (c == '\n') {
- if (ferror(outstr) ||
- (ret = secure_putc('\r', outstr)) < 0)
- goto data_err;
- }
- if ((ret = secure_putc(c, outstr)) < 0)
- goto data_err;
- }
- transflag = 0;
- if (ferror(instr))
- goto file_err;
- if (ferror(outstr) ||
- (ret = secure_flush(fileno(outstr))) < 0)
- goto data_err;
- reply(226, "Transfer complete.");
- return;
-
- case TYPE_I:
- case TYPE_L:
- if ((buf = malloc((u_int)blksize)) == NULL) {
- transflag = 0;
- perror_reply(451, "Local resource failure: malloc");
- return;
- }
- netfd = fileno(outstr);
- filefd = fileno(instr);
- while ((cnt = read(filefd, buf, (u_int)blksize)) > 0 &&
- (ret = secure_write(netfd, buf, cnt)) == cnt)
- byte_count += cnt;
- transflag = 0;
- (void)free(buf);
- if (cnt != 0) {
- if (cnt < 0)
- goto file_err;
- goto data_err;
- }
- if ((ret = secure_flush(netfd)) < 0)
- goto data_err;
- reply(226, "Transfer complete.");
- return;
- default:
- transflag = 0;
- reply(550, "Unimplemented TYPE %d in send_data", type);
- return;
- }
-
-data_err:
- transflag = 0;
- if (ret != -2) perror_reply(426, "Data connection");
- return;
-
-file_err:
- transflag = 0;
- perror_reply(551, "Error on input file");
-}
-
-/*
- * Transfer data from peer to
- * "outstr" using the appropriate
- * encapulation of the data subject
- * to Mode, Structure, and Type.
- *
- * N.B.: Form isn't handled.
- */
-static int
-receive_data(instr, outstr)
- FILE *instr, *outstr;
-{
- register int c;
- volatile int cnt, bare_lfs = 0;
- char buf[FTP_BUFSIZ];
- int ret = 0;
-
- transflag++;
- if (sigsetjmp(urgcatch, 1)) {
- transflag = 0;
- return (-1);
- }
- switch (type) {
-
- case TYPE_I:
- case TYPE_L:
- while ((cnt = secure_read(fileno(instr), buf, sizeof buf)) > 0) {
- if (write(fileno(outstr), buf, cnt) != cnt)
- goto file_err;
- byte_count += cnt;
- }
- transflag = 0;
- ret = cnt;
- if (cnt < 0)
- goto data_err;
- return (0);
-
- case TYPE_E:
- reply(553, "TYPE E not implemented.");
- transflag = 0;
- return (-1);
-
- case TYPE_A:
- while ((c = secure_getc(instr)) >= 0) {
- byte_count++;
- if (c == '\n')
- bare_lfs++;
- while (c == '\r') {
- if (ferror(outstr))
- goto data_err;
- if ((c = secure_getc(instr)) != '\n') {
- (void) putc ('\r', outstr);
- if (c == '\0')
- goto contin2;
- }
- }
- if (c < 0) break;
- (void) putc(c, outstr);
- contin2: ;
- }
- fflush(outstr);
- ret = c;
- if (c == -2 || ferror(instr))
- goto data_err;
- if (ferror(outstr))
- goto file_err;
- transflag = 0;
- if (bare_lfs) {
- lreply(226, "WARNING! %d bare linefeeds received in ASCII mode", bare_lfs);
- reply(0, " File may not have transferred correctly.");
- }
- return (0);
- default:
- reply(550, "Unimplemented TYPE %d in receive_data", type);
- transflag = 0;
- return (-1);
- }
-
-data_err:
- transflag = 0;
- if (ret != -2) perror_reply(426, "Data Connection");
- return (-1);
-
-file_err:
- transflag = 0;
- perror_reply(452, "Error writing file");
- return (-1);
-}
-
-void
-statfilecmd(filename)
- char *filename;
-{
- char line[FTP_BUFSIZ];
- FILE *fin;
- int c, n;
- char str[FTP_BUFSIZ], *p;
-
- if (strlen(filename) + sizeof("/bin/ls -lgA ")
- >= sizeof(line)) {
- reply(501, "filename too long");
- return;
- }
- (void) snprintf(line, sizeof(line), "/bin/ls -lgA %s", filename);
- fin = ftpd_popen(line, "r");
- lreply(211, "status of %s:", filename);
- p = str;
- n = 0;
- while ((c = getc(fin)) != EOF) {
- if (c == '\n') {
- if (ferror(stdout)){
- perror_reply(421, "control connection");
- (void) ftpd_pclose(fin);
- dologout(1);
- /* NOTREACHED */
- }
- if (ferror(fin)) {
- perror_reply(551, filename);
- (void) ftpd_pclose(fin);
- return;
- }
- *p = '\0';
- reply(0, "%s", str);
- p = str;
- n = 0;
- } else {
- *p++ = c;
- n++;
- if (n >= sizeof(str)) {
- reply(551, "output line too long");
- (void) ftpd_pclose(fin);
- return;
- }
- }
- }
- if (p != str) {
- *p = '\0';
- reply(0, "%s", str);
- }
- (void) ftpd_pclose(fin);
- reply(211, "End of Status");
-}
-
-void
-statcmd()
-{
- struct sockaddr_in *sin4;
- u_char *a, *p;
- char str[FTP_BUFSIZ];
-
- lreply(211, "%s FTP server status:", hostname);
- reply(0, " %s", version);
- snprintf(str, sizeof(str), " Connected to %s (%s)",
- remotehost[0] ? remotehost : "", rhost_addra);
- reply(0, "%s", str);
- if (auth_type) reply(0, " Authentication type: %s", auth_type);
- if (logged_in) {
- if (guest)
- reply(0, " Logged in anonymously");
- else
- reply(0, " Logged in as %s", pw->pw_name);
- } else if (askpasswd)
- reply(0, " Waiting for password");
- else if (temp_auth_type)
- reply(0, " Waiting for authentication data");
- else
- reply(0, " Waiting for user name");
- reply(0, " Protection level: %s", levelnames[dlevel]);
- snprintf(str, sizeof(str), " TYPE: %s", typenames[type]);
- if (type == TYPE_A || type == TYPE_E) {
- snprintf(&str[strlen(str)], sizeof(str) - strlen(str),
- ", FORM: %s", formnames[form]);
- }
- if (type == TYPE_L)
- strncat(str, " 8", sizeof (str) - strlen(str) - 1);
- snprintf(&str[strlen(str)], sizeof(str) - strlen(str),
- "; STRUcture: %s; transfer MODE: %s",
- strunames[stru], modenames[mode]);
- reply(0, "%s", str);
- if (data != -1)
- strlcpy(str, " Data connection open", sizeof(str));
- else if (pdata != -1) {
- strlcpy(str, " in Passive mode", sizeof(str));
- sin4 = &pasv_addr;
- goto printaddr;
- } else if (usedefault == 0) {
- sin4 = &data_dest;
-printaddr:
- a = (u_char *) &sin4->sin_addr;
- p = (u_char *) &sin4->sin_port;
-#define UC(b) (((int) b) & 0xff)
- snprintf(str, sizeof(str), " PORT (%d,%d,%d,%d,%d,%d)",
- UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]),
- UC(p[1]));
-#undef UC
- } else
- strlcpy(str, " No data connection", sizeof(str));
- reply(0, "%s", str);
- reply(211, "End of status");
-}
-
-void
-fatal(s)
- char *s;
-{
- reply(451, "Error in server: %s", s);
- reply(221, "Closing connection due to server error.");
- dologout(0);
- /* NOTREACHED */
-}
-
-char cont_char = ' ';
-
-/*
- * XXX callers need to limit total length of output string to
- * FTP_BUFSIZ bytes for now.
- */
-#ifdef STDARG
-void
-reply(int n, char *fmt, ...)
-#else
-/* VARARGS2 */
-void
-reply(n, fmt, p0, p1, p2, p3, p4, p5)
- int n;
- char *fmt;
-#endif
-{
- char buf[FTP_BUFSIZ];
-#ifdef STDARG
- va_list ap;
-
- va_start(ap, fmt);
- vsnprintf(buf, sizeof(buf), fmt, ap);
- va_end(ap);
-#else
- snprintf(buf, sizeof(buf), fmt, p0, p1, p2, p3, p4, p5);
-#endif
-
- if (auth_type) {
- /*
- * Deal with expansion in mk_{safe,priv},
- * radix_encode, gss_seal, plus slop.
- */
- char in[FTP_BUFSIZ*3/2], out[FTP_BUFSIZ*3/2];
- int length = 0, kerror;
- if (n) snprintf(in, sizeof(in), "%d%c", n, cont_char);
- else in[0] = '\0';
- strncat(in, buf, sizeof (in) - strlen(in) - 1);
-#ifdef GSSAPI
- /* reply (based on level) */
- if (strcmp(auth_type, "GSSAPI") == 0) {
- gss_buffer_desc in_buf, out_buf;
- OM_uint32 maj_stat, min_stat;
- int conf_state;
-
- in_buf.value = in;
- in_buf.length = strlen(in);
- maj_stat = gss_seal(&min_stat, gcontext,
- clevel == PROT_P, /* private */
- GSS_C_QOP_DEFAULT,
- &in_buf, &conf_state,
- &out_buf);
- if (maj_stat != GSS_S_COMPLETE) {
-#if 0
-/* Don't setup an infinite loop */
- /* generally need to deal */
- secure_gss_error(maj_stat, min_stat,
- (clevel==PROT_P)?
- "gss_seal ENC didn't complete":
- "gss_seal MIC didn't complete");
-#endif /* 0 */
- } else if ((clevel == PROT_P) && !conf_state) {
-#if 0
-/* Don't setup an infinite loop */
- secure_error("GSSAPI didn't encrypt message");
-#endif /* 0 */
- } else {
- memcpy(out, out_buf.value,
- length=out_buf.length);
- gss_release_buffer(&min_stat, &out_buf);
- }
- }
-#endif /* GSSAPI */
- /* Other auth types go here ... */
- if (length >= sizeof(in) / 4 * 3) {
- syslog(LOG_ERR, "input to radix_encode too long");
- fputs(in, stdout);
- } else if ((kerror = radix_encode(out, in, &length, 0))) {
- syslog(LOG_ERR, "Couldn't encode reply (%s)",
- radix_error(kerror));
- fputs(in,stdout);
- } else
- printf("%s%c%s", clevel == PROT_P ? "632" : "631",
- n ? cont_char : '-', in);
- } else {
- if (n) printf("%d%c", n, cont_char);
- fputs(buf, stdout);
- }
- printf("\r\n");
- (void)fflush(stdout);
- if (debug) {
- if (n) syslog(LOG_DEBUG, "<--- %d%c", n, cont_char);
- syslog(LOG_DEBUG, "%s", buf);
- }
-}
-
-/*
- * XXX callers need to limit total length of output string to
- * FTP_BUFSIZ
- */
-#ifdef STDARG
-void
-lreply(int n, char *fmt, ...)
-#else
-/* VARARGS2 */
-void
-lreply(n, fmt, p0, p1, p2, p3, p4, p5)
- int n;
- char *fmt;
-#endif
-{
- char buf[FTP_BUFSIZ];
-#ifdef STDARG
- va_list ap;
-
- va_start(ap, fmt);
- vsnprintf(buf, sizeof(buf), fmt, ap);
- va_end(ap);
-#else
- snprintf(buf, sizeof(buf), fmt, p0, p1, p2, p3, p4, p5);
-#endif
- cont_char = '-';
- reply(n, "%s", buf);
- cont_char = ' ';
-}
-
-void
-ack(s)
- char *s;
-{
- reply(250, "%s command successful.", s);
-}
-
-void
-nack(s)
- char *s;
-{
- reply(502, "%s command not implemented.", s);
-}
-
-/* ARGSUSED */
-void
-yyerror(s)
- char *s;
-{
- char *cp;
-
- cp = strchr(cbuf,'\n');
- if (cp)
- *cp = '\0';
- reply(500, "'%.*s': command not understood.",
- (int) (FTP_BUFSIZ - sizeof("'': command not understood.")),
- cbuf);
-}
-
-void
-delete_file(name)
- char *name;
-{
- struct stat st;
-
- if (logging > 1) syslog(LOG_NOTICE, "del %s", path_expand(name));
-
- if (stat(name, &st) < 0) {
- perror_reply(550, name);
- return;
- }
- if ((st.st_mode&S_IFMT) == S_IFDIR) {
- if (rmdir(name) < 0) {
- perror_reply(550, name);
- return;
- }
- goto done;
- }
- if (unlink(name) < 0) {
- perror_reply(550, name);
- return;
- }
-done:
- ack("DELE");
-}
-
-void
-cwd(path)
- char *path;
-{
- if (chdir(path) < 0)
- perror_reply(550, path);
- else
- ack("CWD");
-}
-
-void
-makedir(name)
- char *name;
-{
- if (logging > 1) syslog(LOG_NOTICE, "mkdir %s", path_expand(name));
-
- if (mkdir(name, 0777) < 0)
- perror_reply(550, name);
- else
- reply(257, "MKD command successful.");
-}
-
-void
-removedir(name)
- char *name;
-{
- if (logging > 1) syslog(LOG_NOTICE, "rmdir %s", path_expand(name));
-
- if (rmdir(name) < 0)
- perror_reply(550, name);
- else
- ack("RMD");
-}
-
-void
-pwd()
-{
- if (getcwd(pathbuf, sizeof pathbuf) == (char *)NULL)
-#ifdef POSIX
- perror_reply(550, pathbuf);
-#else
- reply(550, "%s.", pathbuf);
-#endif
- else
- reply(257, "\"%s\" is current directory.", pathbuf);
-}
-
-char *
-renamefrom(name)
- char *name;
-{
- struct stat st;
-
- if (stat(name, &st) < 0) {
- perror_reply(550, name);
- return ((char *)0);
- }
- reply(350, "File exists, ready for destination name");
- return (name);
-}
-
-void
-renamecmd(from, to)
- char *from, *to;
-{
- if(logging > 1)
- syslog(LOG_NOTICE, "rename %s %s", path_expand(from), to);
-
- if (rename(from, to) < 0)
- perror_reply(550, "rename");
- else
- ack("RNTO");
-}
-
-static void
-dolog(sin4)
- struct sockaddr_in *sin4;
-{
- struct hostent *hp = gethostbyaddr((char *)&sin4->sin_addr,
- sizeof (struct in_addr), AF_INET);
- time_t t, time();
- extern char *ctime();
- krb5_error_code retval;
-
- if (hp != NULL) {
- (void) strncpy(remotehost, hp->h_name, sizeof (remotehost));
- remotehost[sizeof (remotehost) - 1] = '\0';
- } else
- remotehost[0] = '\0';
- strncpy(rhost_addra, inet_ntoa(sin4->sin_addr), sizeof (rhost_addra));
- rhost_addra[sizeof (rhost_addra) - 1] = '\0';
- retval = pty_make_sane_hostname((struct sockaddr *) sin4, maxhostlen,
- stripdomain, always_ip, &rhost_sane);
- if (retval) {
- fprintf(stderr, "make_sane_hostname: %s\n",
- error_message(retval));
- exit(1);
- }
-#ifdef SETPROCTITLE
- snprintf(proctitle, sizeof(proctitle), "%s: connected", rhost_sane);
- setproctitle(proctitle);
-#endif /* SETPROCTITLE */
-
- if (logging) {
- t = time((time_t *) 0);
- syslog(LOG_INFO, "connection from %s (%s) at %s",
- rhost_addra, remotehost, ctime(&t));
- }
-}
-
-/*
- * Record logout in wtmp file
- * and exit with supplied status.
- */
-void
-dologout(status)
- int status;
-{
- if (logged_in) {
- (void) krb5_seteuid((uid_t)0);
- pty_logwtmp(ttyline, "", "");
- }
- if (have_creds) {
-#ifdef GSSAPI
- krb5_cc_destroy(kcontext, ccache);
-#endif
- }
- /* beware of flushing buffers after a SIGPIPE */
- _exit(status);
-}
-
-void
-myoob(sig)
- int sig;
-{
- char *cp, *cs;
-#ifndef strpbrk
- extern char *strpbrk();
-#endif
-
- /* only process if transfer occurring */
- if (!transflag)
- return;
- cp = tmpline;
- if (ftpd_getline(cp, sizeof(tmpline), stdin) == NULL) {
- reply(221, "You could at least say goodbye.");
- dologout(0);
- }
- upper(cp);
- if ((cs = strpbrk(cp, "\r\n")))
- *cs++ = '\0';
- if (strcmp(cp, "ABOR") == 0) {
- tmpline[0] = '\0';
- reply(426, "Transfer aborted. Data connection closed.");
- reply(226, "Abort successful");
- siglongjmp(urgcatch, 1);
- }
- if (strcmp(cp, "STAT") == 0) {
- if (file_size != (off_t) -1)
- reply(213, "Status: %lu of %lu bytes transferred",
- (unsigned long) byte_count,
- (unsigned long) file_size);
- else
- reply(213, "Status: %lu bytes transferred",
- (unsigned long) byte_count);
- }
-}
-
-/*
- * Note: a response of 425 is not mentioned as a possible response to
- * the PASV command in RFC959. However, it has been blessed as
- * a legitimate response by Jon Postel in a telephone conversation
- * with Rick Adams on 25 Jan 89.
- */
-void
-passive()
-{
- int len;
- register char *p, *a;
-
- pdata = socket(AF_INET, SOCK_STREAM, 0);
- if (pdata < 0) {
- perror_reply(425, "Can't open passive connection");
- return;
- }
- pasv_addr = ctrl_addr;
- pasv_addr.sin_port = 0;
- (void) krb5_seteuid((uid_t)0);
- if (bind(pdata, (struct sockaddr *)&pasv_addr, sizeof(pasv_addr)) < 0) {
- (void) krb5_seteuid((uid_t)pw->pw_uid);
- goto pasv_error;
- }
- if (krb5_seteuid((uid_t)pw->pw_uid)) {
- fatal("seteuid user");
- }
- len = sizeof(pasv_addr);
- if (getsockname(pdata, (struct sockaddr *) &pasv_addr, &len) < 0)
- goto pasv_error;
- if (listen(pdata, 1) < 0)
- goto pasv_error;
- a = (char *) &pasv_addr.sin_addr;
- p = (char *) &pasv_addr.sin_port;
-
-#define UC(b) (((int) b) & 0xff)
-
- reply(227, "Entering Passive Mode (%d,%d,%d,%d,%d,%d)", UC(a[0]),
- UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1]));
- return;
-
-pasv_error:
- (void) close(pdata);
- pdata = -1;
- perror_reply(425, "Can't open passive connection");
- return;
-}
-
-/*
- * Generate unique name for file with basename "local".
- * The file named "local" is already known to exist.
- * Generates failure reply on error.
- */
-static char *
-gunique(local)
- char *local;
-{
- static char new[MAXPATHLEN];
- struct stat st;
- char *cp = strrchr(local, '/');
- int count = 0;
-
- if (cp)
- *cp = '\0';
- if (stat(cp ? local : ".", &st) < 0) {
- perror_reply(553, cp ? local : ".");
- return((char *) 0);
- }
- if (cp)
- *cp = '/';
- (void) strncpy(new, local, sizeof(new) - 1);
- new[sizeof(new) - 1] = '\0';
- cp = new + strlen(new);
- *cp++ = '.';
- for (count = 1; count < 100; count++) {
- (void) snprintf(cp, sizeof(new) - (cp - new), "%d", count);
- if (stat(new, &st) < 0)
- return(new);
- }
- reply(452, "Unique file name cannot be created.");
- return((char *) 0);
-}
-
-/*
- * Format and send reply containing system error number.
- */
-void
-perror_reply(code, string)
- int code;
- char *string;
-{
- char *err_string;
- size_t extra_len;
-
- err_string = strerror(errno);
- if (err_string == NULL)
- err_string = "(unknown error)";
- extra_len = strlen(err_string) + sizeof("(truncated): .");
-
- /*
- * XXX knows about FTP_BUFSIZ in reply()
- */
- if (strlen(string) + extra_len > FTP_BUFSIZ) {
- reply(code, "(truncated)%.*s: %s.",
- (int) (FTP_BUFSIZ - extra_len), string, err_string);
- } else {
- reply(code, "%s: %s.", string, err_string);
- }
-}
-
-void
-auth(atype)
-char *atype;
-{
- if (auth_type)
- reply(534, "Authentication type already set to %s", auth_type);
- else
-#ifdef GSSAPI
- if (strcmp(atype, "GSSAPI") == 0)
- reply(334, "Using authentication type %s; ADAT must follow",
- temp_auth_type = atype);
- else
-#endif /* GSSAPI */
- /* Other auth types go here ... */
- reply(504, "Unknown authentication type: %s", atype);
-}
-
-int
-auth_data(adata)
-char *adata;
-{
- int kerror, length;
-
- if (auth_type) {
- reply(503, "Authentication already established");
- return(0);
- }
- if (!temp_auth_type) {
- reply(503, "Must identify AUTH type before ADAT");
- return(0);
- }
-#ifdef GSSAPI
- if (strcmp(temp_auth_type, "GSSAPI") == 0) {
- int replied = 0;
- int found = 0;
- gss_cred_id_t server_creds, deleg_creds;
- gss_name_t client;
- OM_uint32 ret_flags;
- int rad_len;
- gss_buffer_desc name_buf;
- gss_name_t server_name;
- OM_uint32 acquire_maj, acquire_min, accept_maj, accept_min,
- stat_maj, stat_min;
- gss_OID mechid;
- gss_buffer_desc tok, out_tok;
- char gbuf[FTP_BUFSIZ];
- u_char gout_buf[FTP_BUFSIZ];
- char localname[MAXHOSTNAMELEN];
- char service_name[MAXHOSTNAMELEN+10];
- char **gservice;
- struct hostent *hp;
- stat_maj = 0;
- accept_maj = 0;
- acquire_maj = 0;
-
- kerror = radix_encode(adata, gout_buf, &length, 1);
- if (kerror) {
- reply(501, "Couldn't decode ADAT (%s)",
- radix_error(kerror));
- syslog(LOG_ERR, "Couldn't decode ADAT (%s)",
- radix_error(kerror));
- return(0);
- }
- tok.value = gout_buf;
- tok.length = length;
-
- if (gethostname(localname, MAXHOSTNAMELEN)) {
- reply(501, "couldn't get local hostname (%d)\n", errno);
- syslog(LOG_ERR, "Couldn't get local hostname (%d)", errno);
- return 0;
- }
- if (!(hp = gethostbyname(localname))) {
- reply(501, "couldn't canonicalize local hostname\n");
- syslog(LOG_ERR, "Couldn't canonicalize local hostname");
- return 0;
- }
- strncpy(localname, hp->h_name, sizeof(localname) - 1);
- localname[sizeof(localname) - 1] = '\0';
-
- for (gservice = gss_services; *gservice; gservice++) {
- snprintf(service_name, sizeof(service_name),
- "%s@%s", *gservice, localname);
- name_buf.value = service_name;
- name_buf.length = strlen(name_buf.value) + 1;
- if (debug)
- syslog(LOG_INFO, "importing <%s>", service_name);
- stat_maj = gss_import_name(&stat_min, &name_buf,
- gss_nt_service_name,
- &server_name);
- if (stat_maj != GSS_S_COMPLETE) {
- reply_gss_error(501, stat_maj, stat_min,
- "importing name");
- syslog(LOG_ERR, "gssapi error importing name");
- return 0;
- }
-
- acquire_maj = gss_acquire_cred(&acquire_min, server_name, 0,
- GSS_C_NULL_OID_SET, GSS_C_ACCEPT,
- &server_creds, NULL, NULL);
- (void) gss_release_name(&stat_min, &server_name);
-
- if (acquire_maj != GSS_S_COMPLETE)
- continue;
-
- found++;
-
- gcontext = GSS_C_NO_CONTEXT;
-
- accept_maj = gss_accept_sec_context(&accept_min,
- &gcontext, /* context_handle */
- server_creds, /* verifier_cred_handle */
- &tok, /* input_token */
- GSS_C_NO_CHANNEL_BINDINGS, /* channel bindings */
- &client, /* src_name */
- &mechid, /* mech_type */
- &out_tok, /* output_token */
- &ret_flags,
- NULL, /* ignore time_rec */
- &deleg_creds /* forwarded credentials */
- );
- if (accept_maj==GSS_S_COMPLETE||accept_maj==GSS_S_CONTINUE_NEEDED)
- break;
- }
-
- if (found) {
- if (accept_maj!=GSS_S_COMPLETE && accept_maj!=GSS_S_CONTINUE_NEEDED) {
- reply_gss_error(535, accept_maj, accept_min,
- "accepting context");
- syslog(LOG_ERR, "failed accepting context");
- (void) gss_release_cred(&stat_min, &server_creds);
- if (ret_flags & GSS_C_DELEG_FLAG)
- (void) gss_release_cred(&stat_min,
- &deleg_creds);
- return 0;
- }
- } else {
- /* Kludge to make sure the right error gets reported, so we don't *
- * get those nasty "error: no error" messages. */
- if(stat_maj != GSS_S_COMPLETE)
- reply_gss_error(501, stat_maj, stat_min,
- "acquiring credentials");
- else
- reply_gss_error(501, acquire_maj, acquire_min,
- "acquiring credentials");
- syslog(LOG_ERR, "gssapi error acquiring credentials");
- return 0;
- }
-
- if (out_tok.length) {
- if (out_tok.length >= ((FTP_BUFSIZ - sizeof("ADAT="))
- / 4 * 3)) {
- secure_error("ADAT: reply too long");
- syslog(LOG_ERR, "ADAT: reply too long");
- (void) gss_release_cred(&stat_min, &server_creds);
- if (ret_flags & GSS_C_DELEG_FLAG)
- (void) gss_release_cred(&stat_min,
- &deleg_creds);
- return(0);
- }
-
- rad_len = out_tok.length;
- kerror = radix_encode(out_tok.value, gbuf,
- &rad_len, 0);
- out_tok.length = rad_len;
- if (kerror) {
- secure_error("Couldn't encode ADAT reply (%s)",
- radix_error(kerror));
- syslog(LOG_ERR, "couldn't encode ADAT reply");
- (void) gss_release_cred(&stat_min, &server_creds);
- if (ret_flags & GSS_C_DELEG_FLAG)
- (void) gss_release_cred(&stat_min,
- &deleg_creds);
- return(0);
- }
- if (accept_maj == GSS_S_COMPLETE) {
- reply(235, "ADAT=%s", gbuf);
- } else {
- /* If the server accepts the security data, and
- requires additional data, it should respond
- with reply code 335. */
- reply(335, "ADAT=%s", gbuf);
- }
- replied = 1;
- (void) gss_release_buffer(&stat_min, &out_tok);
- }
- if (accept_maj == GSS_S_COMPLETE) {
- /* GSSAPI authentication succeeded */
- stat_maj = gss_display_name(&stat_min, client,
- &client_name, &mechid);
- if (stat_maj != GSS_S_COMPLETE) {
- /* "If the server rejects the security data (if
- a checksum fails, for instance), it should
- respond with reply code 535." */
- reply_gss_error(535, stat_maj, stat_min,
- "extracting GSSAPI identity name");
- log_gss_error(LOG_ERR, stat_maj, stat_min,
- "gssapi error extracting identity");
- (void) gss_release_cred(&stat_min, &server_creds);
- if (ret_flags & GSS_C_DELEG_FLAG)
- (void) gss_release_cred(&stat_min,
- &deleg_creds);
- return 0;
- }
- auth_type = temp_auth_type;
- temp_auth_type = NULL;
-
- (void) gss_release_cred(&stat_min, &server_creds);
- if (ret_flags & GSS_C_DELEG_FLAG) {
- if (want_creds)
- ftpd_gss_convert_creds(client_name.value,
- deleg_creds);
- (void) gss_release_cred(&stat_min, &deleg_creds);
- }
-
- /* If the server accepts the security data, but does
- not require any additional data (i.e., the security
- data exchange has completed successfully), it must
- respond with reply code 235. */
- if (!replied)
- {
- if (ret_flags & GSS_C_DELEG_FLAG && !have_creds)
- reply(235, "GSSAPI Authentication succeeded, but could not accept forwarded credentials");
- else
- reply(235, "GSSAPI Authentication succeeded");
- }
-
- return(1);
- } else if (accept_maj == GSS_S_CONTINUE_NEEDED) {
- /* If the server accepts the security data, and
- requires additional data, it should respond with
- reply code 335. */
- if (!replied)
- reply(335, "more data needed");
- (void) gss_release_cred(&stat_min, &server_creds);
- if (ret_flags & GSS_C_DELEG_FLAG)
- (void) gss_release_cred(&stat_min, &deleg_creds);
- return(0);
- } else {
- /* "If the server rejects the security data (if
- a checksum fails, for instance), it should
- respond with reply code 535." */
- reply_gss_error(535, stat_maj, stat_min,
- "GSSAPI failed processing ADAT");
- syslog(LOG_ERR, "GSSAPI failed processing ADAT");
- (void) gss_release_cred(&stat_min, &server_creds);
- if (ret_flags & GSS_C_DELEG_FLAG)
- (void) gss_release_cred(&stat_min, &deleg_creds);
- return(0);
- }
- }
-#endif /* GSSAPI */
- /* Other auth types go here ... */
- /* Also need to check authorization, but that is done in user() */
- return(0);
-}
-
-static char *onefile[] = {
- "",
- 0
-};
-
-/* returns:
- * n>=0 on success
- * -1 on error
- * -2 on security error
- *
- * XXX callers need to limit total length of output string to
- * FTP_BUFSIZ
- */
-static int
-secure_fprintf(FILE *stream, char *fmt, ...)
-#if !defined(__cplusplus) && (__GNUC__ > 2)
- __attribute__((__format__(__printf__, 2, 3)))
-#endif
- ;
-
-static int
-secure_fprintf(FILE *stream, char *fmt, ...)
-{
- char s[FTP_BUFSIZ];
- int rval;
- va_list ap;
-
- va_start(ap, fmt);
- if (dlevel == PROT_C) rval = vfprintf(stream, fmt, ap);
- else {
- vsnprintf(s, sizeof(s), fmt, ap);
- rval = secure_write(fileno(stream), s, strlen(s));
- }
- va_end(ap);
-
- return(rval);
-}
-
-void
-send_file_list(whichfiles)
- char *whichfiles;
-{
- struct stat st;
- DIR *dirp = NULL;
- struct dirent *dir;
- FILE *volatile dout = NULL;
- register char **volatile dirlist, *dirname;
- volatile int simple = 0;
-#ifndef strpbrk
- char *strpbrk();
-#endif
- volatile int ret = 0;
-
- if (strpbrk(whichfiles, "~{[*?") != NULL) {
- extern char **ftpglob(), *globerr;
-
- globerr = NULL;
- dirlist = ftpglob(whichfiles);
- if (globerr != NULL) {
- reply(550, globerr);
- return;
- } else if (dirlist == NULL) {
- errno = ENOENT;
- perror_reply(550, whichfiles);
- return;
- }
- } else {
- onefile[0] = whichfiles;
- dirlist = onefile;
- simple = 1;
- }
-
- if (sigsetjmp(urgcatch, 1)) {
- transflag = 0;
- (void)secure_flush(fileno(dout));
- return;
- }
- while ((dirname = *dirlist++)) {
- if (stat(dirname, &st) < 0) {
- /*
- * If user typed "ls -l", etc, and the client
- * used NLST, do what the user meant.
- */
- if (dirname[0] == '-' && *dirlist == NULL &&
- transflag == 0) {
- retrieve("/bin/ls %s", dirname);
- return;
- }
- perror_reply(550, whichfiles);
- if (dout != NULL) {
- (void) fclose(dout);
- transflag = 0;
- data = -1;
- pdata = -1;
- }
- return;
- }
-
- if ((st.st_mode&S_IFMT) == S_IFREG) {
- if (dout == NULL) {
- dout = dataconn("file list", (off_t)-1, "w");
- if (dout == NULL)
- return;
- transflag++;
- }
- if ((ret = secure_fprintf(dout, "%s%s\n", dirname,
- type == TYPE_A ? "\r" : "")) < 0)
- goto data_err;
- byte_count += strlen(dirname) + 1;
- continue;
- } else if ((st.st_mode&S_IFMT) != S_IFDIR)
- continue;
-
- if ((dirp = opendir(dirname)) == NULL)
- continue;
-
- while ((dir = readdir(dirp)) != NULL) {
- char nbuf[MAXPATHLEN];
-
- if (dir->d_name[0] == '.' && dir->d_name[1] == '\0')
- continue;
- if (dir->d_name[0] == '.' && dir->d_name[1] == '.' &&
- dir->d_name[2] == '\0')
- continue;
-
- if (strlen(dirname) + strlen(dir->d_name)
- + 1 /* slash */
- + 2 /* CRLF */
- + 1 > sizeof(nbuf)) {
- syslog(LOG_ERR,
- "send_file_list: pathname too long");
- ret = -2; /* XXX */
- goto data_err;
- }
- snprintf(nbuf, sizeof(nbuf), "%s/%s",
- dirname, dir->d_name);
-
- /*
- * We have to do a stat to insure it's
- * not a directory or special file.
- */
- if (simple || (stat(nbuf, &st) == 0 &&
- (st.st_mode&S_IFMT) == S_IFREG)) {
- if (dout == NULL) {
- dout = dataconn("file list", (off_t)-1,
- "w");
- if (dout == NULL)
- return;
- transflag++;
- }
- if (nbuf[0] == '.' && nbuf[1] == '/')
- {
- if ((ret = secure_fprintf(dout, "%s%s\n", &nbuf[2],
- type == TYPE_A ? "\r" : "")) < 0)
- goto data_err;
- }
- else
- if ((ret = secure_fprintf(dout, "%s%s\n", nbuf,
- type == TYPE_A ? "\r" : "")) < 0)
- goto data_err;
- byte_count += strlen(nbuf) + 1;
- }
- }
- (void) closedir(dirp);
- }
- if (dout != NULL ) {
- ret = secure_write(fileno(dout), "", 0);
- if (ret >= 0)
- ret = secure_flush(fileno(dout));
- }
-data_err:
- if (dout == NULL)
- reply(550, "No files found.");
- else if (ferror(dout) != 0 || ret == EOF)
- perror_reply(550, "Data connection");
- else if (ret != -2)
- reply(226, "Transfer complete.");
-
- transflag = 0;
- if (dout != NULL)
- (void) fclose(dout);
- data = -1;
- pdata = -1;
-}
-
-#ifdef SETPROCTITLE
-/*
- * clobber argv so ps will show what we're doing.
- * (stolen from sendmail)
- * warning, since this is usually started from inetd.conf, it
- * often doesn't have much of an environment or arglist to overwrite.
- */
-
-setproctitle(buf)
-char *buf;
-{
- register char *p, *bp, ch;
- register int i;
-
- /* make ps print our process name */
- p = Argv[0];
- *p++ = '-';
-
- i = strlen(buf);
- if (i > LastArgv - p - 2) {
- i = LastArgv - p - 2;
- buf[i] = '\0';
- }
- bp = buf;
- while (ch = *bp++)
- if (ch != '\n' && ch != '\r')
- *p++ = ch;
- while (p < LastArgv)
- *p++ = ' ';
-}
-#endif /* SETPROCTITLE */
-
-#ifdef GSSAPI
-/* A more general callback would probably use a void*, but currently I
- only need an int in both cases. */
-static void with_gss_error_text(void (*cb)(const char *, int, int),
- OM_uint32 maj_stat, OM_uint32 min_stat,
- int misc);
-
-static void
-log_gss_error_1(const char *msg, int severity, int is_major)
-{
- syslog(severity, "... GSSAPI error %s: %s",
- is_major ? "major" : "minor", msg);
-}
-
-static void
-log_gss_error(int severity, OM_uint32 maj_stat, OM_uint32 min_stat,
- const char *s)
-{
- syslog(severity, s);
- with_gss_error_text(log_gss_error_1, maj_stat, min_stat, severity);
-}
-
-static void
-reply_gss_error_1(const char *msg, int code, int is_major)
-{
- lreply(code, "GSSAPI error %s: %s",
- is_major ? "major" : "minor", msg);
-}
-
-void
-reply_gss_error(int code, OM_uint32 maj_stat, OM_uint32 min_stat, char *s)
-{
- with_gss_error_text(reply_gss_error_1, maj_stat, min_stat, code);
- reply(code, "GSSAPI error: %s", s);
-}
-
-static void with_gss_error_text(void (*cb)(const char *, int, int),
- OM_uint32 maj_stat, OM_uint32 min_stat,
- int misc)
-{
- /* a lot of work just to report the error */
- OM_uint32 gmaj_stat, gmin_stat;
- gss_buffer_desc msg;
- OM_uint32 msg_ctx;
- msg_ctx = 0;
- while (!msg_ctx) {
- gmaj_stat = gss_display_status(&gmin_stat, maj_stat,
- GSS_C_GSS_CODE,
- GSS_C_NULL_OID,
- &msg_ctx, &msg);
- if ((gmaj_stat == GSS_S_COMPLETE)||
- (gmaj_stat == GSS_S_CONTINUE_NEEDED)) {
- (*cb)((char*)msg.value, misc, 1);
- (void) gss_release_buffer(&gmin_stat, &msg);
- }
- if (gmaj_stat != GSS_S_CONTINUE_NEEDED)
- break;
- }
- msg_ctx = 0;
- while (!msg_ctx) {
- gmaj_stat = gss_display_status(&gmin_stat, min_stat,
- GSS_C_MECH_CODE,
- GSS_C_NULL_OID,
- &msg_ctx, &msg);
- if ((gmaj_stat == GSS_S_COMPLETE)||
- (gmaj_stat == GSS_S_CONTINUE_NEEDED)) {
- (*cb)((char*)msg.value, misc, 0);
- (void) gss_release_buffer(&gmin_stat, &msg);
- }
- if (gmaj_stat != GSS_S_CONTINUE_NEEDED)
- break;
- }
-}
-
-void
-secure_gss_error(maj_stat, min_stat, s)
-OM_uint32 maj_stat, min_stat;
-char *s;
-{
- reply_gss_error(535, maj_stat, min_stat, s);
- return;
-}
-
-
-/* ftpd_gss_userok -- hide details of getting the name and verifying it */
-/* returns 0 for OK */
-static int
-ftpd_gss_userok(gclient_name, name)
- gss_buffer_t gclient_name;
- char *name;
-{
- int retval = -1;
- krb5_principal p;
-
- if (krb5_parse_name(kcontext, gclient_name->value, &p) != 0)
- return -1;
- if (krb5_kuserok(kcontext, p, name))
- retval = 0;
- else
- retval = 1;
- krb5_free_principal(kcontext, p);
- return retval;
-}
-
-/* ftpd_gss_convert_creds -- write out forwarded creds */
-/* (code lifted from login.krb5) */
-static void
-ftpd_gss_convert_creds(name, creds)
- char *name;
- gss_cred_id_t creds;
-{
- OM_uint32 major_status, minor_status;
- krb5_principal me;
- char ccname[MAXPATHLEN];
-
- /* Set up ccache */
- if (krb5_parse_name(kcontext, name, &me))
- return;
-
- snprintf(ccname, sizeof(ccname), "FILE:/tmp/krb5cc_ftpd%ld",
- (long) getpid());
- if (krb5_cc_resolve(kcontext, ccname, &ccache))
- return;
- if (krb5_cc_initialize(kcontext, ccache, me))
- return;
-
- /* Copy GSS creds into ccache */
- major_status = gss_krb5_copy_ccache(&minor_status, creds, ccache);
- if (major_status != GSS_S_COMPLETE)
- goto cleanup;
-
- have_creds = 1;
- return;
-
-cleanup:
- krb5_cc_destroy(kcontext, ccache);
-}
-
-
-#endif /* GSSAPI */
+++ /dev/null
-/*
- * appl/gssftp/ftpd/ftp_var.h
- *
- * Copyright 2001 by the Massachusetts Institute of Technology.
- * All Rights Reserved.
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- *
- *
- * Prototypes for various functions in the ftpd sources.
- */
-
-#ifndef FTPD_VAR_H__
-#define FTPD_VAR_H__
-
-/* Prototypes */
-
-#ifdef GSSAPI
-#include <gssapi/gssapi.h>
-#include <gssapi/gssapi_generic.h>
-#endif
-
-/* radix.c */
-char *radix_error (int);
-int radix_encode (unsigned char *, unsigned char *, int *, int);
-
-/* ftpd.c */
-void ack(char *);
-int auth_data(char *);
-void auth(char *);
-void cwd(char *);
-void delete_file(char *);
-void dologout(int);
-void fatal(char *);
-void makedir(char *);
-void nack(char *);
-void pass(char *);
-void passive(void);
-void perror_reply(int, char *);
-void pwd(void);
-void removedir(char *);
-void renamecmd(char *, char *);
-char *renamefrom(char *);
-void retrieve(char *, char *);
-void send_file_list(char *);
-void setdlevel(int);
-void statcmd(void);
-void statfilecmd(char *);
-void store_file(char *, char *, int);
-void user(char *);
-void yyerror(char *);
-
-#ifdef GSSAPI
-void
-reply_gss_error(int, OM_uint32, OM_uint32, char *);
-#endif
-
-
-#if defined(STDARG) || (defined(__STDC__) && ! defined(VARARGS)) || defined(HAVE_STDARG_H)
-extern void reply(int, char *, ...)
-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
- __attribute__ ((__format__ (__printf__, 2, 3)))
-#endif
- ;
-extern void lreply(int, char *, ...)
-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
- __attribute__ ((__format__ (__printf__, 2, 3)))
-#endif
- ;
-#endif
-
-
-/* ftpcmd.y */
-void upper(char *);
-char *ftpd_getline(char *, int, FILE *);
-#endif /* FTPD_VAR_H__ */
-
-/* popen.c */
-FILE * ftpd_popen(char *, char *);
-int ftpd_pclose(FILE *);
+++ /dev/null
-/*
- * 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.
- *
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)logwtmp.c 5.7 (Berkeley) 2/25/91";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <utmp.h>
-#include <unistd.h>
-#include <string.h>
-
-#ifdef HAVE_PATHS_H
-#include <paths.h>
-#endif
-
-#ifdef WTMP_FILE
-#define WTMPFILE WTMP_FILE
-#else
-#ifdef _PATH_WTMP
-#define WTMPFILE _PATH_WTMP
-#endif /* _PATH_WTMP */
-#endif /* WTMP_FILE */
-
-#ifndef WTMPFILE
-#define WTMPFILE "/usr/adm/wtmp"
-#endif
-
-static int fd = -1;
-
-/*
- * Modified version of logwtmp that holds wtmp file open
- * after first call, for use with ftp (which may chroot
- * after login, but before logout).
- */
-void ftp_logwtmp(line, name, host)
- char *line, *name, *host;
-{
- struct utmp ut;
- struct stat buf;
- time_t time();
-
- if (fd < 0 && (fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0)
- return;
- if (fstat(fd, &buf) == 0) {
- (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
- (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
-#ifndef NO_UT_HOST
- (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
-#endif
- (void)time(&ut.ut_time);
- if (write(fd, (char *)&ut, sizeof(struct utmp)) !=
- sizeof(struct utmp))
- (void)ftruncate(fd, buf.st_size);
- }
-}
+++ /dev/null
-/*
- * 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.
- *
- * @(#)pathnames.h 5.2 (Berkeley) 6/1/90
- */
-
-#define _PATH_FTPUSERS_DEFAULT "/etc/ftpusers"
+++ /dev/null
-/*
- * Copyright (c) 1988 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software written by Ken Arnold and
- * published in UNIX Review, Vol. 6, No. 8.
- *
- * 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 lint
-static char sccsid[] = "@(#)popen.c 5.9 (Berkeley) 2/25/91";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <signal.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "ftpd_var.h"
-
-/*
- * Special version of popen which avoids call to shell. This insures noone
- * may create a pipe to a hidden program as a side effect of a list or dir
- * command.
- */
-static int *pids;
-static int fds;
-
-#define MAX_ARGV 100
-#define MAX_GARGV 1000
-
-FILE *
-ftpd_popen(program, type)
- char *program, *type;
-{
- register char *cp;
- FILE *volatile iop;
- int argc, gargc, pdes[2], pid;
- char **pop, *argv[MAX_ARGV], *gargv[MAX_GARGV], *vv[2];
- extern char **ftpglob(), **copyblk();
- extern void blkfree(char **);
-
- if ((*type != 'r' && *type != 'w') || type[1])
- return(NULL);
-
- if (!pids) {
- if ((fds = getdtablesize()) <= 0)
- return(NULL);
- if ((pids = (int *)malloc((u_int)(fds * sizeof(int)))) == NULL)
- return(NULL);
- memset(pids, 0, fds * sizeof(int));
- }
- if (pipe(pdes) < 0)
- return(NULL);
-
- /* break up string into pieces */
- for (argc = 0, cp = program; argc < MAX_ARGV - 1; cp = NULL)
- if (!(argv[argc++] = strtok(cp, " \t\n")))
- break;
- argv[MAX_ARGV-1] = NULL;
- for (argc = 0; argv[argc]; argc++)
- argv[argc] = strdup(argv[argc]);
-
- /* glob each piece */
- gargv[0] = argv[0];
- for (gargc = argc = 1; argv[argc]; argc++) {
- if (!(pop = ftpglob(argv[argc]))) { /* globbing failed */
- vv[0] = argv[argc];
- vv[1] = NULL;
- pop = copyblk(vv);
- }
- argv[argc] = (char *)pop; /* save to free later */
- while (*pop && gargc < MAX_GARGV)
- gargv[gargc++] = *pop++;
- }
- gargv[gargc] = NULL;
-
- iop = NULL;
- switch(pid = fork()) {
- case -1: /* error */
- (void)close(pdes[0]);
- (void)close(pdes[1]);
- goto pfree;
- /* NOTREACHED */
- case 0: /* child */
- if (*type == 'r') {
- if (pdes[1] != 1) {
- dup2(pdes[1], 1);
- dup2(pdes[1], 2); /* stderr, too! */
- (void)close(pdes[1]);
- }
- (void)close(pdes[0]);
- } else {
- if (pdes[0] != 0) {
- dup2(pdes[0], 0);
- (void)close(pdes[0]);
- }
- (void)close(pdes[1]);
- }
- execv(gargv[0], gargv);
- _exit(1);
- }
- /* parent; assume fdopen can't fail... */
- if (*type == 'r') {
- iop = fdopen(pdes[0], type);
- (void)close(pdes[1]);
- } else {
- iop = fdopen(pdes[1], type);
- (void)close(pdes[0]);
- }
- pids[fileno(iop)] = pid;
-
-pfree: for (argc = 1; argv[argc] != NULL; argc++) {
- blkfree((char **)argv[argc]);
- free(argv[argc]);
- }
- return(iop);
-}
-
-int
-ftpd_pclose(iop)
- FILE *iop;
-{
- register int fdes;
-#ifdef USE_SIGPROCMASK
- sigset_t old, new;
-#else
- int omask;
-#endif
-#ifdef WAIT_USES_INT
- int stat_loc;
-#else
- union wait stat_loc;
-#endif
- int pid;
-
- /*
- * pclose returns -1 if stream is not associated with a
- * `popened' command, or, if already `pclosed'.
- */
- if (pids == 0 || pids[fdes = fileno(iop)] == 0)
- return(-1);
- (void)fclose(iop);
-#ifdef USE_SIGPROCMASK
- sigemptyset(&old);
- sigemptyset(&new);
- sigaddset(&new,SIGINT);
- sigaddset(&new,SIGQUIT);
- sigaddset(&new,SIGHUP);
- sigprocmask(SIG_BLOCK, &new, &old);
- while ((pid = wait((int *)&stat_loc)) != pids[fdes] && pid != -1);
- sigprocmask(SIG_SETMASK, &old, NULL);
-#else
- omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP));
- while ((pid = wait((int *)&stat_loc)) != pids[fdes] && pid != -1);
- sigsetmask(omask);
-#endif
- pids[fdes] = 0;
-#ifdef WAIT_USES_INT
- return(pid == -1 ? -1 : stat_loc);
-#else
- return(pid == -1 ? -1 : stat_loc.w_status);
-#endif
-}
+++ /dev/null
-#include <stdio.h>
-
-#define CRED_DECL extern AUTH_DAT kdata;
-#define SESSION &kdata.session
-#define myaddr data_source
-#define hisaddr data_dest
-
-int secure_flush (int);
-int secure_putc (int, FILE *);
-int secure_getc (FILE *);
-int secure_write (int, unsigned char *, unsigned int);
-int secure_read (int, char *, unsigned int);
-void secure_gss_error (OM_uint32 maj_stat, OM_uint32 min_stat, char *s);
-
-void secure_error(char *, ...)
-#if !defined(__cplusplus) && (__GNUC__ > 2)
- __attribute__((__format__(__printf__, 1, 2)))
-#endif
- ;
+++ /dev/null
-/*-
- * Copyright (c) 1990 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 lint
-static char sccsid[] = "@(#)vers.c 5.1 (Berkeley) 6/24/90";
-#endif /* not lint */
-
-char version[] = "Version 5.60";
+++ /dev/null
-thisconfigdir=.
-myfulldir=appl/libpty
-mydir=.
-BUILDTOP=$(REL)..$(S)..
-RELDIR=../appl/libpty
-
-SED = sed
-
-KRB5_RUN_ENV= @KRB5_RUN_ENV@
-PROG_LIBPATH=-L$(TOPLIBD)
-PROG_RPATH=$(KRB5_LIBDIR)
-
-LIBBASE=pty
-LIBMAJOR=1
-LIBMINOR=2
-
-STLIBOBJS= cleanup.o getpty.o init_slave.o open_ctty.o open_slave.o \
- update_utmp.o update_wtmp.o vhangup.o void_assoc.o pty_err.o \
- logwtmp.o init.o sane_hostname.o
-
-STOBJLISTS=OBJS.ST
-
-INSTALLFILE = cp
-
-# for pty-int.h
-LOCALINCLUDES=-I. -I$(srcdir)
-
-FILES= Makefile cleanup.c getpty.c init_slave.c open_ctty.c open_slave.c update_utmp.c update_wtmp.c vhangup.c void_assoc.c pty_err.h pty_err.c\
-logwtmp.c init.c
-
-CFILES=$(srcdir)/cleanup.c $(srcdir)/getpty.c $(srcdir)/init_slave.c \
- $(srcdir)/open_ctty.c $(srcdir)/open_slave.c \
- $(srcdir)/update_utmp.c $(srcdir)/update_wtmp.c $(srcdir)/vhangup.c \
- $(srcdir)/void_assoc.c $(srcdir)/logwtmp.c \
- $(srcdir)/init.c $(srcdir)/sane_hostname.c
-
-
-SRCS=pty_err.c $(CFILES)
-SHLIB_EXPDEPS = \
- $(COM_ERR_DEPLIB)
-SHLIB_EXPLIBS= -lcom_err
-SHLIB_DIRS=-L$(TOPLIBD)
-SHLIB_RDIRS=$(KRB5_LIBDIR)
-
-DEPLIBS=
-
-#
-all-unix:: includes pty_err.h
-
-all-unix:: all-liblinks
-
-dump-utmp: dump-utmp.o
- $(CC) $(LDFLAGS) -o dump-utmp dump-utmp.o
-dump-utmp.o: dump-utmp.c
-
-pty_paranoia: pty_paranoia.o $(COM_ERR_DEPLIB) $(PTY_DEPLIB)
- $(CC_LINK) -o pty_paranoia pty_paranoia.o $(PTY_LIB) $(COM_ERR_LIB) $(LIBS)
-
-check-paranoia: pty_paranoia
- $(KRB5_RUN_ENV) $(VALGRIND) ./pty_paranoia
-
-install-unix:: install-libs
-
-clean-unix::
- $(RM) libpty.a $(BUILDTOP)/include/libpty.h pty_err.c pty_err.h
-clean-unix:: clean-liblinks clean-libs clean-libobjs
-
-depend:: includes pty_err.h
-
-#install:: libpty.h
-# $(INSTALL_DATA) $(srcdir)/libpty.h $(DESTDIR)$(KRB5_INCDIR)/libpty.h
-
-includes:: libpty.h
- if cmp $(srcdir)/libpty.h \
- $(BUILDTOP)/include/libpty.h >/dev/null 2>&1; then :; \
- else \
- (set -x; $(RM) $(BUILDTOP)/include/libpty.h; \
- $(CP) $(srcdir)/libpty.h \
- $(BUILDTOP)/include/libpty.h) ; \
- fi
-
-includes:: $(BUILDTOP)/include/autoconf.h
-
-clean-unix::
- $(RM) $(BUILDTOP)/include/libpty.h
-
-
-
-clean-unix:: clean-liblinks clean-libs clean-libobjs clean-files
-
-clean-files::
- rm -f *~ \#* *.bak \
- *.otl *.aux *.toc *.PS *.dvi *.x9700 *.ps \
- *.cp *.fn *.ky *.log *.pg *.tp *.vr \
- *.o profiled/?*.o libcom_err.a libcom_err_p.a \
- com_err.o compile_et \
- et.ar TAGS y.tab.c lex.yy.c error_table.c \
- et_lex.lex.c \
- test1.h test1.c test2.h test2.c test_et \
- eddep makedep *.ln
-
-pty_err.o: pty_err.c
-pty_err.h: pty_err.et
-pty_err.c: pty_err.et
-
-$(BUILDTOP)/include/autoconf.h: $(SRCTOP)/include/autoconf.h.in
- (cd $(BUILDTOP)/include; $(MAKE) autoconf.h)
-
-@libpriv_frag@
-@lib_frag@
-@libobj_frag@
-
+++ /dev/null
- This file is to serve as documentation and usage notes on
-libpty until
-more formal docs are written. By that point, it will probably
-describe how pty can be broken out of the Kerberos distribution.
-
-void pty_init(void);
-
- Initialize error tables.
-
-
-long pty_getpty ( int *fd, char *slave, int slavelength);
- Find and initialize a clean master pty. This should open the
-pty as fd, and return the name of the slave. It should return 0 or an
-error code. The slavelength parameter should include the maximum
-length allocated for a slave name. The slave may not be initialized, although any
-
-operating-system specific initialization (for example, unlockpt and
-grantpt) may be performed.
-
-long pty_open_slave (/*in */ char * slave, /* out*/ int *fd)
-
- Initialize the slave side by dissociating the current terminal
-and by setting process groups, etc. In addition, it will initialize
-the terminal flags (termios or old BSD) appropriately; the application
-may have to do additional customization, but this should sanitize
-things. In addition, the pty will be opened securely, and will become
-the controlling terminal. This procedure will fail unless the process
-is running as root. Ideally, pty_open_slave will be called in a child
-process of the process that called pty_getpty. If an operating system
-implements setsid() per the POSIX spec, but does not implement
-TIOCNOTTY, this procedure will not be able to insure that the
-controlling terminal is established if it is called in the parent
-process. Unfortunately, the parent process must not write to the pty
-until the slave side is opened. Also, the parent process should not
-open the slave side through other means unless it is prepared to have
-that file descriptor subjected to a vhangup() or revoke() when
-pty_open_slave is called in the child. So, ideally, the parent calls
-pty_getpty, forks, waits for the slave to call pty_open_slave, then
-continues. Since this synchronization may be difficult to build in to
-existing programs, pty_open_slave makes an effort to function if
-called in the parent under operating systems where this is possible.
-Currently, I haven't found any operating systems where this isn't
-possible. Also note that pty_open_slave will succeed only once per process.
-
-long pty_open_ctty(int *fd, char *line)
-
- Attempt to disassociate the current process from its controlling terminal and open line as a new controlling terminal. No assumption about line being the slave side of a pty is made.
-
-long pty_initialize_slave (int fd)
-
- Perform the non-security related initializations on the slave
-side of a pty. For example, push the appropriate streams, set termios
-structures, etc. This is included in pty_open_slave. I am interested
-in any suggestions on how to pass information on the state to which
-the application wants the terminal initialized. For example, rlogind
-wants a transparent channel, while other programs likely want cooked
-mode. I can't take a termios structure because I may be on a
-non-termios system. Currently, I push the streams, do a bit of
-cleanup, but don't really modify the terminal that much. Another
-possible goal for this function would be to do enough initialization
-that the slave side of the pty can be treated simply as a tty instead
-of a pty after this call.
-
-
-long pty_update_utmp ( int process_type, int pid, char *user, char
-*line, char *host, int flags)
-
- Update the utmp information or return an error.The
-process_type is one of the magic types defined in libpty.h. The flags
-are logical combinations of one of the following:
-
- PTY_TTYSLOT_USABLE: The tty pointed to by the line
- parameter is the first tty that would be found by
- searching stdin then stdout. In other words,
- ttyslot() would return the right slot in utmp on
- systems where ttyslot() is cannonically used. Note
- that for inserting utmp entries for new logins, it
- is not always possible to find the right place if
- this flag is not given. Thus, for programs like
- telnetd that set up utmp entries, it is important to
- be able to set this flag on the initial utmp update.
- It is expected that this flag may be cleared on
- update_utmp calls to remove utmp entries.
-
- PTY_UTMP_USERNAME_VALID: the username field in the
- utmp entry associated with this line contains the
- user who (is/was) associated with the line.
- Regardless of this flag, the utmp file will contain
- the username specified after this call. However, if
- a username is needed by the system for wtmp logout
- (Solaris 2.1 for example), then the system can fetch
- the user from the utmp record before doing the wtmp
- update. This will only be attempted if the username
- is a null pointer.
-
-long pty_cleanup(char *slave, pid_t pid, int update_wtmp)
-
- Clean up after the slave application has exited. Close down
-the pty, HUPing processes associated with it. (pid is the pid of the
-slave process that may have died, slave is the name of the slave
-terminal.) PID is allowed to be zero if unknown; this may disable
-some cleanup operations. This routine may fork on some systems. As
-such, SIGCHLD may be generated and blocked for some time during the
-routine. In addition, on systems without waitpid() or wait4(), wait()
-may be called.
-
-
-
+++ /dev/null
-/*
- * pty_cleanup: Kill processes associated with pty.
- *
- * (C)Copyright 1995, 1996 by the Massachusetts Institute of Technology.
- *
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that copyright notice and this permission
- * notice appear in supporting documentation, and that the name of
- * M.I.T. not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability
- * of this software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- */
-
-#include "com_err.h"
-#include "libpty.h"
-#include "pty-int.h"
-#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>
-#endif
-
-long pty_cleanup (char *slave,
- /* May be zero for unknown. */
- int pid,
- int update_utmp)
-{
-#ifdef VHANG_LAST
- int retval, fd;
-#endif
-
- if (update_utmp)
- pty_update_utmp(PTY_DEAD_PROCESS, pid, "", slave, (char *)0, PTY_UTMP_USERNAME_VALID);
-
- (void)chmod(slave, 0666);
- (void)chown(slave, 0, 0);
-#ifdef HAVE_REVOKE
- revoke(slave);
- /*
- * Revoke isn't guaranteed to send a SIGHUP to the processes it
- * dissociates from the terminal. The best solution without a Posix
- * mechanism for forcing a hangup is to killpg() the process
- * group of the pty. This will at least kill the shell and
- * hopefully, the child processes. This is not always the case, however.
- * If the shell puts each job in a process group and doesn't pass
- * along SIGHUP, all processes may not die.
- */
- if ( pid > 0 ) {
-#ifdef HAVE_KILLPG
- killpg(pid, SIGHUP);
-#else
- kill( -(pid), SIGHUP );
-#endif /*HAVE_KILLPG*/
- }
-#else /* HAVE_REVOKE*/
-#ifdef VHANG_LAST
- {
- int status;
-#ifdef POSIX_SIGNALS
- sigset_t old, new;
- sigemptyset(&new);
- sigaddset(&new, SIGCHLD);
- sigprocmask ( SIG_BLOCK, &new, &old);
-#else /*POSIX_SIGNALS*/
- int mask = sigblock(sigmask(SIGCHLD));
-#endif /*POSIX_SIGNALS*/
- switch (retval = fork()) {
- case -1:
-#ifdef POSIX_SIGNALS
- sigprocmask(SIG_SETMASK, &old, 0);
-#else /*POSIX_SIGNALS*/
- sigsetmask(mask);
-#endif /*POSIX_SIGNALS*/
- return errno;
- case 0:
- ptyint_void_association();
- if ((retval = pty_open_ctty(slave, &fd)))
- exit(retval);
- ptyint_vhangup();
- exit(0);
- break;
- default:
-#ifdef HAVE_WAITPID
- waitpid(retval, &status, 0);
-#else /*HAVE_WAITPID*/
- wait(&status);
-#endif
-#ifdef POSIX_SIGNALS
- sigprocmask(SIG_SETMASK, &old, 0);
-#else /*POSIX_SIGNALS*/
- sigsetmask(mask);
-#endif /*POSIX_SIGNALS*/
-
- break;
- }
- }
-#endif /*VHANG_LAST*/
-#endif /* HAVE_REVOKE*/
-#ifndef HAVE_STREAMS
- slave[strlen("/dev/")] = 'p';
- (void)chmod(slave, 0666);
- (void)chown(slave, 0, 0);
-#endif
- return 0;
-}
+++ /dev/null
-K5_AC_INIT(getpty.c)
-CONFIG_RULES
-AC_PROG_AWK
-AC_CHECK_FUNCS(fchmod fchown revoke vhangup killpg _getpty)
-dnl
-LOGINLIBS=
-dnl
-dnl Make our operating system-specific security checks and definitions for
-dnl login.
-dnl In addition, the following code decides what streams modules will
-dnl be pushed onto a pty.In particular, if HAVE_STREAMS is defined and
-dnl HAVE_LINE_PUSH is not defined, modules may be pushed by inserting
-dnl An appropriate generic ifdef for each module in init_slave.c and
-dnl AC_DEFINES for the operating systems that need the modules.
-dnl Each OS that supports streams has a different idea of what you want to
-dnl push.
-dnl
-case $krb5_cv_host in
-*-*-ultrix*)
-echo "Disabling initial vhangup and setsid because they break under Ultrix..."
-AC_DEFINE([OPEN_CTTY_ONLY_ONCE],[1],[Define on Ultrix where an initial vhangup breaks])
-ac_cv_func_setsid=no # setsid doesn't do the right thing under Ultrix even though present
-;;
-
-*-*-aix3*) # AIX has streams include files but not streams TTY
-# Moreover, strops.h trashes sys/ioctl.h
-krb5_cv_has_streams=no
-;;
-alpha*-dec-osf*)
- AC_MSG_RESULT(will open ctty prior to revoke due to OSF/1 lossage)
- AC_DEFINE(REVOKE_NEEDS_OPEN,1,[Define if ctty needs to be opened before revoke as on OSF/1])
- ;;
-*-*-solaris*)
- AC_DEFINE(PUSH_PTEM,1,[push ptem?])
- AC_DEFINE(PUSH_LDTERM,1,[push ldterm?])
- AC_DEFINE(PUSH_TTCOMPAT,1,[push ttcompat?])
- ;;
-*-*-hpux*)
- krb5_cv_has_streams=no
- ;;
-esac
-dnl
-AC_CHECK_LIB(util,openpty, [AC_DEFINE(HAVE_OPENPTY,1,[Define if openpty is provided in util library]) LIBS="$LIBS -lutil"])
-AC_TYPE_MODE_T
-AC_CHECK_TYPE(time_t, long)
-AC_CHECK_FUNCS(setreuid gettosbyname setsid ttyname line_push ptsname grantpt openpty)
-AC_CHECK_HEADERS(unistd.h stdlib.h string.h libutil.h pty.h sys/filio.h sys/sockio.h sys/label.h sys/tty.h sys/wait.h ttyent.h lastlog.h sys/select.h util.h sys/stream.h)
-AC_CHECK_FUNCS(waitpid)
-CHECK_SIGNALS
-AC_CHECK_HEADER(termios.h,[AC_CHECK_FUNC(cfsetispeed,AC_DEFINE(POSIX_TERMIOS,1,[Define for POSIX termios interface]))])
-
-AC_CHECK_HEADER(sys/ptyvar.h, [], [],
-[#if HAVE_SYS_STREAM_H
-#include <sys/stream.h>
-#endif
-#if HAVE_SYS_TTY_H
-#include <sys/tty.h>
-#endif])
-
-######################################################################
-#
-# utmp related hair here. There's lots of it.
-#
-
-AC_CHECK_HEADERS(utmp.h utmpx.h)
-AC_CHECK_FUNCS(setutent setutxent setutsent updwtmp updwtmpx logwtmp getutmp getutmpx)
-AC_CHECK_FUNCS(utmpname utmpxname)
-
-AC_DEFUN(K5_CHECK_UT_MEMBER,
-[AC_MSG_CHECKING([for $2 in struct $1])
-AC_CACHE_VAL([krb5_cv_struct_$1_$2],
-[AC_TRY_COMPILE([#include <sys/types.h>
-#include <$1.h>], [struct $1 u; u.$2;],
-eval "krb5_cv_struct_$1_$2=yes", eval "krb5_cv_struct_$1_$2=no")])
-if eval "test \"`echo '$krb5_cv_struct_'$1'_'$2`\" = yes"; then
- AC_MSG_RESULT(yes)
- krb5_tr_ut=HAVE_STRUCT_`echo $1'_'$2 | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- AC_DEFINE_UNQUOTED($krb5_tr_ut,1,[Define if $2 field present in $1])
-else
- AC_MSG_RESULT(no)
-fi])
-
-if test "$ac_cv_header_utmp_h" = yes; then
- AC_MSG_RESULT(checking struct utmp members)
- for krb5_mem in ut_host ut_syslen ut_addr ut_id ut_pid ut_type ut_exit; do
- K5_CHECK_UT_MEMBER(utmp, $krb5_mem)
- done
-fi
-
-if test "$ac_cv_header_utmpx_h" = yes; then
- AC_MSG_RESULT(checking struct utmpx members)
- for krb5_mem in ut_host ut_syslen ut_addr ut_id ut_pid ut_type ut_exit; do
- K5_CHECK_UT_MEMBER(utmpx, $krb5_mem)
- done
-fi
-
-AC_DEFUN(K5_CHECK_UT_EXIT_MEMBER,
-[AC_MSG_CHECKING([for ut_exit.$2 in struct $1])
-AC_CACHE_VAL([krb5_cv_struct_$1_ut_exit_$2],
-[AC_TRY_COMPILE([#include <sys/types.h>
-#include <$1.h>], [struct $1 u; u.ut_exit.$2;],
-eval "krb5_cv_struct_$1_ut_exit_$2=yes",
-eval "krb5_cv_struct_$1_ut_exit_$2=no")])
-if eval "test \"`echo '$krb5_cv_struct_'$1'_ut_exit_'$2`\" = yes"; then
- AC_MSG_RESULT(yes)
- ifelse([$3], , :, [$3])
-else
- AC_MSG_RESULT(no)
- ifelse([$4], , :, [$4])
-fi])
-
-if test "$krb5_cv_struct_utmp_ut_exit" = yes; then
- AC_MSG_RESULT(checking for working ut_exit.e_exit in struct utmp)
- for krb5_mem in __e_exit ut_e_exit ut_exit e_exit; do
- K5_CHECK_UT_EXIT_MEMBER(utmp, $krb5_mem,
-[krb5_utmp_e_exit=$krb5_mem
-krb5_utmp_e_termination=`echo $krb5_mem|sed -e 's%_exit$%_termination%'`], )
- done
- if test "${krb5_utmp_e_exit+set}" = set; then
- AC_MSG_RESULT([working ut_exit.e_exit in utmp is $krb5_utmp_e_exit])
- AC_DEFINE_UNQUOTED(PTY_UTMP_E_EXIT, $krb5_utmp_e_exit,[Define to utmp exit field name])
- AC_DEFINE_UNQUOTED(PTY_UTMP_E_TERMINATION, $krb5_utmp_e_termination,[Define to utmp termination field name])
- else
- AC_MSG_RESULT([cannot find working ut_exit.e_exit in utmp])
- fi
-fi
-
-if test "$krb5_cv_struct_utmpx_ut_exit" = yes; then
- AC_MSG_RESULT(checking for working ut_exit.e_exit in struct utmpx)
- for krb5_mem in __e_exit ut_e_exit ut_exit e_exit; do
- K5_CHECK_UT_EXIT_MEMBER(utmpx, $krb5_mem,
-[krb5_utmpx_e_exit=$krb5_mem
-krb5_utmpx_e_termination=`echo $krb5_mem|sed -e 's%_exit$%_termination%'`], )
- done
- if test "${krb5_utmpx_e_exit+set}" = set; then
- AC_MSG_RESULT([working ut_exit.e_exit in utmpx is $krb5_utmpx_e_exit])
- AC_DEFINE_UNQUOTED(PTY_UTMPX_E_EXIT, $krb5_utmpx_e_exit,[Define to utmpx exit field name])
- AC_DEFINE_UNQUOTED(PTY_UTMPX_E_TERMINATION, $krb5_utmpx_e_termination,[Define to utmpx termination field name])
- else
- AC_MSG_RESULT([cannot find working ut_exit.e_exit in utmpx])
- fi
-fi
-
-if test "$ac_cv_header_utmpx_h" = yes; then
- AC_MSG_CHECKING(consistency of utmpx API)
- if test "$ac_cv_func_setutxent" = yes; then
- if test "$krb5_cv_struct_utmpx_ut_id" = yes \
- && test "$krb5_cv_struct_utmpx_ut_type" = yes \
- && test "$krb5_cv_struct_utmpx_ut_pid" = yes; then
- AC_MSG_RESULT(ok)
- else
- AC_MSG_RESULT(not ok)
- AC_MSG_ERROR([have setutxent but no ut_id, ut_type, or ut_pid in utmpx])
- fi
- else
- AC_MSG_RESULT(not ok)
- AC_MSG_ERROR([have utmpx.h but no setutxent])
- fi
-fi
-
-if test "$ac_cv_func_setutent" = yes && \
- test "$ac_cv_header_utmpx_h" = no; then
- AC_MSG_CHECKING(consistency of sysV-ish utmp API)
- if test "$ac_cv_header_utmp_h" = yes; then
- if test "$krb5_cv_struct_utmp_ut_id" = yes \
- && test "$krb5_cv_struct_utmp_ut_type" = yes \
- && test "$krb5_cv_struct_utmp_ut_pid" = yes; then
- AC_MSG_RESULT(ok)
- else
- AC_MSG_RESULT(not ok)
- AC_MSG_ERROR([have setutent but no ut_id, ut_type, or ut_pid in utmp])
- fi
- else
- AC_MSG_RESULT(not ok)
- AC_MSG_ERROR([have setutent but no utmp.h])
- fi
-fi
-
-#
-# end of utmp-related hair
-#
-######################################################################
-dnl
-KRB5_NEED_PROTO([#ifdef HAVE_UTMP_H
-#include <utmp.h>
-#endif
-#ifdef HAVE_UTMPX_H
-#include <utmpx.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-],getutmp)
-dnl
-#########################################
-KRB5_NEED_PROTO([#include <sys/types.h>
-#ifdef HAVE_UTMP_H
-#include <utmp.h>
-#endif
-#ifdef HAVE_LIBUTIL_H
-#include <libutil.h>
-#endif
-#ifdef HAVE_UTIL_H
-#include <util.h>
-#endif
-],logwtmp)
-########################################
-KRB5_NEED_PROTO([#include <unistd.h>
-],revoke)
-########################################
-dnl
-AC_MSG_CHECKING([streams interface])
-AC_CACHE_VAL(krb5_cv_has_streams,
-[AC_TRY_COMPILE(
-[#include <sys/stream.h>
-#include <sys/stropts.h>], [],
-krb5_cv_has_streams=yes, krb5_cv_has_streams=no)])
-AC_MSG_RESULT($krb5_cv_has_streams)
-if test $krb5_cv_has_streams = yes; then
-AC_DEFINE(HAVE_STREAMS,1,[Define if have streams])
-fi
-dnl
-dnl
-dnl
-AC_MSG_CHECKING([arguments to getpgrp])
-AC_CACHE_VAL(krb5_cv_getpgrp_args,
-[AC_TRY_COMPILE(
-[#ifndef __STDC__
-#define __STDC__ 1
-#endif
-#include <unistd.h>
-#include <sys/types.h>], [pid_t pid = getpgrp(getpid())],
-krb5_cv_getpgrp_args=pid, krb5_cv_getpgrp_args=void)])
-AC_MSG_RESULT($krb5_cv_getpgrp_args)
-if test $krb5_cv_getpgrp_args = pid; then
-AC_DEFINE(GETPGRP_ONEARG,1,[Define if getpgrp takes one arg])
-fi
-dnl
-dnl
-AC_MSG_CHECKING([number of arguments to setpgrp])
-AC_CACHE_VAL(krb5_cv_setpgrp_args,
-[AC_TRY_COMPILE(
-[#ifndef __STDC__
-#define __STDC__ 1
-#endif
-#include <unistd.h>],[setpgrp(0,0)],
-krb5_cv_setpgrp_args=two, krb5_cv_setpgrp_args=void)])
-AC_MSG_RESULT($krb5_cv_setpgrp_args)
-if test $krb5_cv_setpgrp_args = two; then
-AC_DEFINE(SETPGRP_TWOARG,1,[Define if setpgrp takes two args])
-fi
-dnl
-KRB5_AC_INET6
-AC_C_CONST
-KRB5_BUILD_LIBRARY
-KRB5_BUILD_LIBOBJS
-KRB5_BUILD_PROGRAM
-KRB5_RUN_FLAGS
-V5_AC_OUTPUT_MAKEFILE
+++ /dev/null
-#
-# Generated makefile dependencies follow.
-#
-pty_err.so pty_err.po $(OUTPRE)pty_err.$(OBJEXT): $(COM_ERR_DEPS) \
- pty_err.c
-cleanup.so cleanup.po $(OUTPRE)cleanup.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h cleanup.c \
- libpty.h pty-int.h pty_err.h
-getpty.so getpty.po $(OUTPRE)getpty.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(COM_ERR_DEPS) $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/port-sockets.h getpty.c libpty.h \
- pty-int.h pty_err.h
-init_slave.so init_slave.po $(OUTPRE)init_slave.$(OBJEXT): \
- $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
- init_slave.c libpty.h pty-int.h pty_err.h
-open_ctty.so open_ctty.po $(OUTPRE)open_ctty.$(OBJEXT): \
- $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
- libpty.h open_ctty.c pty-int.h pty_err.h
-open_slave.so open_slave.po $(OUTPRE)open_slave.$(OBJEXT): \
- $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
- libpty.h open_slave.c pty-int.h pty_err.h
-update_utmp.so update_utmp.po $(OUTPRE)update_utmp.$(OBJEXT): \
- $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-platform.h \
- $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/port-sockets.h \
- libpty.h pty-int.h pty_err.h update_utmp.c
-update_wtmp.so update_wtmp.po $(OUTPRE)update_wtmp.$(OBJEXT): \
- $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
- libpty.h pty-int.h pty_err.h update_wtmp.c
-vhangup.so vhangup.po $(OUTPRE)vhangup.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h libpty.h \
- pty-int.h pty_err.h vhangup.c
-void_assoc.so void_assoc.po $(OUTPRE)void_assoc.$(OBJEXT): \
- $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
- libpty.h pty-int.h pty_err.h void_assoc.c
-logwtmp.so logwtmp.po $(OUTPRE)logwtmp.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h libpty.h \
- logwtmp.c pty-int.h pty_err.h
-init.so init.po $(OUTPRE)init.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h init.c \
- libpty.h pty-int.h pty_err.h
-sane_hostname.so sane_hostname.po $(OUTPRE)sane_hostname.$(OBJEXT): \
- $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(SRCTOP)/include/fake-addrinfo.h \
- $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- libpty.h pty-int.h pty_err.h sane_hostname.c
+++ /dev/null
-/*
- * Copyright 2001 by the Massachusetts Institute of Technology.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that copyright notice and this permission
- * notice appear in supporting documentation, and that the name of
- * M.I.T. not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability
- * of this software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- * dump-utmp.c: dump utmp and utmpx format files for debugging purposes.
- */
-
-#include <sys/types.h>
-#include <sys/file.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#ifndef UTMPX
-#ifdef HAVE_UTMPX_H
-#define UTMPX
-#endif
-#endif
-
-#if defined(HAVE_UTMPNAME) || defined(HAVE_UTMPXNAME)
-#define UTN /* we can set utmp or utmpx for getut*() */
-#endif
-
-#ifdef UTMPX
-#include <utmpx.h>
-void print_utx(int, const struct utmpx *);
-#endif
-#include <utmp.h>
-
-void print_ut(int, const struct utmp *);
-
-void usage(const char *);
-
-#if defined (HAVE_STRUCT_UTMP_UT_TYPE) || defined (UTMPX)
-char *ut_typename(int);
-
-char *
-ut_typename(int t) {
- switch (t) {
-#define S(N) case N : return #N
-#define S2(N,N2) case N : return #N2
- S(EMPTY);
- S(RUN_LVL);
- S(BOOT_TIME);
- S(OLD_TIME);
- S(NEW_TIME);
- S2(INIT_PROCESS,INIT);
- S2(LOGIN_PROCESS,LOGIN);
- S2(USER_PROCESS,USER);
- S2(DEAD_PROCESS,DEAD);
- S(ACCOUNTING);
- default: return "??";
- }
-}
-#endif
-
-#define S2D(x) (sizeof(x) * 2.4 + 1.5)
-
-void
-print_ut(int all, const struct utmp *u)
-{
- int lu, ll;
-#ifdef HAVE_STRUCT_UTMP_UT_ID
- int lid;
-#endif
-#ifdef HAVE_STRUCT_UTMP_UT_PID
- int lpid;
-#endif
-#ifdef PTY_UTMP_E_EXIT
- int let, lee;
-#endif
-
-#ifdef HAVE_STRUCT_UTMP_UT_TYPE
- if (!all && ((u->ut_type == EMPTY) || (u->ut_type == DEAD_PROCESS)))
- return;
-#endif
-
- lu = sizeof(u->ut_name);
- ll = sizeof(u->ut_line);
- printf("%-*.*s:", lu, lu, u->ut_name);
- printf("%-*.*s:", ll, ll, u->ut_line);
-#ifdef HAVE_STRUCT_UTMP_UT_ID
- lid = sizeof(u->ut_id);
- printf("%-*.*s:", lid, lid, u->ut_id);
-#endif
-#ifdef HAVE_STRUCT_UTMP_UT_PID
- lpid = S2D(u->ut_pid);
- printf("%*ld", lpid, (long)u->ut_pid);
-#endif
-#ifdef PTY_UTMP_E_EXIT
- let = S2D(u->ut_exit.PTY_UTMP_E_TERMINATION);
- lee = S2D(u->ut_exit.PTY_UTMP_E_EXIT);
- printf("(%*ld,", let, (long)u->ut_exit.PTY_UTMP_E_TERMINATION);
- printf("%*ld)", lee, (long)u->ut_exit.PTY_UTMP_E_EXIT);
-#endif
-#ifdef HAVE_STRUCT_UTMP_UT_TYPE
- printf(" %-9s", ut_typename(u->ut_type));
-#endif
- printf(" %s", ctime(&u->ut_time) + 4);
-#ifdef HAVE_STRUCT_UTMP_UT_HOST
- if (u->ut_host[0])
- printf(" %.*s\n", (int) sizeof(u->ut_host), u->ut_host);
-#endif
-
- return;
-}
-
-#ifdef UTMPX
-void
-print_utx(int all, const struct utmpx *u)
-{
- int lu, ll, lid, lpid;
-#ifdef PTY_UTMPX_E_EXIT
- int let, lee;
-#endif
-
- if (!all && ((u->ut_type == EMPTY) || (u->ut_type == DEAD_PROCESS)))
- return;
-
- lu = sizeof(u->ut_user);
- ll = sizeof(u->ut_line);
- lid = sizeof(u->ut_id);
- printf("%-*.*s:", lu, lu, u->ut_user);
- printf("%-*.*s:", ll, ll, u->ut_line);
- printf("%-*.*s", lid, lid, u->ut_id);
- if (lu + ll + lid >= 60)
- printf("\n");
- else
- printf(":");
- lpid = S2D(u->ut_pid);
- printf("%*ld", lpid, (long)u->ut_pid);
-#ifdef PTY_UTMPX_E_EXIT
- let = S2D(u->ut_exit.PTY_UTMPX_E_TERMINATION);
- lee = S2D(u->ut_exit.PTY_UTMPX_E_EXIT);
- printf("(%*ld,", let, (long)u->ut_exit.PTY_UTMPX_E_TERMINATION);
- printf("%*ld)", lee, (long)u->ut_exit.PTY_UTMPX_E_EXIT);
-#endif
- printf(" %-9s", ut_typename(u->ut_type));
- printf(" %s", ctime(&u->ut_tv.tv_sec) + 4);
-#ifdef HAVE_STRUCT_UTMPX_UT_HOST
- if (u->ut_host[0])
- printf(" %s\n", u->ut_host);
-#endif
-
- return;
-}
-#endif
-
-#ifdef UTMPX
-#define OPTX "x"
-#else
-#define OPTX
-#endif
-#ifdef UTN
-#define OPTG "g"
-#else
-#define OPTG
-#endif
-#define OPTS "a" OPTX OPTG
-
-void
-usage(const char *prog)
-{
- fprintf(stderr, "usage: %s [-" OPTS "] file\n", prog);
- exit(1);
-}
-
-int
-main(int argc, char **argv)
-{
- int c;
- int all, is_utmpx, do_getut;
- int f;
- char *fn;
- size_t recsize;
- size_t nread;
- union {
- struct utmp ut;
-#ifdef UTMPX
- struct utmpx utx;
-#endif
- } u;
-
- all = is_utmpx = do_getut = 0;
- recsize = sizeof(struct utmp);
-
- while ((c = getopt(argc, argv, OPTS)) != EOF) {
- switch (c) {
- case 'a':
- all = 1;
- break;
-#ifdef UTMPX
- case 'x':
- is_utmpx = 1;
- recsize = sizeof(struct utmpx);
- break;
-#endif
-#ifdef UTN
- case 'g':
- do_getut = 1;
- break;
-#endif
- default:
- usage(argv[0]);
- }
- }
- if (argc <= optind)
- usage(argv[0]);
- fn = argv[optind];
- if (!do_getut) {
- f = open(fn, O_RDONLY);
- if (f == -1) {
- perror(fn);
- exit(1);
- }
- while ((nread = read(f, &u, recsize)) > 0) {
- if (nread < recsize) {
- fprintf(stderr, "short read");
- close(f);
- exit(1);
- }
- if (is_utmpx) {
-#ifdef UTMPX
- print_utx(all, &u.utx);
-#else
- abort();
-#endif
- } else {
- print_ut(all, &u.ut);
- }
- }
- if (nread == -1) {
- perror("read");
- exit(1);
- }
- close(f);
- } else {
- if (is_utmpx) {
-#ifdef UTMPX
-#ifdef HAVE_UTMPXNAME
- struct utmpx *utxp;
- utmpxname(fn);
- setutxent();
- while ((utxp = getutxent()) != NULL)
- print_utx(all, utxp);
-#else
- fprintf(stderr, "no utmpxname(); can't use getutxent()\n");
- exit(1);
-#endif
-#else
- abort();
-#endif
- } else {
-#ifdef HAVE_UTMPNAME
- struct utmp *utp;
- utmpname(fn);
- setutxent();
- while ((utp = getutent()) != NULL)
- print_ut(all, utp);
-#else
- fprintf(stderr, "no utmpname(); can't use getutent()\n");
- exit(1);
-#endif
- }
- }
- exit(0);
-}
+++ /dev/null
-/*
- * pty_getpty: open a PTY master.
- *
- * Copyright 1995, 1996 by the Massachusetts Institute of Technology.
- *
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that copyright notice and this permission
- * notice appear in supporting documentation, and that the name of
- * M.I.T. not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability
- * of this software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- */
-
-#include "com_err.h"
-#include "libpty.h"
-#include "pty-int.h"
-#include "k5-platform.h"
-
-long
-ptyint_getpty_ext(int *fd, char *slave, int slavelength, int do_grantpt)
-{
-#if !defined(HAVE__GETPTY) && !defined(HAVE_OPENPTY)
- char *cp;
- char *p;
- int i,ptynum;
- struct stat stb;
- char slavebuf[1024];
-#endif
-
-#ifdef HAVE__GETPTY
- char *slaveret; /*Temporary to hold pointer to slave*/
-#endif /*HAVE__GETPTY*/
-
-#ifdef HAVE_OPENPTY
- int slavefd;
-
- if(openpty(fd, &slavefd, slave, (struct termios *) 0,
- (struct winsize *) 0)) return 1;
- close(slavefd);
- return 0;
-#else /*HAVE_OPENPTY*/
-#ifdef HAVE__GETPTY
- /* This code is included for Irix; as of version 5.3, Irix has /dev/ptmx,
- * but it fails to work properly; even after calling unlockpt,
- * root gets permission denied opening the pty.
- * The code to support _getpty should be removed if Irix gets working
- * streams ptys in favor of maintaining the least needed code
- * paths.
- */
- if ((slaveret = _getpty(fd, O_RDWR|O_NDELAY, 0600, 0)) == 0) {
- *fd = -1;
- return PTY_GETPTY_NOPTY;
- }
- if (strlcpy(slave, slaveret, slavelength) >= slavelength) {
- close(*fd);
- *fd = -1;
- return PTY_GETPTY_SLAVE_TOOLONG;
- }
- return 0;
-#else /*HAVE__GETPTY*/
-
- *fd = open("/dev/ptym/clone", O_RDWR|O_NDELAY); /* HPUX*/
-#ifdef HAVE_STREAMS
- if (*fd < 0) *fd = open("/dev/ptmx",O_RDWR|O_NDELAY); /*Solaris*/
-#endif
- if (*fd < 0) *fd = open("/dev/ptc", O_RDWR|O_NDELAY); /* AIX */
- if (*fd < 0) *fd = open("/dev/pty", O_RDWR|O_NDELAY); /* sysvimp */
-
- if (*fd >= 0) {
-
-#if defined(HAVE_GRANTPT)&&defined(HAVE_STREAMS)
- if (do_grantpt)
- if (grantpt(*fd) || unlockpt(*fd)) return PTY_GETPTY_STREAMS;
-#endif
-
-#ifdef HAVE_PTSNAME
- p = ptsname(*fd);
-#else
-#ifdef HAVE_TTYNAME
- p = ttyname(*fd);
-#else
- /* XXX If we don't have either what do we do */
-#endif
-#endif
- if (p) {
- if (strlcpy(slave, p, slavelength) >= slavelength) {
- close (*fd);
- *fd = -1;
- return PTY_GETPTY_SLAVE_TOOLONG;
- }
- return 0;
- }
-
- if (fstat(*fd, &stb) < 0) {
- close(*fd);
- return PTY_GETPTY_FSTAT;
- }
- ptynum = (int)(stb.st_rdev&0xFF);
- snprintf(slavebuf, sizeof(slavebuf), "/dev/ttyp%x", ptynum);
- if (strlen(slavebuf) > slavelength - 1) {
- close(*fd);
- *fd = -1;
- return PTY_GETPTY_SLAVE_TOOLONG;
- }
- strncpy(slave, slavebuf, slavelength);
- return 0;
- } else {
- for (cp = "pqrstuvwxyzPQRST";*cp; cp++) {
- snprintf(slavebuf,sizeof(slavebuf),"/dev/ptyXX");
- slavebuf[sizeof("/dev/pty") - 1] = *cp;
- slavebuf[sizeof("/dev/ptyp") - 1] = '0';
- if (stat(slavebuf, &stb) < 0)
- break;
- for (i = 0; i < 16; i++) {
- slavebuf[sizeof("/dev/ptyp") - 1] = "0123456789abcdef"[i];
- *fd = open(slavebuf, O_RDWR);
- if (*fd < 0) continue;
-
- /* got pty */
- slavebuf[sizeof("/dev/") - 1] = 't';
- if (strlen(slavebuf) > slavelength -1) {
- close(*fd);
- *fd = -1;
- return PTY_GETPTY_SLAVE_TOOLONG;
- }
- strncpy(slave, slavebuf, slavelength);
- return 0;
- }
- }
- return PTY_GETPTY_NOPTY;
- }
-#endif /*HAVE__GETPTY*/
-#endif /* HAVE_OPENPTY */
-}
-
-long
-pty_getpty(int *fd, char *slave, int slavelength)
-{
- return ptyint_getpty_ext(fd, slave, slavelength, 1);
-}
+++ /dev/null
-/*
- * pty_init: Initialize internal state of pty.
- *
- * Currently initializes error tables.
- *
- * Copyright 1995 by the Massachusetts Institute of Technology.
- *
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that copyright notice and this permission
- * notice appear in supporting documentation, and that the name of
- * M.I.T. not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability
- * of this software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- */
-
-#include "com_err.h"
-#include "libpty.h"
-#include "pty-int.h"
-
-long pty_init(void)
-{
- initialize_pty_error_table();
- return 0;
-}
+++ /dev/null
-/*
- * pty_init_slave: open slave side of terminal, clearing for use.
- *
- * Copyright 1995, 1996 by the Massachusetts Institute of Technology.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that copyright notice and this permission
- * notice appear in supporting documentation, and that the name of
- * M.I.T. not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability
- * of this software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- */
-
-#include "com_err.h"
-#include "libpty.h"
-#include "pty-int.h"
-
-/* * The following is an array of modules that should be pushed on the
- * stream. See configure.in for caviats and notes about when this
- * array is used and not used.
- */
-#if defined(HAVE_STREAMS)&&(!defined(HAVE_LINE_PUSH))
-static char *push_list[] = {
-#ifdef PUSH_PTEM
- "ptem",
-#endif
-#ifdef PUSH_LDTERM
- "ldterm",
-#endif
-#ifdef PUSH_TTCOMPAT
-"ttcompat",
-#endif
- 0};
-#endif /*HAVE_STREAMS but not HAVE_LINE_PUSH*/
-
-
-
-long pty_initialize_slave (int fd)
-{
-#if defined(POSIX_TERMIOS) && !defined(ultrix)
- struct termios new_termio;
-#else
- struct sgttyb b;
-#endif /* POSIX_TERMIOS */
- int pid;
-
-#ifdef HAVE_STREAMS
-#ifdef HAVE_LINE_PUSH
- while (ioctl (fd, I_POP, 0) == 0); /*Clear out any old lined's*/
-
- if (line_push(fd) < 0)
- {
- (void) close(fd); fd = -1;
- return PTY_OPEN_SLAVE_LINE_PUSHFAIL;
- }
-#else /*No line_push */
- {
- char **module = &push_list[0];
- while (*module)
- if (ioctl(fd, I_PUSH, *(module++)) < 0)
- return PTY_OPEN_SLAVE_PUSH_FAIL;
- }
-
-#endif /*LINE_PUSH*/
-#endif /*HAVE_STREAMS*/
-
- /*
- * Under Ultrix 3.0, the pgrp of the slave pty terminal
- * needs to be set explicitly. Why rlogind works at all
- * without this on 4.3BSD is a mystery.
- */
-#ifdef GETPGRP_ONEARG
- pid = getpgrp(getpid());
-#else
- pid = getpgrp();
-#endif
-
-#ifdef TIOCSPGRP
- ioctl(fd, TIOCSPGRP, &pid);
-#endif
-
-
-#if defined(POSIX_TERMIOS) && !defined(ultrix)
- tcsetpgrp(fd, pid);
- tcgetattr(fd,&new_termio);
- new_termio.c_cc[VMIN] = 1;
- new_termio.c_cc[VTIME] = 0;
- tcsetattr(fd,TCSANOW,&new_termio);
-#endif /* POSIX_TERMIOS */
-
- return 0;
-}
+++ /dev/null
-/*
- * Header file for manipulation of ptys and utmp entries.
- *
- * Copyright 1995 by the Massachusetts Institute of Technology.
- *
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that copyright notice and this permission
- * notice appear in supporting documentation, and that the name of
- * M.I.T. not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability
- * of this software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- */
-
-#ifndef __LIBPTY_H__
-
-/* Constants for pty_update_utmp */
-#define PTY_LOGIN_PROCESS 0
-#define PTY_USER_PROCESS 1
-#define PTY_DEAD_PROCESS 2
-
-/* flags to update_utmp*/
-#define PTY_TTYSLOT_USABLE (0x1)
-#define PTY_UTMP_USERNAME_VALID (0x2)
-
-long pty_init(void);
-long pty_getpty ( int *fd, char *slave, int slavelength);
-
-long pty_open_slave (const char *slave, int *fd);
-long pty_open_ctty (const char *slave, int *fd);
-
-long pty_initialize_slave ( int fd);
-long pty_update_utmp(int process_type, int pid, const char *user,
- const char *tty_line, const char *host, int flags);
-
-long pty_logwtmp(const char *tty, const char *user, const char *host);
-
-long pty_cleanup(char *slave, int pid, int update_utmp);
-
-#ifndef SOCK_DGRAM
-struct sockaddr;
-#endif
-
-long pty_make_sane_hostname(const struct sockaddr *, int, int, int, char **);
-#define __LIBPTY_H__
-#endif
+++ /dev/null
-/*
- * pty_logwtmp: Implement the logwtmp function if not present.
- *
- * Copyright 1995, 2001 by the Massachusetts Institute of Technology.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that copyright notice and this permission
- * notice appear in supporting documentation, and that the name of
- * M.I.T. not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability
- * of this software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- */
-
-#include "com_err.h"
-#include "libpty.h"
-#include "pty-int.h"
-
-#if defined(HAVE_SETUTXENT) || defined(HAVE_SETUTENT)
-#ifdef HAVE_SETUTXENT
-#define PTY_STRUCT_UTMPX struct utmpx
-#else
-#define PTY_STRUCT_UTMPX struct utmp
-#endif
-
-#ifdef NEED_LOGWTMP_PROTO
-void logwtmp(const char *, const char *, const char *);
-#endif
-
-long
-pty_logwtmp(const char *tty, const char *user, const char *host)
-{
-#ifndef HAVE_LOGWTMP
- PTY_STRUCT_UTMPX utx;
- int loggingin;
- size_t len;
- const char *cp;
- char utmp_id[5];
-#endif
-
-#ifdef HAVE_LOGWTMP
- logwtmp(tty,user,host);
- return 0;
-#else
-
- loggingin = (user[0] != '\0');
-
- memset(&utx, 0, sizeof(utx));
- strncpy(utx.ut_line, tty, sizeof(utx.ut_line));
- strncpy(utx.ut_user, user, sizeof(utx.ut_user));
-#if (defined(HAVE_SETUTXENT) && defined(HAVE_STRUCT_UTMPX_UT_HOST)) \
- || (!defined(HAVE_SETUTXENT) && defined(HAVE_STRUCT_UTMP_UT_HOST))
- strncpy(utx.ut_host, host, sizeof(utx.ut_host));
- utx.ut_host[sizeof(utx.ut_host) - 1] = '\0';
-#endif
-#ifdef HAVE_SETUTXENT
- gettimeofday(&utx.ut_tv, NULL);
-#else
- (void)time(&utx.ut_time);
-#endif
- utx.ut_pid = (loggingin ? getpid() : 0);
- utx.ut_type = (loggingin ? USER_PROCESS : DEAD_PROCESS);
-
- len = strlen(tty);
- if (len >= 2)
- cp = tty + len - 2;
- else
- cp = tty;
- snprintf(utmp_id, sizeof(utmp_id), "kr%s", cp);
- strncpy(utx.ut_id, utmp_id, sizeof(utx.ut_id));
-
-#ifdef HAVE_SETUTXENT
- return ptyint_update_wtmpx(&utx);
-#else
- return ptyint_update_wtmp(&utx);
-#endif
-
-#endif /* !HAVE_LOGWTMP */
-}
-
-#else /* !(defined(HAVE_SETUTXENT) || defined(HAVE_SETUTENT)) */
-
-long
-pty_logwtmp(const char *tty, const char *user, const char *host)
-{
- struct utmp ut;
-
-#ifdef HAVE_LOGWTMP
- logwtmp(tty,user,host);
- return 0;
-#else
-
- memset(&ut, 0, sizeof(ut));
-#ifdef HAVE_STRUCT_UTMP_UT_HOST
- strncpy(ut.ut_host, host, sizeof(ut.ut_host));
- ut.ut_host[sizeof(ut.ut_host) - 1] = '\0';
-#endif
- strncpy(ut.ut_line, tty, sizeof(ut.ut_line));
- strncpy(ut.ut_name, user, sizeof(ut.ut_name));
- return ptyint_update_wtmp(&ut);
-
-#endif /* !HAVE_LOGWTMP */
-}
-
-#endif /* !(defined(HAVE_SETUTXENT) || defined(HAVE_SETUTENT)) */
+++ /dev/null
-/*
- * pty_open_ctty: Open and establish controlling terminal.
- *
- * Copyright 1995, 1996 by the Massachusetts Institute of Technology.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that copyright notice and this permission
- * notice appear in supporting documentation, and that the name of
- * M.I.T. not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability
- * of this software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- */
-
-#include "com_err.h"
-#include "libpty.h"
-#include "pty-int.h"
-
-/*
- * This function will be called twice. The first time it will acquire
- * a controlling terminal from which to vhangup() or revoke() (see
- * comments in open_slave.c); the second time, it will be to open the
- * actual slave device for use by the application. We no longer call
- * ptyint_void_association(), as that will be called in
- * pty_open_slave() to avoid spurious calls to setsid(), etc.
- *
- * It is assumed that systems where vhangup() exists and does break
- * the ctty association will allow the slave to be re-acquired as the
- * ctty. Also, if revoke() or vhangup() doesn't break the ctty
- * association, we assume that we can successfully reopen the slave.
- *
- * This function doesn't check whether we actually acquired the ctty;
- * we assume that the caller will check that, or that it doesn't
- * matter in the particular case.
- */
-long
-pty_open_ctty(const char *slave, int *fd)
-{
-
-#ifdef ultrix
- /*
- * The Ultrix (and other BSD tty drivers) require the process
- * group to be zero, in order to acquire the new tty as a
- * controlling tty. This may actually belong in
- * ptyint_void_association().
- */
- (void) setpgrp(0, 0);
-#endif
- *fd = open(slave, O_RDWR);
- if (*fd < 0)
- return PTY_OPEN_SLAVE_OPENFAIL;
-#ifdef ultrix
- setpgrp(0, getpid());
-#endif
-
-#ifdef TIOCSCTTY
- ioctl(*fd, TIOCSCTTY, 0); /* Don't check return.*/
-#endif /* TIOCSTTY */
- return 0;
-}
+++ /dev/null
-/*
- * pty_open_slave: open slave side of terminal, clearing for use.
- *
- * Copyright 1995, 1996, 2001 by the Massachusetts Institute of
- * Technology.
- *
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that copyright notice and this permission
- * notice appear in supporting documentation, and that the name of
- * M.I.T. not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability
- * of this software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- */
-
-#include "com_err.h"
-#include "libpty.h"
-#include "pty-int.h"
-
-long
-pty_open_slave(const char *slave, int *fd)
-{
- int tmpfd;
- long retval;
-
- /* Sanity check. */
- if (slave == NULL || *slave == '\0')
- return PTY_OPEN_SLAVE_TOOSHORT;
-
- /* First, set up a new session and void old associations. */
- ptyint_void_association();
-
- /*
- * Make a first attempt at acquiring the ctty under certain
- * condisions. This is necessary for several reasons:
- *
- * Under Irix, if you open a pty slave and then close it, a
- * subsequent open of the slave will cause the master to read EOF.
- * To prevent this, don't close the first fd until we do the real
- * open following vhangup().
- *
- * Under Tru64 v5.0, if there isn't a fd open on the slave,
- * revoke() fails with ENOTTY, curiously enough.
- *
- * Anyway, sshd seems to make a practice of doing this.
- */
-#if defined(VHANG_FIRST) || defined(REVOKE_NEEDS_OPEN)
- retval = pty_open_ctty(slave, fd);
- if (retval)
- return retval;
- if (*fd < 0)
- return PTY_OPEN_SLAVE_OPENFAIL;
-#endif
-
- /* chmod and chown the slave. */
- if (chmod(slave, 0))
- return PTY_OPEN_SLAVE_CHMODFAIL;
- if (chown(slave, 0, 0) == -1)
- return PTY_OPEN_SLAVE_CHOWNFAIL;
-
-#ifdef HAVE_REVOKE
- if (revoke(slave) < 0) {
- return PTY_OPEN_SLAVE_REVOKEFAIL;
- }
-#else /* !HAVE_REVOKE */
-#ifdef VHANG_FIRST
- ptyint_vhangup();
-#endif
-#endif /* !HAVE_REVOKE */
-
- /* Open the pty for real. */
- retval = pty_open_ctty(slave, &tmpfd);
-#if defined(VHANG_FIRST) || defined(REVOKE_NEEDS_OPEN)
- close(*fd);
-#endif
- if (retval) {
- *fd = -1;
- return PTY_OPEN_SLAVE_OPENFAIL;
- }
- *fd = tmpfd;
- retval = pty_initialize_slave(*fd);
- if (retval)
- return retval;
- /* Make sure it's really our ctty. */
- tmpfd = open("/dev/tty", O_RDWR|O_NDELAY);
- if (tmpfd < 0) {
- close(*fd);
- *fd = -1;
- return PTY_OPEN_SLAVE_NOCTTY;
- }
- close(tmpfd);
- return 0;
-}
+++ /dev/null
-/* Includes needed by libpty*/
-#ifndef __PTY_INT_H__
-#include <pty_err.h>
-#include <sys/types.h>
-
-#if defined(_AIX) && defined(_THREAD_SAFE)
-/* On AIX 4.3.3, both utmp.h and utmpx.h will define struct utmp_data,
- and they'll define them differently, if _THREAD_SAFE is defined.
-
- We don't actually care about this library being thread-safe, but
- for various reasons we do use both versions of the interface at the
- moment.
-
- So trick the system headers into not "helping" us in that area.
-
- This is an ugly hack, and shouldn't be needed. Bleah. */
-# undef _THREAD_SAFE
-#endif
-
-#include "autoconf.h"
-
-#ifdef HAVE_UTMP_H
-#include <utmp.h>
-#endif
-#ifdef HAVE_UTMPX_H
-#include <utmpx.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef __SCO__
-#include <sys/unistd.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef HAVE_PTY_H
-#include <pty.h>
-#endif
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/file.h>
-#include <sys/time.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <pwd.h>
-
-#ifdef HAVE_SYS_LABEL_H
-/* only SunOS 4? */
-#include <sys/label.h>
-#include <sys/audit.h>
-#include <pwdadj.h>
-#endif
-
-#include <signal.h>
-
-#ifdef hpux
-#include <sys/ptyio.h>
-#endif
-#ifdef sysvimp
-#include <compat.h>
-#endif
-
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-#ifdef HAVE_STREAMS
-#include <sys/stream.h>
-#include <sys/stropts.h>
-#endif
-
-#if defined(POSIX_TERMIOS) && !defined(ultrix)
-#include <termios.h>
-#else
-#include <sgtty.h>
-#endif
-
-#include "port-sockets.h"
-#include <string.h>
-#include <sys/param.h>
-
-#ifdef HAVE_UTIL_H
-#include <util.h>
-#endif
-
-#ifdef HAVE_STREAMS
-/* krlogin doesn't test sys/tty... */
-#ifdef HAVE_SYS_TTY_H
-#include <sys/tty.h>
-#endif
-
-
-
-#ifdef HAVE_SYS_PTYVAR_H
-/* Solaris actually uses packet mode, so the real macros are needed too */
-#include <sys/ptyvar.h>
-#endif
-#endif
-
-#if defined(HAVE_VHANGUP) && !defined(OPEN_CTTY_ONLY_ONCE) \
- && !defined(HAVE_REVOKE)
-/*
- * Breaks under Ultrix and others where you cannot get controlling
- * terminal twice.
- */
-#define VHANG_FIRST
-#define VHANG_LAST
-#endif
-
-#if defined(NEED_GETUTMPX_PROTOTYPE)
-extern void getutmpx (const struct utmp *, struct utmpx *);
-#endif
-
-#if defined(NEED_REVOKE_PROTO)
-extern int revoke(const char *);
-#endif
-
-/* Internal functions */
-long ptyint_void_association(void);
-long ptyint_open_ctty (char *slave, int *fd);
-long ptyint_getpty_ext(int *, char *, int, int);
-#ifdef HAVE_SETUTXENT
-long ptyint_update_wtmpx(struct utmpx *utx);
-#endif
-#if !(defined(WTMPX_FILE) && defined(HAVE_UPDWTMPX)) \
- || !defined(HAVE_SETUXENT)
-long ptyint_update_wtmp(struct utmp *ut);
-#endif
-void ptyint_vhangup(void);
-
-#define __PTY_INT_H__
-#endif
+++ /dev/null
-#
-# util/pty/pty_err.et
-#
-# Copyright 1995 by the Massachusetts Institute of Technology.
-# All Rights Reserved.
-#
-#
-# Permission to use, copy, modify, and
-# distribute this software and its documentation for any purpose and
-# without fee is hereby granted, provided that the above copyright
-# notice appear in all copies and that both that copyright notice and
-# this permission notice appear in supporting documentation, and that
-# the name of M.I.T. not be used in advertising or publicity pertaining
-# to distribution of the software without specific, written prior
-# permission. Furthermore if you modify this software you must label
-# your software as modified software and not distribute it in such a
-# fashion that it might be confused with the original M.I.T. software.
-# M.I.T. makes no representations about the suitability of
-# this software for any purpose. It is provided "as is" without express
-# or implied warranty.
-#
-
-# libpty--pty handling error table
-
-error_table pty
-
-error_code PTY_GETPTY_STREAMS, "Failed to unlock or grant streams pty."
-
-error_code PTY_GETPTY_FSTAT, "fstat of master pty failed"
-
-error_code PTY_GETPTY_NOPTY, "All terminal ports in use"
-
-error_code PTY_GETPTY_SLAVE_TOOLONG, "buffer to hold slave pty name is too short"
-
-error_code PTY_OPEN_SLAVE_OPENFAIL, "Failed to open slave side of pty"
-error_code PTY_OPEN_SLAVE_CHMODFAIL, "Failed to chmod slave side of pty"
-
-error_code PTY_OPEN_SLAVE_NOCTTY, "Unable to set controlling terminal"
-error_code PTY_OPEN_SLAVE_CHOWNFAIL, "Failed to chown slave side of pty"
-error_code PTY_OPEN_SLAVE_LINE_PUSHFAIL, "Call to line_push failed to push streams on slave pty"
-
-error_code PTY_OPEN_SLAVE_PUSH_FAIL, "Failed to push stream on slave side of pty"
-
-
-error_code PTY_OPEN_SLAVE_REVOKEFAIL, "Failed to revoke slave side of pty"
-
-error_code PTY_UPDATE_UTMP_PROCTYPE_INVALID, "bad process type passed to pty_update_utmp"
-error_code PTY_OPEN_SLAVE_TOOSHORT, "Slave pty name is zero-length"
-
-end
+++ /dev/null
-/*
- * Copyright 2001 by the Massachusetts Institute of Technology.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that copyright notice and this permission
- * notice appear in supporting documentation, and that the name of
- * M.I.T. not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability
- * of this software for any purpose. It is provided "as is" without
- * express or implied warranty.
- */
-
-/*
- * A rant on the nature of pseudo-terminals:
- * -----------------------------------------
- *
- * Controlling terminals and job control:
- *
- * First, some explanation of job control and controlling terminals is
- * necessary for background. This discussion applies to hardwired
- * terminals as well as ptys. On most modern systems, all processes
- * belong to a process group. A process whose process group id (pgid)
- * is the sames as its pid is the process group leader of its process
- * group. Process groups belong to sessions. On a modern system, a
- * process that is not currently a process group leader may create a
- * new session by calling setsid(), which makes it a session leader as
- * well as a process group leader, and also removes any existing
- * controlling terminal (ctty) association. Only a session leader may
- * acquire a ctty. It's not clear how systems that don't have
- * setsid() handle ctty acquisition, though probably any process group
- * leader that doesn't have a ctty may acquire one that way.
- *
- * A terminal that is a ctty has an associated foreground process
- * group, which is a member of the terminal's associated session.
- * This process group gets read/write access to the terminal and will
- * receive terminal-generated signals (e.g. SIGINT, SIGTSTP). Process
- * groups belonging to the session but not in the foreground may get
- * signals that suspend them if they try to read/write from the ctty,
- * depending on various terminal settings.
- *
- * On many systems, the controlling process (the session leader
- * associated with a ctty) exiting will cause the session to lose its
- * ctty, even though some processes may continue to have open file
- * descriptors on the former ctty. It is possible for a process to
- * have no file descriptors open on its controlling tty, but to
- * reacquire such by opening /dev/tty, as long as its session still
- * has a ctty.
- *
- * On ptys in general:
- *
- * Ptys have a slave side and a master side. The slave side looks
- * like a hardwired serial line to the application that opens it;
- * usually, telnetd or rlogind, etc. opens the slave and hands it to
- * the login program as stdin/stdout/stderr. The master side usually
- * gets the actual network traffic written to/from it. Roughly, the
- * master and slave are two ends of a bidirectional pair of FIFOs,
- * though this can get complicated by other things.
- *
- * The master side of a pty is theoretically a single-open device.
- * This MUST be true on systems that have BSD-style ptys, since there
- * is usually no way to allocate an unused pty except by attempting to
- * open all the master pty nodes in the system.
- *
- * Often, but not always, the last close of a slave device will cause
- * the master to get an EOF. Closing the master device will sometimes
- * cause the foreground process group of the slave to get a SIGHUP,
- * but that may depend on terminal settings.
- *
- * BSD ptys:
- *
- * On a BSD-derived system, the master nodes are named like
- * /dev/ptyp0, and the slave nodes are named like /dev/ttyp0. The
- * last two characters are the variable ones, and a shell-glob type
- * pattern for a slave device is usually of the form
- * /dev/tty[p-z][0-9a-f], though variants are known to exist.
- *
- * System V cloning ptys:
- *
- * There is a cloning master device (usually /dev/ptmx, but the name
- * can vary) that gets opened. Each open of the cloning master
- * results in an open file descriptor of a unique master device. The
- * application calls ptsname() to find the pathname to the slave node.
- *
- * In theory, the slave side of the pty is locked out until the
- * process opening the master calls grantpt() to adjust permissions
- * and unlockpt() to unlock the slave. It turns out that Unix98
- * doesn't require that the slave actually get locked out, or that
- * unlockpt() actually do anything on such systems. At least AIX
- * allows the slave to be opened prior to calling unlockpt(), but most
- * other SysV-ish systems seem to actually lock out the slave.
- *
- * Pty security:
- *
- * It's not guaranteed on a BSD-ish system that a slave can't be
- * opened when the master isn't open. It's even possible to acquire
- * the slave as a ctty (!) if the open is done as non-blocking. It's
- * possible to open the master corresponding to an open slave, which
- * creates some security issues: once this master is open, data
- * written to the slave will actually pass to the master.
- *
- * On a SysV-ish system, the close of the master will invalidate any
- * open file descriptors on the slave.
- *
- * In general, there are two functions that can be used to "clean" a
- * pty slave, revoke() and vhangup(). revoke() will invalidate all
- * file descriptors open on a particular pathname (often this only
- * works on terminal devices), usually by invalidating the underlying
- * vnode. vhangup() will send a SIGHUP to the foreground process
- * group of the control terminal. On many systems, it also has
- * revoke() semantics.
- *
- * If a process acquires a controlling terminal in order to perform a
- * vhangup(), the reopen of the controlling terminal after the
- * vhangup() call should be done prior to the close of the file
- * descriptor used to initially acquire the controlling terminal,
- * since that will likely prevent the process on the master side from
- * reading a spurious EOF due to all file descriptors to the slave
- * being closed.
- *
- * Known quirks of various OSes:
- *
- * AIX 4.3.3:
- *
- * If the environment variable XPG_SUS_ENV is not equal to "ON", then
- * it's possible to open the slave prior to calling unlockpt().
- */
-
-/*
- * NOTE: this program will get reworked at some point to actually test
- * passing of data between master and slave, and to do general cleanup.
- *
- * This is rather complex, so it bears some explanation.
- *
- * There are multiple child processes and a parent process. These
- * communicate via pipes (which we assume here to be unidirectional).
- * The pipes are:
- *
- * pp1 - parent -> any children
- *
- * p1p - any children -> parent
- *
- * p21 - only child2 -> child1
- *
- * A parent process will acquire a pty master and slave via
- * pty_getpty(). It will then fork a process, child1. It then does a
- * waitpid() for child1, and then writes to child2 via syncpipe pp1.
- * It then reads from child3 via syncpipe p1p, then closes the
- * master. It writes to child3 via syncpipe pp1 to indicate that it
- * has closed the master. It then reads from child3 via syncpipe p1p
- * and exits with a value appropriate to what it read from child3.
- *
- * child1 will acquire the slave as its ctty and fork child2; child1
- * will exit once it reads from the syncpipe p21 from child2.
- *
- * child2 will set a signal handler for SIGHUP and then write to
- * child1 via syncpipe p21 to indicate that child2 has set up the
- * handler. It will then read from the syncpipe pp1 from the parent
- * to confirm that the parent has seen child1 exit, and then checks to
- * see if it still has a ctty. Under Unix98, and likely earlier
- * System V derivatives, the exiting of the session leader associated
- * with a ctty (in this case, child1) will cause the entire session to
- * lose its ctty.
- *
- * child2 will then check to see if it can reopen the slave, and
- * whether it has a ctty after reopening it. This should fail on most
- * systems.
- *
- * child2 will then fork child3 and immediately exit.
- *
- * child3 will write to the syncpipe p1p and read from the syncpipe
- * pp1. It will then check if it has a ctty and then attempt to
- * reopen the slave. This should fail. It will then write to the
- * parent via syncpipe p1p and exit.
- *
- * If this doesn't fail, child3 will attempt to write to the open
- * slave fd. This should fail unless a prior call to revoke(),
- * etc. failed due to lack of permissions, e.g. NetBSD when running as
- * non-root.
- */
-
-#include "com_err.h"
-#include "libpty.h"
-#include "pty-int.h"
-#include <sys/wait.h>
-#include <stdlib.h>
-
-char *prog;
-int masterfd, slavefd;
-char slave[64], slave2[64];
-pid_t pid1, pid2, pid3;
-int status1, status2;
-int pp1[2], p1p[2], p21[2];
-
-void handler(int);
-void rdsync(int, int *, const char *);
-void wrsync(int, int, const char *);
-void testctty(const char *);
-void testex(int, const char *);
-void testwr(int, const char *);
-void child1(void);
-void child2(void);
-void child3(void);
-
-void
-handler(int sig)
-{
- printf("pid %ld got signal %d\n", (long)getpid(), sig);
- fflush(stdout);
- return;
-}
-
-void
-rdsync(int fd, int *status, const char *caller)
-{
- int n;
- char c;
-
-#if 0
- printf("rdsync: %s: starting\n", caller);
- fflush(stdout);
-#endif
- while ((n = read(fd, &c, 1)) < 0) {
- if (errno != EINTR) {
- fprintf(stderr, "rdsync: %s", caller);
- perror("");
- exit(1);
- } else {
- printf("rdsync: %s: got EINTR; looping\n", caller);
- fflush(stdout);
- }
- }
- if (!n) {
- fprintf(stderr, "rdsync: %s: unexpected EOF\n", caller);
- exit(1);
- }
- printf("rdsync: %s: got sync byte\n", caller);
- fflush(stdout);
- if (status != NULL)
- *status = c;
-}
-
-void
-wrsync(int fd, int status, const char *caller)
-{
- int n;
- char c;
-
- c = status;
- while ((n = write(fd, &c, 1)) < 0) {
- if (errno != EINTR) {
- fprintf(stderr, "wrsync: %s", caller);
- perror("");
- exit(1);
- } else {
- printf("wrsync: %s: got EINTR; looping\n", caller);
- fflush(stdout);
- }
- }
-#if 0
- printf("wrsync: %s: sent sync byte\n", caller);
-#endif
- fflush(stdout);
-}
-
-void
-testctty(const char *caller)
-{
- int fd;
-
- fd = open("/dev/tty", O_RDWR|O_NONBLOCK);
- if (fd < 0) {
- printf("%s: no ctty\n", caller);
- } else {
- printf("%s: have ctty\n", caller);
- }
-}
-
-void
-testex(int fd, const char *caller)
-{
- fd_set rfds, xfds;
- struct timeval timeout;
- int n;
- char c;
-
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
- FD_ZERO(&rfds);
- FD_ZERO(&xfds);
- FD_SET(fd, &rfds);
- FD_SET(fd, &xfds);
-
- n = select(fd + 1, &rfds, NULL, &xfds, &timeout);
- if (n < 0) {
- fprintf(stderr, "testex: %s: ", caller);
- perror("select");
- }
- if (n) {
- if (FD_ISSET(fd, &rfds) || FD_ISSET(fd, &xfds)) {
- n = read(fd, &c, 1);
- if (!n) {
- printf("testex: %s: got EOF\n", caller);
- fflush(stdout);
- return;
- } else if (n == -1) {
- printf("testex: %s: got errno=%ld (%s)\n",
- caller, (long)errno, strerror(errno));
- } else {
- printf("testex: %s: read 1 byte!?\n", caller);
- }
- }
- } else {
- printf("testex: %s: no exceptions or readable fds\n", caller);
- }
-}
-
-void
-testwr(int fd, const char *caller)
-{
- fd_set wfds;
- struct timeval timeout;
- int n;
-
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
- FD_ZERO(&wfds);
- FD_SET(fd, &wfds);
-
- n = select(fd + 1, NULL, &wfds, NULL, &timeout);
- if (n < 0) {
- fprintf(stderr, "testwr: %s: ", caller);
- perror("select");
- }
- if (n) {
- if (FD_ISSET(fd, &wfds)) {
- printf("testwr: %s: is writable\n", caller);
- fflush(stdout);
- }
- }
-}
-
-
-void
-child3(void)
-{
- int n;
-
- ptyint_void_association();
- slavefd = open(slave, O_RDWR|O_NONBLOCK);
- if (slavefd < 0) {
- wrsync(p1p[1], 1, "[02] child3->parent");
- printf("child3: failed reopen of slave\n");
- fflush(stdout);
- exit(1);
- }
-#ifdef TIOCSCTTY
- ioctl(slavefd, TIOCSCTTY, 0);
-#endif
-
- printf("child3: reopened slave\n");
- testctty("child3: after reopen of slave");
- testwr(slavefd, "child3: after reopen of slave");
- testex(slavefd, "child3: after reopen of slave");
- close(slavefd);
- testctty("child3: after close of slave");
-
- /*
- * Sync for parent to close master.
- */
- wrsync(p1p[1], 0, "[02] child3->parent");
- rdsync(pp1[0], NULL, "[03] parent->child3");
-
- testctty("child3: after close of master");
- printf("child3: attempting reopen of slave\n");
- fflush(stdout);
- slavefd = open(slave, O_RDWR|O_NONBLOCK);
- if (slavefd < 0) {
- printf("child3: failed reopen of slave after master close: "
- "errno=%ld (%s)\n", (long)errno, strerror(errno));
- wrsync(p1p[1], 0, "[04] child3->parent");
- fflush(stdout);
- exit(0);
- }
- if (fcntl(slavefd, F_SETFL, 0) == -1) {
- perror("child3: fcntl");
- wrsync(p1p[1], 2, "[04] child3->parent");
- exit(1);
- }
-#ifdef TIOCSCTTY
- ioctl(slavefd, TIOCSCTTY, 0);
-#endif
- printf("child3: reopened slave after master close\n");
- testctty("child3: after reopen of slave after master close");
- testwr(slavefd, "child3: after reopen of slave after master close");
- testex(slavefd, "child3: after reopen of slave after master close");
- n = write(slavefd, "foo", 4);
- if (n < 0) {
- printf("child3: writing to slave of closed master: errno=%ld (%s)\n",
- (long)errno, strerror(errno));
- wrsync(p1p[1], 1, "[04] child3->parent");
- } else {
- printf("child3: wrote %d byes to slave of closed master\n", n);
- fflush(stdout);
- wrsync(p1p[1], 2, "[04] child3->parent");
- }
- rdsync(pp1[0], NULL, "[05] parent->child3");
- testex(slavefd, "child3: after parent reopen of master");
- testwr(slavefd, "child3: after parent reopen of master");
- fflush(stdout);
- n = write(slavefd, "bar", 4);
- if (n < 0) {
- perror("child3: writing to slave");
- } else {
- printf("child3: wrote %d bytes to slave\n", n);
- fflush(stdout);
- }
- wrsync(p1p[1], 0, "[06] child3->parent");
- rdsync(pp1[0], NULL, "[07] parent->child3");
- wrsync(p1p[1], 0, "[08] child3->parent");
- exit(0);
-}
-
-void
-child2(void)
-{
- struct sigaction sa;
-
- close(p21[0]);
- setpgid(0, 0);
- sa.sa_flags = 0;
- sigemptyset(&sa.sa_mask);
- sa.sa_handler = handler;
- if (sigaction(SIGHUP, &sa, NULL) < 0) {
- wrsync(p21[1], 1, "[00] child2->child1");
- perror("child2: sigaction");
- fflush(stdout);
- exit(1);
- }
- printf("child2: set up signal handler\n");
- testctty("child2: after start");
- testwr(slavefd, "child2: after start");
- wrsync(p21[1], 0, "[00] child2->child1");
- rdsync(pp1[0], NULL, "[01] parent->child2");
-
- testctty("child2: after child1 exit");
- testex(slavefd, "child2: after child1 exit");
- testwr(slavefd, "child2: after child1 exit");
- close(slavefd);
- testctty("child2: after close of slavefd");
- slavefd = open(slave, O_RDWR|O_NONBLOCK);
- if (slavefd < 0) {
- wrsync(p1p[1], 1, "[02] child2->parent");
- printf("child2: failed reopen of slave\n");
- fflush(stdout);
- exit(1);
- }
-#ifdef TIOCSCTTY
- ioctl(slavefd, TIOCSCTTY, 0);
-#endif
- printf("child2: reopened slave\n");
- testctty("child2: after reopen of slave");
- fflush(stdout);
- close(slavefd);
- pid3 = fork();
- if (!pid3) {
- child3();
- } else if (pid3 == -1) {
- wrsync(p1p[1], 1, "[02] child2->parent");
- perror("child2: fork of child3");
- exit(1);
- }
- printf("child2: forked child3=%ld\n", (long)pid3);
- fflush(stdout);
- exit(0);
-}
-
-void
-child1(void)
-{
- int status;
-
-#if 0
- setuid(1);
-#endif
- close(pp1[1]);
- close(p1p[0]);
- close(masterfd);
- ptyint_void_association();
- slavefd = open(slave, O_RDWR|O_NONBLOCK);
- if (slavefd < 0) {
- perror("child1: open slave");
- exit(1);
- }
-#ifdef TIOCSCTTY
- ioctl(slavefd, TIOCSCTTY, 0);
-#endif
-
- printf("child1: opened slave\n");
- testctty("child1: after slave open");
-
- if (pipe(p21) < 0) {
- perror("pipe child2->child1");
- exit(1);
- }
- pid2 = fork();
- if (!pid2) {
- child2();
- } else if (pid2 == -1) {
- perror("child1: fork child2");
- exit(1);
- }
- close(p21[1]);
- printf("child1: forked child2=%ld\n", (long)pid2);
- fflush(stdout);
- rdsync(p21[0], &status, "[00] child2->child1");
- exit(status);
-}
-
-int
-main(int argc, char *argv[])
-{
- long retval;
- int status;
- char buf[4];
- int n;
-
- prog = argv[0];
-
- printf("parent: pid=%ld\n", (long)getpid());
-
- retval = ptyint_getpty_ext(&masterfd, slave, sizeof(slave), 0);
-
- if (retval) {
- com_err(prog, retval, "open master");
- exit(1);
- }
-#if 0
- chown(slave, 1, -1);
-#endif
- printf("parent: master opened; slave=%s\n", slave);
- fflush(stdout);
-
-#if defined(HAVE_GRANTPT) && defined(HAVE_STREAMS)
-#ifdef O_NOCTTY
- printf("parent: attempting to open slave before unlockpt\n");
- fflush(stdout);
- slavefd = open(slave, O_RDWR|O_NONBLOCK|O_NOCTTY);
- if (slavefd < 0) {
- printf("parent: failed slave open before unlockpt errno=%ld (%s)\n",
- (long)errno, strerror(errno));
- } else {
- printf("parent: WARNING: "
- "succeeded in opening slave before unlockpt\n");
- }
- close(slavefd);
-#endif
- if (grantpt(masterfd) < 0) {
- perror("parent: grantpt");
- exit(1);
- }
- if (unlockpt(masterfd) < 0) {
- perror("parent: unlockpt");
- exit(1);
- }
-#endif /* HAVE_GRANTPT && HAVE_STREAMS */
-
- if (pipe(pp1) < 0) {
- perror("pipe parent->child1");
- exit(1);
- }
- if (pipe(p1p) < 0) {
- perror("pipe child1->parent");
- exit(1);
- }
-
- pid1 = fork();
- if (!pid1) {
- child1();
- } else if (pid1 == -1) {
- perror("fork of child1");
- exit(1);
- }
- printf("parent: forked child1=%ld\n", (long)pid1);
- fflush(stdout);
- if (waitpid(pid1, &status1, 0) < 0) {
- perror("waitpid for child1");
- exit(1);
- }
- printf("parent: child1 exited, status=%d\n", status1);
- if (status1)
- exit(status1);
-
- wrsync(pp1[1], 0, "[01] parent->child2");
- rdsync(p1p[0], &status, "[02] child3->parent");
- if (status) {
- fprintf(stderr, "child2 or child3 got an error\n");
- exit(1);
- }
-
- printf("parent: closing master\n");
- fflush(stdout);
- close(masterfd);
- chmod(slave, 0666);
- printf("parent: closed master\n");
- wrsync(pp1[1], 0, "[03] parent->child3");
-
- rdsync(p1p[0], &status, "[04] child3->parent");
- switch (status) {
- case 1:
- break;
- case 0:
- exit(0);
- default:
- fprintf(stderr, "child3 got an error\n");
- fflush(stdout);
- exit(1);
- }
-
- retval = pty_getpty(&masterfd, slave2, sizeof(slave2));
- printf("parent: new master opened; slave=%s\n", slave2);
-#if 0
-#ifdef HAVE_REVOKE
- printf("parent: revoking\n");
- revoke(slave2);
-#endif
-#endif
- fflush(stdout);
- wrsync(pp1[1], 0, "[05] parent->child3");
- rdsync(p1p[0], NULL, "[06] child3->parent");
-
- n = read(masterfd, buf, 4);
- if (n < 0) {
- perror("parent: reading from master");
- } else {
- printf("parent: read %d bytes (%.*s) from master\n", n, n, buf);
- fflush(stdout);
- }
- chmod(slave2, 0666);
- close(masterfd);
- wrsync(pp1[1], 0, "[07] parent->child3");
- rdsync(p1p[0], NULL, "[08] child3->parent");
- fflush(stdout);
- exit(0);
-}
+++ /dev/null
-/*
- * pty_make_sane_hostname: Make a sane hostname from an IP address.
- * This returns allocated memory!
- *
- * Copyright 1999, 2000, 2001 by the Massachusetts Institute of
- * Technology.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that copyright notice and this permission
- * notice appear in supporting documentation, and that the name of
- * M.I.T. not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability
- * of this software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- */
-#include "com_err.h"
-#include "pty-int.h"
-#include <sys/socket.h>
-#include "libpty.h"
-#include <arpa/inet.h>
-
-#include "socket-utils.h"
-#include "fake-addrinfo.h"
-
-static void
-downcase (char *s)
-{
- for (; *s != '\0'; s++)
- *s = tolower ((int) *s);
-}
-
-long
-pty_make_sane_hostname(const struct sockaddr *addr, int maxlen,
- int strip_ldomain, int always_ipaddr, char **out)
-{
- struct addrinfo *ai = 0;
- char addrbuf[NI_MAXHOST];
-#ifdef HAVE_STRUCT_UTMP_UT_HOST
- struct utmp ut;
-#else
- struct utmpx utx;
-#endif
- char *cp, *domain;
- char lhost[MAXHOSTNAMELEN];
- size_t ut_host_len;
-
- /* Note that on some systems (e.g., AIX 4.3.3), we may get an IPv6
- address such as ::FFFF:18.18.1.71 when an IPv4 connection comes
- in. That's okay; at least on AIX, getnameinfo will deal with
- that properly. */
-
- *out = NULL;
- if (maxlen && maxlen < 16)
- /* assume they meant 16, otherwise IPv4 addr won't fit */
- maxlen = 16;
-#ifdef HAVE_STRUCT_UTMP_UT_HOST
- ut_host_len = sizeof (ut.ut_host);
-#else
- ut_host_len = sizeof (utx.ut_host);
-#endif
- if (maxlen == 0)
- maxlen = ut_host_len;
- *out = malloc(ut_host_len);
- if (*out == NULL)
- return ENOMEM;
-
- if (always_ipaddr) {
- use_ipaddr:
- if (getnameinfo (addr, socklen (addr), addrbuf, sizeof (addrbuf),
- (char *)0, 0, NI_NUMERICHOST) == 0)
- strncpy(*out, addrbuf, ut_host_len);
- else
- strncpy(*out, "??", ut_host_len);
- (*out)[ut_host_len - 1] = '\0';
- return 0;
- }
-
- /* If we didn't want to chop off the local domain, this would be
- much simpler -- just a single getnameinfo call and a strncpy. */
- if (getnameinfo(addr, socklen (addr), addrbuf, sizeof (addrbuf),
- (char *) NULL, 0, NI_NAMEREQD) != 0)
- goto use_ipaddr;
- downcase (addrbuf);
- if (strip_ldomain) {
- struct addrinfo hints;
- (void) gethostname(lhost, sizeof (lhost));
- memset (&hints, 0, sizeof (hints));
- hints.ai_family = PF_UNSPEC;
- hints.ai_flags = AI_CANONNAME;
- if (getaddrinfo(lhost, (char *)NULL, &hints, &ai) == 0
- && ai != NULL) {
- if (ai->ai_canonname != NULL) {
- downcase (ai->ai_canonname);
- domain = strchr (ai->ai_canonname, '.');
- if (domain != NULL) {
- cp = strstr (addrbuf, domain);
- if (cp != NULL)
- *cp = '\0';
- }
- }
- freeaddrinfo (ai);
- }
- }
- strncpy(*out, addrbuf, ut_host_len);
- (*out)[ut_host_len - 1] = '\0';
- if (strlen(*out) >= maxlen)
- goto use_ipaddr;
- return 0;
-}
+++ /dev/null
-/*
- * pty_update_utmp: Update or create a utmp entry
- *
- * Copyright 1995, 2001 by the Massachusetts Institute of Technology.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that copyright notice and this permission
- * notice appear in supporting documentation, and that the name of
- * M.I.T. not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability
- * of this software for any purpose. It is provided "as is" without
- * express or implied warranty.
- */
-
-/*
- * Rant about the historical vagaries of utmp:
- * -------------------------------------------
- *
- * There exist many subtly incompatible incarnations of utmp, ranging
- * from BSD to System V to Unix98 and everywhere in between. This
- * rant attempts to collect in one place as much knowledge as possible
- * about this portability nightmare.
- *
- * BSD:
- * ----
- *
- * The simplest (and earliest? possibly dating back to Version 7...)
- * case is 4.x BSD utmp/wtmp. There are no auxiliary files. There is
- * only a struct utmp, declared in utmp.h. Its contents usually
- * include:
- *
- * char ut_line[]
- * char ut_name[]
- * char ut_host[]
- * long ut_time
- *
- * The meanings of these fields follow their names reasonbly well.
- * The ut_line field usually is the pathname of the tty device
- * associated with the login, with the leading "/dev/" stripped off.
- *
- * It is believed that ut_host is nul-terminated, while the other
- * strings are merely nul-padded.
- *
- * Generally, ut_name is an empty string for a logout record in both
- * utmp and wtmp. For entries made by the window system or other
- * terminal emulation stuff, ut_host is an empty string (at least
- * under SunOS 4.x, it seems). The macro nonuser() is used to
- * determine this if a utmp entry is made by the window system on at
- * least SunOS 4.x.
- *
- * The native login never clears its own utmp entry or writes its own
- * logout record; its parent (one of init, rlogind, telnetd, etc.)
- * should handle that. In theory, getty could do that, but getty
- * usually doesn't fork to exec login.
- *
- * Old (c. 1984) System V:
- * -----------------------
- *
- * This is partially conjecture, based on some reading of
- * /usr/xpg2include/utmp.h on a SunOS 4.x system. There appears to
- * only be a struct utmp, declared in utmp.h. It is likely used for
- * both utmp and wtmp files. It is quite likely that the utmp is only
- * supposed to be accessed via the getutline()/pututline() API. The
- * contents of struct utmp seem to include:
- *
- * char ut_user[]
- * char ut_id[]
- * char ut_line[]
- * short ut_pid
- * short ut_type
- * struct exit_status ut_exit
- * time_t ut_time
- *
- * On these systems, ut_name is often #define'ed to be ut_user to be
- * somewhat compatible with the BSD-style utmp. Note that there is
- * not necessarily a ut_host field in this utmp structure.
- *
- * The ut_id field bears some explanation. The systems that use this
- * style of utmp also use a sysV-ish init, which starts processes out
- * of /etc/inittab rather than /etc/ttys, and has the concept of
- * runlevels. The first field in each line of /etc/inittab contains a
- * unique ID field. init probably gets really confused if there are
- * conflicts here. Every process that init starts gets its own entry
- * written to utmp.
- *
- * It is possible for multiple entries to have the same ut_line but
- * different ut_id values, since the sysadmin will be responsible for
- * assigning values to ut_id. Usually, ut_id is four characters,
- * while the permissible unique ID values for entries in /etc/inittab
- * are constrained to two characters, but this is not always the
- * case. In the case where we are emulating the vendor's login
- * program and being run out of getty, we need to account for which
- * value of ut_id was used by the getty, since pututline() will search
- * based on ut_id and not ut_line for some reason.
- *
- * The ut_pid and ut_type fields are used for bookkeeping by init.
- * The ut_type field gets the value INIT_PROCESS for processes started
- * by init. It gets the value LOGIN_PROCESS if it is a process that
- * is prompting for a login name, and it gets the value USER_PROCESS
- * for an actual valid login. When the process dies, either init
- * cleans up after it and records a DEAD_PROCESS entry in utmp, or the
- * process itself does so. It's not completely clear which actually
- * happens, though it is quite possible that init only cleans up after
- * processes that it starts itself.
- *
- * Other values of ut_type exist; they're largely internal bookkeeping
- * for init's runlevels and such, and don't really interest this
- * library at all.
- *
- * The ut_exit field contains the following members:
- *
- * short e_termination
- * short e_exit
- *
- * It is not clear how these values are used; presumably they record
- * the process termination status of dead processes.
- *
- * There is no uniform API for manipulating wtmp on systems that use
- * this sort of utmp structure; it can be assumed that the structure
- * can be directly written to the wtmp file.
- *
- * Unix98:
- * -------
- *
- * This description also likely applies to later System V derivatives
- * as well as systems conforming to earlier X/Open standards such as
- * XPG4. There is a new header, utmpx.h, which defines a struct utmpx
- * and a new getutxline()/pututxline() API for accessing it. Some
- * systems actually have a utmpx file on disk; others use the utmpx
- * API to access a file named utmp, just to further confuse matters.
- *
- * The utmpx structure is guaranteed (by Unix98) to contain at least
- * the following:
- *
- * char ut_user[]
- * char ut_line[]
- * char ut_id[]
- * pid_t ut_pid
- * short ut_type
- * struct timeval ut_tv
- *
- * It is not guaranteed to contain, but often does contain, the
- * following:
- *
- * char ut_host[]
- * int ut_syslen
- * int ut_session
- * struct exit_status ut_exit
- *
- * The ut_syslen field, on systems that contain it, contains the
- * number of significant characters in ut_host, including the
- * terminating nul character.
- *
- * The main difference between this struct utmpx and the struct utmp
- * used by early sysV derivatives is the change from a time_t or long
- * for ut_time to a struct timeval for ut_tv.
- *
- * Comments in various header files imply that ut_session is used for
- * window systems, but it's not clear how. Perhaps it contains the
- * session ID of the session running the window system, e.g. the xdm
- * or X server on an X11 system.
- *
- * Most of the description of the earlier sysV format probably applies
- * here, with suitable changes of names. On systems that maintain
- * utmpx and utmp files in parallel, it is assumed that using the
- * pututxline() API is sufficient to keep them in sync. There are no
- * known counterexamples to this.
- *
- * Nevertheless, there are, on some systems, API functions getutmp()
- * and getutmpx() that appear to convert from struct utmpx to struct
- * utmp and vice versa. This could be useful when there is a wtmp
- * file but not a corresponding wtmpx file.
- *
- * Incidentally, ut_exit is sometimes present in the struct utmp but
- * not the struct utmpx for a given system. Sometimes, it exists in
- * both, but contains differently named members. It's probably one of
- * the least portable pieces in this whole mess.
- *
- * Known Quirks of Specific OSes:
- * ------------------------------
- *
- * Solaris 2.x:
- *
- * Has utmpd, which will automatically clean up utmpx, utmp, wtmpx,
- * wtmp after process termination, provided that pututxline() was
- * used.
- *
- * Solaris 8 seems to have a bug in utmpname() that causes
- * garbage filenames to be generated. Solaris 7 (and possibly Solaris
- * 8) have a bug in utmpxname() that prevents them from looking at
- * anything other than /var/adm/utmpx, it seems. For some reason,
- * though, utmpname() goes and looks at the corresponding utmpx file.
- *
- * Solaris 7 (and may be 8 as well) has a bug in pututline() that
- * interacts badly with prior invocation of getutline(): if
- * getutline() finds an entry, calling pututline() without first
- * calling setutent() will overwrite the record following the one that
- * was intended.
- *
- * Also, ut_exit in utmpx contains ut_e_termination and
- * ut_e_exit (otherwise it contains the expected e_termination and
- * e_exit) only if _XPG4_2 is defined and __EXTENSIONS__ is not, which
- * is not a compilation environment we're likely to encourage. The
- * ut_exit field of utmp contains the expected fields.
- *
- * If _XPG4_2 is not defined or __EXTENSIONS__ is defined, the
- * functions getutmp(), getutmpx(), updwtmp(), and updwtmpx() are
- * available, as well as the undocumented functions makeutx() and
- * modutx().
- *
- * All the files utmp, utmpx, wtmp, and wtmpx exist.
- *
- * HP-UX 10.x:
- *
- * There is a curious interaction between how we allocate pty masters
- * and how ttyname() works. It seems that if /dev/ptmx/clone is
- * opened, a call to ptsname() on the master fd gets a filename of the
- * form /dev/pty/tty[pqrs][0-9a-f], while ttyname() called on a fd
- * opened with that filename returns a filename of the form
- * /dev/tty[pqrs][0-9a-f] instead. These two filenames are actually
- * hardlinks to the same special device node, so it shouldn't be a
- * security problem.
- *
- * We can't call ttyname() in the parent because it would involve
- * possibly acquiring a controlling terminal (which would be
- * potentially problematic), so we have to resort to some trickery in
- * order to ensure that the ut_line in the wtmp logout and login
- * records match. If they don't match, various utilities such as last
- * will get confused. Of course it's likely an OS bug that ttyname()
- * and ptsname() are inconsistent in this way, but it's one that isn't
- * too painful to work around.
- *
- * It seems that the HP-UX native telnetd has problems similar to ours
- * in this area, though it manages to write the correct logout record
- * to wtmp somehow. It probably does basically what we do here:
- * search for a record with a matching ut_pid and grab its ut_line for
- * writing into the logout record. Interestingly enough, its
- * LOGIN_PROCESS record is of the form pty/tty[pqrs][0-9][a-f].
- *
- * Uses four-character unique IDs for /etc/inittab, which means that
- * programs not running out of init should use two-character ut_id
- * fields to avoid conflict.
- *
- * In utmpx, ut_exit contains __e_termination and __e_exit, while
- * ut_exit in utmp contains the expected fields.
- *
- * There is no wtmpx file, despite there being utmp and utmpx files.
- *
- * HP-UX 11.23:
- *
- * In addition to other HP-UX issues, 11.23 includes yet another utmp
- * management interface in utmps.h. This interface updates a umtpd
- * daemon which then manages local files. Directly accessing the files
- * through the existing, yet deprecated, utmp.h interface results in
- * nothing.
- *
- * Irix 6.x:
- *
- * In utmpx, ut_exit contains __e_termination and __e_exit, which get
- * #define aliases e_termination and e_exit if _NO_XOPEN4 is true.
- * Curiously enough, utmp.h declares ut_exit to have __e_termination
- * and __e_exit as well, but does #define e_termination
- * __e_termination, etc. if another header (utmpx.h) hasn't already
- * declared struct __exit_status. It seems that the default
- * compilation environment has the effect of making _NO_XOPEN4 true
- * though.
- *
- * If _NO_XOPEN4 is true, getutmp(), getutmpx(), updwtmp(), and
- * updwtmpx() are available, as well as the undocumented functions
- * makeutx() and modutx().
- *
- * All the files utmp, utmpx, wtmp, and wtmpx exist.
- *
- * Tru64 Unix 4.x:
- *
- * In utmpx, ut_exit contains ut_termination and ut_exit, while utmp
- * contains the expected fields. The files utmp and wtmp seem to
- * exist, but not utmpx or wtmpx.
- *
- * When writing a logout entry, the presence of a non-empty username
- * confuses last.
- *
- * AIX 4.3.x:
- *
- * The ut_exit field seems to exist in utmp, but not utmpx. The files
- * utmp and wtmp seem to exist, but not utmpx, or wtmpx.
- *
- * libpty Implementation Decisions:
- * --------------------------------
- *
- * We choose to use the pututxline() whenever possible, falling back
- * to pututline() and calling write() to write out struct utmp if
- * necessary. The code to handle pututxline() and pututline() is
- * rather similar, since the structure members are quite similar, and
- * we make the assumption that it will never be necessary to call
- * both. This allows us to avoid duplicating lots of code, by means
- * of some slightly demented macros.
- *
- * If neither pututxline() nor pututline() are available, we assume
- * BSD-style utmp files and behave accordingly, writing the structure
- * out to disk ourselves.
- *
- * On systems where updwtmpx() or updwtmp() are available, we use
- * those to update the wtmpx or wtmp file. When they're not
- * available, we write the utmpx or utmp structure out to disk
- * ourselves, though sometimes conversion from utmpx to utmp format is
- * needed.
- *
- * We assume that at logout the system is ok with with having an empty
- * username both in utmp and wtmp.
- */
-
-#include "com_err.h"
-#include "libpty.h"
-#include "pty-int.h"
-#include "k5-platform.h"
-
-#if !defined(UTMP_FILE) && defined(_PATH_UTMP)
-#define UTMP_FILE _PATH_UTMP
-#endif
-
-/* if it is *still* missing, assume SunOS */
-#ifndef UTMP_FILE
-#define UTMP_FILE "/etc/utmp"
-#endif
-
-/*
- * The following grossness exists to avoid duplicating lots of code
- * between the cases where we have an old-style sysV utmp and where we
- * have a modern (Unix98 or XPG4) utmpx, or the new (hp-ux 11.23) utmps.
- * See the above history rant for further explanation.
- */
-#if defined(HAVE_SETUTXENT) || defined(HAVE_SETUTENT) || defined(HAVE_SETUTSENT)
-#ifdef HAVE_SETUTSENT
-#include <utmps.h>
-#define PTY_STRUCT_UTMPX struct utmps
-#define PTY_SETUTXENT setutsent
-#define PTY_GETUTXENT GETUTSENT
-#define PTY_GETUTXLINE GETUTSLINE
-#define PTY_PUTUTXLINE PUTUTSLINE
-#define PTY_ENDUTXENT endutsent
-#else
-#ifdef HAVE_SETUTXENT
-#define PTY_STRUCT_UTMPX struct utmpx
-#define PTY_SETUTXENT setutxent
-#define PTY_GETUTXENT getutxent
-#define PTY_GETUTXLINE getutxline
-#define PTY_PUTUTXLINE pututxline
-#define PTY_ENDUTXENT endutxent
-#else
-#define PTY_STRUCT_UTMPX struct utmp
-#define PTY_SETUTXENT setutent
-#define PTY_GETUTXENT getutent
-#define PTY_GETUTXLINE getutline
-#define PTY_PUTUTXLINE pututline
-#define PTY_ENDUTXENT endutent
-#endif
-#endif
-static int better(const PTY_STRUCT_UTMPX *, const PTY_STRUCT_UTMPX *,
- const PTY_STRUCT_UTMPX *);
-static int match_pid(const PTY_STRUCT_UTMPX *,
- const PTY_STRUCT_UTMPX *);
-static PTY_STRUCT_UTMPX *best_utxent(const PTY_STRUCT_UTMPX *);
-
-/*
- * Utility function to determine whether A is a better match for
- * SEARCH than B. Should only be called by best_utxent().
- */
-static int
-better(const PTY_STRUCT_UTMPX *search,
- const PTY_STRUCT_UTMPX *a, const PTY_STRUCT_UTMPX *b)
-{
- if (strncmp(search->ut_id, b->ut_id, sizeof(b->ut_id))) {
- if (!strncmp(search->ut_id, a->ut_id, sizeof(a->ut_id))) {
- return 1;
- }
- }
-
- if (strncmp(a->ut_id, b->ut_id, sizeof(b->ut_id))) {
- /* Got different UT_IDs; find the right one. */
- if (!strncmp(search->ut_id, b->ut_id, sizeof(b->ut_id))) {
- /* Old entry already matches; use it. */
- return 0;
- }
- if (a->ut_type == LOGIN_PROCESS
- && b->ut_type != LOGIN_PROCESS) {
- /* Prefer LOGIN_PROCESS */
- return 1;
- }
- if (search->ut_type == DEAD_PROCESS
- && a->ut_type == USER_PROCESS
- && b->ut_type != USER_PROCESS) {
- /*
- * Try USER_PROCESS if we're entering a DEAD_PROCESS.
- */
- return 1;
- }
- return 0;
- } else {
- /*
- * Bad juju. We shouldn't get two entries with identical
- * ut_id fields for the same value of ut_line. pututxline()
- * will probably pick the first entry, in spite of the strange
- * state of utmpx, if we rewind with setutxent() first.
- *
- * For now, return 0, to force the earlier entry to be used.
- */
- return 0;
- }
-}
-
-static int
-match_pid(const PTY_STRUCT_UTMPX *search, const PTY_STRUCT_UTMPX *u)
-{
- if (u->ut_type != LOGIN_PROCESS && u->ut_type != USER_PROCESS)
- return 0;
- if (u->ut_pid == search->ut_pid) {
- /*
- * One of ut_line or ut_id should match, else some nastiness
- * may result. We can fall back to searching by ut_line if
- * need be. This should only really break if we're login.krb5
- * running out of getty, or we're cleaning up after the vendor
- * login, and either the vendor login or the getty has
- * different ideas than we do of what both ut_id and ut_line
- * should be. It should be rare, though. We may want to
- * remove this restriction later.
- */
- if (!strncmp(u->ut_line, search->ut_line, sizeof(u->ut_line)))
- return 1;
- if (!strncmp(u->ut_id, search->ut_id, sizeof(u->ut_id)))
- return 1;
- }
- return 0;
-}
-
-/*
- * This expects to be called with SEARCH pointing to a struct utmpx
- * with its ut_type equal to USER_PROCESS or DEAD_PROCESS, since if
- * we're making a LOGIN_PROCESS entry, we presumably don't care about
- * preserving existing state. At the very least, the ut_pid, ut_line,
- * ut_id, and ut_type fields must be filled in by the caller.
- */
-static PTY_STRUCT_UTMPX *
-best_utxent(const PTY_STRUCT_UTMPX *search)
-{
- PTY_STRUCT_UTMPX utxtmp, *utxp;
- int i, best;
-
- memset(&utxtmp, 0, sizeof(utxtmp));
-
- /*
- * First, search based on pid, but only if non-zero.
- */
- if (search->ut_pid) {
- i = 0;
- PTY_SETUTXENT();
- while ((utxp = PTY_GETUTXENT()) != NULL) {
- if (match_pid(search, utxp)) {
- return utxp;
- }
- i++;
- }
- }
- /*
- * Uh-oh, someone didn't enter our pid. Try valiantly to search
- * by terminal line.
- */
- i = 0;
- best = -1;
- PTY_SETUTXENT();
- while ((utxp = PTY_GETUTXLINE(search)) != NULL) {
- if (better(search, utxp, &utxtmp)) {
- utxtmp = *utxp;
- best = i;
- }
- memset(utxp, 0, sizeof(*utxp));
- i++;
- }
- if (best == -1)
- return NULL;
- PTY_SETUTXENT();
- for (i = 0; i <= best; i++) {
- if (utxp != NULL)
- memset(utxp, 0, sizeof(*utxp));
- utxp = PTY_GETUTXLINE(search);
- }
- return utxp;
-}
-
-/*
- * All calls to this function for a given login session must have the
- * pids be equal; various things will break if this is not the case,
- * since we do some searching based on the pid. Note that if a parent
- * process calls this via pty_cleanup(), it should still pass the
- * child's pid rather than its own.
- */
-long
-pty_update_utmp(int process_type, int pid, const char *username,
- const char *line, const char *host, int flags)
-{
- PTY_STRUCT_UTMPX utx, *utxtmp, utx2;
- const char *cp;
- size_t len;
- char utmp_id[5];
-
- /*
- * Zero things out in case there are fields we don't handle here.
- * They tend to be non-portable anyway.
- */
- memset(&utx, 0, sizeof(utx));
- utxtmp = NULL;
- cp = line;
- if (strncmp(cp, "/dev/", sizeof("/dev/") - 1) == 0)
- cp += sizeof("/dev/") - 1;
- strncpy(utx.ut_line, cp, sizeof(utx.ut_line));
- utx.ut_pid = pid;
- switch (process_type) {
- case PTY_LOGIN_PROCESS:
- utx.ut_type = LOGIN_PROCESS;
- break;
- case PTY_USER_PROCESS:
- utx.ut_type = USER_PROCESS;
- break;
- case PTY_DEAD_PROCESS:
- utx.ut_type = DEAD_PROCESS;
- break;
- default:
- return PTY_UPDATE_UTMP_PROCTYPE_INVALID;
- }
- len = strlen(line);
- if (len >= 2) {
- cp = line + len - 1;
- if (*(cp - 1) != '/')
- cp--; /* last two characters, unless it's a / */
- } else
- cp = line;
- /*
- * HP-UX has mostly 4-character inittab ids, while most other sysV
- * variants use only 2-charcter inittab ids, so to avoid
- * conflicts, we pick 2-character ut_ids for our own use. We may
- * want to feature-test for this, but it would be somewhat of a
- * pain, and would eit cross-compiling.
- */
-#ifdef __hpux
- strlcpy(utmp_id, cp, sizeof(utmp_id));
-#else
- if (len > 2 && *(cp - 1) != '/')
- snprintf(utmp_id, sizeof(utmp_id), "k%s", cp - 1);
- else
- snprintf(utmp_id, sizeof(utmp_id), "k0%s", cp);
-#endif
- strncpy(utx.ut_id, utmp_id, sizeof(utx.ut_id));
- /*
- * Get existing utmpx entry for PID or LINE, if any, so we can
- * copy some stuff from it. This is particularly important if we
- * are login.krb5 and are running out of getty, since getty will
- * have written the entry for the line with ut_type ==
- * LOGIN_PROCESS, and what it has recorded in ut_id may not be
- * what we come up with, since that's up to the whim of the
- * sysadmin who writes the inittab entry.
- *
- * Note that we may be screwed if we try to write a logout record
- * for a vendor's login program, since it may construct ut_line
- * and ut_id differently from us; even though we search on ut_pid,
- * we validate against ut_id or ut_line to sanity-check. We may
- * want to rethink whether to actually include this check, since
- * it should be highly unlikely that there will be a bogus entry
- * in utmpx matching our pid.
- */
- if (process_type != PTY_LOGIN_PROCESS)
- utxtmp = best_utxent(&utx);
-
-#ifdef HAVE_SETUTXENT
- if (gettimeofday(&utx.ut_tv, NULL))
- return errno;
-#else
- (void)time(&utx.ut_time);
-#endif
- /*
- * On what system is there not ut_host? Unix98 doesn't mandate
- * this field, but we have yet to see a system that supports utmpx
- * that doesn't have it. For what it's worth, some ancient utmp
- * headers on svr4 systems imply that there's no ut_host in struct
- * utmp...
- */
-#if (defined(HAVE_SETUTXENT) && defined(HAVE_STRUCT_UTMPX_UT_HOST)) \
- || (!defined(HAVE_SETUTXENT) && defined(HAVE_STRUCT_UTMP_UT_HOST))
- if (host != NULL) {
- strncpy(utx.ut_host, host, sizeof(utx.ut_host));
- /* Unlike other things in utmpx, ut_host is nul-terminated? */
- utx.ut_host[sizeof(utx.ut_host) - 1] = '\0';
- } else
- utx.ut_host[0] = '\0';
-#if (defined(HAVE_SETUTXENT) && defined(HAVE_STRUCT_UTMPX_UT_SYSLEN)) \
- || (!defined (HAVE_SETUTXENT) && defined(HAVE_STRUCT_UTMP_UT_SYSLEN))
- if (host != NULL)
- utx.ut_syslen = strlen(utx.ut_host) + 1;
- else
- utx.ut_syslen = 0;
-#endif
-#endif
-
- /* XXX deal with ut_addr? */
-
- if (utxtmp != NULL) {
- /*
- * For entries not of type LOGIN_PROCESS, override some stuff
- * with what was in the previous entry we found, if any.
- */
- strncpy(utx.ut_id, utxtmp->ut_id, sizeof(utx.ut_id));
- utx.ut_pid = utxtmp->ut_pid;
- }
-
- strncpy(utx.ut_user, username, sizeof(utx.ut_user));
-
- /*
- * Make a copy now and deal with copying relevant things out of
- * utxtmp in case setutxline() or pututxline() clobbers utxtmp.
- * (After all, the returned pointer from the getutx*() functions
- * is allowed to point to static storage that may get overwritten
- * by subsequent calls to related functions.)
- */
- utx2 = utx;
- if (process_type == PTY_DEAD_PROCESS && utxtmp != NULL) {
- /*
- * Use ut_line from old entry to avoid confusing last on
- * HP-UX.
- */
- strncpy(utx2.ut_line, utxtmp->ut_line, sizeof(utx2.ut_line));
- }
-
- PTY_SETUTXENT();
- PTY_PUTUTXLINE(&utx);
- PTY_ENDUTXENT();
-
- /* Don't record LOGIN_PROCESS entries. */
- if (process_type == PTY_LOGIN_PROCESS)
- return 0;
-
-#ifdef HAVE_SETUTXENT
- return ptyint_update_wtmpx(&utx2);
-#else
- return ptyint_update_wtmp(&utx2);
-#endif
-}
-
-#else /* !(HAVE_SETUTXENT || HAVE_SETUTENT) */
-
-long
-pty_update_utmp(int process_type, int pid, const char *username,
- const char *line, const char *host, int flags)
-{
- struct utmp ent, ut;
- const char *cp;
- int tty, lc, fd;
- off_t seekpos;
- ssize_t ret;
- struct stat statb;
-
- memset(&ent, 0, sizeof(ent));
-#ifdef HAVE_STRUCT_UTMP_UT_HOST
- if (host)
- strncpy(ent.ut_host, host, sizeof(ent.ut_host));
-#endif
- strncpy(ent.ut_name, username, sizeof(ent.ut_name));
- cp = line;
- if (strncmp(cp, "/dev/", sizeof("/dev/") - 1) == 0)
- cp += sizeof("/dev/") - 1;
- strncpy(ent.ut_line, cp, sizeof(ent.ut_line));
- (void)time(&ent.ut_time);
-
- if (flags & PTY_TTYSLOT_USABLE)
- tty = ttyslot();
- else {
- tty = -1;
- fd = open(UTMP_FILE, O_RDONLY);
- if (fd == -1)
- return errno;
- for (lc = 0; ; lc++) {
- seekpos = lseek(fd, (off_t)(lc * sizeof(struct utmp)), SEEK_SET);
- if (seekpos != (off_t)(lc * sizeof(struct utmp)))
- break;
- if (read(fd, (char *) &ut, sizeof(struct utmp))
- != sizeof(struct utmp))
- break;
- if (strncmp(ut.ut_line, ent.ut_line, sizeof(ut.ut_line)) == 0) {
- tty = lc;
- break;
- }
- }
- close(fd);
- }
- if (tty > 0) {
- fd = open(UTMP_FILE, O_WRONLY);
- if (fd == -1)
- return 0;
- if (fstat(fd, &statb)) {
- close(fd);
- return 0;
- }
- seekpos = lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET);
- if (seekpos != (off_t)(tty * sizeof(struct utmp))) {
- close(fd);
- return 0;
- }
- ret = write(fd, (char *)&ent, sizeof(struct utmp));
- if (ret != sizeof(struct utmp)) {
- ftruncate(fd, statb.st_size);
- }
- close(fd);
- }
- /* Don't record LOGIN_PROCESS entries. */
- if (process_type == PTY_LOGIN_PROCESS)
- return 0;
- else
- return ptyint_update_wtmp(&ent);
-}
-#endif
+++ /dev/null
-/*
- * ptyint_update_wtmp: Update wtmp.
- *
- * Copyright 1995, 2001 by the Massachusetts Institute of Technology.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that copyright notice and this permission
- * notice appear in supporting documentation, and that the name of
- * M.I.T. not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability
- * of this software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- */
-
-#include "com_err.h"
-#include "libpty.h"
-#include "pty-int.h"
-
-#if !defined(WTMP_FILE) && defined(_PATH_WTMP)
-#define WTMP_FILE _PATH_WTMP
-#endif
-
-#if !defined(WTMPX_FILE) && defined(_PATH_WTMPX)
-#define WTMPX_FILE _PATH_WTMPX
-#endif
-
-/* if it is *still* missing, assume SunOS */
-#ifndef WTMP_FILE
-#define WTMP_FILE "/usr/adm/wtmp"
-#endif
-
-#ifdef HAVE_SETUTXENT
-
-#if defined(HAVE_GETUTMP) && defined(NEED_GETUTMP_PROTO)
-extern void getutmp(const struct utmpx *, struct utmp *);
-#endif
-
-/*
- * Welcome to conditional salad.
- *
- * This really wants to take a (const struct utmpx *) but updutmpx()
- * on Solaris at least doesn't take a const argument. *sigh*
- */
-long
-ptyint_update_wtmpx(struct utmpx *ent)
-{
-#if !(defined(HAVE_UPDWTMPX) && defined(WTMPX_FILE))
- struct utmp ut;
-#endif
-
-#if defined(HAVE_UPDWTMPX) && defined(WTMPX_FILE)
- updwtmpx(WTMPX_FILE, ent);
- return 0;
-#else
-
-#ifdef HAVE_GETUTMP
- getutmp(ent, &ut);
-#else /* Emulate getutmp(). Yuck. */
- memset(&ut, 0, sizeof(ut));
- strncpy(ut.ut_name, ent->ut_user, sizeof(ut.ut_name));
- strncpy(ut.ut_line, ent->ut_line, sizeof(ut.ut_line));
- ut.ut_time = ent->ut_tv.tv_sec;
-#ifdef HAVE_STRUCT_UTMP_UT_HOST
- strncpy(ut.ut_host, ent->ut_host, sizeof(ut.ut_host));
- ut.ut_host[sizeof(ut.ut_host) - 1] = '\0';
-#ifdef HAVE_STRUCT_UTMP_UT_SYSLEN
- ut.ut_syslen = strlen(ut.ut_host) + 1;
-#endif
-#endif
-#ifdef HAVE_STRUCT_UTMP_UT_ID
- strncpy(ut.ut_id, ent->ut_id, sizeof(ut.ut_id));
-#endif
-#ifdef HAVE_STRUCT_UTMP_UT_PID
- ut.ut_pid = ent->ut_pid;
-#endif
-#ifdef HAVE_STRUCT_UTMP_UT_TYPE
- ut.ut_type = ent->ut_type;
-#endif
-#if defined(PTY_UTMP_E_EXIT) && defined(PTY_UTMPX_E_EXIT)
- ut.ut_exit.PTY_UTMP_E_EXIT = ent->ut_exit.PTY_UTMPX_E_EXIT;
- ut.ut_exit.PTY_UTMP_E_TERMINATION =
- ent->ut_exit.PTY_UTMPX_E_TERMINATION;
-#endif
-#endif /* !HAVE_GETUTMP */
-
- return ptyint_update_wtmp(&ut);
-#endif /* !(defined(WTMPX_FILE) && defined(HAVE_UPDWTMPX)) */
-}
-
-#endif /* HAVE_SETUTXENT */
-
-#if !(defined(WTMPX_FILE) && defined(HAVE_UPDWTMPX)) \
- || !defined(HAVE_SETUTXENT)
-
-long
-ptyint_update_wtmp(struct utmp *ent)
-{
-#ifndef HAVE_UPDWTMP
- int fd;
- struct stat statb;
-#endif
-
-#ifdef HAVE_UPDWTMP
- updwtmp(WTMP_FILE, ent);
-#else
- fd = open(WTMP_FILE, O_WRONLY | O_APPEND, 0);
- if (fd != -1 && !fstat(fd, &statb)) {
- if (write(fd, (char *)ent, sizeof(struct utmp))
- != sizeof(struct utmp))
- (void)ftruncate(fd, statb.st_size);
- (void)close(fd);
- }
-#endif
- /*
- * no current failure cases; file not found is not failure!
- */
- return 0;
-}
-
-#endif
+++ /dev/null
-/*
- * pty_open_slave: open slave side of terminal, clearing for use.
- *
- * Copyright 1995 by the Massachusetts Institute of Technology.
- *
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that copyright notice and this permission
- * notice appear in supporting documentation, and that the name of
- * M.I.T. not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability
- * of this software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- */
-
-#include "com_err.h"
-#include "libpty.h"
-#include "pty-int.h"
-
-void ptyint_vhangup(void)
-{
-#ifdef HAVE_VHANGUP
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
- /* Initialize "sa" structure. */
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
-
-#endif
-
-#ifdef POSIX_SIGNALS
- sa.sa_handler = SIG_IGN;
- (void) sigaction(SIGHUP, &sa, (struct sigaction *)0);
- vhangup();
- sa.sa_handler = SIG_DFL;
- (void) sigaction(SIGHUP, &sa, (struct sigaction *)0);
-#else
- signal(SIGHUP, SIG_IGN);
- vhangup();
- signal(SIGHUP, SIG_DFL);
-#endif
-#endif
-}
+++ /dev/null
-/*
- * ptyint_void_association(): Void association with controlling terminal
- *
- * Copyright 1995, 1996 by the Massachusetts Institute of Technology.
- *
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that copyright notice and this permission
- * notice appear in supporting documentation, and that the name of
- * M.I.T. not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability
- * of this software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- */
-
-#include "com_err.h"
-#include "libpty.h"
-#include "pty-int.h"
-
-/*
- * This function gets called to set up the current process as a
- * session leader (hence, can't be called except from a process that
- * isn't already a session leader) and dissociates the controlling
- * terminal (if any) from the session.
- */
-long
-ptyint_void_association(void)
-{
- int fd;
-#ifdef HAVE_SETSID
- (void) setsid();
-#endif
- /* Void tty association first */
-#ifdef TIOCNOTTY
- fd = open("/dev/tty", O_RDWR);
- if (fd >= 0) {
- ioctl(fd, TIOCNOTTY, 0);
- close(fd);
- }
-#endif
- return 0;
-}
+++ /dev/null
-#
-# 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.
-#
-# @(#)Config.generic 5.5 (Berkeley) 3/1/91
-#
-
-# This is the configuration file for building all of
-# telnet/telnetd/libtelnet. If you want to add your
-# own local configuration for a specific machine that
-# is already listed here, it is best to create a new
-# file called "Config.local", and put the definitions
-# there. If you are adding definitions for a new system
-# type, you can add them here. In this case, please send
-# the new definition, and any changes you have to make to
-# the code, back to "dab@cray.com" so that your changes
-# can be put into the next release.
-#
-# Each definition must have the form:
-#
-# <target>:
-# make -f Makefile.generic ${WHAT} \
-# <definitions>
-
-# DEFINES=
-#
-# Variables to be defined when actually compiling the source. Defined
-# as: DEFINES="-D<var> -D<var2> ... -D<varn>"
-#
-# TELNET/TELNETD CONFIGURATION
-#
-# LINEMODE Turns on support in telnetd for the linemode option.
-# (Linemode is always on in the client).
-#
-# KLUDGELINEMODE Define this to get the kludged up version of linemode
-# that was in 4.3BSD. This is a good thing to have
-# around for talking to older systems. This has no
-# effect on telnetd if LINEMODE has not been defined.
-#
-# DIAGNOSTICS Turns on diagnostic code in telnetd; adds extra
-# logic and checks, and debuging output if started
-# with the -D option.
-#
-# NO_URGENT Define this if you don't want telnetd to send
-# IAC DM in urgent mode when the pty output queue
-# is flushed.
-#
-# GENERATE_GA Turns on code to allow the generation of Go Ahead(GA)
-# if the server is WONT SGA. This code is imprecise,
-# it generates the GA when two seconds have elapsed
-# and no input or output has occurred.
-#
-# AUTHENTICATION Enable the AUTHENTICATION option.
-#
-# ENCRYPTION Enable the ENCRYPT option.
-#
-# KRB4 Enable Kerberos Version 4 Authentication code
-# in libtelnet/libtelnet.a
-#
-# KRB5 Enable Kerberos Version 5 Authentication code
-# in libtelnet/libtelnet.a
-#
-# SPX Enable SPX authentication code in.
-# libtelnet/libtelnet.a
-#
-# RSA_ENCPWD
-#
-# KRB4_ENCPWD
-#
-#
-# DES_ENCRYPTION Enable DES encryption/decryption, requires
-# getting a the initial key from Kerberos. This
-# works with both Kerberos Version 4 and 5.
-#
-# ENV_HACK Turn on code to recognize and allow
-# interoperability with systems that have their
-# definitions for ENV_VALUE and ENV_VAR reversed.
-#
-# LOCAL SYSYTEM PARAMATERS
-#
-# TERMCAP Define this if your system is termcap based,
-# otherwise a terminfo based system is assumed.
-#
-# SYSV_TERMIO Use the System V termio structure. (implies USE_TERMIO)
-#
-# NO_CC_T Define this if your termio.h file does not have
-# a typedef for cc_t.
-#
-# USE_TERMIO Define this if you have the POSIX termios structures.
-# This code works under the BSD 4.4 terminal driver.
-#
-# HAS_GETTOS Define this if you have the setsockopt() option for
-# setting the IP Type Of Service bits, (IP_TOS) and
-# you have the gettosbyname() function.
-#
-# NEWINIT Turns on the new init code for UNICOS systems.
-#
-# STREAMS This system needs <sys/stream.h> for <sys/tty.h>
-# (Sun 4.0.3)
-#
-# FILIO_H This system should use <sys/fileo.h> instead
-# of <sys/ioctl.h> (Sun 4.0.3)
-#
-# HAVE_fd_set This system has a typedef for fd_set, but does
-# not have FDSET() defined.
-#
-# NO_STRING_H If you don't have <string.h>, but have <strings.h>
-#
-# LOGIN_PROGRAM= Specifies the login program to use. By default,
-# it is /bin/login, or whatever is specified by
-# _PATH_LOGIN in <paths.h>
-#
-# NO_LOGIN_P If /bin/login doesn't understand the "-p"
-# (preserve environment) option.
-#
-# LOGIN_ARGS if /bin/login understands environment variables
-# after the login name. Only used if NO_LOGIN_P
-# is defined.
-#
-# NO_LOGIN_F If /bin/login doesn't understand the "-f" option.
-# Only used if AUTHENTICATION is defined.
-#
-# LOGIN_CAP_F If /bin/login understands the "-F" option (which
-# works like "-f", but root logins are allowed).
-# Only used if NO_LOGIN_F is not defined.
-#
-# LOGIN_R This says that /bin/login understands the "-r host"
-# option. Only used if NO_LOGIN_F is defined (and
-# the system supports the TIOCSTI ioctl).
-#
-# LOGIN_HOST Only applies if LOGIN_R is defined. This
-# specifies the hostname to be passed to "login -r"
-# for successfully authenticated logins. This
-# defaults to "localhost" (don't forget to include
-# the quotes, e.g. -DLOGIN_HOST=\"localhost\").
-#
-# It can also be set to host (-DLOGIN_HOST=host)
-# to have the real hostname passed to "/bin/login -r".
-# NOTE: If you do this, then anyone that wants to
-# allow authenticated login access will have
-# to add those remote hosts to their .rhosts,
-# which sort of defeats the whole purpose of
-# authenticated login...
-#
-# NO_BSD_SETJMP For UNICOS releases prior to 7.0. Turns off
-# the inclusion of <bsdsetjmp.h>.
-#
-# STREAMS If the system has streams; causes <sys/stream.h>
-# to be included instead of <sys/tty.h>
-#
-# MUST_ALIGN If !KRB & !HAVE_KRB4_DES_LIB and your words
-# must be word aligned.
-#
-# STREAMSPTY Use /dev/ptmx to get a clean pty. Uses
-# streams packet mode rather than Berkeley.
-# Appropriate for SVr4 derivatives.
-#
-# UTMPX System has /etc/utmpx as well as /etc/utmp.
-# Use makeutx and modutx to update utmp/x and wtmp/x.
-# Appropriate for SVr4 derivatives.
-#
-# HAS_CGETENT If your system has the cgetent() and cgetstr()
-# routines. This is a 4.4BSD feature, that
-# eliminates grabbing the getty gettytab.c source.
-# You need to include getent.o on the LIB_OBJ
-# line if this is defined.
-#
-# OLD_ENVIRON Support for the old environment option.
-
-# LIB_OBJ=
-# This is a list of object files that are needed but are not in
-# the standard C library.
-#
-# strcasecmp.o If you don't have strncasecmp(3)
-# strdup.o If you don't have strdup(3)
-# setenv.o If you don't have setenv(3) and unsetenv(3)
-# setsid.o If you don't have the POSIX setsid() call
-# strerror.o If you don't have strerror(3)
-# strftime.o If you don't have strftime(3)
-# getopt.o If you don't have getopt(3)
-# herror.o If you don't have herror(3)
-# gettytab.o If you can get gettytab.c from getty source.
-# getent.o If you can't get gettytab.c (or have
-# HAS_CGETENT defined...)
-# mem.o If you don't have mem*(3) routines.
-
-# LIB_SRC=
-# This is a list of source modules for specificed in LIB_OBJ.
-# This information is used by make for checking dependencies.
-
-
-# LIBS=
-# This is a list of libraries to be included. This will always
-# include the telnet library, and will also include either -lcurses
-# or -ltermcap, -lutil for 4.4bsd, and -lnet for UNICOS5.0 and earlier.
-# Also -lkrb & -ldes if Kerberos.
-
-# LIBPATH=
-# This is a list of the paths to all the libraries listed in LIBS.
-# This information is used by make for checking dependencies.
-# Don't forget libc.a
-
-# VPATH=
-# Directory where gettytab.c can be found, if you have it.
-
-# LIBEXEC=
-# Directory where the telnetd executable should be installed.
-
-# LCCFLAGS=
-# Local flags for ${CC} (like -O)
-
-# AR=
-# Name of "ar" program, usually just "ar".
-
-# ARFLAGS
-# Flags to pass to ${AR}
-
-# RANLIB
-# Name of "ranlib" program, set it to "NONE" if you don't
-# have a "ranlib".
-
-all:
- @echo "You must specify what type of system you are on,"
- @echo "or setup a Config.local file for your system."
- @echo "Known system types are:"
- @echo
- @echo " 4.4bsd 4.3reno 4.4bsd.auth 4.3reno.auth 4.3tahoe 4.3bsd"
- @echo " bsdi1.0 bsdi1.0.auth"
- @echo " unicos8.1 unicos8.0 unicos7.C unicos7.0"
- @echo " unicos8.1.auth unicos8.0.auth unicos7.0.auth"
- @echo " unicos7.C.auth unicos7.0.des.auth"
- @echo " unicos6.1 unicos6.0 unicos5.1 unicos5.0"
- @echo " sun3.5 sun4.0.3c sun4.0 sun4.1 sun4.1.auth"
- @echo " solaris2.2 solaris2.2.auth"
- @echo " dynix3.0.12 dynix3.0.17"
- @echo " ultrix3.1 ultrix4.0 ultrix4.1 ultrix4.3 ultrix4.3.auth"
- @echo " irix4.0.1"
- @echo " hpux8.0"
- @echo " next1.0"
- @echo " convex"
-
-4.4bsd:
- make -f Makefile.generic ${WHAT} \
- LIBS="-lutil -ltermcap ../libtelnet/libtelnet.a" \
- LIBPATH="/usr/lib/libc.a /usr/lib/libtermcap.a \
- ../libtelnet/libtelnet.a" \
- DEST=${DESTDIR}/usr/bin \
- DEFINES=${ODEFS}"-DLINEMODE -DTERMCAP -DKLUDGELINEMODE \
- -DDEFAULT_IM='\"\r\n4.4 BSD UNIX (%h) (%t)\r\n\r\r\n\r\"' \
- -DUSE_TERMIO -DDIAGNOSTICS -DENV_HACK -DOLD_ENVIRON \
- -DHAS_CGETENT" \
- INCLUDES="-I.." \
- LIB_OBJ="getent.o" \
- LIB_SRC="getent.c" \
- AR=ar ARFLAGS=cq RANLIB=ranlib \
- LIBEXEC=${DESTDIR}/usr/libexec \
- CC="${CC}" LCCFLAGS="-O"
-
-4.3reno:
- make -f Makefile.generic ${WHAT} \
- LIBS="-lutil -ltermcap ../libtelnet/libtelnet.a ${AUTH_LIB}" \
- LIBPATH="/lib/libc.a /usr/lib/libtermcap.a \
- ../libtelnet/libtelnet.a ${AUTH_LIBPATH}" \
- DEST=${DESTDIR}/usr/bin \
- DEFINES=${ODEFS}"-DLINEMODE -DTERMCAP -DKLUDGELINEMODE \
- -DDEFAULT_IM='\"\r\n4.3BSD-Reno UNIX (%h) (%t)\r\n\r\r\n\r\"' \
- -DUSE_TERMIO -DDIAGNOSTICS -DENV_HACK \
- -DOLD_ENVIRON ${AUTH_DEF}" \
- INCLUDES="-I.. ${AUTH_INC}" \
- LIB_OBJ="gettytab.o" \
- LIB_SRC="gettytab.c" \
- AR=ar ARFLAGS=cq RANLIB=ranlib \
- VPATH=/usr/src/libexec/getty \
- LIBEXEC=${DESTDIR}/usr/libexec \
- CC="${CC}" LCCFLAGS="-O"
-
-
-4.4bsd.auth 4.3reno.auth:
- make -f ../Config.generic `basename $@ .auth` WHAT=${WHAT} \
- AUTH_LIB="-lkrb -ldes" \
- AUTH_LIBPATH="/usr/lib/libkrb.a /usr/lib/libdes.a" \
- AUTH_DEF="-DAUTHENTICATION -DENCRYPTION -DKRB4 -DDES_ENCRYPTION"
-
-4.3tahoe:
- @echo $@ is untested... it may or may not work..."
- make -f Makefile.generic ${WHAT} \
- LIBS="-ltermcap ../libtelnet/libtelnet.a" \
- LIBPATH="/lib/libc.a /usr/lib/libtermcap.a \
- ../libtelnet/libtelnet.a" \
- DEST=${DESTDIR}/usr/bin \
- DEFINES=${ODEFS}"-DTERMCAP -DKLUDGELINEMODE \
- -DDEFAULT_IM='\"\r\n4.3BSD-Tahoe UNIX (%h) (%t)\r\n\r\r\n\r\"'\
- -DDIAGNOSTICS -DENV_HACK -DOLD_ENVIRON" \
- INCLUDES="-I.." \
- LIB_OBJ="strdup.o setsid.o strftime.o gettytab.o" \
- LIB_SRC="strdup.c setsid.c strftime.c gettytab.c" \
- AR=ar ARFLAGS=cq RANLIB=ranlib \
- VPATH=/usr/src/etc/getty \
- LIBEXEC=${DESTDIR}/etc \
- CC="${CC}" LCCFLAGS="-O"
-
-4.3bsd:
- @echo $@ is untested... it may or may not work..."
- make -f Makefile.generic ${WHAT} \
- LIBS="-ltermcap ../libtelnet/libtelnet.a" \
- LIBPATH="/lib/libc.a /usr/lib/libtermcap.a \
- ../libtelnet/libtelnet.a" \
- DEST=${DESTDIR}/usr/bin \
- DEFINES=${ODEFS}"-DTERMCAP -DKLUDGELINEMODE \
- -DDEFAULT_IM='\"\r\n4.3BSD UNIX (%h) (%t)\r\n\r\r\n\r\"' \
- -DDIAGNOSTICS -DENV_HACK -DOLD_ENVIRON" \
- INCLUDES="-I.." \
- LIB_OBJ="strdup.o setsid.o strftime.o \
- gettytab.o getopt.o herror.o" \
- LIB_SRC="strdup.c setsid.c strftime.c \
- gettytab.c getopt.c herror.c" \
- AR=ar ARFLAGS=cq RANLIB=ranlib \
- VPATH=/usr/src/etc/getty \
- LIBEXEC=${DESTDIR}/etc \
- CC="${CC}" LCCFLAGS="-O"
-
-bsdi1.0:
- make -f Makefile.generic ${WHAT} \
- LIBS="-lutil -ltermcap ../libtelnet/libtelnet.a ${AUTH_LIB}" \
- LIBPATH="/lib/libc.a /usr/lib/libtermcap.a \
- ../libtelnet/libtelnet.a ${AUTH_LIBPATH}" \
- DEST=${DESTDIR}/usr/bin \
- DEFINES=${ODEFS}"-DLINEMODE -DTERMCAP -DKLUDGELINEMODE \
- -DDEFAULT_IM='\"\r\nBSDI BSD/386 1.0 (%h) (%t)\r\n\r\r\n\r\"' \
- -DUSE_TERMIO -DDIAGNOSTICS -DENV_HACK \
- -DOLD_ENVIRON ${AUTH_DEF}" \
- INCLUDES="-I.. ${AUTH_INC}" \
- LIB_OBJ="gettytab.o" \
- LIB_SRC="gettytab.c" \
- AR=ar ARFLAGS=cq RANLIB=ranlib \
- VPATH=/usr/src/libexec/getty \
- LIBEXEC=${DESTDIR}/usr/libexec \
- CC="${CC}" LCCFLAGS="-O"
-
-bsdi1.0.auth:
- make -f ../Config.generic `basename $@ .auth` WHAT=${WHAT} \
- AUTH_LIB="-lkrb -ldes" \
- AUTH_LIBPATH="/usr/lib/libkrb.a /usr/lib/libdes.a" \
- AUTH_DEF="-DAUTHENTICATION -DENCRYPTION -DKRB4 -DDES_ENCRYPTION"
- AUTH_INC=-I/usr/include/kerberosIV
-
-unicos8.1:
- make -f Makefile.generic ${WHAT} \
- LIBS="-lcurses -L../libtelnet -ltelnet ${AUTH_LIB}" \
- LIBPATH="/lib/libc.a /usr/lib/libcurses.a \
- ../libtelnet/libtelnet.a ${AUTH_LIBPATH}" \
- DEST=${DESTDIR}/usr/ucb \
- DEFINES=${ODEFS}"-Dvfork=fork -Dsignal=bsdsignal \
- -DLINEMODE -DKLUDGELINEMODE \
- -DSYSV_TERMIO -DHAS_GETTOS ${AUTH_DEF} \
- -DDEFAULT_IM='\"\r\nCray UNICOS 8.1 (%h) (%t)\r\n\r\r\n\r\"' \
- -DDIAGNOSTICS -DENV_HACK -DOLD_ENVIRON" \
- AR=bld ARFLAGS=cq RANLIB=NONE \
- LIBEXEC=${DESTDIR}/etc \
- INCLUDES="-I.. ${AUTH_INC}" \
- LIB_OBJ="getent.o" \
- LIB_SRC="getent.c" \
-
-unicos8.0:
- make -f Makefile.generic ${WHAT} \
- LIBS="-lcurses -L../libtelnet -ltelnet ${AUTH_LIB}" \
- LIBPATH="/lib/libc.a /usr/lib/libcurses.a \
- ../libtelnet/libtelnet.a ${AUTH_LIBPATH}" \
- DEST=${DESTDIR}/usr/ucb \
- DEFINES=${ODEFS}"-Dvfork=fork -Dsignal=bsdsignal \
- -DLINEMODE -DKLUDGELINEMODE \
- -DSYSV_TERMIO -DHAS_GETTOS ${AUTH_DEF} \
- -DDEFAULT_IM='\"\r\nCray UNICOS 8.0 (%h) (%t)\r\n\r\r\n\r\"' \
- -DDIAGNOSTICS -DENV_HACK -DOLD_ENVIRON" \
- AR=bld ARFLAGS=cq RANLIB=NONE \
- LIBEXEC=${DESTDIR}/etc \
- INCLUDES="-I.. ${AUTH_INC}" \
- LIB_OBJ="getent.o" \
- LIB_SRC="getent.c" \
- CC="${CC}" LCCFLAGS="-O"
-
-unicos7.C:
- make -f Makefile.generic ${WHAT} \
- LIBS="-lcurses -L../libtelnet -ltelnet ${AUTH_LIB}" \
- LIBPATH="/lib/libc.a /usr/lib/libcurses.a \
- ../libtelnet/libtelnet.a ${AUTH_LIBPATH}"\
- DEST=${DESTDIR}/usr/ucb \
- DEFINES=${ODEFS}"-Dvfork=fork -Dsignal=bsdsignal \
- -DLINEMODE -DKLUDGELINEMODE \
- -DSYSV_TERMIO -DHAS_GETTOS ${AUTH_DEF} \
- -DDEFAULT_IM='\"\r\nCray UNICOS 7.C (%h) (%t)\r\n\r\r\n\r\"' \
- -DDIAGNOSTICS -DENV_HACK -DOLD_ENVIRON" \
- AR=bld ARFLAGS=cq RANLIB=NONE \
- LIBEXEC=${DESTDIR}/etc \
- INCLUDES="-I.. ${AUTH_INC}" \
- LIB_OBJ="getent.o" \
- LIB_SRC="getent.c" \
- CC="${CC}" LCCFLAGS="-O"
-
-
-unicos7.0:
- make -f Makefile.generic ${WHAT} \
- LIBS="-lcurses -L../libtelnet -ltelnet -lkrb" \
- LIBPATH="/lib/libc.a /usr/lib/libcurses.a \
- ../libtelnet/libtelnet.a /usr/lib/libkrb.a" \
- DEST=${DESTDIR}/usr/ucb \
- DEFINES=${ODEFS}"-Dvfork=fork -Dsignal=bsdsignal \
- -DLINEMODE -DKLUDGELINEMODE \
- -DSYSV_TERMIO -DHAS_GETTOS \
- -DDEFAULT_IM='\"\r\nCray UNICOS 7.0 (%h) (%t)\r\n\r\r\n\r\"' \
- -DDIAGNOSTICS -DENV_HACK -DOLD_ENVIRON" \
- AR=bld ARFLAGS=cq RANLIB=NONE \
- LIBEXEC=${DESTDIR}/etc \
- INCLUDES="-I.." \
- LIB_OBJ="getent.o" \
- LIB_SRC="getent.c" \
- CC="${CC}" LCCFLAGS="-O"
-
-# As of UNICOS 7.0.5.2, there is no longer a /usr/lib/libdes.a
-# If you still have a /usr/lib/libdes.a, use the "unicos7.0.des.auth"
-# target instead of "unicos7.0.auth".
-
-unicos8.1.auth unicos8.0.auth unicos7.0.auth:
- make -f ../Config.generic `basename $@ .auth` WHAT=${WHAT} \
- AUTH_LIB=-lkrb AUTH_LIBPATH=/usr/lib/libkrb.a \
- AUTH_INC=-I/usr/include/krb \
- AUTH_DEF="-DAUTHENTICATION -DENCRYPTION -DKRB4 -DDES_ENCRYPTION"
-
-unicos7.C.auth unicos7.0.des.auth:
- make -f ../Config.generic `basename $@ .des.auth` WHAT=${WHAT} \
- AUTH_LIB="-lkrb -ldes" \
- AUTH_LIBPATH="/usr/lib/libkrb.a /usr/lib/libdes.a" \
- AUTH_INC=-I/usr/include/krb \
- AUTH_DEF="-DAUTHENTICATION -DENCRYPTION -DKRB4 -DDES_ENCRYPTION"
-
-unicos6.1:
- make -f Makefile.generic ${WHAT} \
- LIBS="-lcurses -L../libtelnet -ltelnet" \
- LIBPATH="/lib/libc.a /usr/lib/libcurses.a \
- ../libtelnet/libtelnet.a" \
- DEST=${DESTDIR}/usr/ucb \
- DEFINES=${ODEFS}"-Dvfork=fork -Dsignal=bsdsignal \
- -DKLUDGELINEMODE -DUSE_TERMIO -DHAS_GETTOS \
- -DLINEMODE -DSYSV_TERMIO -DNEWINIT \
- -DNO_LOGIN_F -DNO_LOGIN_P -DNO_BSD_SETJMP \
- -DLOGIN_ARGS \
- -DDEFAULT_IM='\"\r\nCray UNICOS 6.1 (%h) (%t)\r\n\r\r\n\r\"' \
- -DDIAGNOSTICS -DENV_HACK -DOLD_ENVIRON" \
- AR=bld ARFLAGS=cq RANLIB=NONE \
- LIBEXEC=${DESTDIR}/etc \
- INCLUDES="-I.." \
- LIB_OBJ="getent.o parsetos.o" \
- LIB_SRC="getent.c parsetos.c" \
- CC="${CC}" LCCFLAGS="-O"
-
-unicos6.0:
- @echo $@ is untested... it may or may not work..."
- make -f Makefile.generic ${WHAT} \
- LIBS="-lcurses -L../libtelnet -ltelnet" \
- LIBPATH="/lib/libc.a /usr/lib/libcurses.a \
- ../libtelnet/libtelnet.a" \
- DEST=${DESTDIR}/usr/ucb \
- DEFINES=${ODEFS}"-Dvfork=fork -Dsignal=bsdsignal \
- -DKLUDGELINEMODE -DUSE_TERMIO -DHAS_GETTOS \
- -DLINEMODE -DSYSV_TERMIO -DNEWINIT \
- -DNO_LOGIN_F -DNO_LOGIN_P -DNO_BSD_SETJMP \
- -DLOGIN_ARGS \
- -DDEFAULT_IM='\"\r\nCray UNICOS 6.0 (%h) (%t)\r\n\r\r\n\r\"' \
- -DDIAGNOSTICS -DENV_HACK -DOLD_ENVIRON" \
- AR=bld ARFLAGS=cq RANLIB=NONE \
- LIBEXEC=${DESTDIR}/etc \
- INCLUDES="-I.." \
- LIB_OBJ="getent.o parsetos.o" \
- LIB_SRC="getent.c parsetos.c" \
- CC="${CC}" LCCFLAGS="-O"
-
-unicos5.1:
- @echo $@ is untested... it may or may not work..."
- make -f Makefile.generic ${WHAT} \
- LIBS="-lnet -lcurses -L../libtelnet -ltelnet" \
- LIBPATH="/lib/libc.a /usr/lib/libcurses.a \
- ../libtelnet/libtelnet.a" \
- DEST=${DESTDIR}/usr/ucb \
- DEFINES=${ODEFS}"-Dvfork=fork -Dsignal=sigset \
- -DKLUDGELINEMODE -DSYSV_TERMIO -DNO_CC_T \
- -DUNICOS5 -DLINEMODE -DSYSV_TERMIO \
- -DNEWINIT -DNO_LOGIN_F -DNO_LOGIN_P -DNO_BSD_SETJMP \
- -DLOGIN_ARGS \
- -DDEFAULT_IM='\"\r\nCray UNICOS 5.1 (%h) (%t)\r\n\r\r\n\r\"' \
- -DDIAGNOSTICS -DENV_HACK -DOLD_ENVIRON" \
- INCLUDES="-I.." \
- LIB_OBJ="getent.o strerror.o setsid.o strftime.o" \
- LIB_SRC="getent.c strerror.c setsid.c strftime.c" \
- AR=bld ARFLAGS=cq RANLIB=NONE \
- LIBEXEC=${DESTDIR}/etc \
- CC="${CC}" LCCFLAGS="-O"
-
-unicos5.0:
- @echo $@ is untested... it may or may not work..."
- make -f Makefile.generic ${WHAT} \
- LIBS="-lnet -lcurses -L../libtelnet -ltelnet" \
- LIBPATH="/lib/libc.a /usr/lib/libcurses.a \
- ../libtelnet/libtelnet.a" \
- DEST=${DESTDIR}/usr/ucb \
- DEFINES=${ODEFS}"-Dvfork=fork -Dsignal=sigset \
- -DKLUDGELINEMODE -DSYSV_TERMIO -DNO_CC_T \
- -DUNICOS5 -DUNICOS50 -DLINEMODE -DSYSV_TERMIO \
- -DNEWINIT -DNO_LOGIN_F -DNO_LOGIN_P -DNO_BSD_SETJMP \
- -DLOGIN_ARGS \
- -DDEFAULT_IM='\"\r\nCray UNICOS 5.0 (%h) (%t)\r\n\r\r\n\r\"' \
- -DDIAGNOSTICS -DENV_HACK -DOLD_ENVIRON" \
- INCLUDES="-I.." \
- LIB_OBJ="getent.o strerror.o setsid.o strftime.o" \
- LIB_SRC="getent.c strerror.c setsid.c strftime.c" \
- AR=bld ARFLAGS=cq RANLIB=NONE \
- LIBEXEC=${DESTDIR}/etc \
- CC="${CC}" LCCFLAGS="-O"
-
-sun3.5:
- @echo $@ is untested... it may or may not work..."
- make -f Makefile.generic ${WHAT} \
- LIBS="-ltermcap ../libtelnet/libtelnet.a" \
- LIBPATH="/lib/libc.a /usr/lib/libtermcap.a \
- ../libtelnet/libtelnet.a" \
- DEST=${DESTDIR}/usr/ucb \
- DEFINES=${ODEFS}"-DTERMCAP -DKLUDGELINEMODE \
- -DHAVE_fd_set \
- -DDIAGNOSTICS -DENV_HACK -DOLD_ENVIRON \
- -DDEFAULT_IM='\"\r\nSunOS UNIX 3.5 (%h) (%t)\r\n\r\r\n\r\"' \
- -DNO_LOGIN_P" \
- INCLUDES="-I.." \
- LIB_OBJ="getent.o strdup.o strerror.o setsid.o \
- setenv.o strftime.o strcasecmp.o herror.o" \
- LIB_SRC="getent.c strdup.c strerror.c setsid.c \
- setenv.c strftime.c strcasecmp.c herror.c" \
- AR=ar ARFLAGS=cq RANLIB=ranlib \
- LIBEXEC=${DESTDIR}/usr/etc/in.telnetd \
- CC="${CC}" LCCFLAGS="-O"
-
-sun4.0.3c sun4.0:
- @echo $@ is untested... it may or may not work..."
- make -f Makefile.generic ${WHAT} \
- LIBS="-ltermcap ../libtelnet/libtelnet.a" \
- LIBPATH="/lib/libc.a /usr/lib/libtermcap.a \
- ../libtelnet/libtelnet.a" \
- DEST=${DESTDIR}/usr/ucb \
- DEFINES=${ODEFS}"-DFILIO_H -DTERMCAP -DUSE_TERMIO -DNO_CC_T \
- -DKLUDGELINEMODE \
- -DDEFAULT_IM='\"\r\nSunOS UNIX 4.0 (%h) (%t)\r\n\r\r\n\r\"' \
- -DSTREAMS -DDIAGNOSTICS -DENV_HACK -DOLD_ENVIRON \
- " \
- INCLUDES="-I.." \
- LIB_OBJ="getent.o strerror.o setsid.o setenv.o \
- strcasecmp.o strftime.o herror.o" \
- LIB_SRC="getent.c strerror.c setsid.c setenv.c \
- strcasecmp.c strftime.c herror.c" \
- AR=ar ARFLAGS=cq RANLIB=ranlib \
- LIBEXEC=${DESTDIR}/usr/etc/in.telnetd \
- CC="${CC}" LCCFLAGS="-O"
-
-sun4.1:
- make -f Makefile.generic ${WHAT} \
- LIBS="-ltermcap ../libtelnet/libtelnet.a ${AUTH_LIB}" \
- LIBPATH="/lib/libc.a /usr/lib/libtermcap.a \
- ../libtelnet/libtelnet.a ${AUTH_LIBPATH}" \
- DEST=${DESTDIR}/usr/ucb \
- DEFINES=${ODEFS}"-DFILIO_H -DTERMCAP -DUSE_TERMIO \
- -DKLUDGELINEMODE -DSTREAMS \
- -DDEFAULT_IM='\"\r\nSunOS UNIX 4.1 (%h) (%t)\r\n\r\r\n\r\"' \
- -DDIAGNOSTICS -DENV_HACK -DOLD_ENVIRON ${AUTH_DEF}" \
- INCLUDES="-I.. ${AUTH_INC}" \
- LIB_OBJ="getent.o strerror.o setenv.o herror.o" \
- LIB_SRC="getent.c strerror.c setenv.c herror.c" \
- AR=ar ARFLAGS=cq RANLIB=ranlib \
- LIBEXEC=${DESTDIR}/usr/etc/in.telnetd \
- CC="${CC}" LCCFLAGS="-O"
-
-sun4.1.auth:
- make -f ../Config.generic `basename $@ .auth` WHAT=${WHAT} \
- AUTH_LIB="-lkrb -ldes" \
- AUTH_LIBPATH="/usr/lib/libkrb.a /usr/lib/libdes.a" \
- AUTH_DEF="-DAUTHENTICATION -DENCRYPTION -DKRB4 -DDES_ENCRYPTION"
-
-sol2.2 solaris2.2:
- make -f Makefile.generic ${WHAT} \
- LIBS="-ltermlib ../libtelnet/libtelnet.a" \
- LIBPATH="/usr/ccs/lib/libtermlib.a ../libtelnet/libtelnet.a \
- /usr/lib/libc.a /usr/ucblib/libucb.a \
- /usr/lib/libsocket.a /usr/lib/libnsl.a" \
- DEST=${DESTDIR}/usr/ucb \
- DEFINES="-DFILIO_H -DUSE_TERMIO -DKLUDGELINEMODE \
- -DSTREAMS -DSTREAMSPTY -DDIAGNOSTICS -DSOLARIS \
- -DENV_HACK -DOLD_ENVIRON -DNO_LOGIN_P -DUTMPX \
- -DDEFAULT_IM='\"\r\n\r\nUNIX(r) System V Release 4.0 (%h)\r\n\r\n\"' \
- -DLOGIN_ARGS" \
- INCLUDES="-I.. -I/usr/ucbinclude" \
- LIB_OBJ="getent.o strerror.o setenv.o herror.o" \
- LIB_SRC="getent.c strerror.c setenv.c herror.c" \
- AR=ar ARFLAGS=cq RANLIB=NONE \
- LIBEXEC=${DESTDIR}/usr/etc/in.telnetd \
- CC="${CC}" LCCFLAGS="-O"
-
-sol2.2.auth solaris2.2.auth:
- make -f ../Config.generic `basename $@ .auth` WHAT=${WHAT} \
- AUTH_LIB="-lkrb" AUTH_LIBPATH="/usr/lib/libkrb.a" \
- AUTH_INC=-I/usr/include/kerberos \
- AUTH_DEF="-DAUTHENTICATION -DKRB4"
-
-dynix3.0.12:
- @echo $@ is untested... it may or may not work..."
- make -f Makefile.generic ${WHAT} \
- LIBS="-ltermcap ../libtelnet/libtelnet.a" \
- LIBPATH="/lib/libc.a /usr/lib/libtermcap.a \
- ../libtelnet/libtelnet.a" \
- DEST=${DESTDIR}/usr/ucb \
- DEFINES=${ODEFS}"-DTERMCAP -DKLUDGELINEMODE \
- -DDEFAULT_IM='\"\r\nDYNIX(R) V3.0.12 (%h) (%t)\r\n\r\r\n\r\"' \
- -DDIAGNOSTICS -DENV_HACK -DOLD_ENVIRON -DNO_STRING_H " \
- INCLUDES="-I.." \
- LIB_OBJ="getent.o strchr.o strrchr.o strdup.o strerror.o \
- setsid.o setenv.o strcasecmp.o strftime.o getopt.o \
- mem.o" \
- LIB_SRC="getent.c strchr.c strrchr.c strdup.c strerror.c \
- setsid.c setenv.c strcasecmp.c strftime.c getopt.c \
- mem.o" \
- AR=ar ARFLAGS=cq RANLIB=ranlib \
- LIBEXEC=${DESTDIR}/usr/etc \
- CC="${CC}" LCCFLAGS="-O"
-
-dynix3.0.17:
- make -f Makefile.generic ${WHAT} \
- LIBS="-ltermcap ../libtelnet/libtelnet.a -lseq" \
- LIBPATH="/lib/libc.a /usr/lib/libtermcap.a \
- ../libtelnet/libtelnet.a /usr/lib/libseq.a" \
- DEST=${DESTDIR}/usr/ucb \
- DEFINES=${ODEFS}"-DTERMCAP -DKLUDGELINEMODE \
- -DDIAGNOSTICS -DENV_HACK -DOLD_ENVIRON -DNO_STRING_H \
- -DDEFAULT_IM='\"\r\nDYNIX(R) V3.0.17 (%h) (%t)\r\n\r\r\n\r\"' \
- " \
- INCLUDES="-I.." \
- LIB_OBJ="getent.o strchr.o strrchr.o strdup.o strerror.o \
- setsid.o strftime.o mem.o" \
- LIB_SRC="getent.c strchr.c strrchr.c strdup.c strerror.c \
- setsid.c strftime.c mem.c" \
- AR=ar ARFLAGS=cq RANLIB=ranlib \
- LIBEXEC=${DESTDIR}/usr/etc \
- CC="${CC}" LCCFLAGS="-O"
-
-ultrix3.1:
- @echo $@ is untested... it may or may not work..."
- make -f Makefile.generic ${WHAT} \
- LIBS="-ltermcap ../libtelnet/libtelnet.a" \
- LIBPATH="/lib/libc.a /usr/lib/libtermcap.a \
- ../libtelnet/libtelnet.a" \
- DEST=${DESTDIR}/usr/ucb \
- DEFINES=${ODEFS}"-DTERMCAP -DKLUDGELINEMODE \
- -DNO_LOGIN_F -DNO_LOGIN_P -DNO_LOGIN_H \
- -DDIAGNOSTICS -DENV_HACK -DOLD_ENVIRON -DUSE_TERMIO \
- -DDEFAULT_IM='\"\r\nULTRIX V3.1 (%h) (%t)\r\n\r\r\n\r\"' \
- -YPOSIX" \
- INCLUDES="-I.." \
- LIB_OBJ="getent.o strdup.o strerror.o setenv.o \
- strftime.o herror.o" \
- LIB_SRC="getent.c strdup.c strerror.c setenv.c \
- strftime.c herror.c" \
- AR=ar ARFLAGS=cq RANLIB=ranlib \
- LIBEXEC=${DESTDIR}/usr/etc \
- CC="${CC}" LCCFLAGS="-O"
-
-ultrix4.0:
- @echo $@ is untested... it may or may not work..."
- make -f Makefile.generic ${WHAT} \
- LIBS="-ltermcap ../libtelnet/libtelnet.a" \
- LIBPATH="/lib/libc.a /usr/lib/libtermcap.a \
- ../libtelnet/libtelnet.a" \
- DEST=${DESTDIR}/usr/ucb \
- DEFINES=${ODEFS}"-DUSE_TERMIO -DTERMCAP \
- -DDEFAULT_IM='\"\r\nULTRIX V4.0 (%h) (%t)\r\n\r\r\n\r\"' \
- -DKLUDGELINEMODE -DDIAGNOSTICS \
- -DNO_LOGIN_F -DNO_LOGIN_P -DNO_LOGIN_H \
- -DENV_HACK -DOLD_ENVIRON" \
- INCLUDES="-I.." \
- LIB_OBJ="getent.o strdup.o strerror.o setsid.o \
- setenv.o strftime.o" \
- LIB_SRC="getent.c strdup.c strerror.c setsid.c \
- setenv.c strftime.c" \
- AR=ar ARFLAGS=cq RANLIB=ranlib \
- LIBEXEC=${DESTDIR}/usr/etc \
- CC="${CC}" LCCFLAGS="-O"
-
-ultrix4.1:
- make -f Makefile.generic ${WHAT} \
- LIBS="-ltermcap ../libtelnet/libtelnet.a" \
- LIBPATH="/lib/libc.a /usr/lib/libtermcap.a \
- ../libtelnet/libtelnet.a" \
- DEST=${DESTDIR}/usr/ucb \
- DEFINES=${ODEFS}"-DUSE_TERMIO -DTERMCAP \
- -DDEFAULT_IM='\"\r\nULTRIX V4.1 (%h) (%t)\r\n\r\r\n\r\"' \
- -DKLUDGELINEMODE -DDIAGNOSTICS \
- -DNO_LOGIN_F -DNO_LOGIN_P -DNO_LOGIN_H \
- -DENV_HACK -DOLD_ENVIRON" \
- INCLUDES="-I.." \
- LIB_OBJ="getent.o strdup.o" \
- LIB_SRC="getent.c strdup.c" \
- AR=ar ARFLAGS=cq RANLIB=ranlib \
- LIBEXEC=${DESTDIR}/usr/etc \
- CC="${CC}" LCCFLAGS="-O"
-
-ultrix4.3:
- make -f Makefile.generic ${WHAT} \
- LIBS="-ltermcap ../libtelnet/libtelnet.a ${AUTH_LIB}" \
- LIBPATH="/lib/libc.a /usr/lib/libtermcap.a \
- ../libtelnet/libtelnet.a ${AUTH_LIBPATH}" \
- DEST=${DESTDIR}/usr/ucb \
- DEFINES=${ODEFS}"-DUSE_TERMIO -DTERMCAP \
- -DDEFAULT_IM='\"\r\nULTRIX V4.3 (%h) (%t)\r\n\r\r\n\r\"' \
- -DKLUDGELINEMODE -DDIAGNOSTICS \
- -DNO_LOGIN_F -DNO_LOGIN_P -DNO_LOGIN_H \
- -DENV_HACK -DOLD_ENVIRON ${AUTH_DEF}" \
- INCLUDES="-I.. ${AUTH_INC}" \
- LIB_OBJ="getent.o strdup.o" \
- LIB_SRC="getent.c strdup.c" \
- AR=ar ARFLAGS=cq RANLIB=ranlib \
- LIBEXEC=${DESTDIR}/usr/etc \
- CC="${CC}" LCCFLAGS="-g"
-
-ultrix4.3.auth:
- make -f ../Config.generic `basename $@ .auth` WHAT=${WHAT} \
- AUTH_LIB="-lkrb -ldes" \
- AUTH_LIBPATH="/usr/lib/libkrb.a /usr/lib/libdes.a" \
- AUTH_DEF="-DAUTHENTICATION -DKRB4"
-
-irix4.0.1:
- @echo $@ is untested... it may or may not work..."
- make -f Makefile.generic ${WHAT} \
- LIBS="-ltermlib ../libtelnet/libtelnet.a" \
- LIBPATH="/usr/lib/libc.a /usr/lib/libtermlib.a \
- ../libtelnet/libtelnet.a" \
- DEST=${DESTDIR}/usr/bin \
- DEFINES=${ODEFS}"-Dvfork=fork -DUSE_TERMIO \
- -DDEFAULT_IM='\"\r\n\r\nIRIX System V.3 (%h) (%t)\r\n\r\r\n\r\"' \
- -DNO_LOGIN_F -DNO_LOGIN_P \
- -DDIAGNOSTICS " \
- INCLUDES="-I.." \
- LIB_OBJ="getent.o setenv.o" \
- LIB_SRC="getent.c setenv.c" \
- AR=ar ARFLAGS=cq RANLIB=NONE \
- LIBEXEC=${DESTDIR}/etc \
- CC="${CC}" LCCFLAGS="-O"
-
-hpux8.0:
- @echo $@ is untested... it may or may not work..."
- make -f Makefile.generic ${WHAT} \
- LIBS="-ltermcap ../libtelnet/libtelnet.a" \
- LIBPATH="/lib/libc.a /usr/lib/libtermcap.a \
- ../libtelnet/libtelnet.a" \
- DEST=${DESTDIR}/usr/bin \
- DEFINES=${ODEFS}"-Dvfork=fork -DUSE_TERMIO \
- -DDEFAULT_IM='\"\r\n\r\nHP-UX 8.0 (%h) (%t)\r\n\r\r\n\r\"' \
- -DNO_LOGIN_F -DNO_LOGIN_P -DNO_LOGIN_H \
- -DDIAGNOSTICS -DLOGIN_ARGS" \
- INCLUDES="-I.." \
- LIB_OBJ="getent.o setenv.o" \
- LIB_SRC="getent.c setenv.c" \
- AR=ar ARFLAGS=cq RANLIB=NONE \
- LIBEXEC=${DESTDIR}/etc \
- CC="${CC}" LCCFLAGS="-O"
-
-next1.0:
- @echo $@ is untested... it may or may not work..."
- make -f Makefile.generic ${WHAT} \
- LIBS="../libtelnet/libtelnet.a -ltermcap -lsys_s ${AUTH_LIB}" \
- LIBPATH="/lib/libc.a /lib/libsys_s.a /usr/lib/libtermcap.a \
- ../libtelnet/libtelnet.a ${AUTH_LIBPATH}" \
- DEST=${DESTDIR}/usr/ucb \
- DEFINES=${ODEFS}"-bsd -DTERMCAP -DKLUDGELINEMODE \
- -DDEFAULT_IM='\"\r\nNeXT 1.0 (%h) (%t)\r\n\r\r\n\r\"' \
- -DDIAGNOSTICS -DENV_HACK -DOLD_ENVIRON \
- -DNO_STRING_H -Dgetenv=getenv_ ${AUTH_DEF}" \
- INCLUDES="-I.. ${AUTH_INC}" \
- LIB_OBJ="strdup.o setenv.o setsid.o strftime.o \
- strcasecmp.o gettytab.o" \
- LIB_SRC=s"trdup.c setenv.c setsid.c strftime.c \
- strcasecmp.c gettytab.c" \
- CC="${CC}" LCCFLAGS="-O" \
- VPATH=../../getty \
- AR=ar ARFLAGS=cq RANLIB=ranlib \
- LIBEXEC=${DESTDIR}/usr/etc
-
-#
-# For the convex, make symbolic links to the tc[sg]getattr.c routines,
-# because we are using posix stuff, but not the posix library...
-# Pass the stuff to Makefile.generic by passing the object/source names
-# in through LIB_OBJ and LIB_SRC
-#
-convex:
- @echo $@ is untested... it may or may not work..."
- ln -s ../../rel_usr/src/lib/libc/posix/tcsetattr.c tcsetattr.c
- ln -s ../../rel_usr/src/lib/libc/posix/tcgetattr.c tcgetattr.c
- make -f Makefile.generic ${WHAT} \
- LIBS="-ltermcap ../libtelnet/libtelnet.a" \
- LIBPATH="../libtelnet/libtelnet.a" \
- AR=ar ARFLAGS=cq RANLIB=ranlib \
- LIBEXEC=${DESTDIR}/usr/etc/in.telnetd \
- CC="${CC}" LCCFLAGS="-g ${OPTLEV} -Dconvex" \
- DEFINES=${ODEFS}"-DUSE_TERMIO -DLINEMODE \
- -DDEFAULT_IM='\"\r\nConvex (%h) (%t)\r\n\r\r\n\r\"' \
- -DDIAGNOSTICS -DENV_HACK -DOLD_ENVIRON" \
- INCLUDES="-I.." \
- LIB_OBJ="getent.o setsid.o strftime.o \
- tcsetattr.o tcgetattr.o" \
- LIB_SRC="getent.c setsid.c strftime.c \
- tcsetattr.c tcgetattr.c"
-
-clean cleandir:
- make -f Makefile.generic $@
+++ /dev/null
-thisconfigdir=.
-myfulldir=appl/telnet
-mydir=.
-BUILDTOP=$(REL)..$(S)..
-SUBDIRS=libtelnet telnet telnetd
+++ /dev/null
-
-This is a distribution of both client and server telnet. These programs
-have been compiled on:
- telnet telnetd
- BSD 4.4 x x
- BSD 4.3 Reno X X
- UNICOS 8.0 X X
- UNICOS 7.C X X
- UNICOS 7.0 X X
- UNICOS 6.1 X X
- BSDI 1.0 X X
- Solaris 2.2 x x (no linemode in server)
- Solaris 2.3 x x (no linemode in server)
- SunOs 4.1.3 X X (no linemode in server)
- Ultrix 4.3 X X (no linemode in server)
- DYNIX V3.0.17.9 X X (no linemode in server)
- HP-UX 8.0 x x (no linemode in server)
-
-In addition, previous versions have been compiled on the following
-machines, but were not available for testing this version.
- telnet telnetd
- Next1.0 X X
- UNICOS 6.0 X X
- UNICOS 5.1 X X
- UNICOS 5.0 X X
- SunOs 4.0.3c X X (no linemode in server)
- BSD 4.3 X X (no linemode in server)
- DYNIX V3.0.12 X X (no linemode in server)
- Ultrix 3.1 X X (no linemode in server)
- Ultrix 4.0 X X (no linemode in server)
- SunOs 3.5 X X (no linemode in server)
-
-This code should work, but there are no guarantees.
-
-January 19, 1994
-
-This is a list of some of the changes since the last tar release
-of telnet/telnetd. There are probably other changes that aren't
-listed here, but this should hit a lot of the main ones.
-
- General:
- Changed #define for AUTHENTICATE to AUTHENTICATION
- Changed #define for ENCRYPT to ENCRYPTION
- Changed #define for DES_ENCRYPT to DES_ENCRYPTION
-
- Added support for SPX authentication: -DSPX
-
- Added support for Kerberos Version 5 authentication: -DKRB5
-
- Added support for ANSI C function prototypes
-
- Added support for the NEW-ENVIRON option (RFC-1572)
- including support for USERVAR.
-
- Made support for the old Environment Option (RFC-1408)
- conditional on -DOLD_ENVIRON
-
- Added #define ENV_HACK - support for RFC 1571
-
- The encryption code is removed from the public distributions.
- Domestic 4.4 BSD distributions contain the encryption code.
-
- ENV_HACK: Code to deal with systems that only implement
- the old ENVIRON option, and have reversed definitions
- of ENV_VAR and ENV_VAL. Also fixes ENV processing in
- client to handle things besides just the default set...
-
- NO_BSD_SETJMP: UNICOS configuration for
- UNICOS 6.1/6.0/5.1/5.0 systems.
-
- STREAMSPTY: Use /dev/ptmx to get a clean pty. This
- is for SVr4 derivatives (Like Solaris)
-
- UTMPX: For systems that have /etc/utmpx. This is for
- SVr4 derivatives (Like Solaris)
-
- Definitions for BSDI 1.0
-
- Definitions for 4.3 Reno and 4.4 BSD.
-
- Definitions for UNICOS 8.0 and UNICOS 7.C
-
- Definitions for Solaris 2.0
-
- Definitions for HP-UX 8.0
-
- Latest Copyright notices from Berkeley.
-
- FLOW-CONTROL: support for RFC-XXXx
-
-
- Client Specific:
-
- Fix the "send" command to not send garbage...
-
- Fix status message for "skiprc"
-
- Make sure to send NAWS after telnet has been suspended
- or an external command has been run, if the window size
- has changed.
-
- sysV88 support.
-
- Server Specific:
-
- Support flowcontrol option in non-linemode servers.
-
- -k Server supports Kludge Linemode, but will default to
- either single character mode or real Linemode support.
- The user will have to explicitly ask to switch into
- kludge linemode. ("stty extproc", or escape back to
- to telnet and say "mode line".)
-
- -u Specify the length of the hostname field in the utmp
- file. Hostname longer than this length will be put
- into the utmp file in dotted decimal notation, rather
- than putting in a truncated hostname.
-
- -U Registered hosts only. If a reverse hostname lookup
- fails, the connection will be refused.
-
- -f/-F
- Allows forwarding of credentials for KRB5.
-
-Februrary 22, 1991:
-
- Features:
-
- This version of telnet/telnetd has support for both
- the AUTHENTICATION and ENCRYPTION options. The
- AUTHENTICATION option is fairly well defined, and
- an option number has been assigned to it. The
- ENCRYPTION option is still in a state of flux; an
- option number has been assigned to, but it is still
- subject to change. The code is provided in this release
- for experimental and testing purposes.
-
- The telnet "send" command can now be used to send
- do/dont/will/wont commands, with any telnet option
- name. The rules for when do/dont/will/wont are sent
- are still followed, so just because the user requests
- that one of these be sent doesn't mean that it will
- be sent...
-
- The telnet "getstatus" command no longer requires
- that option printing be enabled to see the response
- to the "DO STATUS" command.
-
- A -n flag has been added to telnetd to disable
- keepalives.
-
- A new telnet command, "auth" has been added (if
- AUTHENTICATE is defined). It has four sub-commands,
- "status", "disable", "enable" and "help".
-
- A new telnet command, "encrypt" has been added (if
- ENCRYPT is defined). It has many sub-commands:
- "enable", "type", "start", "stop", "input",
- "-input", "output", "-output", "status", and "help".
-
- The LOGOUT option is now supported by both telnet
- and telnetd, a new command, "logout", was added
- to support this.
-
- Several new toggle options were added:
- "autoencrypt", "autodecrypt", "autologin", "authdebug",
- "encdebug", "skiprc", "verbose_encrypt"
-
- An "rlogin" interface has been added. If the program
- is named "rlogin", or the "-r" flag is given, then
- an rlogin type of interface will be used.
- ~. Terminates the session
- ~<susp> Suspend the session
- ~^] Escape to telnet command mode
- ~~ Pass through the ~.
- BUG: If you type the rlogin escape character
- in the middle of a line while in rlogin
- mode, you cannot erase it or any characters
- before it. Hopefully this can be fixed
- in a future release...
-
- General changes:
-
- A "libtelnet.a" has now been created. This libraray
- contains code that is common to both telnet and
- telnetd. This is also where library routines that
- are needed, but are not in the standard C library,
- are placed.
-
- The makefiles have been re-done. All of the site
- specific configuration information has now been put
- into a single "Config.generic" file, in the top level
- directory. Changing this one file will take care of
- all three subdirectories. Also, to add a new/local
- definition, a "Config.local" file may be created
- at the top level; if that file exists, the subdirectories
- will use that file instead of "Config.generic".
-
- Many 1-2 line functions in commands.c have been
- removed, and just inserted in-line, or replaced
- with a macro.
-
- Bug Fixes:
-
- The non-termio code in both telnet and telnetd was
- setting/clearing CTLECH in the sg_flags word. This
- was incorrect, and has been changed to set/clear the
- LCTLECH bit in the local mode word.
-
- The SRCRT #define has been removed. If IP_OPTIONS
- and IPPROTO_IP are defined on the system, then the
- source route code is automatically enabled.
-
- The NO_GETTYTAB #define has been removed; there
- is a compatability routine that can be built into
- libtelnet to achive the same results.
-
- The server, telnetd, has been switched to use getopt()
- for parsing the argument list.
-
- The code for getting the input/output speeds via
- cfgetispeed()/cfgetospeed() was still not quite
- right in telnet. Posix says if the ispeed is 0,
- then it is really equal to the ospeed.
-
- The suboption processing code in telnet now has
- explicit checks to make sure that we received
- the entire suboption (telnetd was already doing this).
-
- The telnet code for processing the terminal type
- could cause a core dump if an existing connection
- was closed, and a new connection opened without
- exiting telnet.
-
- Telnetd was doing a TCSADRAIN when setting the new
- terminal settings; This is not good, because it means
- that the tcsetattr() will hang waiting for output to
- drain, and telnetd is the only one that will drain
- the output... The fix is to use TCSANOW which does
- not wait.
-
- Telnetd was improperly setting/clearing the ISTRIP
- flag in the c_lflag field, it should be using the
- c_iflag field.
-
- When the child process of telnetd was opening the
- slave side of the pty, it was re-setting the EXTPROC
- bit too early, and some of the other initialization
- code was wiping it out. This would cause telnetd
- to go out of linemode and into single character mode.
-
- One instance of leaving linemode in telnetd forgot
- to send a WILL ECHO to the client, the net result
- would be that the user would see double character
- echo.
-
- If the MODE was being changed several times very
- quickly, telnetd could get out of sync with the
- state changes and the returning acks; and wind up
- being left in the wrong state.
-
-September 14, 1990:
-
- Switch the client to use getopt() for parsing the
- argument list. The 4.3Reno getopt.c is included for
- systems that don't have getopt().
-
- Use the posix _POSIX_VDISABLE value for what value
- to use when disabling special characters. If this
- is undefined, it defaults to 0x3ff.
-
- For non-termio systems, TIOCSETP was being used to
- change the state of the terminal. This causes the
- input queue to be flushed, which we don't want. This
- is now changed to TIOCSETN.
-
- Take out the "#ifdef notdef" around the code in the
- server that generates a "sync" when the pty oputput
- is flushed. The potential problem is that some older
- telnet clients may go into an infinate loop when they
- receive a "sync", if so, the server can be compiled
- with "NO_URGENT" defined.
-
- Fix the client where it was setting/clearing the OPOST
- bit in the c_lflag field, not the c_oflag field.
-
- Fix the client where it was setting/clearing the ISTRIP
- bit in the c_lflag field, not the c_iflag field. (On
- 4.3Reno, this is the ECHOPRT bit in the c_lflag field.)
- The client also had its interpretation of WILL BINARY
- and DO BINARY reversed.
-
- Fix a bug in client that would cause a core dump when
- attempting to remove the last environment variable.
-
- In the client, there were a few places were switch()
- was being passed a character, and if it was a negative
- value, it could get sign extended, and not match
- the 8 bit case statements. The fix is to and the
- switch value with 0xff.
-
- Add a couple more printoption() calls in the client, I
- don't think there are any more places were a telnet
- command can be received and not printed out when
- "options" is on.
-
- A new flag has been added to the client, "-a". Currently,
- this just causes the USER name to be sent across, in
- the future this may be used to signify that automatic
- authentication is requested.
-
- The USER variable is now only sent by the client if
- the "-a" or "-l user" options are explicity used, or
- if the user explicitly asks for the "USER" environment
- variable to be exported. In the server, if it receives
- the "USER" environment variable, it won't print out the
- banner message, so that only "Password:" will be printed.
- This makes the symantics more like rlogin, and should be
- more familiar to the user. (People are not used to
- getting a banner message, and then getting just a
- "Password:" prompt.)
-
- Re-vamp the code for starting up the child login
- process. The code was getting ugly, and it was
- hard to tell what was really going on. What we
- do now is after the fork(), in the child:
- 1) make sure we have no controlling tty
- 2) open and initialize the tty
- 3) do a setsid()/setpgrp()
- 4) makes the tty our controlling tty.
- On some systems, #2 makes the tty our controlling
- tty, and #4 is a no-op. The parent process does
- a gets rid of any controlling tty after the child
- is fork()ed.
-
- Use the strdup() library routine in telnet, instead
- of the local savestr() routine. If you don't have
- strdup(), you need to define NO_STRDUP.
-
- Add support for ^T (SIGINFO/VSTATUS), found in the
- 4.3Reno distribution. This maps to the AYT character.
- You need a 4-line bugfix in the kernel to get this
- to work properly:
-
- > *** tty_pty.c.ORG Tue Sep 11 09:41:53 1990
- > --- tty_pty.c Tue Sep 11 17:48:03 1990
- > ***************
- > *** 609,613 ****
- > if ((tp->t_lflag&NOFLSH) == 0)
- > ttyflush(tp, FREAD|FWRITE);
- > ! pgsignal(tp->t_pgrp, *(unsigned int *)data);
- > return(0);
- > }
- > --- 609,616 ----
- > if ((tp->t_lflag&NOFLSH) == 0)
- > ttyflush(tp, FREAD|FWRITE);
- > ! pgsignal(tp->t_pgrp, *(unsigned int *)data, 1);
- > ! if ((*(unsigned int *)data == SIGINFO) &&
- > ! ((tp->t_lflag&NOKERNINFO) == 0))
- > ! ttyinfo(tp);
- > return(0);
- > }
-
- The client is now smarter when setting the telnet escape
- character; it only sets it to one of VEOL and VEOL2 if
- one of them is undefined, and the other one is not already
- defined to the telnet escape character.
-
- Handle TERMIOS systems that have seperate input and output
- line speed settings imbedded in the flags.
-
- Many other minor bug fixes.
-
-June 20, 1990:
- Re-organize makefiles and source tree. The telnet/Source
- directory is now gone, and all the source that was in
- telnet/Source is now just in the telnet directory.
-
- Seperate makefile for each system are now gone. There
- are two makefiles, Makefile and Makefile.generic.
- The "Makefile" has the definitions for the various
- system, and "Makefile.generic" does all the work.
- There is a variable called "WHAT" that is used to
- specify what to make. For example, in the telnet
- directory, you might say:
- make 4.4bsd WHAT=clean
- to clean out the directory.
-
- Add support for the ENVIRON and XDISPLOC options.
- In order for the server to work, login has to have
- the "-p" option to preserve environment variables.
-
- Add the SOFT_TAB and LIT_ECHO modes in the LINEMODE support.
-
- Add the "-l user" option to command line and open command
- (This is passed through the ENVIRON option).
-
- Add the "-e" command line option, for setting the escape
- character.
-
- Add the "-D", diagnostic, option to the server. This allows
- the server to print out debug information, which is very
- useful when trying to debug a telnet that doesn't have any
- debugging ability.
-
- Turn off the literal next character when not in LINEMODE.
-
- Don't recognize ^Y locally, just pass it through.
-
- Make minor modifications for Sun4.0 and Sun4.1
-
- Add support for both FORW1 and FORW2 characters. The
- telnet escpape character is set to whichever of the
- two is not being used. If both are in use, the escape
- character is not set, so when in linemode the user will
- have to follow the escape character with a <CR> or <EOF)
- to get it passed through.
-
- Commands can now be put in single and double quotes, and
- a backslash is now an escape character. This is needed
- for allowing arbitrary strings to be assigned to environment
- variables.
-
- Switch telnetd to use macros like telnet for keeping
- track of the state of all the options.
-
- Fix telnetd's processing of options so that we always do
- the right processing of the LINEMODE option, regardless
- of who initiates the request to turn it on. Also, make
- sure that if the other side went "WILL ECHO" in response
- to our "DO ECHO", that we send a "DONT ECHO" to get the
- option turned back off!
-
- Fix the TERMIOS setting of the terminal speed to handle both
- BSD's seperate fields, and the SYSV method of CBAUD bits.
-
- Change how we deal with the other side refusing to enable
- an option. The sequence used to be: send DO option; receive
- WONT option; send DONT option. Now, the sequence is: send
- DO option; receive WONT option. Both should be valid
- according to the spec, but there has been at least one
- client implementation of telnet identified that can get
- really confused by this. (The exact sequence, from a trace
- on the server side, is (numbers are number of responses that
- we expect to get after that line...):
-
- send WILL ECHO 1 (initial request)
- send WONT ECHO 2 (server is changing state)
- recv DO ECHO 1 (first reply, ok. expect DONT ECHO next)
- send WILL ECHO 2 (server changes state again)
- recv DONT ECHO 1 (second reply, ok. expect DO ECHO next)
- recv DONT ECHO 0 (third reply, wrong answer. got DONT!!!)
- *** send WONT ECHO (send WONT to acknowledge the DONT)
- send WILL ECHO 1 (ask again to enable option)
- recv DO ECHO 0
-
- recv DONT ECHO 0
- send WONT ECHO 1
- recv DONT ECHO 0
- recv DO ECHO 1
- send WILL ECHO 0
- (and the last 5 lines loop forever)
-
- The line with the "***" is last of the WILL/DONT/WONT sequence.
- The change to the server to not generate that makes this same
- example become:
-
- send will ECHO 1
- send wont ECHO 2
- recv do ECHO 1
- send will ECHO 2
- recv dont ECHO 1
- recv dont ECHO 0
- recv do ECHO 1
- send will ECHO 0
-
- There is other option negotiation going on, and not sending
- the third part changes some of the timings, but this specific
- example no longer gets stuck in a loop. The "telnet.state"
- file has been modified to reflect this change to the algorithm.
-
- A bunch of miscellaneous bug fixes and changes to make
- lint happier.
-
- This version of telnet also has some KERBEROS stuff in
- it. This has not been tested, it uses an un-authorized
- telnet option number, and uses an out-of-date version
- of the (still being defined) AUTHENTICATION option.
- There is no support for this code, do not enable it.
-
-
-March 1, 1990:
-CHANGES/BUGFIXES SINCE LAST RELEASE:
- Some support for IP TOS has been added. Requires that the
- kernel support the IP_TOS socket option (currently this
- is only in UNICOS 6.0).
-
- Both telnet and telnetd now use the cc_t typedef. typedefs are
- included for systems that don't have it (in termios.h).
-
- SLC_SUSP was not supported properly before. It is now.
-
- IAC EOF was not translated properly in telnetd for SYSV_TERMIO
- when not in linemode. It now saves a copy of the VEOF character,
- so that when ICANON is turned off and we can't trust it anymore
- (because it is now the VMIN character) we use the saved value.
-
- There were two missing "break" commands in the linemode
- processing code in telnetd.
-
- Telnetd wasn't setting the kernel window size information
- properly. It was using the rows for both rows and columns...
-
-Questions/comments go to
- David Borman
- Cray Research, Inc.
- 655F Lone Oak Drive
- Eagan, MN 55123
- dab@cray.com.
-
-README: You are reading it.
-
-Config.generic:
- This file contains all the OS specific definitions. It
- has pre-definitions for many common system types, and is
- in standard makefile fromat. See the comments at the top
- of the file for more information.
-
-Config.local:
- This is not part of the distribution, but if this file exists,
- it is used instead of "Config.generic". This allows site
- specific configuration without having to modify the distributed
- "Config.generic" file.
-
-kern.diff:
- This file contains the diffs for the changes needed for the
- kernel to support LINEMODE is the server. These changes are
- for a 4.3BSD system. You may need to make some changes for
- your particular system.
-
- There is a new bit in the terminal state word, TS_EXTPROC.
- When this bit is set, several aspects of the terminal driver
- are disabled. Input line editing, character echo, and
- mapping of signals are all disabled. This allows the telnetd
- to turn of these functions when in linemode, but still keep
- track of what state the user wants the terminal to be in.
-
- New ioctl()s:
-
- TIOCEXT Turn on/off the TS_EXTPROC bit
- TIOCGSTATE Get t_state of tty to look at TS_EXTPROC bit
- TIOCSIG Generate a signal to processes in the
- current process group of the pty.
-
- There is a new mode for packet driver, the TIOCPKT_IOCTL bit.
- When packet mode is turned on in the pty, and the TS_EXTPROC
- bit is set, then whenever the state of the pty is changed, the
- next read on the master side of the pty will have the TIOCPKT_IOCTL
- bit set, and the data will contain the following:
- struct xx {
- struct sgttyb a;
- struct tchars b;
- struct ltchars c;
- int t_state;
- int t_flags;
- }
- This allows the process on the server side of the pty to know
- when the state of the terminal has changed, and what the new
- state is.
-
- However, if you define USE_TERMIO or SYSV_TERMIO, the code will
- expect that the structure returned in the TIOCPKT_IOCTL is
- the termio/termios structure.
-
-stty.diff:
- This file contains the changes needed for the stty(1) program
- to report on the current status of the TS_EXTPROC bit. It also
- allows the user to turn on/off the TS_EXTPROC bit. This is useful
- because it allows the user to say "stty -extproc", and the
- LINEMODE option will be automatically disabled, and saying "stty
- extproc" will re-enable the LINEMODE option.
-
-telnet.state:
- Both the client and server have code in them to deal
- with option negotiation loops. The algorithm that is
- used is described in this file.
-
-telnet:
- This directory contains the client code. No kernel changes are
- needed to use this code.
-
-telnetd:
- This directory contains the server code. If LINEMODE or KLUDGELINEMODE
- are defined, then the kernel modifications listed above are needed.
-
-libtelnet:
- This directory contains code that is common to both the client
- and the server.
-
-arpa:
- This directory has a new <arpa/telnet.h>
-
-libtelnet/Makefile.4.4:
-telnet/Makefile.4.4:
-telnetd/Makefile.4.4:
- These are the makefiles that can be used on a 4.3Reno
- system when this software is installed in /usr/src/lib/libtelnet,
- /usr/src/libexec/telnetd, and /usr/src/usr.bin/telnet.
-
-
-The following TELNET options are supported:
-
- LINEMODE:
- The LINEMODE option is supported as per RFC1116. The
- FORWARDMASK option is not currently supported.
-
- BINARY: The client has the ability to turn on/off the BINARY
- option in each direction. Turning on BINARY from
- server to client causes the LITOUT bit to get set in
- the terminal driver on both ends, turning on BINARY
- from the client to the server causes the PASS8 bit
- to get set in the terminal driver on both ends.
-
- TERMINAL-TYPE:
- This is supported as per RFC1091. On the server side,
- when a terminal type is received, termcap/terminfo
- is consulted to determine if it is a known terminal
- type. It keeps requesting terminal types until it
- gets one that it recongnizes, or hits the end of the
- list. The server side looks up the entry in the
- termcap/terminfo data base, and generates a list of
- names which it then passes one at a time to each
- request for a terminal type, duplicating the last
- entry in the list before cycling back to the beginning.
-
- NAWS: The Negotiate about Window Size, as per RFC 1073.
-
- TERMINAL-SPEED:
- Implemented as per RFC 1079
-
- TOGGLE-FLOW-CONTROL:
- Implemented as per RFC 1080
-
- TIMING-MARK:
- As per RFC 860
-
- SGA: As per RFC 858
-
- ECHO: As per RFC 857
-
- LOGOUT: As per RFC 727
-
- STATUS:
- The server will send its current status upon
- request. It does not ask for the clients status.
- The client will request the servers current status
- from the "send getstatus" command.
-
- ENVIRON:
- This option is currently being defined by the IETF
- Telnet Working Group, and an RFC has not yet been
- issued, but should be in the near future...
-
- X-DISPLAY-LOCATION:
- This functionality can be done through the ENVIRON
- option, it is added here for completeness.
-
- AUTHENTICATION:
- This option is currently being defined by the IETF
- Telnet Working Group, and an RFC has not yet been
- issued. The basic framework is pretty much decided,
- but the definitions for the specific authentication
- schemes is still in a state of flux.
-
- ENCRYPTION:
- This option is currently being defined by the IETF
- Telnet Working Group, and an RFC has not yet been
- issued. The draft RFC is still in a state of flux,
- so this code may change in the future.
+++ /dev/null
-/*
- * Copyright (c) 1983, 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.
- *
- * @(#)telnet.h 8.1 (Berkeley) 6/2/93
- */
-
-#ifndef _TELNET_H_
-#define _TELNET_H_
-
-/*
- * Definitions for the TELNET protocol.
- */
-#define IAC 255 /* interpret as command: */
-#define DONT 254 /* you are not to use option */
-#define DO 253 /* please, you use option */
-#define WONT 252 /* I won't use option */
-#define WILL 251 /* I will use option */
-#define SB 250 /* interpret as subnegotiation */
-#define GA 249 /* you may reverse the line */
-#define EL 248 /* erase the current line */
-#define EC 247 /* erase the current character */
-#define AYT 246 /* are you there */
-#define AO 245 /* abort output--but let prog finish */
-#define IP 244 /* interrupt process--permanently */
-#define BREAK 243 /* break */
-#define DM 242 /* data mark--for connect. cleaning */
-#define NOP 241 /* nop */
-#define SE 240 /* end sub negotiation */
-#define EOR 239 /* end of record (transparent mode) */
-#define ABORT 238 /* Abort process */
-#define SUSP 237 /* Suspend process */
-#define xEOF 236 /* End of file: EOF is already used... */
-
-#define SYNCH 242 /* for telfunc calls */
-
-#ifdef TELCMDS
-char *telcmds[] = {
- "EOF", "SUSP", "ABORT", "EOR",
- "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC",
- "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0,
-};
-#else
-extern char *telcmds[];
-#endif
-
-#define TELCMD_FIRST xEOF
-#define TELCMD_LAST IAC
-#define TELCMD_OK(x) ((unsigned int)(x) <= TELCMD_LAST && \
- (unsigned int)(x) >= TELCMD_FIRST)
-#define TELCMD(x) telcmds[(x)-TELCMD_FIRST]
-
-/* telnet options */
-#define TELOPT_BINARY 0 /* 8-bit data path */
-#define TELOPT_ECHO 1 /* echo */
-#define TELOPT_RCP 2 /* prepare to reconnect */
-#define TELOPT_SGA 3 /* suppress go ahead */
-#define TELOPT_NAMS 4 /* approximate message size */
-#define TELOPT_STATUS 5 /* give status */
-#define TELOPT_TM 6 /* timing mark */
-#define TELOPT_RCTE 7 /* remote controlled transmission and echo */
-#define TELOPT_NAOL 8 /* negotiate about output line width */
-#define TELOPT_NAOP 9 /* negotiate about output page size */
-#define TELOPT_NAOCRD 10 /* negotiate about CR disposition */
-#define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */
-#define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */
-#define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */
-#define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */
-#define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */
-#define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */
-#define TELOPT_XASCII 17 /* extended ascic character set */
-#define TELOPT_LOGOUT 18 /* force logout */
-#define TELOPT_BM 19 /* byte macro */
-#define TELOPT_DET 20 /* data entry terminal */
-#define TELOPT_SUPDUP 21 /* supdup protocol */
-#define TELOPT_SUPDUPOUTPUT 22 /* supdup output */
-#define TELOPT_SNDLOC 23 /* send location */
-#define TELOPT_TTYPE 24 /* terminal type */
-#define TELOPT_EOR 25 /* end or record */
-#define TELOPT_TUID 26 /* TACACS user identification */
-#define TELOPT_OUTMRK 27 /* output marking */
-#define TELOPT_TTYLOC 28 /* terminal location number */
-#define TELOPT_3270REGIME 29 /* 3270 regime */
-#define TELOPT_X3PAD 30 /* X.3 PAD */
-#define TELOPT_NAWS 31 /* window size */
-#define TELOPT_TSPEED 32 /* terminal speed */
-#define TELOPT_LFLOW 33 /* remote flow control */
-#define TELOPT_LINEMODE 34 /* Linemode option */
-#define TELOPT_XDISPLOC 35 /* X Display Location */
-#define TELOPT_OLD_ENVIRON 36 /* Old - Environment variables */
-#define TELOPT_AUTHENTICATION 37/* Authenticate */
-#define TELOPT_ENCRYPT 38 /* Encryption option */
-#define TELOPT_NEW_ENVIRON 39 /* New - Environment variables */
-#define TELOPT_EXOPL 255 /* extended-options-list */
-
-
-#define NTELOPTS (1+TELOPT_NEW_ENVIRON)
-#ifdef TELOPTS
-char *telopts[NTELOPTS+1] = {
- "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME",
- "STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP",
- "NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS",
- "NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
- "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT",
- "SEND LOCATION", "TERMINAL TYPE", "END OF RECORD",
- "TACACS UID", "OUTPUT MARKING", "TTYLOC",
- "3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW",
- "LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION",
- "ENCRYPT", "NEW-ENVIRON",
- 0,
-};
-#define TELOPT_FIRST TELOPT_BINARY
-#define TELOPT_LAST TELOPT_NEW_ENVIRON
-#define TELOPT_OK(x) ((unsigned int)(x) <= TELOPT_LAST)
-#define TELOPT(x) telopts[(x)-TELOPT_FIRST]
-#endif
-
-/* sub-option qualifiers */
-#define TELQUAL_IS 0 /* option is... */
-#define TELQUAL_SEND 1 /* send option */
-#define TELQUAL_INFO 2 /* ENVIRON: informational version of IS */
-#define TELQUAL_REPLY 2 /* AUTHENTICATION: client version of IS */
-#define TELQUAL_NAME 3 /* AUTHENTICATION: client version of IS */
-
-#define LFLOW_OFF 0 /* Disable remote flow control */
-#define LFLOW_ON 1 /* Enable remote flow control */
-#define LFLOW_RESTART_ANY 2 /* Restart output on any char */
-#define LFLOW_RESTART_XON 3 /* Restart output only on XON */
-
-/*
- * LINEMODE suboptions
- */
-
-#define LM_MODE 1
-#define LM_FORWARDMASK 2
-#define LM_SLC 3
-
-#define MODE_EDIT 0x01
-#define MODE_TRAPSIG 0x02
-#define MODE_ACK 0x04
-#define MODE_SOFT_TAB 0x08
-#define MODE_LIT_ECHO 0x10
-
-#define MODE_MASK 0x1f
-
-/* Not part of protocol, but needed to simplify things... */
-#define MODE_FLOW 0x0100
-#define MODE_ECHO 0x0200
-#define MODE_INBIN 0x0400
-#define MODE_OUTBIN 0x0800
-#define MODE_FORCE 0x1000
-
-#define SLC_SYNCH 1
-#define SLC_BRK 2
-#define SLC_IP 3
-#define SLC_AO 4
-#define SLC_AYT 5
-#define SLC_EOR 6
-#define SLC_ABORT 7
-#define SLC_EOF 8
-#define SLC_SUSP 9
-#define SLC_EC 10
-#define SLC_EL 11
-#define SLC_EW 12
-#define SLC_RP 13
-#define SLC_LNEXT 14
-#define SLC_XON 15
-#define SLC_XOFF 16
-#define SLC_FORW1 17
-#define SLC_FORW2 18
-
-#define NSLC 18
-
-/*
- * For backwards compatability, we define SLC_NAMES to be the
- * list of names if SLC_NAMES is not defined.
- */
-#define SLC_NAMELIST "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \
- "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \
- "LNEXT", "XON", "XOFF", "FORW1", "FORW2", 0,
-#ifdef SLC_NAMES
-char *slc_names[] = {
- SLC_NAMELIST
-};
-#else
-extern char *slc_names[];
-#define SLC_NAMES SLC_NAMELIST
-#endif
-
-#define SLC_NAME_OK(x) ((unsigned int)(x) <= NSLC)
-#define SLC_NAME(x) slc_names[x]
-
-#define SLC_NOSUPPORT 0
-#define SLC_CANTCHANGE 1
-#define SLC_VARIABLE 2
-#define SLC_DEFAULT 3
-#define SLC_LEVELBITS 0x03
-
-#define SLC_FUNC 0
-#define SLC_FLAGS 1
-#define SLC_VALUE 2
-
-#define SLC_ACK 0x80
-#define SLC_FLUSHIN 0x40
-#define SLC_FLUSHOUT 0x20
-
-#define OLD_ENV_VAR 1
-#define OLD_ENV_VALUE 0
-#define NEW_ENV_VAR 0
-#define NEW_ENV_VALUE 1
-#define ENV_ESC 2
-#define ENV_USERVAR 3
-
-/*
- * AUTHENTICATION suboptions
- */
-
-/*
- * Who is authenticating who ...
- */
-#define AUTH_WHO_CLIENT 0 /* Client authenticating server */
-#define AUTH_WHO_SERVER 1 /* Server authenticating client */
-#define AUTH_WHO_MASK 1
-
-/*
- * amount of authentication done
- */
-#define AUTH_HOW_ONE_WAY 0
-#define AUTH_HOW_MUTUAL 2
-#define AUTH_HOW_MASK 2
-
-/*
- * should we be encrypting? (not yet formally standardized)
- */
-#define AUTH_ENCRYPT_OFF 0
-#define AUTH_ENCRYPT_ON 4
-#define AUTH_ENCRYPT_MASK 4
-
-#define AUTHTYPE_NULL 0
-#define AUTHTYPE_KERBEROS_V4 1
-#define AUTHTYPE_KERBEROS_V5 2
-#define AUTHTYPE_SPX 3
-#define AUTHTYPE_MINK 4
-#define AUTHTYPE_CNT 5
-
-#define AUTHTYPE_TEST 99
-
-#ifdef AUTH_NAMES
-char *authtype_names[] = {
- "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 0,
-};
-#else
-extern char *authtype_names[];
-#endif
-
-#define AUTHTYPE_NAME_OK(x) ((unsigned int)(x) < AUTHTYPE_CNT)
-#define AUTHTYPE_NAME(x) authtype_names[x]
-
-/*
- * ENCRYPTion suboptions
- */
-#define ENCRYPT_IS 0 /* I pick encryption type ... */
-#define ENCRYPT_SUPPORT 1 /* I support encryption types ... */
-#define ENCRYPT_REPLY 2 /* Initial setup response */
-#define ENCRYPT_START 3 /* Am starting to send encrypted */
-#define ENCRYPT_END 4 /* Am ending encrypted */
-#define ENCRYPT_REQSTART 5 /* Request you start encrypting */
-#define ENCRYPT_REQEND 6 /* Request you send encrypting */
-#define ENCRYPT_ENC_KEYID 7
-#define ENCRYPT_DEC_KEYID 8
-#define ENCRYPT_CNT 9
-
-#define ENCTYPE_ANY 0
-#define ENCTYPE_DES_CFB64 1
-#define ENCTYPE_DES_OFB64 2
-#define ENCTYPE_CNT 3
-
-#ifdef ENCRYPT_NAMES
-char *encrypt_names[] = {
- "IS", "SUPPORT", "REPLY", "START", "END",
- "REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID",
- 0,
-};
-char *enctype_names[] = {
- "ANY", "DES_CFB64", "DES_OFB64", 0,
-};
-#else
-extern char *encrypt_names[];
-extern char *enctype_names[];
-#endif
-
-
-#define ENCRYPT_NAME_OK(x) ((unsigned int)(x) < ENCRYPT_CNT)
-#define ENCRYPT_NAME(x) encrypt_names[x]
-
-#define ENCTYPE_NAME_OK(x) ((unsigned int)(x) < ENCTYPE_CNT)
-#define ENCTYPE_NAME(x) enctype_names[x]
-
-#endif /* !_TELNET_H_ */
+++ /dev/null
-K5_AC_INIT(configure.in)
-CONFIG_RULES
-dnl AC_CONFIG_SUBDIRS(libtelnet telnet telnetd)
-dnl
-dnl from old libtelnet/configure.in, plus additional header & func checks
-dnl
-AC_REPLACE_FUNCS([strcasecmp strdup setsid strerror strftime getopt herror parsetos])
-AC_CHECK_FUNCS(setenv unsetenv getenv gettosbyname cgetent gettosbyname vsnprintf)
-AC_CHECK_HEADERS(stdlib.h string.h unistd.h arpa/nameser.h sys/select.h arpa/inet.h sys/filio.h curses.h utmp.h sys/time.h sys/tty.h sac.h sys/ptyvar.h sys/stream.h sys/utsname.h memory.h)
-if test $ac_cv_func_setenv = no || test $ac_cv_func_unsetenv = no \
- || test $ac_cv_func_getenv = no; then
- SETENVSRC=setenv.c
- SETENVOBJ=setenv.o
- AC_SUBST([SETENVSRC])
- AC_SUBST([SETENVOBJ])
- AC_DEFINE([NEED_SETENV],1,[Define if setenv needs to be defined])
-fi
-dnl
-KRB5_NEED_PROTO([#include <stdlib.h>],setenv)
-AC_C_CONST
-KRB5_BUILD_LIBRARY
-KRB5_BUILD_LIBOBJS
-dnl
-old_LIBS="$LIBS"
-dnl
-dnl from old telnet/configure.in
-dnl
-AC_PROG_INSTALL
-AC_FUNC_VFORK
-AC_HEADER_STDARG
-case $krb5_cv_host in
-*-*-solaris*)
- if test "$ac_cv_c_compiler_gnu" = yes; then
- # Solaris 8 at least has curses.h that is noisy under gcc
- ac_cv_header_curses_h=yes
- fi
- ;;
-esac
-dnl
-dnl On some systems, term.h requires curses.h inclusion
-AC_CHECK_HEADERS(term.h,,,dnl
-[#ifdef HAVE_CURSES_H
-#include <curses.h>
-#endif
-])
-dnl
-AC_CHECK_LIB(termcap,main,AC_DEFINE(TERMCAP,1,[Define if termcap library is available])
-LIBS="$LIBS -ltermcap")
-AC_CHECK_LIB(curses,setupterm,LIBS="$LIBS -lcurses",
- AC_CHECK_LIB(ncurses,setupterm,LIBS="$LIBS -lncurses")
-)
-AC_CHECK_FUNC(tgetent, , [AC_MSG_ERROR([Could not find tgetent; are you missing a curses/ncurses library?])])
-KRB5_AC_INET6
-AC_CHECK_FUNCS(setupterm)
-AC_CHECK_HEADER(termios.h,AC_DEFINE(USE_TERMIO,1,[Define if termio should be used]) ac_termio=1)
-if test -z "$ac_termio"; then
-AC_CHECK_HEADER(termio.h,AC_DEFINE(SYSV_TERMIO,1,[Define if SysV termio interface is found]),ac_sysv_termio=1)
-if test -z "$ac_sysv_termio"; then
- AC_MSG_CHECKING([for cc_t in termio.h])
- AC_CACHE_VAL(krb_cv_type_cc_t,
- [AC_TRY_LINK([cc_t],[#include <termio.h>],
- [cc_t foo;],krb_cv_type_cc_t=yes,krb_cv_type_cc_t=no)])
- AC_MSG_RESULT($krb_cv_type_cc_t)
- if test $krb_cv_type_cc_t = no; then
- AC_DEFINE(NO_CC_T,1,[Define if termio.h does not define type cc_t])
- fi
-fi
-fi
-KRB5_NEED_PROTO([#include <unistd.h>
-#include <stdlib.h>],parsetos,1)
-dnl
-KRB5_NEED_PROTO([#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>],herror,1)
-dnl
-CHECK_SIGNALS
-dnl
-KRB5_BUILD_PROGRAM
-dnl
-TELNET_LIBS="$LIBS"
-AC_SUBST(TELNET_LIBS)
-LIBS="$old_LIBS"
-dnl
-dnl from old telnetd/configure.in
-dnl
-dnl AC_PROG_INSTALL
-AC_CHECK_LIB(termcap,main,AC_DEFINE(TERMCAP)
-LIBS="$LIBS -ltermcap",
- AC_CHECK_LIB(curses,setupterm,LIBS="$LIBS -lcurses",
- AC_CHECK_LIB(ncurses,setupterm,LIBS="$LIBS -lncurses")
-))
-dnl ... whole termios.h/termio.h/NO_CC_T thing again ...
-AC_HEADER_TIME
-dnl KRB5_AC_INET6
-dnl
-dnl Test if speed_t needs to be defined
-AC_CACHE_CHECK([if speed_t is defined], krb5_cv_type_speed_t,
-[AC_TRY_COMPILE(dnl
-[#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-#ifndef USE_TERMIO
-#include <sgtty.h>
-#else
-# ifdef SYSV_TERMIO
-# include <termio.h>
-# else
-# include <termios.h>
-# endif
-#endif
-],[speed_t termspeed],krb5_cv_type_speed_t=yes, krb5_cv_type_speed_t=no)])
-if test $krb5_cv_type_speed_t = no; then
- AC_DEFINE(speed_t, int, [Define if system termios interface doesn't define speed_t])
-fi;
-dnl
-dnl
-dnl Make our operating system-specific security checks and definitions for
-dnl login.
-dnl
-case $krb5_cv_host in
-*-*-hpux*)
- broken_streams=yes
- ;;
-*-*-linux*)
- # Someday Linux may have a Streams user-level interface, so checking
- # for sys/stream.h may not always work. But I'm reasonably
- # sure Linux will never require pushing magic streams modules onto
- # pty's! :-) --- TYT
- broken_streams=yes
- ;;
-*-*-irix*)
- # Irix doesn't have a working granpt, and more over
- # you can't push anything onto a pty, so telnetd really
- # Really wants to treat it as if it doesn't have streams
- broken_streams=yes
- ;;
-esac
-if test -z "$broken_streams" -a "$ac_cv_header_sys_stream_h" = yes; then
- AC_CHECK_FUNC(grantpt,AC_DEFINE(STREAMSPTY,1,[Define if streams pty interface should be used]))
-fi
-AC_MSG_CHECKING([if setpgrp takes two arguments])
-dnl
-AC_CACHE_VAL(krb5_cv_sys_setpgrp_two,
-[AC_TRY_LINK(
-[#include <unistd.h>],[setpgrp(0,0)],
-krb5_cv_sys_setpgrp_two=yes,krb5_cv_sys_setpgrp_two=no)])
-AC_MSG_RESULT($krb5_cv_sys_setpgrp_two)
-if test $krb5_cv_sys_setpgrp_two = yes; then
- AC_DEFINE(SETPGRP_TWOARG,1,[Define if setpgrp takes two arguments])
-fi
-dnl
-KRB5_NEED_PROTO([#include <stdlib.h>],unsetenv,1)
-dnl KRB5_NEED_PROTO([#include <stdlib.h>],setenv,1)
-dnl KRB5_BUILD_PROGRAM
-dnl
-TELNETD_LIBS="$LIBS"
-AC_SUBST(TELNETD_LIBS)
-LIBS="$old_LIBS"
-dnl
-KRB5_AC_LIBUTIL
-V5_AC_OUTPUT_MAKEFILE(. libtelnet telnet telnetd)
+++ /dev/null
-# No dependencies here.
+++ /dev/null
-*** h/ioctl.h.old Tue May 23 14:50:42 1989
---- h/ioctl.h Tue Aug 29 18:24:49 1989
-***************
-*** 214,219 ****
---- 214,220 ----
- #define TIOCPKT_START 0x08 /* start output */
- #define TIOCPKT_NOSTOP 0x10 /* no more ^S, ^Q */
- #define TIOCPKT_DOSTOP 0x20 /* now do ^S ^Q */
-+ #define TIOCPKT_IOCTL 0x40 /* state change of pty driver */
- #define TIOCSTOP _IO('t', 111) /* stop output, like ^S */
- #define TIOCSTART _IO('t', 110) /* start output, like ^Q */
- #define TIOCMSET _IOW('t', 109, int) /* set all modem bits */
-***************
-*** 226,231 ****
---- 227,235 ----
- #define TIOCUCNTL _IOW('t', 102, int) /* pty: set/clr usr cntl mode */
- #define UIOCCMD(n) _IO('u', n) /* usr cntl op "n" */
- #define TIOCCONS _IO('t', 98) /* become virtual console */
-+ #define TIOCEXT _IOW('t', 97, int) /* pty: external processing */
-+ #define TIOCGSTATE _IOR('t', 96, int) /* pty: get internal state */
-+ #define TIOCSIG _IO('t', 95) /* pty: generate signal */
-
- #define OTTYDISC 0 /* old, v7 std tty driver */
- #define NETLDISC 1 /* line discip for berk net */
-*** h/tty.h.old Tue May 23 14:51:01 1989
---- h/tty.h Wed Aug 23 11:30:40 1989
-***************
-*** 70,75 ****
---- 70,76 ----
- struct ttychars t_chars; /* tty */
- struct winsize t_winsize; /* window size */
- /* be careful of tchars & co. */
-+ #ifndef NO_T_CHARS_DEFINES
- #define t_erase t_chars.tc_erase
- #define t_kill t_chars.tc_kill
- #define t_intrc t_chars.tc_intrc
-***************
-*** 84,89 ****
---- 85,91 ----
- #define t_flushc t_chars.tc_flushc
- #define t_werasc t_chars.tc_werasc
- #define t_lnextc t_chars.tc_lnextc
-+ #endif
- };
-
- #define TTIPRI 28
-***************
-*** 124,129 ****
---- 126,132 ----
- #define TS_LNCH 0x080000 /* next character is literal */
- #define TS_TYPEN 0x100000 /* retyping suspended input (PENDIN) */
- #define TS_CNTTB 0x200000 /* counting tab width; leave FLUSHO alone */
-+ #define TS_EXTPROC 0x400000 /* external processing of data */
-
- #define TS_LOCAL (TS_BKSL|TS_QUOT|TS_ERASE|TS_LNCH|TS_TYPEN|TS_CNTTB)
-
-*** sys/tty.c.old Tue May 23 14:52:28 1989
---- sys/tty.c Thu Aug 24 09:31:49 1989
-***************
-*** 275,280 ****
---- 275,285 ----
- */
- switch (com) {
-
-+ /* get internal state - needed for TS_EXTPROC bit */
-+ case TIOCGSTATE:
-+ *(int *)data = tp->t_state;
-+ break;
-+
- /* get discipline number */
- case TIOCGETD:
- *(int *)data = tp->t_line;
-***************
-*** 752,757 ****
---- 757,763 ----
- */
- if ((tp->t_state&TS_TYPEN) == 0 && (t_flags&PASS8) == 0)
- c &= 0177;
-+ if ((tp->t_state&TS_EXTPROC) == 0) {
- /*
- * Check for literal nexting very first
- */
-***************
-*** 834,839 ****
---- 840,846 ----
- else if (c == '\\')
- tp->t_state |= TS_BKSL;
- }
-+ }
-
- /*
- * Cbreak mode, don't process line editing
-***************
-*** 851,856 ****
---- 858,864 ----
- goto endcase;
- }
-
-+ if ((tp->t_state&TS_EXTPROC) == 0) {
- /*
- * From here on down cooked mode character
- * processing takes place.
-***************
-*** 911,916 ****
---- 919,925 ----
- goto endcase;
- }
- }
-+ }
-
- /*
- * Check for input buffer overflow
-***************
-*** 933,938 ****
---- 942,948 ----
- } else if (tp->t_rocount++ == 0)
- tp->t_rocol = tp->t_col;
- tp->t_state &= ~TS_QUOT;
-+ if ((tp->t_state&TS_EXTPROC) == 0) {
- if (c == '\\')
- tp->t_state |= TS_QUOT;
- if (tp->t_state&TS_ERASE) {
-***************
-*** 948,953 ****
---- 958,964 ----
- i--;
- }
- }
-+ }
- }
- endcase:
- /*
-***************
-*** 998,1005 ****
- return (-1);
- /*
- * Turn tabs to spaces as required
- */
-! if (c == '\t' && (tp->t_flags&TBDELAY) == XTABS) {
- register int s;
-
- c = 8 - (tp->t_col&7);
---- 1009,1022 ----
- return (-1);
- /*
- * Turn tabs to spaces as required
-+ *
-+ * Special case if we have external processing, we don't
-+ * do the tab expansion because we'll probably get it
-+ * wrong. If tab expansion needs to be done, let it
-+ * happen externally.
- */
-! if ((tp->t_state&TS_EXTPROC) == 0 &&
-! c == '\t' && (tp->t_flags&TBDELAY) == XTABS) {
- register int s;
-
- c = 8 - (tp->t_col&7);
-***************
-*** 1497,1503 ****
- int s;
- char *nextc();
-
-! if ((tp->t_flags&ECHO) == 0)
- return;
- tp->t_flags &= ~FLUSHO;
- c &= 0377;
---- 1514,1520 ----
- int s;
- char *nextc();
-
-! if ((tp->t_flags&ECHO) == 0 || (tp->t_state&TS_EXTPROC))
- return;
- tp->t_flags &= ~FLUSHO;
- c &= 0377;
-***************
-*** 1618,1624 ****
-
- if ((tp->t_state&TS_CNTTB) == 0)
- tp->t_flags &= ~FLUSHO;
-! if ((tp->t_flags&ECHO) == 0)
- return;
- c &= 0377;
- if (tp->t_flags&RAW) {
---- 1635,1641 ----
-
- if ((tp->t_state&TS_CNTTB) == 0)
- tp->t_flags &= ~FLUSHO;
-! if ((tp->t_flags&ECHO) == 0 || (tp->t_state&TS_EXTPROC))
- return;
- c &= 0377;
- if (tp->t_flags&RAW) {
-*** sys/tty_pty.c.old Tue May 23 14:52:43 1989
---- sys/tty_pty.c Tue Aug 29 18:48:36 1989
-***************
-*** 208,213 ****
---- 208,214 ----
- return (EIO);
- tp->t_oproc = ptsstart;
- (void)(*linesw[tp->t_line].l_modem)(tp, 1);
-+ tp->t_state &= ~TS_EXTPROC;
- pti = &pt_ioctl[minor(dev)];
- pti->pt_flags = 0;
- pti->pt_send = 0;
-***************
-*** 247,252 ****
---- 248,275 ----
- error = ureadc((int)pti->pt_send, uio);
- if (error)
- return (error);
-+ if (pti->pt_send & TIOCPKT_IOCTL) {
-+ struct xx {
-+ struct sgttyb a;
-+ struct tchars b;
-+ struct ltchars c;
-+ int d;
-+ int e;
-+ } cb;
-+ cb.a.sg_ispeed = tp->t_ispeed;
-+ cb.a.sg_ospeed = tp->t_ospeed;
-+ cb.a.sg_erase = tp->t_erase;
-+ cb.a.sg_kill = tp->t_kill;
-+ cb.a.sg_flags = tp->t_flags;
-+ bcopy((caddr_t)&tp->t_intrc,
-+ (caddr_t)&cb.b, sizeof(cb.b));
-+ bcopy((caddr_t)&tp->t_suspc,
-+ (caddr_t)&cb.c, sizeof(cb.c));
-+ cb.d = tp->t_state;
-+ cb.e = ((unsigned)tp->t_flags)>>16;
-+ cc = MIN(uio->uio_resid, sizeof(cb));
-+ uiomove(&cb, cc, UIO_READ, uio);
-+ }
- pti->pt_send = 0;
- return (0);
- }
-***************
-*** 483,488 ****
---- 506,533 ----
- * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG.
- * ttywflush(tp) will hang if there are characters in the outq.
- */
-+ if (cmd == TIOCEXT) {
-+ /*
-+ * When the TS_EXTPROC bit is being toggled, we need
-+ * to send an TIOCPKT_IOCTL if the packet driver
-+ * is turned on.
-+ */
-+ if (*(int *)data) {
-+ if (pti->pt_flags & PF_PKT) {
-+ pti->pt_send |= TIOCPKT_IOCTL;
-+ ptcwakeup(tp);
-+ }
-+ tp->t_state |= TS_EXTPROC;
-+ } else {
-+ if ((tp->t_state & TS_EXTPROC) &&
-+ (pti->pt_flags & PF_PKT)) {
-+ pti->pt_send |= TIOCPKT_IOCTL;
-+ ptcwakeup(tp);
-+ }
-+ tp->t_state &= ~TS_EXTPROC;
-+ }
-+ return (0);
-+ } else
- if (cdevsw[major(dev)].d_open == ptcopen)
- switch (cmd) {
-
-***************
-*** 525,530 ****
---- 570,583 ----
- while (getc(&tp->t_outq) >= 0)
- ;
- break;
-+
-+ case TIOCSIG:
-+ if (*(unsigned int *)data >= NSIG)
-+ return(EINVAL);
-+ if ((tp->t_flags&NOFLSH) == 0)
-+ ttyflush(tp, FREAD|FWRITE);
-+ gsignal(tp->t_pgrp, *(unsigned int *)data);
-+ return(0);
- }
- error = ttioctl(tp, cmd, data, flag);
- /*
-***************
-*** 549,554 ****
---- 602,624 ----
- return (0);
- }
- error = ENOTTY;
-+ }
-+ /*
-+ * If external processing and packet mode send ioctl packet.
-+ */
-+ if ((tp->t_state & TS_EXTPROC) && (pti->pt_flags & PF_PKT)) {
-+ switch(cmd) {
-+ case TIOCSETP:
-+ case TIOCSETN:
-+ case TIOCSETC:
-+ case TIOCSLTC:
-+ case TIOCLBIS:
-+ case TIOCLBIC:
-+ case TIOCLSET:
-+ pti->pt_send |= TIOCPKT_IOCTL;
-+ default:
-+ break;
-+ }
- }
- stop = (tp->t_flags & RAW) == 0 &&
- tp->t_stopc == CTRL('s') && tp->t_startc == CTRL('q');
+++ /dev/null
-thisconfigdir=..
-myfulldir=appl/telnet/libtelnet
-mydir=libtelnet
-BUILDTOP=$(REL)..$(S)..$(S)..
-# derived from the original Makefile.generic
-#
-# 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.
-#
-# @(#)Makefile.generic 5.5 (Berkeley) 3/1/91
-#
-AUTH_DEF=-DAUTHENTICATION -DENCRYPTION -DDES_ENCRYPTION -DKRB5 -DFORWARD \
- -UNO_LOGIN_F -DLOGIN_CAP_F -DLOGIN_PROGRAM=KRB5_PATH_LOGIN
-LOCALINCLUDES=-I.. -I$(srcdir)/..
-DEFINES = -DTELNET_BUFSIZE=65535 $(AUTH_DEF)
-LIBOBJS=@LIBOBJS@
-
-SETENVSRC=@SETENVSRC@
-SETENVOBJ=@SETENVOBJ@
-
-LIBBASE=telnet
-LIBMAJOR=0
-LIBMINOR=0
-RELDIR=../../../appl/telnet/libtelnet
-STOBJLISTS=OBJS.ST
-
-SRCS= $(srcdir)/auth.c \
- $(srcdir)/encrypt.c \
- $(srcdir)/genget.c \
- $(srcdir)/misc.c \
- $(srcdir)/kerberos5.c \
- $(srcdir)/forward.c \
- $(srcdir)/enc_des.c \
- $(srcdir)/setenv.c \
- $(srcdir)/getent.c \
- $(srcdir)/parsetos.c \
- $(srcdir)/strdup.c \
- $(srcdir)/strcasecmp.c \
- $(srcdir)/strchr.c \
- $(srcdir)/strrchr.c \
- $(srcdir)/strftime.c \
- $(srcdir)/strerror.c
-
-STLIBOBJS= auth.o encrypt.o genget.o \
- misc.o kerberos5.o forward.o enc_des.o \
- $(LIBOBJS) getent.o $(SETENVOBJ)
-
-TELNET_H= $(srcdir)/../arpa/telnet.h
-
-all:: all-libs
-
-clean:: clean-libs clean-libobjs
-
-auth.o: $(TELNET_H)
-auth.o: encrypt.h
-auth.o: auth.h
-auth.o: misc-proto.h
-encrypt.o: $(TELNET_H)
-encrypt.o: encrypt.h
-encrypt.o: misc.h
-kerberos5.o: $(TELNET_H)
-kerberos5.o: encrypt.h
-kerberos5.o: auth.h
-kerberos5.o: misc.h
-misc.o: misc.h
-enc_des.o: $(TELNET_H)
-enc_des.o: encrypt.h
-enc_des.o: key-proto.h
-enc_des.o: misc-proto.h
-install::
-
-@libpriv_frag@
-@lib_frag@
-@libobj_frag@
-
+++ /dev/null
-/*-
- * Copyright (c) 1991, 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.
- *
- * @(#)auth-proto.h 8.1 (Berkeley) 6/4/93
- */
-
-/*
- * Copyright (C) 1990 by the Massachusetts Institute of Technology
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- */
-
-#if defined(AUTHENTICATION)
-Authenticator *findauthenticator (int, int);
-
-void auth_init (char *, int);
-int auth_cmd (int, char **);
-void auth_request (void);
-void auth_send (unsigned char *, int);
-void auth_send_retry (void);
-void auth_is (unsigned char *, int);
-void auth_reply (unsigned char *, int);
-void auth_finished (Authenticator *, int);
-void auth_wait (char *);
-int auth_check (char *);
-int auth_must_encrypt (void);
-void auth_disable_name (char *);
-void auth_gen_printsub (unsigned char *, int, unsigned char *, unsigned int);
-
-
-int getauthmask (char *, int *);
-int auth_enable (char *);
-int auth_disable (char *);
-int auth_onoff (char *, int);
-int auth_togdebug (int);
-int auth_status (void);
-void auth_name (unsigned char *, int);
-int auth_sendname (unsigned char *, int);
-void auth_debug (int);
-void auth_printsub (unsigned char *, int, unsigned char *, unsigned int);
-
-
-#ifdef KRB5
-int kerberos5_init (Authenticator *, int);
-int kerberos5_send (Authenticator *);
-void kerberos5_is (Authenticator *, unsigned char *, int);
-void kerberos5_reply (Authenticator *, unsigned char *, int);
-int kerberos5_status (Authenticator *, char *, int);
-void kerberos5_printsub (unsigned char *, int, unsigned char *, unsigned int);
-void kerberos5_cleanup (void);
-#endif
-#endif
+++ /dev/null
-/*-
- * Copyright (c) 1991, 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.
- */
-
-/* based on @(#)auth.c 8.1 (Berkeley) 6/4/93 */
-
-/*
- * Copyright (C) 1990 by the Massachusetts Institute of Technology
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- */
-
-
-#if defined(AUTHENTICATION)
-#include <stdio.h>
-#include <sys/types.h>
-#include <signal.h>
-#define AUTH_NAMES
-#include <arpa/telnet.h>
-#ifdef __STDC__
-#include <stdlib.h>
-#include <unistd.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#include <strings.h>
-#endif
-
-#include "encrypt.h"
-#include "auth.h"
-#include "misc-proto.h"
-#include "auth-proto.h"
-
-#define typemask(x) (1<<((x)-1))
-
-
-
-int auth_debug_mode = 0;
-int auth_has_failed = 0;
-int auth_enable_encrypt = 0;
-int auth_client_non_unix = 0;
-static char *Name = "Noname";
-static int Server = 0;
-static Authenticator *authenticated = 0;
-static int authenticating = 0;
-static int validuser = 0;
-static unsigned char _auth_send_data[256];
-static unsigned char *auth_send_data;
-static int auth_send_cnt = 0;
-
-/*
- * Authentication types supported. Plese note that these are stored
- * in priority order, i.e. try the first one first.
- */
-Authenticator authenticators[] = {
-#ifdef SPX
- { AUTHTYPE_SPX, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL,
- spx_init,
- spx_send,
- spx_is,
- spx_reply,
- spx_status,
- spx_printsub },
- { AUTHTYPE_SPX, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
- spx_init,
- spx_send,
- spx_is,
- spx_reply,
- spx_status,
- spx_printsub },
-#endif
-#ifdef KRB5
-#ifdef ENCRYPTION
- { AUTHTYPE_KERBEROS_V5,
- AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL|AUTH_ENCRYPT_ON,
- kerberos5_init,
- kerberos5_send,
- kerberos5_is,
- kerberos5_reply,
- kerberos5_status,
- kerberos5_printsub },
-#endif
- { AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL,
- kerberos5_init,
- kerberos5_send,
- kerberos5_is,
- kerberos5_reply,
- kerberos5_status,
- kerberos5_printsub },
- { AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY,
- kerberos5_init,
- kerberos5_send,
- kerberos5_is,
- kerberos5_reply,
- kerberos5_status,
- kerberos5_printsub },
-#endif
- { 0, },
-};
-
-static Authenticator NoAuth = { 0 };
-
-static int i_support = 0;
-static int i_wont_support = 0;
-
- Authenticator *
-findauthenticator(type, way)
- int type;
- int way;
-{
- Authenticator *ap = authenticators;
-
- while (ap->type && (ap->type != type || ap->way != way))
- ++ap;
- return(ap->type ? ap : 0);
-}
-
- void
-auth_init(name, server)
- char *name;
- int server;
-{
- Authenticator *ap = authenticators;
-
- Server = server;
- Name = name;
-
- i_support = 0;
- authenticated = 0;
- authenticating = 0;
- while (ap->type) {
- if (!ap->init || (*ap->init)(ap, server)) {
- i_support |= typemask(ap->type);
- if (auth_debug_mode)
- printf(">>>%s: I support auth type %d %d\r\n",
- Name,
- ap->type, ap->way);
- }
- ++ap;
- }
-}
-
- void
-auth_disable_name(name)
- char *name;
-{
- int x;
- for (x = 0; x < AUTHTYPE_CNT; ++x) {
- if (!strcasecmp(name, AUTHTYPE_NAME(x))) {
- i_wont_support |= typemask(x);
- break;
- }
- }
-}
-
- int
-getauthmask(type, maskp)
- char *type;
- int *maskp;
-{
- register int x;
-
- if (!strcasecmp(type, AUTHTYPE_NAME(0))) {
- *maskp = -1;
- return(1);
- }
-
- for (x = 1; x < AUTHTYPE_CNT; ++x) {
- if (!strcasecmp(type, AUTHTYPE_NAME(x))) {
- *maskp = typemask(x);
- return(1);
- }
- }
- return(0);
-}
-
- int
-auth_enable(type)
- char * type;
-{
- return(auth_onoff(type, 1));
-}
-
- int
-auth_disable(type)
- char * type;
-{
- return(auth_onoff(type, 0));
-}
-
- int
-auth_onoff(type, on)
- char *type;
- int on;
-{
- int i, mask = -1;
- Authenticator *ap;
-
- if (!strcasecmp(type, "?") || !strcasecmp(type, "help")) {
- printf("auth %s 'type'\n", on ? "enable" : "disable");
- printf("Where 'type' is one of:\n");
- printf("\t%s\n", AUTHTYPE_NAME(0));
- mask = 0;
- for (ap = authenticators; ap->type; ap++) {
- if ((mask & (i = typemask(ap->type))) != 0)
- continue;
- mask |= i;
- printf("\t%s\n", AUTHTYPE_NAME(ap->type));
- }
- return(0);
- }
-
- if (!getauthmask(type, &mask)) {
- printf("%s: invalid authentication type\n", type);
- return(0);
- }
- if (on)
- i_wont_support &= ~mask;
- else
- i_wont_support |= mask;
- return(1);
-}
-
- int
-auth_togdebug(on)
- int on;
-{
- if (on < 0)
- auth_debug_mode ^= 1;
- else
- auth_debug_mode = on;
- printf("auth debugging %s\n", auth_debug_mode ? "enabled" : "disabled");
- return(1);
-}
-
- int
-auth_status()
-{
- Authenticator *ap;
- int i, mask;
-
- if (i_wont_support == -1)
- printf("Authentication disabled\n");
- else
- printf("Authentication enabled\n");
-
- mask = 0;
- for (ap = authenticators; ap->type; ap++) {
- if ((mask & (i = typemask(ap->type))) != 0)
- continue;
- mask |= i;
- printf("%s: %s\n", AUTHTYPE_NAME(ap->type),
- (i_wont_support & typemask(ap->type)) ?
- "disabled" : "enabled");
- }
- return(1);
-}
-
-/*
- * This routine is called by the server to start authentication
- * negotiation.
- */
- void
-auth_request()
-{
- static unsigned char str_request[64] = { IAC, SB,
- TELOPT_AUTHENTICATION,
- TELQUAL_SEND, };
- Authenticator *ap = authenticators;
- unsigned char *e = str_request + 4;
-
- if (!authenticating) {
- authenticating = 1;
- while (ap->type) {
- if (i_support & ~i_wont_support & typemask(ap->type)) {
- if (ap->type == AUTHTYPE_KERBEROS_V4 ||
- !auth_client_non_unix) {
- if (auth_debug_mode) {
- printf(">>>%s: Sending type %d %d\r\n",
- Name, ap->type, ap->way);
- }
- *e++ = ap->type;
- *e++ = ap->way;
- }
- }
- ++ap;
- }
- if (auth_client_non_unix) {
- ap = authenticators;
- while (ap->type) {
- if (i_support & ~i_wont_support & typemask(ap->type)) {
- *e++ = ap->type;
- *e++ = ap->way;
- }
- ++ap;
- }
- }
- *e++ = IAC;
- *e++ = SE;
- net_write(str_request, e - str_request);
- printsub('>', &str_request[2], e - str_request - 2);
- }
-}
-
-/*
- * This is called when an AUTH SEND is received.
- * It should never arrive on the server side (as only the server can
- * send an AUTH SEND).
- * You should probably respond to it if you can...
- *
- * If you want to respond to the types out of order (i.e. even
- * if he sends LOGIN KERBEROS and you support both, you respond
- * with KERBEROS instead of LOGIN (which is against what the
- * protocol says)) you will have to hack this code...
- */
- void
-auth_send(data, cnt)
- unsigned char *data;
- int cnt;
-{
- if (Server) {
- if (auth_debug_mode) {
- printf(">>>%s: auth_send called!\r\n", Name);
- }
- return;
- }
-
- if (auth_debug_mode) {
- printf(">>>%s: auth_send got:", Name);
- printd(data, cnt); printf("\r\n");
- }
-
- /*
- * Save the list of authentication mechanisms
- */
- auth_send_cnt = cnt;
- if (auth_send_cnt > sizeof(_auth_send_data))
- auth_send_cnt = sizeof(_auth_send_data);
- memcpy(_auth_send_data, data, (unsigned) auth_send_cnt);
- auth_send_data = _auth_send_data;
-
- auth_send_retry();
-}
-
-/*
- * Try the next authentication mechanism on the list, and see if it
- * works.
- */
-void auth_send_retry()
-{
- Authenticator *ap;
- static unsigned char str_none[] = { IAC, SB, TELOPT_AUTHENTICATION,
- TELQUAL_IS, AUTHTYPE_NULL, 0,
- IAC, SE };
-
- if (Server) {
- if (auth_debug_mode) {
- printf(">>>%s: auth_send_retry called!\r\n", Name);
- }
- return;
- }
-
- for (;(auth_send_cnt -= 2) >= 0; auth_send_data += 2) {
- if (auth_debug_mode)
- printf(">>>%s: He supports %d\r\n", Name, *auth_send_data);
- if (!(i_support & typemask(*auth_send_data)))
- continue;
- if (i_wont_support & typemask(*auth_send_data))
- continue;
- ap = findauthenticator(auth_send_data[0], auth_send_data[1]);
- if (!ap || !ap->send)
- continue;
- if ((ap->way & AUTH_ENCRYPT_MASK) && !auth_enable_encrypt)
- continue;
-
- if (auth_debug_mode)
- printf(">>>%s: Trying %d %d\r\n", Name, auth_send_data[0],
- auth_send_data[1]);
- if ((*ap->send)(ap)) {
- /*
- * Okay, we found one we like and did it. we can go
- * home now.
- */
- if (auth_debug_mode)
- printf(">>>%s: Using type %d\r\n", Name, *auth_send_data);
- auth_send_data += 2;
- return;
- }
- }
- net_write(str_none, sizeof(str_none));
- printsub('>', &str_none[2], sizeof(str_none) - 2);
- if (auth_debug_mode)
- printf(">>>%s: Sent failure message\r\n", Name);
- auth_finished(0, AUTH_REJECT);
- auth_has_failed = 1;
-#ifdef KANNAN
- /*
- * We requested strong authentication, however no mechanisms worked.
- * Therefore, exit on client end.
- */
- printf("Unable to securely authenticate user ... exit\n");
- exit(0);
-#endif /* KANNAN */
-}
-
- void
-auth_is(data, cnt)
- unsigned char *data;
- int cnt;
-{
- Authenticator *ap;
-
- if (cnt < 2)
- return;
-
- if (data[0] == AUTHTYPE_NULL) {
- auth_finished(0, AUTH_REJECT);
- return;
- }
-
- if ((ap = findauthenticator(data[0], data[1]))) {
- if (ap->is)
- (*ap->is)(ap, data+2, cnt-2);
- } else if (auth_debug_mode)
- printf(">>>%s: Invalid authentication in IS: %d\r\n",
- Name, *data);
-}
-
- void
-auth_reply(data, cnt)
- unsigned char *data;
- int cnt;
-{
- Authenticator *ap;
-
- if (cnt < 2)
- return;
-
- if ((ap = findauthenticator(data[0], data[1]))) {
- if (ap->reply)
- (*ap->reply)(ap, data+2, cnt-2);
- } else if (auth_debug_mode)
- printf(">>>%s: Invalid authentication in SEND: %d\r\n",
- Name, *data);
-}
-
- void
-auth_name(data, cnt)
- unsigned char *data;
- int cnt;
-{
- unsigned char savename[256];
-
- if (cnt < 1) {
- if (auth_debug_mode)
- printf(">>>%s: Empty name in NAME\r\n", Name);
- return;
- }
- if (cnt > sizeof(savename) - 1) {
- if (auth_debug_mode)
- printf(">>>%s: Name in NAME (%d) exceeds %d length\r\n",
- Name, cnt, (int) sizeof(savename)-1);
- return;
- }
- memcpy(savename, data, (unsigned) cnt);
- savename[cnt] = '\0'; /* Null terminate */
- if (auth_debug_mode)
- printf(">>>%s: Got NAME [%s]\r\n", Name, savename);
- auth_encrypt_user((const char *)savename);
-}
-
- int
-auth_sendname(cp, len)
- unsigned char *cp;
- int len;
-{
- static unsigned char str_request[256+6]
- = { IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_NAME, };
- register unsigned char *e = str_request + 4;
- register unsigned char *ee = &str_request[sizeof(str_request)-2];
-
- while (--len >= 0) {
- if ((*e++ = *cp++) == IAC)
- *e++ = IAC;
- if (e >= ee)
- return(0);
- }
- *e++ = IAC;
- *e++ = SE;
- net_write(str_request, e - str_request);
- printsub('>', &str_request[2], e - &str_request[2]);
- return(1);
-}
-
- void
-auth_finished(ap, result)
- Authenticator *ap;
- int result;
-{
- if (!(authenticated = ap))
- authenticated = &NoAuth;
- validuser = result;
-}
-
- /* ARGSUSED */
- static void
-auth_intr(sig)
- int sig;
-{
- auth_finished(0, AUTH_REJECT);
-}
-
- void
-auth_wait(name)
- char *name;
-{
- if (auth_debug_mode)
- printf(">>>%s: in auth_wait.\r\n", Name);
-
- if (Server && !authenticating)
- return;
-
- (void) signal(SIGALRM, auth_intr);
- alarm(30);
- while (!authenticated)
- if (telnet_spin())
- break;
- alarm(0);
- (void) signal(SIGALRM, SIG_DFL);
-}
-
- int
-auth_check(name)
- char *name;
-{
- /*
- * Now check to see if the user is valid or not
- */
- if (!authenticated || authenticated == &NoAuth)
- return(AUTH_REJECT);
-
- if (validuser == AUTH_VALID)
- validuser = AUTH_USER;
-
- if (authenticated->status)
- validuser = (*authenticated->status)(authenticated,
- name, validuser);
- return(validuser);
-}
-
-int auth_must_encrypt()
-{
- if (authenticated &&
- ((authenticated->way & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_ON))
- return 1;
- return 0;
-}
-
- void
-auth_debug(mode)
- int mode;
-{
- auth_debug_mode = mode;
-}
-
- void
-auth_printsub(data, cnt, buf, buflen)
- unsigned char *data, *buf;
- int cnt;
- unsigned int buflen;
-{
- Authenticator *ap;
-
- if ((ap = findauthenticator(data[1], data[2])) && ap->printsub)
- (*ap->printsub)(data, cnt, buf, buflen);
- else
- auth_gen_printsub(data, cnt, buf, buflen);
-}
-
- void
-auth_gen_printsub(data, cnt, buf, buflen)
- unsigned char *data, *buf;
- int cnt;
- unsigned int buflen;
-{
- register unsigned char *cp;
- unsigned char tbuf[16];
-
- cnt -= 3;
- data += 3;
- buf[buflen-1] = '\0';
- buf[buflen-2] = '*';
- buflen -= 2;
- for (; cnt > 0; cnt--, data++) {
- snprintf((char *)tbuf, sizeof(tbuf), " %d", *data);
- for (cp = tbuf; *cp && buflen > 0; --buflen)
- *buf++ = *cp++;
- if (buflen <= 0)
- return;
- }
- *buf = '\0';
-}
-#endif
+++ /dev/null
-/*-
- * Copyright (c) 1991, 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.
- *
- * @(#)auth.h 8.1 (Berkeley) 6/4/93
- */
-
-/*
- * Copyright (C) 1990 by the Massachusetts Institute of Technology
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- */
-
-#ifndef __AUTH__
-#define __AUTH__
-
-#define AUTH_REJECT 0 /* Rejected */
-#define AUTH_UNKNOWN 1 /* We don't know who he is, but he's okay */
-#define AUTH_OTHER 2 /* We know him, but not his name */
-#define AUTH_USER 3 /* We know he name */
-#define AUTH_VALID 4 /* We know him, and he needs no password */
-
-typedef struct XauthP {
- int type;
- int way;
- int (*init) (struct XauthP *, int);
- int (*send) (struct XauthP *);
- void (*is) (struct XauthP *, unsigned char *, int);
- void (*reply) (struct XauthP *, unsigned char *, int);
- int (*status) (struct XauthP *, char *, int);
- void (*printsub) (unsigned char *, int, unsigned char *, unsigned int);
-} Authenticator;
-
-#include "auth-proto.h"
-
-#define OPTS_FORWARD_CREDS 0x00000002
-#define OPTS_FORWARDABLE_CREDS 0x00000001
-
-extern int auth_debug_mode;
-#endif
+++ /dev/null
-#
-# Generated makefile dependencies follow.
-#
-auth.so auth.po $(OUTPRE)auth.$(OBJEXT): $(srcdir)/../arpa/telnet.h \
- auth-proto.h auth.c auth.h enc-proto.h encrypt.h misc-proto.h
-encrypt.so encrypt.po $(OUTPRE)encrypt.$(OBJEXT): $(srcdir)/../arpa/telnet.h \
- enc-proto.h encrypt.c encrypt.h misc-proto.h misc.h
-genget.so genget.po $(OUTPRE)genget.$(OBJEXT): genget.c \
- misc-proto.h misc.h
-misc.so misc.po $(OUTPRE)misc.$(OBJEXT): auth-proto.h \
- auth.h enc-proto.h encrypt.h misc-proto.h misc.c misc.h
-kerberos5.so kerberos5.po $(OUTPRE)kerberos5.$(OBJEXT): \
- $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
- $(COM_ERR_DEPS) $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/krb5.h $(srcdir)/../arpa/telnet.h \
- auth-proto.h auth.h enc-proto.h encrypt.h kerberos5.c \
- krb5forw.h misc-proto.h misc.h
-forward.so forward.po $(OUTPRE)forward.$(OBJEXT): $(BUILDTOP)/include/krb5/krb5.h \
- $(COM_ERR_DEPS) $(SRCTOP)/include/krb5.h forward.c \
- krb5forw.h
-enc_des.so enc_des.po $(OUTPRE)enc_des.$(OBJEXT): $(BUILDTOP)/include/krb5/krb5.h \
- $(COM_ERR_DEPS) $(SRCTOP)/include/krb5.h $(srcdir)/../arpa/telnet.h \
- enc-proto.h enc_des.c encrypt.h key-proto.h misc-proto.h
-setenv.so setenv.po $(OUTPRE)setenv.$(OBJEXT): misc-proto.h \
- setenv.c
-getent.so getent.po $(OUTPRE)getent.$(OBJEXT): getent.c \
- gettytab.h
-parsetos.so parsetos.po $(OUTPRE)parsetos.$(OBJEXT): \
- misc-proto.h parsetos.c
-strdup.so strdup.po $(OUTPRE)strdup.$(OBJEXT): strdup.c
-strcasecmp.so strcasecmp.po $(OUTPRE)strcasecmp.$(OBJEXT): \
- strcasecmp.c
-strchr.so strchr.po $(OUTPRE)strchr.$(OBJEXT): strchr.c
-strrchr.so strrchr.po $(OUTPRE)strrchr.$(OBJEXT): strrchr.c
-strftime.so strftime.po $(OUTPRE)strftime.$(OBJEXT): \
- strftime.c
-strerror.so strerror.po $(OUTPRE)strerror.$(OBJEXT): \
- strerror.c
+++ /dev/null
-/*-
- * Copyright (c) 1991, 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.
- *
- * @(#)enc-proto.h 8.1 (Berkeley) 6/4/93
- */
-
-/*
- * Copyright (C) 1990 by the Massachusetts Institute of Technology
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- */
-#ifdef ENCRYPTION
-void encrypt_init (char *, int);
-Encryptions *findencryption (int);
-Encryptions *finddecryption (int);
-void encrypt_send_supprt (void);
-void encrypt_auto (int);
-void decrypt_auto (int);
-void encrypt_debug (int);
-void encrypt_is (unsigned char *, int);
-void encrypt_reply (unsigned char *, int);
-void encrypt_start_input (int);
-void encrypt_session_key (Session_Key *, int);
-void encrypt_end_input (void);
-void encrypt_start_output (int);
-void encrypt_end_output (void);
-void encrypt_send_request_start (void);
-void encrypt_send_request_end (void);
-void encrypt_send_end (void);
-void encrypt_wait (void);
-int encrypt_is_encrypting (void);
-int EncryptAutoEnc (int);
-int EncryptAutoDec (int);
-int EncryptEnable (char *, char *);
-int EncryptDisable (char *, char *);
-int EncryptDebug (int);
-int EncryptType (char *, char *);
-int EncryptStart (char *);
-int EncryptStartInput (void);
-int EncryptStartOutput (void);
-int EncryptStop (char *);
-int EncryptStopInput (void);
-int EncryptStopOutput (void);
-int EncryptStatus (void);
-int EncryptVerbose (int);
-void encrypt_send_support (void);
-void encrypt_send_keyid (int, unsigned char *, unsigned int, int);
-int net_write (unsigned char *, int);
-void encrypt_gen_printsub (unsigned char *, int, unsigned char *, int);
-void encrypt_printsub (unsigned char *, int, unsigned char *, int);
-
-
-void encrypt_request_start (unsigned char *, int);
-void encrypt_request_end (void);
-void encrypt_enc_keyid (unsigned char *, int);
-void encrypt_dec_keyid (unsigned char *, int);
-void encrypt_support (unsigned char *, int);
-void encrypt_start (unsigned char *, int);
-void encrypt_end (void);
-
-
-#ifdef TELENTD
-void encrypt_wait (void);
-#else
-void printsub (int, unsigned char *, int);
-int encrypt_cmd (int, char **);
-void encrypt_display (void);
-#endif
-
-void krbdes_encrypt (unsigned char *, int);
-int krbdes_decrypt (int);
-int krbdes_is (unsigned char *, int);
-int krbdes_reply (unsigned char *, int);
-void krbdes_init (int);
-int krbdes_start (int, int);
-void krbdes_session (Session_Key *, int);
-void krbdes_printsub (unsigned char *, int, unsigned char *, int);
-
-void cfb64_encrypt (unsigned char *, int);
-int cfb64_decrypt (int);
-void cfb64_init (int);
-int cfb64_start (int, int);
-int cfb64_is (unsigned char *, int);
-int cfb64_reply (unsigned char *, int);
-void cfb64_session (Session_Key *, int);
-int cfb64_keyid (int, unsigned char *, int *);
-void cfb64_printsub (unsigned char *, int, unsigned char *, int);
-
-void ofb64_encrypt (unsigned char *, int);
-int ofb64_decrypt (int);
-void ofb64_init (int);
-int ofb64_start (int, int);
-int ofb64_is (unsigned char *, int);
-int ofb64_reply (unsigned char *, int);
-void ofb64_session (Session_Key *, int);
-int ofb64_keyid (int, unsigned char *, int *);
-void ofb64_printsub (unsigned char *, int, unsigned char *, int);
-#endif /* ENCRYPTION */
+++ /dev/null
-/*-
- * Copyright (c) 1991, 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.
- */
-
-/*
- * Copyright (C) 1998 by the FundsXpress, INC.
- *
- * All rights reserved.
- *
- * Export of this software from the United States of America may require
- * a specific license from the United States Government. It is the
- * responsibility of any person or organization contemplating export to
- * obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of FundsXpress. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. FundsXpress makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/* based on @(#)enc_des.c 8.1 (Berkeley) 6/4/93 */
-
-#ifdef ENCRYPTION
-# ifdef AUTHENTICATION
-# ifdef DES_ENCRYPTION
-#include <krb5.h>
-#include <arpa/telnet.h>
-#include <stdio.h>
-#ifdef __STDC__
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#include <strings.h>
-#endif
-
-#include "encrypt.h"
-#include "key-proto.h"
-#include "misc-proto.h"
-
-extern int encrypt_debug_mode;
-
-extern krb5_context telnet_context;
-
-#define CFB 0
-#define OFB 1
-
-#define NO_SEND_IV 1
-#define NO_RECV_IV 2
-#define NO_KEYID 4
-#define IN_PROGRESS (NO_SEND_IV|NO_RECV_IV|NO_KEYID)
-#define SUCCESS 0
-#define FAILED -1
-
-
-struct fb {
- Block temp_feed;
- unsigned char fb_feed[64];
- int need_start;
- int state[2];
- int keyid[2];
- int once;
- int validkey;
- struct stinfo {
- Block str_output;
- Block str_feed;
- Block str_iv;
- unsigned char str_keybytes[8]; /* yuck */
- krb5_keyblock str_key;
- int str_index;
- int str_flagshift;
- } streams[2];
-};
-
-static struct fb fb[2];
-
-struct keyidlist {
- char *keyid;
- int keyidlen;
- char *key;
- int keylen;
- int flags;
-} keyidlist [] = {
- { "\0", 1, 0, 0, 0 }, /* default key of zero */
- { 0, 0, 0, 0, 0 }
-};
-
-#define KEYFLAG_MASK 03
-
-#define KEYFLAG_NOINIT 00
-#define KEYFLAG_INIT 01
-#define KEYFLAG_OK 02
-#define KEYFLAG_BAD 03
-
-#define KEYFLAG_SHIFT 2
-
-#define SHIFT_VAL(a,b) (KEYFLAG_SHIFT*((a)+((b)*2)))
-
-#define FB64_IV 1
-#define FB64_IV_OK 2
-#define FB64_IV_BAD 3
-
-
-void fb64_stream_iv (Block, struct stinfo *);
-void fb64_init (struct fb *);
-static int fb64_start (struct fb *, int, int);
-int fb64_is (unsigned char *, int, struct fb *);
-int fb64_reply (unsigned char *, int, struct fb *);
-static void fb64_session (Session_Key *, int, struct fb *);
-void fb64_stream_key (Block, struct stinfo *);
-int fb64_keyid (int, unsigned char *, int *, struct fb *);
-void fb64_printsub (unsigned char *, int, unsigned char *, int,
- unsigned char *);
-
-static void ecb_encrypt(stp, in, out)
- struct stinfo *stp;
- Block in;
- Block out;
-{
- krb5_error_code code;
- krb5_data din;
- krb5_enc_data dout;
-
- din.length = 8;
- din.data = in;
-
- dout.ciphertext.length = 8;
- dout.ciphertext.data = out;
- dout.enctype = ENCTYPE_UNKNOWN;
-
- code = krb5_c_encrypt(telnet_context, &stp->str_key, 0, 0,
- &din, &dout);
- /* XXX I'm not sure what to do if this fails */
- if (code)
- com_err("libtelnet", code, "encrypting stream data");
-}
-
- void
-cfb64_init(server)
- int server;
-{
- fb64_init(&fb[CFB]);
- fb[CFB].fb_feed[4] = ENCTYPE_DES_CFB64;
- fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, CFB);
- fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, CFB);
-}
-
- void
-ofb64_init(server)
- int server;
-{
- fb64_init(&fb[OFB]);
- fb[OFB].fb_feed[4] = ENCTYPE_DES_OFB64;
- fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, OFB);
- fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, OFB);
-}
-
- void
-fb64_init(fbp)
- register struct fb *fbp;
-{
- memset(fbp, 0, sizeof(*fbp));
- fbp->state[0] = fbp->state[1] = FAILED;
- fbp->fb_feed[0] = IAC;
- fbp->fb_feed[1] = SB;
- fbp->fb_feed[2] = TELOPT_ENCRYPT;
- fbp->fb_feed[3] = ENCRYPT_IS;
-}
-
-/*
- * Returns:
- * -1: some error. Negotiation is done, encryption not ready.
- * 0: Successful, initial negotiation all done.
- * 1: successful, negotiation not done yet.
- * 2: Not yet. Other things (like getting the key from
- * Kerberos) have to happen before we can continue.
- */
- int
-cfb64_start(dir, server)
- int dir;
- int server;
-{
- return(fb64_start(&fb[CFB], dir, server));
-}
- int
-ofb64_start(dir, server)
- int dir;
- int server;
-{
- return(fb64_start(&fb[OFB], dir, server));
-}
-
- static int
-fb64_start(fbp, dir, server)
- struct fb *fbp;
- int dir;
- int server;
-{
- int x;
- unsigned char *p;
- register int state;
-
- switch (dir) {
- case DIR_DECRYPT:
- /*
- * This is simply a request to have the other side
- * start output (our input). He will negotiate an
- * IV so we need not look for it.
- */
- state = fbp->state[dir-1];
- if (state == FAILED)
- state = IN_PROGRESS;
- break;
-
- case DIR_ENCRYPT:
- state = fbp->state[dir-1];
- if (state == FAILED)
- state = IN_PROGRESS;
- else if ((state & NO_SEND_IV) == 0)
- break;
-
- if (!fbp->validkey) {
- fbp->need_start = 1;
- break;
- }
- state &= ~NO_SEND_IV;
- state |= NO_RECV_IV;
- if (encrypt_debug_mode)
- printf("Creating new feed\r\n");
- /*
- * Create a random feed and send it over.
- */
- {
- krb5_data d;
-
- d.data = fbp->temp_feed;
- d.length = sizeof(fbp->temp_feed);
-
- if (krb5_c_random_make_octets(telnet_context, &d))
- return(FAILED);
- }
-
- p = fbp->fb_feed + 3;
- *p++ = ENCRYPT_IS;
- p++;
- *p++ = FB64_IV;
- for (x = 0; x < sizeof(Block); ++x) {
- if ((*p++ = fbp->temp_feed[x]) == IAC)
- *p++ = IAC;
- }
- *p++ = IAC;
- *p++ = SE;
- printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]);
- net_write(fbp->fb_feed, p - fbp->fb_feed);
- break;
- default:
- return(FAILED);
- }
- return(fbp->state[dir-1] = state);
-}
-
-/*
- * Returns:
- * -1: some error. Negotiation is done, encryption not ready.
- * 0: Successful, initial negotiation all done.
- * 1: successful, negotiation not done yet.
- */
- int
-cfb64_is(data, cnt)
- unsigned char *data;
- int cnt;
-{
- return(fb64_is(data, cnt, &fb[CFB]));
-}
- int
-ofb64_is(data, cnt)
- unsigned char *data;
- int cnt;
-{
- return(fb64_is(data, cnt, &fb[OFB]));
-}
-
- int
-fb64_is(data, cnt, fbp)
- unsigned char *data;
- int cnt;
- struct fb *fbp;
-{
- unsigned char *p;
- register int state = fbp->state[DIR_DECRYPT-1];
-
- if (cnt-- < 1)
- goto failure;
-
- switch (*data++) {
- case FB64_IV:
- if (cnt != sizeof(Block)) {
- if (encrypt_debug_mode)
- printf("CFB64: initial vector failed on size\r\n");
- state = FAILED;
- goto failure;
- }
-
- if (encrypt_debug_mode)
- printf("CFB64: initial vector received\r\n");
-
- if (encrypt_debug_mode)
- printf("Initializing Decrypt stream\r\n");
-
- fb64_stream_iv((void *)data, &fbp->streams[DIR_DECRYPT-1]);
-
- p = fbp->fb_feed + 3;
- *p++ = ENCRYPT_REPLY;
- p++;
- *p++ = FB64_IV_OK;
- *p++ = IAC;
- *p++ = SE;
- printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]);
- net_write(fbp->fb_feed, p - fbp->fb_feed);
-
- state = fbp->state[DIR_DECRYPT-1] = IN_PROGRESS;
- break;
-
- default:
- if (encrypt_debug_mode) {
- printf("Unknown option type: %d\r\n", *(data-1));
- printd(data, cnt);
- printf("\r\n");
- }
- /* FALL THROUGH */
- failure:
- /*
- * We failed. Send an FB64_IV_BAD option
- * to the other side so it will know that
- * things failed.
- */
- p = fbp->fb_feed + 3;
- *p++ = ENCRYPT_REPLY;
- p++;
- *p++ = FB64_IV_BAD;
- *p++ = IAC;
- *p++ = SE;
- printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]);
- net_write(fbp->fb_feed, p - fbp->fb_feed);
-
- break;
- }
- return(fbp->state[DIR_DECRYPT-1] = state);
-}
-
-/*
- * Returns:
- * -1: some error. Negotiation is done, encryption not ready.
- * 0: Successful, initial negotiation all done.
- * 1: successful, negotiation not done yet.
- */
- int
-cfb64_reply(data, cnt)
- unsigned char *data;
- int cnt;
-{
- return(fb64_reply(data, cnt, &fb[CFB]));
-}
- int
-ofb64_reply(data, cnt)
- unsigned char *data;
- int cnt;
-{
- return(fb64_reply(data, cnt, &fb[OFB]));
-}
-
-
- int
-fb64_reply(data, cnt, fbp)
- unsigned char *data;
- int cnt;
- struct fb *fbp;
-{
- register int state = fbp->state[DIR_ENCRYPT-1];
-
- if (cnt-- < 1)
- goto failure;
-
- switch (*data++) {
- case FB64_IV_OK:
- fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]);
- if (state == FAILED)
- state = IN_PROGRESS;
- state &= ~NO_RECV_IV;
- encrypt_send_keyid(DIR_ENCRYPT, (unsigned char *)"\0", 1, 1);
- break;
-
- case FB64_IV_BAD:
- memset(fbp->temp_feed, 0, sizeof(Block));
- fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]);
- state = FAILED;
- break;
-
- default:
- if (encrypt_debug_mode) {
- printf("Unknown option type: %d\r\n", data[-1]);
- printd(data, cnt);
- printf("\r\n");
- }
- /* FALL THROUGH */
- failure:
- state = FAILED;
- break;
- }
- return(fbp->state[DIR_ENCRYPT-1] = state);
-}
-
- void
-cfb64_session(key, server)
- Session_Key *key;
- int server;
-{
- fb64_session(key, server, &fb[CFB]);
-}
-
- void
-ofb64_session(key, server)
- Session_Key *key;
- int server;
-{
- fb64_session(key, server, &fb[OFB]);
-}
-
- static void
-fb64_session(key, server, fbp)
- Session_Key *key;
- int server;
- struct fb *fbp;
-{
- if (!key || key->type != SK_DES) {
- if (encrypt_debug_mode)
- printf("Can't set krbdes's session key (%d != %d)\r\n",
- key ? key->type : -1, SK_DES);
- return;
- }
-
- fbp->validkey = 1;
-
- fb64_stream_key(key->data, &fbp->streams[DIR_ENCRYPT-1]);
- fb64_stream_key(key->data, &fbp->streams[DIR_DECRYPT-1]);
-
- /*
- * Now look to see if krbdes_start() was was waiting for
- * the key to show up. If so, go ahead an call it now
- * that we have the key.
- */
- if (fbp->need_start) {
- fbp->need_start = 0;
- fb64_start(fbp, DIR_ENCRYPT, server);
- }
-}
-
-/*
- * We only accept a keyid of 0. If we get a keyid of
- * 0, then mark the state as SUCCESS.
- */
- int
-cfb64_keyid(dir, kp, lenp)
- int dir, *lenp;
- unsigned char *kp;
-{
- return(fb64_keyid(dir, kp, lenp, &fb[CFB]));
-}
-
- int
-ofb64_keyid(dir, kp, lenp)
- int dir, *lenp;
- unsigned char *kp;
-{
- return(fb64_keyid(dir, kp, lenp, &fb[OFB]));
-}
-
- int
-fb64_keyid(dir, kp, lenp, fbp)
- int dir, *lenp;
- unsigned char *kp;
- struct fb *fbp;
-{
- register int state = fbp->state[dir-1];
-
- if (*lenp != 1 || (*kp != '\0')) {
- *lenp = 0;
- return(state);
- }
-
- if (state == FAILED)
- state = IN_PROGRESS;
-
- state &= ~NO_KEYID;
-
- return(fbp->state[dir-1] = state);
-}
-
- void
-fb64_printsub(data, cnt, buf, buflen, type)
- unsigned char *data, *buf, *type;
- int cnt, buflen;
-{
- char lbuf[32];
- register int i;
- char *cp;
-
- buf[buflen-1] = '\0'; /* make sure it's NULL terminated */
- buflen -= 1;
-
- switch(data[2]) {
- case FB64_IV:
- snprintf(lbuf, sizeof(lbuf), "%s_IV", type);
- cp = lbuf;
- goto common;
-
- case FB64_IV_OK:
- snprintf(lbuf, sizeof(lbuf), "%s_IV_OK", type);
- cp = lbuf;
- goto common;
-
- case FB64_IV_BAD:
- snprintf(lbuf, sizeof(lbuf), "%s_IV_BAD", type);
- cp = lbuf;
- goto common;
-
- default:
- snprintf(lbuf, sizeof(lbuf), " %d (unknown)", data[2]);
- cp = lbuf;
- common:
- for (; (buflen > 0) && (*buf = *cp++); buf++)
- buflen--;
- for (i = 3; i < cnt; i++) {
- snprintf(lbuf, sizeof(lbuf), " %d", data[i]);
- for (cp = lbuf; (buflen > 0) && (*buf = *cp++); buf++)
- buflen--;
- }
- break;
- }
-}
-
- void
-cfb64_printsub(data, cnt, buf, buflen)
- unsigned char *data, *buf;
- int cnt, buflen;
-{
- fb64_printsub(data, cnt, buf, buflen, (unsigned char *) "CFB64");
-}
-
- void
-ofb64_printsub(data, cnt, buf, buflen)
- unsigned char *data, *buf;
- int cnt, buflen;
-{
- fb64_printsub(data, cnt, buf, buflen, (unsigned char *) "OFB64");
-}
-
- void
-fb64_stream_iv(seed, stp)
- Block seed;
- register struct stinfo *stp;
-{
- memcpy(stp->str_iv, seed, sizeof(Block));
- memcpy(stp->str_output, seed, sizeof(Block));
-
- stp->str_index = sizeof(Block);
-}
-
- void
-fb64_stream_key(key, stp)
- Block key;
- register struct stinfo *stp;
-{
- memcpy(stp->str_keybytes, key, sizeof(Block));
- stp->str_key.length = 8;
- stp->str_key.contents = stp->str_keybytes;
- /* the original version of this code uses des ecb mode, but
- it only ever does one block at a time. cbc with a zero iv
- is identical */
- stp->str_key.enctype = ENCTYPE_DES_CBC_RAW;
-
- memcpy(stp->str_output, stp->str_iv, sizeof(Block));
-
- stp->str_index = sizeof(Block);
-}
-
-/*
- * DES 64 bit Cipher Feedback
- *
- * key --->+-----+
- * +->| DES |--+
- * | +-----+ |
- * | v
- * INPUT --(--------->(+)+---> DATA
- * | |
- * +-------------+
- *
- *
- * Given:
- * iV: Initial vector, 64 bits (8 bytes) long.
- * Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt).
- * On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output.
- *
- * V0 = DES(iV, key)
- * On = Dn ^ Vn
- * V(n+1) = DES(On, key)
- */
-
- void
-cfb64_encrypt(s, c)
- register unsigned char *s;
- int c;
-{
- register struct stinfo *stp = &fb[CFB].streams[DIR_ENCRYPT-1];
- register int idx;
-
- idx = stp->str_index;
- while (c-- > 0) {
- if (idx == sizeof(Block)) {
- Block b;
- ecb_encrypt(stp, stp->str_output, b);
- memcpy(stp->str_feed,b,sizeof(Block));
- idx = 0;
- }
-
- /* On encryption, we store (feed ^ data) which is cypher */
- *s = stp->str_output[idx] = (stp->str_feed[idx] ^ *s);
- s++;
- idx++;
- }
- stp->str_index = idx;
-}
-
- int
-cfb64_decrypt(data)
- int data;
-{
- register struct stinfo *stp = &fb[CFB].streams[DIR_DECRYPT-1];
- int idx;
-
- if (data == -1) {
- /*
- * Back up one byte. It is assumed that we will
- * never back up more than one byte. If we do, this
- * may or may not work.
- */
- if (stp->str_index)
- --stp->str_index;
- return(0);
- }
-
- idx = stp->str_index++;
- if (idx == sizeof(Block)) {
- Block b;
- ecb_encrypt(stp, stp->str_output, b);
- memcpy(stp->str_feed, b, sizeof(Block));
- stp->str_index = 1; /* Next time will be 1 */
- idx = 0; /* But now use 0 */
- }
-
- /* On decryption we store (data) which is cypher. */
- stp->str_output[idx] = data;
- return(data ^ stp->str_feed[idx]);
-}
-
-/*
- * DES 64 bit Output Feedback
- *
- * key --->+-----+
- * +->| DES |--+
- * | +-----+ |
- * +-----------+
- * v
- * INPUT -------->(+) ----> DATA
- *
- * Given:
- * iV: Initial vector, 64 bits (8 bytes) long.
- * Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt).
- * On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output.
- *
- * V0 = DES(iV, key)
- * V(n+1) = DES(Vn, key)
- * On = Dn ^ Vn
- */
- void
-ofb64_encrypt(s, c)
- register unsigned char *s;
- int c;
-{
- register struct stinfo *stp = &fb[OFB].streams[DIR_ENCRYPT-1];
- register int idx;
-
- idx = stp->str_index;
- while (c-- > 0) {
- if (idx == sizeof(Block)) {
- Block b;
- ecb_encrypt(stp, stp->str_feed, b);
- memcpy(stp->str_feed,b,sizeof(Block));
- idx = 0;
- }
- *s++ ^= stp->str_feed[idx];
- idx++;
- }
- stp->str_index = idx;
-}
-
- int
-ofb64_decrypt(data)
- int data;
-{
- register struct stinfo *stp = &fb[OFB].streams[DIR_DECRYPT-1];
- int idx;
-
- if (data == -1) {
- /*
- * Back up one byte. It is assumed that we will
- * never back up more than one byte. If we do, this
- * may or may not work.
- */
- if (stp->str_index)
- --stp->str_index;
- return(0);
- }
-
- idx = stp->str_index++;
- if (idx == sizeof(Block)) {
- Block b;
- ecb_encrypt(stp, stp->str_feed, b);
- memcpy(stp->str_feed, b, sizeof(Block));
- stp->str_index = 1; /* Next time will be 1 */
- idx = 0; /* But now use 0 */
- }
-
- return(data ^ stp->str_feed[idx]);
-}
-# endif /* DES_ENCRYPTION */
-# endif /* AUTHENTICATION */
-#else /* ENCRYPTION */
-#include "misc-proto.h"
-#endif /* ENCRYPTION */
+++ /dev/null
-/*-
- * Copyright (c) 1991, 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.
- */
-
-/* based on @(#)encrypt.c 8.1 (Berkeley) 6/4/93 */
-
-/*
- * Copyright (C) 1990 by the Massachusetts Institute of Technology
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- */
-
-#ifdef ENCRYPTION
-
-#include <stdio.h>
-#define ENCRYPT_NAMES
-#include <arpa/telnet.h>
-
-#include "encrypt.h"
-#include "misc.h"
-
-#ifdef __STDC__
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#include <strings.h>
-#endif
-
-/*
- * These functions pointers point to the current routines
- * for encrypting and decrypting data.
- */
-void (*encrypt_output) (unsigned char *, int);
-int (*decrypt_input) (int);
-
-int encrypt_debug_mode = 0;
-static int decrypt_mode = 0;
-static int encrypt_mode = 0;
-static int encrypt_verbose = 0;
-static int autoencrypt = 0;
-static int autodecrypt = 0;
-static int havesessionkey = 0;
-static int Server = 0;
-static char *Name = "Noname";
-
-#define typemask(x) ((x) > 0 ? 1 << ((x)-1) : 0)
-
-static long i_support_encrypt = typemask(ENCTYPE_DES_CFB64)
- | typemask(ENCTYPE_DES_OFB64);
-static long i_support_decrypt = typemask(ENCTYPE_DES_CFB64)
- | typemask(ENCTYPE_DES_OFB64);
-static long i_wont_support_encrypt = 0;
-static long i_wont_support_decrypt = 0;
-#define I_SUPPORT_ENCRYPT (i_support_encrypt & ~i_wont_support_encrypt)
-#define I_SUPPORT_DECRYPT (i_support_decrypt & ~i_wont_support_decrypt)
-
-static long remote_supports_encrypt = 0;
-static long remote_supports_decrypt = 0;
-
-static Encryptions encryptions[] = {
-#ifdef DES_ENCRYPTION
- { "DES_CFB64", ENCTYPE_DES_CFB64,
- cfb64_encrypt,
- cfb64_decrypt,
- cfb64_init,
- cfb64_start,
- cfb64_is,
- cfb64_reply,
- cfb64_session,
- cfb64_keyid,
- cfb64_printsub },
- { "DES_OFB64", ENCTYPE_DES_OFB64,
- ofb64_encrypt,
- ofb64_decrypt,
- ofb64_init,
- ofb64_start,
- ofb64_is,
- ofb64_reply,
- ofb64_session,
- ofb64_keyid,
- ofb64_printsub },
-#endif /* DES_ENCRYPTION */
- { 0, },
-};
-
-static unsigned char str_send[64] = { IAC, SB, TELOPT_ENCRYPT,
- ENCRYPT_SUPPORT };
-static unsigned char str_suplen = 0;
-static unsigned char str_start[72] = { IAC, SB, TELOPT_ENCRYPT };
-static unsigned char str_end[] = { IAC, SB, TELOPT_ENCRYPT, 0, IAC, SE };
-
- Encryptions *
-findencryption(type)
- int type;
-{
- Encryptions *ep = encryptions;
-
- if (!(I_SUPPORT_ENCRYPT & remote_supports_decrypt & typemask(type)))
- return(0);
- while (ep->type && ep->type != type)
- ++ep;
- return(ep->type ? ep : 0);
-}
-
- Encryptions *
-finddecryption(type)
- int type;
-{
- Encryptions *ep = encryptions;
-
- if (!(I_SUPPORT_DECRYPT & remote_supports_encrypt & typemask(type)))
- return(0);
- while (ep->type && ep->type != type)
- ++ep;
- return(ep->type ? ep : 0);
-}
-
-#define MAXKEYLEN 64
-
-static struct key_info {
- unsigned char keyid[MAXKEYLEN];
- int keylen;
- int dir;
- int *modep;
- Encryptions *(*getcrypt)();
-} ki[2] = {
- { { 0 }, 0, DIR_ENCRYPT, &encrypt_mode, findencryption },
- { { 0 }, 0, DIR_DECRYPT, &decrypt_mode, finddecryption },
-};
-
- void
-encrypt_init(name, server)
- char *name;
- int server;
-{
- Encryptions *ep = encryptions;
-
- Name = name;
- Server = server;
- i_support_encrypt = i_support_decrypt = 0;
- remote_supports_encrypt = remote_supports_decrypt = 0;
- encrypt_mode = 0;
- decrypt_mode = 0;
- encrypt_output = 0;
- decrypt_input = 0;
-#ifdef notdef
- encrypt_verbose = !server;
-#endif
-
- str_suplen = 4;
-
- while (ep->type) {
- if (encrypt_debug_mode)
- printf(">>>%s: I will support %s\r\n",
- Name, ENCTYPE_NAME(ep->type));
- i_support_encrypt |= typemask(ep->type);
- i_support_decrypt |= typemask(ep->type);
- if ((i_wont_support_decrypt & typemask(ep->type)) == 0)
- if ((str_send[str_suplen++] = ep->type) == IAC)
- str_send[str_suplen++] = IAC;
- if (ep->init)
- (*ep->init)(Server);
- ++ep;
- }
- str_send[str_suplen++] = IAC;
- str_send[str_suplen++] = SE;
-}
-
-static void
-encrypt_list_types()
-{
- Encryptions *ep = encryptions;
-
- printf("Valid encryption types:\n");
- while (ep->type) {
- printf("\t%s (%d)\r\n", ENCTYPE_NAME(ep->type), ep->type);
- ++ep;
- }
-}
-
- int
-EncryptEnable(type, mode)
- char *type, *mode;
-{
- if (isprefix(type, "help") || isprefix(type, "?")) {
- printf("Usage: encrypt enable <type> [input|output]\n");
- encrypt_list_types();
- return(0);
- }
- if (EncryptType(type, mode))
- return(EncryptStart(mode));
- return(0);
-}
-
- int
-EncryptDisable(type, mode)
- char *type, *mode;
-{
- register Encryptions *ep;
- int ret = 0;
-
- if (isprefix(type, "help") || isprefix(type, "?")) {
- printf("Usage: encrypt disable <type> [input|output]\n");
- encrypt_list_types();
- } else if ((ep = (Encryptions *)genget(type, (char **) encryptions,
- sizeof(Encryptions))) == 0) {
- printf("%s: invalid encryption type\n", type);
- } else if (Ambiguous(ep)) {
- printf("Ambiguous type '%s'\n", type);
- } else {
- if ((mode == 0) || (isprefix(mode, "input") ? 1 : 0)) {
- if (decrypt_mode == ep->type)
- EncryptStopInput();
- i_wont_support_decrypt |= typemask(ep->type);
- ret = 1;
- }
- if ((mode == 0) || (isprefix(mode, "output"))) {
- if (encrypt_mode == ep->type)
- EncryptStopOutput();
- i_wont_support_encrypt |= typemask(ep->type);
- ret = 1;
- }
- if (ret == 0)
- printf("%s: invalid encryption mode\n", mode);
- }
- return(ret);
-}
-
- int
-EncryptType(type, mode)
- char *type;
- char *mode;
-{
- register Encryptions *ep;
- int ret = 0;
-
- if (isprefix(type, "help") || isprefix(type, "?")) {
- printf("Usage: encrypt type <type> [input|output]\n");
- encrypt_list_types();
- } else if ((ep = (Encryptions *)genget(type, (char **) encryptions,
- sizeof(Encryptions))) == 0) {
- printf("%s: invalid encryption type\n", type);
- } else if (Ambiguous(ep)) {
- printf("Ambiguous type '%s'\n", type);
- } else {
- if ((mode == 0) || isprefix(mode, "input")) {
- decrypt_mode = ep->type;
- i_wont_support_decrypt &= ~typemask(ep->type);
- ret = 1;
- }
- if ((mode == 0) || isprefix(mode, "output")) {
- encrypt_mode = ep->type;
- i_wont_support_encrypt &= ~typemask(ep->type);
- ret = 1;
- }
- if (ret == 0)
- printf("%s: invalid encryption mode\n", mode);
- }
- return(ret);
-}
-
- int
-EncryptStart(mode)
- char *mode;
-{
- register int ret = 0;
- if (mode) {
- if (isprefix(mode, "input"))
- return(EncryptStartInput());
- if (isprefix(mode, "output"))
- return(EncryptStartOutput());
- if (isprefix(mode, "help") || isprefix(mode, "?")) {
- printf("Usage: encrypt start [input|output]\n");
- return(0);
- }
- printf("%s: invalid encryption mode 'encrypt start ?' for help\n", mode);
- return(0);
- }
- ret += EncryptStartInput();
- ret += EncryptStartOutput();
- return(ret);
-}
-
- int
-EncryptStartInput()
-{
- if (decrypt_mode) {
- encrypt_send_request_start();
- return(1);
- }
- if (!Server)
- printf("No previous decryption mode, decryption not enabled\r\n");
- return(0);
-}
-
- int
-EncryptStartOutput()
-{
- if (encrypt_mode) {
- encrypt_start_output(encrypt_mode);
- return(1);
- }
- if (!Server)
- printf("No previous encryption mode, encryption not enabled\r\n");
- return(0);
-}
-
- int
-EncryptStop(mode)
- char *mode;
-{
- int ret = 0;
- if (mode) {
- if (isprefix(mode, "input"))
- return(EncryptStopInput());
- if (isprefix(mode, "output"))
- return(EncryptStopOutput());
- if (isprefix(mode, "help") || isprefix(mode, "?")) {
- printf("Usage: encrypt stop [input|output]\n");
- return(0);
- }
- printf("%s: invalid encryption mode 'encrypt stop ?' for help\n", mode);
- return(0);
- }
- ret += EncryptStopInput();
- ret += EncryptStopOutput();
- return(ret);
-}
-
- int
-EncryptStopInput()
-{
- encrypt_send_request_end();
- return(1);
-}
-
- int
-EncryptStopOutput()
-{
- encrypt_send_end();
- return(1);
-}
-
- void
-encrypt_display()
-{
- if (encrypt_output)
- printf("Currently encrypting output with %s\r\n",
- ENCTYPE_NAME(encrypt_mode));
- if (decrypt_input)
- printf("Currently decrypting input with %s\r\n",
- ENCTYPE_NAME(decrypt_mode));
-}
-
- int
-EncryptStatus()
-{
- if (encrypt_output)
- printf("Currently encrypting output with %s\r\n",
- ENCTYPE_NAME(encrypt_mode));
- else if (encrypt_mode) {
- printf("Currently output is clear text.\r\n");
- printf("Last encryption mode was %s\r\n",
- ENCTYPE_NAME(encrypt_mode));
- }
- if (decrypt_input) {
- printf("Currently decrypting input with %s\r\n",
- ENCTYPE_NAME(decrypt_mode));
- } else if (decrypt_mode) {
- printf("Currently input is clear text.\r\n");
- printf("Last decryption mode was %s\r\n",
- ENCTYPE_NAME(decrypt_mode));
- }
- return 1;
-}
-
- void
-encrypt_send_support()
-{
- if (str_suplen) {
- /*
- * If the user has requested that decryption start
- * immediatly, then send a "REQUEST START" before
- * we negotiate the type.
- */
- if (!Server && autodecrypt)
- encrypt_send_request_start();
- net_write(str_send, str_suplen);
- printsub('>', &str_send[2], str_suplen - 2);
- str_suplen = 0;
- }
-}
-
- int
-EncryptDebug(on)
- int on;
-{
- if (on < 0)
- encrypt_debug_mode ^= 1;
- else
- encrypt_debug_mode = on;
- printf("Encryption debugging %s\r\n",
- encrypt_debug_mode ? "enabled" : "disabled");
- return(1);
-}
-
- int
-EncryptVerbose(on)
- int on;
-{
- if (on < 0)
- encrypt_verbose ^= 1;
- else
- encrypt_verbose = on;
- printf("Encryption %s verbose\r\n",
- encrypt_verbose ? "is" : "is not");
- return(1);
-}
-
- int
-EncryptAutoEnc(on)
- int on;
-{
- encrypt_auto(on);
- printf("Automatic encryption of output is %s\r\n",
- autoencrypt ? "enabled" : "disabled");
- return(1);
-}
-
- int
-EncryptAutoDec(on)
- int on;
-{
- decrypt_auto(on);
- printf("Automatic decryption of input is %s\r\n",
- autodecrypt ? "enabled" : "disabled");
- return(1);
-}
-
-/*
- * Called when ENCRYPT SUPPORT is received.
- */
- void
-encrypt_support(typelist, cnt)
- unsigned char *typelist;
- int cnt;
-{
- register int type, use_type = 0;
- Encryptions *ep;
-
- /*
- * Forget anything the other side has previously told us.
- */
- remote_supports_decrypt = 0;
-
- while (cnt-- > 0) {
- type = *typelist++;
- if (encrypt_debug_mode)
- printf(">>>%s: He is supporting %s (%d)\r\n",
- Name,
- ENCTYPE_NAME(type), type);
- if ((type < ENCTYPE_CNT) &&
- (I_SUPPORT_ENCRYPT & typemask(type))) {
- remote_supports_decrypt |= typemask(type);
- if (use_type == 0)
- use_type = type;
- }
- }
- if (use_type) {
- ep = findencryption(use_type);
- if (!ep)
- return;
- type = ep->start ? (*ep->start)(DIR_ENCRYPT, Server) : 0;
- if (encrypt_debug_mode)
- printf(">>>%s: (*ep->start)() returned %d\r\n",
- Name, type);
- if (type < 0)
- return;
- encrypt_mode = use_type;
- if (type == 0)
- encrypt_start_output(use_type);
- }
-}
-
- void
-encrypt_is(data, cnt)
- unsigned char *data;
- int cnt;
-{
- Encryptions *ep;
- register int type, ret;
-
- if (--cnt < 0)
- return;
- type = *data++;
- if (type < ENCTYPE_CNT)
- remote_supports_encrypt |= typemask(type);
- if (!(ep = finddecryption(type))) {
- if (encrypt_debug_mode)
- printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n",
- Name,
- ENCTYPE_NAME_OK(type)
- ? ENCTYPE_NAME(type) : "(unknown)",
- type);
- return;
- }
- if (!ep->is) {
- if (encrypt_debug_mode)
- printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n",
- Name,
- ENCTYPE_NAME_OK(type)
- ? ENCTYPE_NAME(type) : "(unknown)",
- type);
- ret = 0;
- } else {
- ret = (*ep->is)(data, cnt);
- if (encrypt_debug_mode)
- printf("(*ep->is)(%lx, %d) returned %s(%d)\n",
- (unsigned long) data, cnt,
- (ret < 0) ? "FAIL " :
- (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret);
- }
- if (ret < 0) {
- autodecrypt = 0;
- } else {
- decrypt_mode = type;
- if (ret == 0 && autodecrypt)
- encrypt_send_request_start();
- }
-}
-
- void
-encrypt_reply(data, cnt)
- unsigned char *data;
- int cnt;
-{
- Encryptions *ep;
- register int ret, type;
-
- if (--cnt < 0)
- return;
- type = *data++;
- if (!(ep = findencryption(type))) {
- if (encrypt_debug_mode)
- printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n",
- Name,
- ENCTYPE_NAME_OK(type)
- ? ENCTYPE_NAME(type) : "(unknown)",
- type);
- return;
- }
- if (!ep->reply) {
- if (encrypt_debug_mode)
- printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n",
- Name,
- ENCTYPE_NAME_OK(type)
- ? ENCTYPE_NAME(type) : "(unknown)",
- type);
- ret = 0;
- } else {
- ret = (*ep->reply)(data, cnt);
- if (encrypt_debug_mode)
- printf("(*ep->reply)(%lx, %d) returned %s(%d)\n",
- (unsigned long) data, cnt,
- (ret < 0) ? "FAIL " :
- (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret);
- }
- if (encrypt_debug_mode)
- printf(">>>%s: encrypt_reply returned %d\n", Name, ret);
- if (ret < 0) {
- autoencrypt = 0;
- } else {
- encrypt_mode = type;
- if (ret == 0 && autoencrypt)
- encrypt_start_output(type);
- }
-}
-
-/*
- * Called when a ENCRYPT START command is received.
- */
- void
-encrypt_start(data, cnt)
- unsigned char *data;
- int cnt;
-{
- Encryptions *ep;
-
- if (!decrypt_mode) {
- /*
- * Something is wrong. We should not get a START
- * command without having already picked our
- * decryption scheme. Send a REQUEST-END to
- * attempt to clear the channel...
- */
- printf("%s: Warning, Cannot decrypt input stream!!!\r\n", Name);
- encrypt_send_request_end();
- return;
- }
-
- if ((ep = finddecryption(decrypt_mode))) {
- decrypt_input = ep->input;
- if (encrypt_verbose)
- printf("[ Input is now decrypted with type %s ]\r\n",
- ENCTYPE_NAME(decrypt_mode));
- if (encrypt_debug_mode)
- printf(">>>%s: Start to decrypt input with type %s\r\n",
- Name, ENCTYPE_NAME(decrypt_mode));
- } else {
- printf("%s: Warning, Cannot decrypt type %s (%d)!!!\r\n",
- Name,
- ENCTYPE_NAME_OK(decrypt_mode)
- ? ENCTYPE_NAME(decrypt_mode)
- : "(unknown)",
- decrypt_mode);
- encrypt_send_request_end();
- }
-}
-
- void
-encrypt_session_key(key, server)
- Session_Key *key;
- int server;
-{
- Encryptions *ep = encryptions;
-
- havesessionkey = 1;
-
- while (ep->type) {
- if (ep->session)
- (*ep->session)(key, server);
-#ifdef notdef
- if (!encrypt_output && autoencrypt && !server)
- encrypt_start_output(ep->type);
- if (!decrypt_input && autodecrypt && !server)
- encrypt_send_request_start();
-#endif
- ++ep;
- }
-}
-
-/*
- * Called when ENCRYPT END is received.
- */
- void
-encrypt_end()
-{
- decrypt_input = 0;
- if (encrypt_debug_mode)
- printf(">>>%s: Input is back to clear text\r\n", Name);
- if (encrypt_verbose)
- printf("[ Input is now clear text ]\r\n");
-}
-
-/*
- * Called when ENCRYPT REQUEST-END is received.
- */
- void
-encrypt_request_end()
-{
- encrypt_send_end();
-}
-
-/*
- * Called when ENCRYPT REQUEST-START is received. If we receive
- * this before a type is picked, then that indicates that the
- * other side wants us to start encrypting data as soon as we
- * can.
- */
- void
-encrypt_request_start(data, cnt)
- unsigned char *data;
- int cnt;
-{
- if (encrypt_mode == 0) {
- if (Server)
- autoencrypt = 1;
- return;
- }
- encrypt_start_output(encrypt_mode);
-}
-
-static unsigned char str_keyid[(MAXKEYLEN*2)+5] = { IAC, SB, TELOPT_ENCRYPT };
-
-static void encrypt_keyid (struct key_info *kp, unsigned char *, unsigned int);
-
-void encrypt_enc_keyid(keyid, len)
- unsigned char *keyid;
- int len;
-{
- encrypt_keyid(&ki[1], keyid, (unsigned) len);
-}
-
-void encrypt_dec_keyid(keyid, len)
- unsigned char *keyid;
- int len;
-{
- encrypt_keyid(&ki[0], keyid, (unsigned) len);
-}
-
-static void encrypt_keyid(kp, keyid, len)
- struct key_info *kp;
- unsigned char *keyid;
- unsigned int len;
-{
- Encryptions *ep;
- int dir = kp->dir;
- register int ret = 0;
-
- if (!(ep = (*kp->getcrypt)(*kp->modep))) {
- if (len == 0)
- return;
- kp->keylen = 0;
- } else if (len == 0) {
- /*
- * Empty option, indicates a failure.
- */
- if (kp->keylen == 0)
- return;
- kp->keylen = 0;
- if (ep->keyid)
- (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen);
-
- } else if ((len != kp->keylen) ||
- (memcmp(keyid, kp->keyid, len) != 0)) {
- /*
- * Length or contents are different
- */
- kp->keylen = len;
- memcpy(kp->keyid, keyid, len);
- if (ep->keyid)
- (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen);
- } else {
- if (ep->keyid)
- ret = (*ep->keyid)(dir, kp->keyid, &kp->keylen);
- if ((ret == 0) && (dir == DIR_ENCRYPT) && autoencrypt)
- encrypt_start_output(*kp->modep);
- return;
- }
-
- encrypt_send_keyid(dir, kp->keyid, (unsigned) kp->keylen, 0);
-}
-
- void
-encrypt_send_keyid(dir, keyid, keylen, saveit)
- int dir;
- unsigned char *keyid;
- unsigned int keylen;
- int saveit;
-{
- unsigned char *strp;
-
- str_keyid[3] = (dir == DIR_ENCRYPT)
- ? ENCRYPT_ENC_KEYID : ENCRYPT_DEC_KEYID;
- if (saveit) {
- struct key_info *kp = &ki[(dir == DIR_ENCRYPT) ? 0 : 1];
- memcpy(kp->keyid, keyid, keylen);
- kp->keylen = keylen;
- }
-
- for (strp = &str_keyid[4]; keylen > 0; --keylen) {
- if ((*strp++ = *keyid++) == IAC)
- *strp++ = IAC;
- }
- *strp++ = IAC;
- *strp++ = SE;
- net_write(str_keyid, strp - str_keyid);
- printsub('>', &str_keyid[2], strp - str_keyid - 2);
-}
-
- void
-encrypt_auto(on)
- int on;
-{
- if (on < 0)
- autoencrypt ^= 1;
- else
- autoencrypt = on ? 1 : 0;
-}
-
- void
-decrypt_auto(on)
- int on;
-{
- if (on < 0)
- autodecrypt ^= 1;
- else
- autodecrypt = on ? 1 : 0;
-}
-
- void
-encrypt_start_output(type)
- int type;
-{
- Encryptions *ep;
- register unsigned char *p;
- register int i;
-
- if (!(ep = findencryption(type))) {
- if (encrypt_debug_mode) {
- printf(">>>%s: Can't encrypt with type %s (%d)\r\n",
- Name,
- ENCTYPE_NAME_OK(type)
- ? ENCTYPE_NAME(type) : "(unknown)",
- type);
- }
- return;
- }
- if (ep->start) {
- i = (*ep->start)(DIR_ENCRYPT, Server);
- if (encrypt_debug_mode) {
- printf(">>>%s: Encrypt start: %s (%d) %s\r\n",
- Name,
- (i < 0) ? "failed" :
- "initial negotiation in progress",
- i, ENCTYPE_NAME(type));
- }
- if (i)
- return;
- }
- p = str_start + 3;
- *p++ = ENCRYPT_START;
- for (i = 0; i < ki[0].keylen; ++i) {
- if ((*p++ = ki[0].keyid[i]) == IAC)
- *p++ = IAC;
- }
- *p++ = IAC;
- *p++ = SE;
- net_write(str_start, p - str_start);
- net_encrypt();
- printsub('>', &str_start[2], p - &str_start[2]);
- /*
- * If we are already encrypting in some mode, then
- * encrypt the ring (which includes our request) in
- * the old mode, mark it all as "clear text" and then
- * switch to the new mode.
- */
- encrypt_output = ep->output;
- encrypt_mode = type;
- if (encrypt_debug_mode)
- printf(">>>%s: Started to encrypt output with type %s\r\n",
- Name, ENCTYPE_NAME(type));
- if (encrypt_verbose)
- printf("[ Output is now encrypted with type %s ]\r\n",
- ENCTYPE_NAME(type));
-}
-
- void
-encrypt_send_end()
-{
- if (!encrypt_output)
- return;
-
- str_end[3] = ENCRYPT_END;
- net_write(str_end, sizeof(str_end));
- net_encrypt();
- printsub('>', &str_end[2], sizeof(str_end) - 2);
- /*
- * Encrypt the output buffer now because it will not be done by
- * netflush...
- */
- encrypt_output = 0;
- if (encrypt_debug_mode)
- printf(">>>%s: Output is back to clear text\r\n", Name);
- if (encrypt_verbose)
- printf("[ Output is now clear text ]\r\n");
-}
-
- void
-encrypt_send_request_start()
-{
- register unsigned char *p;
- register int i;
-
- p = &str_start[3];
- *p++ = ENCRYPT_REQSTART;
- for (i = 0; i < ki[1].keylen; ++i) {
- if ((*p++ = ki[1].keyid[i]) == IAC)
- *p++ = IAC;
- }
- *p++ = IAC;
- *p++ = SE;
- net_write(str_start, p - str_start);
- printsub('>', &str_start[2], p - &str_start[2]);
- if (encrypt_debug_mode)
- printf(">>>%s: Request input to be encrypted\r\n", Name);
-}
-
- void
-encrypt_send_request_end()
-{
- str_end[3] = ENCRYPT_REQEND;
- net_write(str_end, sizeof(str_end));
- printsub('>', &str_end[2], sizeof(str_end) - 2);
-
- if (encrypt_debug_mode)
- printf(">>>%s: Request input to be clear text\r\n", Name);
-}
-
- void
-encrypt_wait()
-{
- if (encrypt_debug_mode)
- printf(">>>%s: in encrypt_wait\r\n", Name);
- if (!havesessionkey || !(I_SUPPORT_ENCRYPT & remote_supports_decrypt))
- return;
- while (autoencrypt && !encrypt_output)
- if (telnet_spin())
- return;
-}
-
-int encrypt_is_encrypting()
-{
- if (encrypt_output && decrypt_input)
- return 1;
- return 0;
-}
-
- void
-encrypt_debug(mode)
- int mode;
-{
- encrypt_debug_mode = mode;
-}
-
- void
-encrypt_gen_printsub(data, cnt, buf, buflen)
- unsigned char *data, *buf;
- int cnt, buflen;
-{
- char tbuf[16], *cp;
-
- cnt -= 2;
- data += 2;
- buf[buflen-1] = '\0';
- buf[buflen-2] = '*';
- buflen -= 2;;
- for (; cnt > 0; cnt--, data++) {
- snprintf(tbuf, sizeof(tbuf), " %d", *data);
- for (cp = tbuf; *cp && buflen > 0; --buflen)
- *buf++ = *cp++;
- if (buflen <= 0)
- return;
- }
- *buf = '\0';
-}
-
- void
-encrypt_printsub(data, cnt, buf, buflen)
- unsigned char *data, *buf;
- int cnt, buflen;
-{
- Encryptions *ep;
- register int type = data[1];
-
- for (ep = encryptions; ep->type && ep->type != type; ep++)
- ;
-
- if (ep->printsub)
- (*ep->printsub)(data, cnt, buf, buflen);
- else
- encrypt_gen_printsub(data, cnt, buf, buflen);
-}
-#else /* ENCRYPTION */
-#include "misc-proto.h"
-#endif /* ENCRYPTION */
+++ /dev/null
-/*-
- * Copyright (c) 1991, 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.
- *
- * @(#)encrypt.h 8.1 (Berkeley) 6/4/93
- */
-
-/*
- * Copyright (C) 1990 by the Massachusetts Institute of Technology
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- */
-
-#ifdef ENCRYPTION
-# ifndef __ENCRYPTION__
-# define __ENCRYPTION__
-
-#define DIR_DECRYPT 1
-#define DIR_ENCRYPT 2
-
-typedef unsigned char Block[8];
-typedef unsigned char *BlockT;
-typedef struct { Block _; } Schedule[16];
-
-#define VALIDKEY(key) ( key[0] | key[1] | key[2] | key[3] | \
- key[4] | key[5] | key[6] | key[7])
-
-#define SAMEKEY(k1, k2) (!memcmp((void *)k1, (void *)k2, sizeof(Block)))
-
-typedef struct {
- short type;
- int length;
- unsigned char *data;
-} Session_Key;
-
-typedef struct {
- char *name;
- int type;
- void (*output) (unsigned char *, int);
- int (*input) (int);
- void (*init) (int);
- int (*start) (int, int);
- int (*is) (unsigned char *, int);
- int (*reply) (unsigned char *, int);
- void (*session) (Session_Key *, int);
- int (*keyid) (int, unsigned char *, int *);
- void (*printsub) (unsigned char *, int, unsigned char *, int);
-} Encryptions;
-
-#define SK_DES 1 /* Matched Kerberos v5 ENCTYPE_DES */
-
-#include "enc-proto.h"
-
-extern int encrypt_debug_mode;
-extern int (*decrypt_input) (int);
-extern void (*encrypt_output) (unsigned char *, int);
-# endif /* __ENCRYPTION__ */
-#endif /* ENCRYPTION */
+++ /dev/null
-/*
- * appl/telnet/libtelnet/forward.c
- */
-
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-
-/* General-purpose forwarding routines. These routines may be put into */
-/* libkrb5.a to allow widespread use */
-
-#if defined(KERBEROS) || defined(KRB5)
-#include <stdio.h>
-#include <netdb.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "krb5.h"
-#include <errno.h>
-
-#include "krb5forw.h"
-
-#if defined(NEED_SETENV) || defined(NEED_SETENV_PROTO)
-extern int setenv(char *, char *, int);
-#endif
-
-extern char *line; /* see sys_term.c */
-
-/* Decode, decrypt and store the forwarded creds in the local ccache. */
-krb5_error_code
-rd_and_store_for_creds(context, auth_context, inbuf, ticket)
- krb5_context context;
- krb5_auth_context auth_context;
- krb5_data *inbuf;
- krb5_ticket *ticket;
-{
- krb5_creds **creds;
- krb5_error_code retval;
- char ccname[35];
- krb5_ccache ccache = NULL;
-
- if ((retval = krb5_rd_cred(context, auth_context, inbuf, &creds, NULL)))
- return(retval);
-
- snprintf(ccname, sizeof(ccname), "FILE:/tmp/krb5cc_p%ld", (long) getpid());
- setenv("KRB5CCNAME", ccname, 1);
-
- if ((retval = krb5_cc_resolve(context, ccname, &ccache)))
- goto cleanup;
-
- if ((retval = krb5_cc_initialize(context, ccache,
- ticket->enc_part2->client)))
- goto cleanup;
-
- if ((retval = krb5_cc_store_cred(context, ccache, *creds)))
- goto cleanup;
-
-cleanup:
- krb5_free_creds(context, *creds);
- return retval;
-}
-
-#endif /* defined(KRB5) && defined(FORWARD) */
+++ /dev/null
-/*-
- * Copyright (c) 1991, 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.
- */
-
-/* based on @(#)genget.c 8.1 (Berkeley) 6/4/93 */
-
-#include <ctype.h>
-#include "misc.h"
-
-#define LOWER(x) (isupper((int) x) ? tolower((int) x) : (x))
-/*
- * The prefix function returns 0 if *s1 is not a prefix
- * of *s2. If *s1 exactly matches *s2, the negative of
- * the length is returned. If *s1 is a prefix of *s2,
- * the length of *s1 is returned.
- */
- int
-isprefix(s1, s2)
- register char *s1, *s2;
-{
- char *os1;
- register char c1, c2;
-
- if (*s1 == '\0')
- return(-1);
- os1 = s1;
- c1 = *s1;
- c2 = *s2;
- while (LOWER(c1) == LOWER(c2)) {
- if (c1 == '\0')
- break;
- c1 = *++s1;
- c2 = *++s2;
- }
- return(*s1 ? 0 : (*s2 ? (s1 - os1) : (os1 - s1)));
-}
-
-static char *ambiguous; /* special return value for command routines */
-
- char **
-genget(name, table, stlen)
- char *name; /* name to match */
- char **table; /* name entry in table */
- int stlen;
-{
- register char **c, **found;
- register int n;
-
- if (name == 0)
- return 0;
-
- found = 0;
- for (c = table; *c != 0; c = (char **)((char *)c + stlen)) {
- if ((n = isprefix(name, *c)) == 0)
- continue;
- if (n < 0) /* exact match */
- return(c);
- if (found)
- return(&ambiguous);
- found = c;
- }
- return(found);
-}
-
-/*
- * Function call version of Ambiguous()
- */
- int
-Ambiguous(s)
- void *s;
-{
- return((char **)s == &ambiguous);
-}
+++ /dev/null
-/*-
- * Copyright (c) 1991, 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.
- */
-
-/* based on @(#)getent.c 8.1 (Berkeley) 6/4/93 */
-
-#include "gettytab.h"
-
-#ifdef HAVE_CGETENT
-static char *area;
-#endif
-
-/*ARGSUSED*/
-int
-getent(cp, name)
-char *cp, *name;
-{
-#ifdef HAVE_CGETENT
- char *dba[2];
-
- dba[0] = "/etc/gettytab";
- dba[1] = 0;
- return((cgetent(&area, dba, name) == 0) ? 1 : 0);
-#else
- return(0);
-#endif
-}
-
-#ifndef SOLARIS
-/*ARGSUSED*/
-char *
-getstr(id, cpp)
-char *id, **cpp;
-{
-#ifdef HAVE_CGETENT
- char *answer;
- return((cgetstr(area, id, &answer) > 0) ? answer : 0);
-#else
- return(0);
-#endif
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 1987, 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.
- */
-
-/* based on @(#)getopt.c 8.1 (Berkeley) 6/4/93 */
-
-#ifndef __STDC__
-#define const
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/*
- * get option letter from argument vector
- */
-int opterr = 1, /* if error message should be printed */
- optind = 1, /* index into parent argv vector */
- optopt, /* character checked for validity */
- optreset; /* reset getopt */
-char *optarg; /* argument associated with option */
-
-#define BADCH (int)'?'
-#define BADARG (int)':'
-#define EMSG ""
-
-int
-getopt(nargc, nargv, ostr)
- int nargc;
- char * const *nargv;
- const char *ostr;
-{
- static char *place = EMSG; /* option letter processing */
- register char *oli; /* option letter list index */
- char *p;
-
- if (optreset || !*place) { /* update scanning pointer */
- optreset = 0;
- if (optind >= nargc || *(place = nargv[optind]) != '-') {
- place = EMSG;
- return(-1);
- }
- if (place[1] && *++place == '-') { /* found "--" */
- ++optind;
- place = EMSG;
- return(-1);
- }
- } /* option letter okay? */
- if ((optopt = (int)*place++) == (int)':' ||
- !(oli = index(ostr, optopt))) {
- /*
- * if the user didn't specify '-' as an option,
- * assume it means EOF.
- */
- if (optopt == (int)'-')
- return(-1);
- if (!*place)
- ++optind;
- if (opterr && *ostr != ':') {
- if (!(p = rindex(*nargv, '/')))
- p = *nargv;
- else
- ++p;
- (void)fprintf(stderr, "%s: illegal option -- %c\n",
- p, optopt);
- }
- return(BADCH);
- }
- if (*++oli != ':') { /* don't need argument */
- optarg = NULL;
- if (!*place)
- ++optind;
- }
- else { /* need an argument */
- if (*place) /* no white space */
- optarg = place;
- else if (nargc <= ++optind) { /* no arg */
- place = EMSG;
- if (!(p = rindex(*nargv, '/')))
- p = *nargv;
- else
- ++p;
- if (*ostr == ':')
- return(BADARG);
- if (opterr)
- (void)fprintf(stderr,
- "%s: option requires an argument -- %c\n",
- p, optopt);
- return(BADCH);
- }
- else /* white space */
- optarg = nargv[optind];
- place = EMSG;
- ++optind;
- }
- return(optopt); /* dump back option letter */
-}
+++ /dev/null
-/*
- * Copyright (c) 1980 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- */
-
-/* based on @(#)gettytab.c 5.1 (Berkeley) 4/29/85 */
-
-#include <ctype.h>
-
-#define TABBUFSIZ 512
-
-static char *tbuf;
-int hopcount; /* detect infinite loops in termcap, init 0 */
-char *skip();
-char *getstr();
-char *decode();
-
-/*
- * Get an entry for terminal name in buffer bp,
- * from the termcap file. Parse is very rudimentary;
- * we just notice escaped newlines.
- */
-getent(bp, name)
- char *bp, *name;
-{
- register char *cp;
- register int c;
- register int i = 0, cnt = 0;
- char ibuf[TABBUFSIZ];
- char *cp2;
- int tf;
-
- tbuf = bp;
- tf = open("/etc/gettytab", 0);
- if (tf < 0)
- return (-1);
- for (;;) {
- cp = bp;
- for (;;) {
- if (i == cnt) {
- cnt = read(tf, ibuf, TABBUFSIZ);
- if (cnt <= 0) {
- close(tf);
- return (0);
- }
- i = 0;
- }
- c = ibuf[i++];
- if (c == '\n') {
- if (cp > bp && cp[-1] == '\\'){
- cp--;
- continue;
- }
- break;
- }
- if (cp >= bp+TABBUFSIZ) {
- write(2,"Gettytab entry too long\n", 24);
- break;
- } else
- *cp++ = c;
- }
- *cp = 0;
-
- /*
- * The real work for the match.
- */
- if (namatch(name)) {
- close(tf);
- return(nchktc());
- }
- }
-}
-
-/*
- * tnchktc: check the last entry, see if it's tc=xxx. If so,
- * recursively find xxx and append that entry (minus the names)
- * to take the place of the tc=xxx entry. This allows termcap
- * entries to say "like an HP2621 but doesn't turn on the labels".
- * Note that this works because of the left to right scan.
- */
-#define MAXHOP 32
-nchktc()
-{
- register char *p, *q;
- char tcname[16]; /* name of similar terminal */
- char tcbuf[TABBUFSIZ];
- char *holdtbuf = tbuf;
- int l;
-
- p = tbuf + strlen(tbuf) - 2; /* before the last colon */
- while (*--p != ':')
- if (p<tbuf) {
- write(2, "Bad gettytab entry\n", 19);
- return (0);
- }
- p++;
- /* p now points to beginning of last field */
- if (p[0] != 't' || p[1] != 'c')
- return(1);
- strncpy(tcname, p + 3, sizeof(tcname) - 1);
- tcname[sizeof(tcname) - 1] = '\0';
- q = tcname;
- while (*q && *q != ':')
- q++;
- *q = 0;
- if (++hopcount > MAXHOP) {
- write(2, "Getty: infinite tc= loop\n", 25);
- return (0);
- }
- if (getent(tcbuf, tcname) != 1)
- return(0);
- for (q=tcbuf; *q != ':'; q++)
- ;
- l = p - holdtbuf + strlen(q);
- if (l > TABBUFSIZ) {
- write(2, "Gettytab entry too long\n", 24);
- q[TABBUFSIZ - (p-tbuf)] = 0;
- }
- strlcpy(p, q+1, TABBUFSIZ - (p-tbuf));
- tbuf = holdtbuf;
- return(1);
-}
-
-/*
- * Tnamatch deals with name matching. The first field of the termcap
- * entry is a sequence of names separated by |'s, so we compare
- * against each such name. The normal : terminator after the last
- * name (before the first field) stops us.
- */
-namatch(np)
- char *np;
-{
- register char *Np, *Bp;
-
- Bp = tbuf;
- if (*Bp == '#')
- return(0);
- for (;;) {
- for (Np = np; *Np && *Bp == *Np; Bp++, Np++)
- continue;
- if (*Np == 0 && (*Bp == '|' || *Bp == ':' || *Bp == 0))
- return (1);
- while (*Bp && *Bp != ':' && *Bp != '|')
- Bp++;
- if (*Bp == 0 || *Bp == ':')
- return (0);
- Bp++;
- }
-}
-
-/*
- * Skip to the next field. Notice that this is very dumb, not
- * knowing about \: escapes or any such. If necessary, :'s can be put
- * into the termcap file in octal.
- */
-static char *
-skip(bp)
- register char *bp;
-{
-
- while (*bp && *bp != ':')
- bp++;
- if (*bp == ':')
- bp++;
- return (bp);
-}
-
-/*
- * Return the (numeric) option id.
- * Numeric options look like
- * li#80
- * i.e. the option string is separated from the numeric value by
- * a # character. If the option is not found we return -1.
- * Note that we handle octal numbers beginning with 0.
- */
-long
-getnum(id)
- char *id;
-{
- register long i, base;
- register char *bp = tbuf;
-
- for (;;) {
- bp = skip(bp);
- if (*bp == 0)
- return (-1);
- if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
- continue;
- if (*bp == '@')
- return(-1);
- if (*bp != '#')
- continue;
- bp++;
- base = 10;
- if (*bp == '0')
- base = 8;
- i = 0;
- while (isdigit(*bp))
- i *= base, i += *bp++ - '0';
- return (i);
- }
-}
-
-/*
- * Handle a flag option.
- * Flag options are given "naked", i.e. followed by a : or the end
- * of the buffer. Return 1 if we find the option, or 0 if it is
- * not given.
- */
-getflag(id)
- char *id;
-{
- register char *bp = tbuf;
-
- for (;;) {
- bp = skip(bp);
- if (!*bp)
- return (-1);
- if (*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) {
- if (!*bp || *bp == ':')
- return (1);
- else if (*bp == '!')
- return (0);
- else if (*bp == '@')
- return(-1);
- }
- }
-}
-
-/*
- * Get a string valued option.
- * These are given as
- * cl=^Z
- * Much decoding is done on the strings, and the strings are
- * placed in area, which is a ref parameter which is updated.
- * No checking on area overflow.
- */
-char *
-getstr(id, area)
- char *id, **area;
-{
- register char *bp = tbuf;
-
- for (;;) {
- bp = skip(bp);
- if (!*bp)
- return (0);
- if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
- continue;
- if (*bp == '@')
- return(0);
- if (*bp != '=')
- continue;
- bp++;
- return (decode(bp, area));
- }
-}
-
-/*
- * Tdecode does the grung work to decode the
- * string capability escapes.
- */
-static char *
-decode(str, area)
- register char *str;
- char **area;
-{
- register char *cp;
- register int c;
- register char *dp;
- int i;
-
- cp = *area;
- while ((c = *str++) && c != ':') {
- switch (c) {
-
- case '^':
- c = *str++ & 037;
- break;
-
- case '\\':
- dp = "E\033^^\\\\::n\nr\rt\tb\bf\f";
- c = *str++;
-nextc:
- if (*dp++ == c) {
- c = *dp++;
- break;
- }
- dp++;
- if (*dp)
- goto nextc;
- if (isdigit(c)) {
- c -= '0', i = 2;
- do
- c <<= 3, c |= *str++ - '0';
- while (--i && isdigit(*str));
- }
- break;
- }
- *cp++ = c;
- }
- *cp++ = 0;
- str = *area;
- *area = cp;
- return (str);
-}
+++ /dev/null
-/*
- * Copyright (c) 1980 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- *
- * @(#)gettytab.h 5.2 (Berkeley) 1/7/86
- */
-
-/*
- * Getty description definitions.
- */
-struct gettystrs {
- char *field; /* name to lookup in gettytab */
- char *defalt; /* value we find by looking in defaults */
- char *value; /* value that we find there */
-};
-
-struct gettynums {
- char *field; /* name to lookup */
- long defalt; /* number we find in defaults */
- long value; /* number we find there */
- int set; /* we actually got this one */
-};
-
-struct gettyflags {
- char *field; /* name to lookup */
- char invrt; /* name existing in gettytab --> false */
- char defalt; /* true/false in defaults */
- char value; /* true/false flag */
- char set; /* we found it */
-};
-
-/*
- * String values.
- */
-#define NX gettystrs[0].value
-#define CL gettystrs[1].value
-#define IM gettystrs[2].value
-#define LM gettystrs[3].value
-#define ER gettystrs[4].value
-#define KL gettystrs[5].value
-#define ET gettystrs[6].value
-#define PC gettystrs[7].value
-#define TT gettystrs[8].value
-#define EV gettystrs[9].value
-#define LO gettystrs[10].value
-#define HN gettystrs[11].value
-#define HE gettystrs[12].value
-#define IN gettystrs[13].value
-#define QU gettystrs[14].value
-#define XN gettystrs[15].value
-#define XF gettystrs[16].value
-#define BK gettystrs[17].value
-#define SU gettystrs[18].value
-#define DS gettystrs[19].value
-#define RP gettystrs[20].value
-#define FL gettystrs[21].value
-#define WE gettystrs[22].value
-#define LN gettystrs[23].value
-
-/*
- * Numeric definitions.
- */
-#define IS gettynums[0].value
-#define OS gettynums[1].value
-#define SP gettynums[2].value
-#define ND gettynums[3].value
-#define CD gettynums[4].value
-#define TD gettynums[5].value
-#define FD gettynums[6].value
-#define BD gettynums[7].value
-#define TO gettynums[8].value
-#define F0 gettynums[9].value
-#define F0set gettynums[9].set
-#define F1 gettynums[10].value
-#define F1set gettynums[10].set
-#define F2 gettynums[11].value
-#define F2set gettynums[11].set
-#define PF gettynums[12].value
-
-/*
- * Boolean values.
- */
-#define HT gettyflags[0].value
-#define NL gettyflags[1].value
-#define EP gettyflags[2].value
-#define EPset gettyflags[2].set
-#define OP gettyflags[3].value
-#define OPset gettyflags[2].set
-#define AP gettyflags[4].value
-#define APset gettyflags[2].set
-#define EC gettyflags[5].value
-#define CO gettyflags[6].value
-#define CB gettyflags[7].value
-#define CK gettyflags[8].value
-#define CE gettyflags[9].value
-#define PE gettyflags[10].value
-#define RW gettyflags[11].value
-#define XC gettyflags[12].value
-#define LC gettyflags[13].value
-#define UC gettyflags[14].value
-#define IG gettyflags[15].value
-#define PS gettyflags[16].value
-#define HC gettyflags[17].value
-#define UB gettyflags[18].value
-#define AB gettyflags[19].value
-#define DX gettyflags[20].value
-#define RM gettyflags[21].value
-
-int getent (char *, char *);
-long getnum();
-int getflag();
-#ifndef SOLARIS
-char *getstr(char *, char **);
-#endif
-
-extern struct gettyflags gettyflags[];
-extern struct gettynums gettynums[];
-extern struct gettystrs gettystrs[];
-extern int hopcount;
+++ /dev/null
-/*
- * 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.
- */
-
-/* based on @(#)herror.c 8.1 (Berkeley) 6/4/93 */
-
-#include <stdio.h>
-
-char *h_errlist[] = {
- "Error 0",
- "Unknown host", /* 1 HOST_NOT_FOUND */
- "Host name lookup failure", /* 2 TRY_AGAIN */
- "Unknown server error", /* 3 NO_RECOVERY */
- "No address associated with name", /* 4 NO_ADDRESS */
-};
-int h_nerr = { sizeof(h_errlist)/sizeof(h_errlist[0]) };
-
-int h_errno; /* In some version of SunOS this is necessary */
-
-/*
- * herror --
- * print the error indicated by the h_errno value.
- */
-herror(s)
- char *s;
-{
- if (s && *s) {
- fprintf(stderr, "%s: ", s);
- }
- if ((h_errno < 0) || (h_errno >= h_nerr)) {
- fprintf(stderr, "Unknown error\n");
- } else if (h_errno == 0) {
-#if defined(sun)
- fprintf(stderr, "Host unknown\n");
-#endif /* defined(sun) */
- } else {
- fprintf(stderr, "%s\n", h_errlist[h_errno]);
- }
-}
+++ /dev/null
-/*
- * appl/telnet/libtelnet/kerberos5.c
- */
-
-/*-
- * Copyright (c) 1991, 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.
- */
-
-/* based on @(#)kerberos5.c 8.1 (Berkeley) 6/4/93 */
-
-/*
- * Copyright (C) 1990 by the Massachusetts Institute of Technology
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- */
-
-
-#ifdef KRB5
-#include <arpa/telnet.h>
-#include <errno.h>
-#include <stdio.h>
-#include "krb5.h"
-#include "k5-platform.h"
-
-#include "com_err.h"
-#include <netdb.h>
-#include <ctype.h>
-#include <syslog.h>
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#else
-extern char *malloc();
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#include <strings.h>
-#endif
-
-#include "encrypt.h"
-#include "auth.h"
-#include "misc.h"
-
-extern int auth_debug_mode;
-extern int net;
-
-#ifdef FORWARD
-int forward_flags = 0; /* Flags get set in telnet/main.c on -f and -F */
-
-static void kerberos5_forward(Authenticator *);
-
-#include "krb5forw.h"
-
-#endif /* FORWARD */
-
-static unsigned char str_data[TELNET_BUFSIZE] = {IAC, SB, TELOPT_AUTHENTICATION, 0,
- AUTHTYPE_KERBEROS_V5, };
-/*static unsigned char str_name[1024] = { IAC, SB, TELOPT_AUTHENTICATION,
- TELQUAL_NAME, };*/
-
-#define KRB_AUTH 0 /* Authentication data follows */
-#define KRB_REJECT 1 /* Rejected (reason might follow) */
-#define KRB_ACCEPT 2 /* Accepted */
-#define KRB_RESPONSE 3 /* Response for mutual auth. */
-
-#ifdef FORWARD
-#define KRB_FORWARD 4 /* Forwarded credentials follow */
-#define KRB_FORWARD_ACCEPT 5 /* Forwarded credentials accepted */
-#define KRB_FORWARD_REJECT 6 /* Forwarded credentials rejected */
-#endif /* FORWARD */
-
-krb5_auth_context auth_context = 0;
-
-static krb5_data auth;
- /* telnetd gets session key from here */
-static krb5_ticket * ticket = NULL;
-/* telnet matches the AP_REQ and AP_REP with this */
-
-/* some compilers can't hack void *, so we use the Kerberos krb5_pointer,
- which is either void * or char *, depending on the compiler. */
-
-#define Voidptr krb5_pointer
-
-krb5_keyblock *session_key = 0;
-char * telnet_srvtab = NULL;
-char * telnet_krb5_realm = NULL;
-
- static int
-Data(ap, type, d, c)
- Authenticator *ap;
- int type;
- Voidptr d;
- int c;
-{
- unsigned char *p = str_data + 4;
- unsigned char *cd = (unsigned char *)d;
- size_t spaceleft = sizeof(str_data) - 4;
-
- if (c == -1)
- c = strlen((char *)cd);
-
- if (auth_debug_mode) {
- printf("%s:%d: [%d] (%d)",
- str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY",
- str_data[3],
- type, c);
- printd(d, c);
- printf("\r\n");
- }
- *p++ = ap->type;
- *p++ = ap->way;
- *p++ = type;
- spaceleft -= 3;
- while (c-- > 0) {
- if ((*p++ = *cd++) == IAC) {
- *p++ = IAC;
- spaceleft--;
- }
- if ((--spaceleft < 4) && c) {
- errno = ENOMEM;
- return -1;
- }
- }
- *p++ = IAC;
- *p++ = SE;
- if (str_data[3] == TELQUAL_IS)
- printsub('>', &str_data[2], p - &str_data[2]);
- return(net_write(str_data, p - str_data));
-}
-
-krb5_context telnet_context = 0;
-int
-kerberos5_init(ap, server)
- Authenticator *ap;
- int server;
-{
- krb5_error_code retval;
-
- if (server)
- str_data[3] = TELQUAL_REPLY;
- else
- str_data[3] = TELQUAL_IS;
- if (telnet_context == 0) {
- retval = krb5_init_context(&telnet_context);
- if (retval)
- return 0;
- }
- return(1);
-}
-
-void
-kerberos5_cleanup()
-{
- krb5_error_code retval;
- krb5_ccache ccache;
- char *ccname;
-
- if (telnet_context == 0)
- return;
-
- ccname = getenv("KRB5CCNAME");
- if (ccname) {
- retval = krb5_cc_resolve(telnet_context, ccname, &ccache);
- if (!retval)
- retval = krb5_cc_destroy(telnet_context, ccache);
- }
-
- krb5_free_context(telnet_context);
- telnet_context = 0;
-}
-
-
- int
-kerberos5_send(ap)
- Authenticator *ap;
-{
- krb5_error_code r;
- krb5_ccache ccache;
- krb5_creds creds; /* telnet gets session key from here */
- krb5_creds * new_creds = 0;
- int ap_opts;
- char type_check[2];
- krb5_data check_data;
-
-#ifdef ENCRYPTION
- krb5_keyblock *newkey = 0;
-#endif /* ENCRYPTION */
-
- if (!UserNameRequested) {
- if (auth_debug_mode) {
- printf(
- "telnet: Kerberos V5: no user name supplied\r\n");
- }
- return(0);
- }
-
- if ((r = krb5_cc_default(telnet_context, &ccache))) {
- if (auth_debug_mode) {
- printf(
- "telnet: Kerberos V5: could not get default ccache\r\n");
- }
- return(0);
- }
-
- memset(&creds, 0, sizeof(creds));
- if (auth_debug_mode)
- printf("telnet: calling krb5_sname_to_principal\n");
- if ((r = krb5_sname_to_principal(telnet_context, RemoteHostName,
- "host", KRB5_NT_SRV_HST,
- &creds.server))) {
- if (auth_debug_mode)
- printf("telnet: Kerberos V5: error while constructing service name: %s\r\n", error_message(r));
- return(0);
- }
- if (auth_debug_mode)
- printf("telnet: done calling krb5_sname_to_principal\n");
-
- if (telnet_krb5_realm != NULL) {
- krb5_data rdata;
-
- rdata.magic = 0;
- rdata.length = strlen(telnet_krb5_realm);
- rdata.data = strdup(telnet_krb5_realm);
- if (rdata.data == NULL) {
- fprintf(stderr, "malloc failed\n");
- return(0);
- }
- krb5_princ_set_realm(telnet_context, creds.server, &rdata);
- }
-
- if ((r = krb5_cc_get_principal(telnet_context, ccache,
- &creds.client))) {
- if (auth_debug_mode) {
- printf(
- "telnet: Kerberos V5: failure on principal (%s)\r\n",
- error_message(r));
- }
- krb5_free_cred_contents(telnet_context, &creds);
- return(0);
- }
-
- creds.keyblock.enctype=ENCTYPE_DES_CBC_CRC;
- if ((r = krb5_get_credentials(telnet_context, 0,
- ccache, &creds, &new_creds))) {
- if (auth_debug_mode) {
- printf(
- "telnet: Kerberos V5: failure on credentials(%s)\r\n",
- error_message(r));
- }
- krb5_free_cred_contents(telnet_context, &creds);
- return(0);
- }
-
- if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL)
- ap_opts = AP_OPTS_MUTUAL_REQUIRED;
- else
- ap_opts = 0;
-
-#ifdef ENCRYPTION
- ap_opts |= AP_OPTS_USE_SUBKEY;
-#endif /* ENCRYPTION */
-
- if (auth_context) {
- krb5_auth_con_free(telnet_context, auth_context);
- auth_context = 0;
- }
- if ((r = krb5_auth_con_init(telnet_context, &auth_context))) {
- if (auth_debug_mode) {
- printf("Kerberos V5: failed to init auth_context (%s)\r\n",
- error_message(r));
- }
- return(0);
- }
-
- krb5_auth_con_setflags(telnet_context, auth_context,
- KRB5_AUTH_CONTEXT_RET_TIME);
-
- type_check[0] = ap->type;
- type_check[1] = ap->way;
- check_data.magic = KV5M_DATA;
- check_data.length = 2;
- check_data.data = (char *) &type_check;
-
- r = krb5_mk_req_extended(telnet_context, &auth_context, ap_opts,
- &check_data, new_creds, &auth);
-
-#ifdef ENCRYPTION
- krb5_auth_con_getsendsubkey(telnet_context, auth_context, &newkey);
- if (session_key) {
- krb5_free_keyblock(telnet_context, session_key);
- session_key = 0;
- }
-
- if (newkey) {
- /* keep the key in our private storage, but don't use it
- yet---see kerberos5_reply() below */
- if ((newkey->enctype != ENCTYPE_DES_CBC_CRC) &&
- (newkey-> enctype != ENCTYPE_DES_CBC_MD5)) {
- if ((new_creds->keyblock.enctype == ENCTYPE_DES_CBC_CRC) ||
- (new_creds->keyblock.enctype == ENCTYPE_DES_CBC_MD5))
- /* use the session key in credentials instead */
- krb5_copy_keyblock(telnet_context,&new_creds->keyblock,
- &session_key);
- else
- /* XXX ? */;
- } else {
- krb5_copy_keyblock(telnet_context, newkey, &session_key);
- }
- krb5_free_keyblock(telnet_context, newkey);
- }
-#endif /* ENCRYPTION */
- krb5_free_cred_contents(telnet_context, &creds);
- krb5_free_creds(telnet_context, new_creds);
- if (r) {
- if (auth_debug_mode) {
- printf("telnet: Kerberos V5: mk_req failed (%s)\r\n",
- error_message(r));
- }
- return(0);
- }
-
- if (!auth_sendname((unsigned char *) UserNameRequested,
- (int) strlen(UserNameRequested))) {
- if (auth_debug_mode)
- printf("telnet: Not enough room for user name\r\n");
- return(0);
- }
- if (!Data(ap, KRB_AUTH, auth.data, auth.length)) {
- if (auth_debug_mode)
- printf(
- "telnet: Not enough room for authentication data\r\n");
- return(0);
- }
- if (auth_debug_mode) {
- printf("telnet: Sent Kerberos V5 credentials to server\r\n");
- }
- return(1);
-}
-
- void
-kerberos5_is(ap, data, cnt)
- Authenticator *ap;
- unsigned char *data;
- int cnt;
-{
- int r = 0;
- krb5_principal server;
- krb5_keyblock *newkey = NULL;
- krb5_keytab keytabid = 0;
- krb5_data outbuf;
-#ifdef ENCRYPTION
- Session_Key skey;
-#endif
- char errbuf[320];
- char *name;
- char *getenv();
- krb5_data inbuf;
- krb5_authenticator *authenticator;
-
- if (cnt-- < 1)
- return;
- switch (*data++) {
- case KRB_AUTH:
- auth.data = (char *)data;
- auth.length = cnt;
-
- if (!r && !auth_context)
- r = krb5_auth_con_init(telnet_context, &auth_context);
- if (!r) {
- krb5_rcache rcache;
-
- r = krb5_auth_con_getrcache(telnet_context, auth_context,
- &rcache);
- if (!r && !rcache) {
- r = krb5_sname_to_principal(telnet_context, 0, 0,
- KRB5_NT_SRV_HST, &server);
- if (!r) {
- r = krb5_get_server_rcache(telnet_context,
- krb5_princ_component(telnet_context,
- server, 0),
- &rcache);
- krb5_free_principal(telnet_context, server);
- }
- }
- if (!r)
- r = krb5_auth_con_setrcache(telnet_context,
- auth_context, rcache);
- }
- if (!r && telnet_srvtab)
- r = krb5_kt_resolve(telnet_context,
- telnet_srvtab, &keytabid);
- if (!r)
- r = krb5_rd_req(telnet_context, &auth_context, &auth,
- NULL, keytabid, NULL, &ticket);
- if (r) {
- (void) snprintf(errbuf, sizeof(errbuf),
- "krb5_rd_req failed: %s",
- error_message(r));
- goto errout;
- }
-
- /*
- * 256 bytes should be much larger than any reasonable
- * first component of a service name especially since
- * the default is of length 4.
- */
- if (krb5_princ_size(telnet_context,ticket->server) < 1) {
- (void) strlcpy(errbuf, "malformed service name",
- sizeof(errbuf));
- goto errout;
- }
- if (krb5_princ_component(telnet_context,ticket->server,0)->length < 256) {
- char princ[256];
- strncpy(princ,
- krb5_princ_component(telnet_context, ticket->server,0)->data,
- krb5_princ_component(telnet_context, ticket->server,0)->length);
- princ[krb5_princ_component(telnet_context,
- ticket->server,0)->length] = '\0';
- if (strcmp("host", princ)) {
- if(strlen(princ) < sizeof(errbuf) - 39) {
- (void) snprintf(errbuf, sizeof(errbuf), "incorrect service name: \"%s\" != \"host\"",
- princ);
- } else {
- (void) snprintf(errbuf, sizeof(errbuf), "incorrect service name: principal != \"host\"");
- }
- goto errout;
- }
- } else {
- (void) strlcpy(errbuf, "service name too long",
- sizeof(errbuf));
- goto errout;
- }
-
- r = krb5_auth_con_getauthenticator(telnet_context,
- auth_context,
- &authenticator);
- if (r) {
- (void) snprintf(errbuf, sizeof(errbuf),
- "krb5_auth_con_getauthenticator failed: %s",
- error_message(r));
- goto errout;
- }
- if ((ap->way & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_ON &&
- !authenticator->checksum) {
- (void) strlcpy(errbuf,
- "authenticator is missing required checksum",
- sizeof(errbuf));
- goto errout;
- }
- if (authenticator->checksum) {
- char type_check[2];
- krb5_checksum *cksum = authenticator->checksum;
- krb5_keyblock *key;
-
- type_check[0] = ap->type;
- type_check[1] = ap->way;
-
- r = krb5_auth_con_getkey(telnet_context, auth_context,
- &key);
- if (r) {
- (void) snprintf(errbuf, sizeof(errbuf),
- "krb5_auth_con_getkey failed: %s",
- error_message(r));
- goto errout;
- }
- r = krb5_verify_checksum(telnet_context,
- cksum->checksum_type, cksum,
- &type_check, 2, key->contents,
- key->length);
- /*
- * Note that krb5_verify_checksum() will fail if a pre-
- * MIT Kerberos Beta 5 client is attempting to connect
- * to this server (Beta 6 or later). There is not way to
- * fix this without compromising encryption. It would be
- * reasonable to add a -i option to telnetd to ignore
- * checksums (like in klogind). Such an option is not
- * present at this time.
- */
- if (r) {
- (void) snprintf(errbuf, sizeof(errbuf),
- "checksum verification failed: %s",
- error_message(r));
- goto errout;
- }
- krb5_free_keyblock(telnet_context, key);
- }
- krb5_free_authenticator(telnet_context, authenticator);
- if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
- /* do ap_rep stuff here */
- if ((r = krb5_mk_rep(telnet_context, auth_context,
- &outbuf))) {
- (void) snprintf(errbuf, sizeof(errbuf),
- "Make reply failed: %s",
- error_message(r));
- goto errout;
- }
-
- Data(ap, KRB_RESPONSE, outbuf.data, outbuf.length);
- }
- if (krb5_unparse_name(telnet_context,
- ticket->enc_part2 ->client,
- &name))
- name = 0;
- Data(ap, KRB_ACCEPT, name, name ? -1 : 0);
- if (auth_debug_mode) {
- printf(
- "telnetd: Kerberos5 identifies him as ``%s''\r\n",
- name ? name : "");
- }
- auth_finished(ap, AUTH_USER);
-
- if (name)
- free(name);
- krb5_auth_con_getrecvsubkey(telnet_context, auth_context,
- &newkey);
- if (session_key) {
- krb5_free_keyblock(telnet_context, session_key);
- session_key = 0;
- }
- if (newkey) {
- krb5_copy_keyblock(telnet_context, newkey, &session_key);
- krb5_free_keyblock(telnet_context, newkey);
- } else {
- krb5_copy_keyblock(telnet_context,
- ticket->enc_part2->session,
- &session_key);
- }
-
-#ifdef ENCRYPTION
- skey.type = SK_DES;
- skey.length = 8;
- skey.data = session_key->contents;
- encrypt_session_key(&skey, 1);
-#endif
- break;
-#ifdef FORWARD
- case KRB_FORWARD:
- inbuf.length = cnt;
- inbuf.data = (char *)data;
- if ((r = krb5_auth_con_genaddrs(telnet_context, auth_context,
- net, KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR)) ||
- (r = rd_and_store_for_creds(telnet_context, auth_context,
- &inbuf, ticket))) {
-
- char kerrbuf[128];
-
- (void) snprintf(kerrbuf, sizeof(kerrbuf),
- "Read forwarded creds failed: %s",
- error_message(r));
- Data(ap, KRB_FORWARD_REJECT, kerrbuf, -1);
- if (auth_debug_mode)
- printf(
- "telnetd: Could not read forwarded credentials\r\n");
- }
- else
- Data(ap, KRB_FORWARD_ACCEPT, 0, 0);
- if (auth_debug_mode)
- printf("telnetd: Forwarded credentials obtained\r\n");
- break;
-#endif /* FORWARD */
- default:
- if (auth_debug_mode)
- printf("telnetd: Unknown Kerberos option %d\r\n",
- data[-1]);
- Data(ap, KRB_REJECT, 0, 0);
- break;
- }
- return;
-
- errout:
- {
- char eerrbuf[329];
-
- snprintf(eerrbuf, sizeof(eerrbuf), "telnetd: %s", errbuf);
- Data(ap, KRB_REJECT, eerrbuf, -1);
- }
- if (auth_debug_mode)
- printf("telnetd: %s\r\n", errbuf);
- syslog(LOG_ERR, "%s", errbuf);
- if (auth_context) {
- krb5_auth_con_free(telnet_context, auth_context);
- auth_context = 0;
- }
- return;
-}
-
- void
-kerberos5_reply(ap, data, cnt)
- Authenticator *ap;
- unsigned char *data;
- int cnt;
-{
-#ifdef ENCRYPTION
- Session_Key skey;
-#endif
- static int mutual_complete = 0;
-
- if (cnt-- < 1)
- return;
- switch (*data++) {
- case KRB_REJECT:
- if (cnt > 0) {
- printf("[ Kerberos V5 refuses authentication because %.*s ]\r\n",
- cnt, data);
- } else
- printf("[ Kerberos V5 refuses authentication ]\r\n");
- auth_send_retry();
- return;
- case KRB_ACCEPT:
- if (!mutual_complete) {
- if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
- printf("[ Kerberos V5 accepted you, but didn't provide mutual authentication! ]\r\n");
- auth_send_retry();
- return;
- }
-#ifdef ENCRYPTION
- if (session_key) {
- skey.type = SK_DES;
- skey.length = 8;
- skey.data = session_key->contents;
- encrypt_session_key(&skey, 0);
- }
-#endif /* ENCRYPTION */
- }
- if (cnt)
- printf("[ Kerberos V5 accepts you as ``%.*s'' ]\r\n", cnt, data);
- else
- printf("[ Kerberos V5 accepts you ]\r\n");
- auth_finished(ap, AUTH_USER);
-#ifdef FORWARD
- if (forward_flags & OPTS_FORWARD_CREDS)
- kerberos5_forward(ap);
-#endif /* FORWARD */
- break;
- case KRB_RESPONSE:
- if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
- /* the rest of the reply should contain a krb_ap_rep */
- krb5_ap_rep_enc_part *reply;
- krb5_data inbuf;
- krb5_error_code r;
-
- inbuf.length = cnt;
- inbuf.data = (char *)data;
-
- if ((r = krb5_rd_rep(telnet_context, auth_context, &inbuf,
- &reply))) {
- printf("[ Mutual authentication failed: %s ]\r\n",
- error_message(r));
- auth_send_retry();
- return;
- }
- krb5_free_ap_rep_enc_part(telnet_context, reply);
-#ifdef ENCRYPTION
- if (session_key) {
- skey.type = SK_DES;
- skey.length = 8;
- skey.data = session_key->contents;
- encrypt_session_key(&skey, 0);
- }
-#endif /* ENCRYPTION */
- mutual_complete = 1;
- }
- return;
-#ifdef FORWARD
- case KRB_FORWARD_ACCEPT:
- printf("[ Kerberos V5 accepted forwarded credentials ]\r\n");
- return;
- case KRB_FORWARD_REJECT:
- printf("[ Kerberos V5 refuses forwarded credentials because %.*s ]\r\n",
- cnt, data);
- return;
-#endif /* FORWARD */
- default:
- if (auth_debug_mode)
- printf("Unknown Kerberos option %d\r\n", data[-1]);
- return;
- }
- return;
-}
-
- int
-kerberos5_status(ap, name, level)
- Authenticator *ap;
- char *name;
- int level;
-{
- if (level < AUTH_USER)
- return(level);
-
- /*
- * Always copy in UserNameRequested if the authentication
- * is valid, because the higher level routines need it.
- * the name buffer comes from telnetd/telnetd{-ktd}.c
- */
- if (UserNameRequested) {
- strncpy(name, UserNameRequested, 255);
- name[255] = '\0';
- }
-
- if (UserNameRequested &&
- krb5_kuserok(telnet_context, ticket->enc_part2->client,
- UserNameRequested))
- {
- return(AUTH_VALID);
- } else
- return(AUTH_USER);
-}
-
-#define BUMP(buf, len) while (*(buf)) {++(buf), --(len);}
-#define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);}
-
- void
-kerberos5_printsub(data, cnt, buf, buflen)
- unsigned char *data, *buf;
- int cnt;
- unsigned int buflen;
-{
- char lbuf[32];
- register int i;
-
- buf[buflen-1] = '\0'; /* make sure its NULL terminated */
- buflen -= 1;
-
- switch(data[3]) {
- case KRB_REJECT: /* Rejected (reason might follow) */
- strncpy((char *)buf, " REJECT ", buflen);
- goto common;
-
- case KRB_ACCEPT: /* Accepted (name might follow) */
- strncpy((char *)buf, " ACCEPT ", buflen);
- common:
- BUMP(buf, buflen);
- if (cnt <= 4)
- break;
- ADDC(buf, buflen, '"');
- for (i = 4; i < cnt; i++)
- ADDC(buf, buflen, data[i]);
- ADDC(buf, buflen, '"');
- ADDC(buf, buflen, '\0');
- break;
-
-
- case KRB_AUTH: /* Authentication data follows */
- strncpy((char *)buf, " AUTH", buflen);
- goto common2;
-
- case KRB_RESPONSE:
- strncpy((char *)buf, " RESPONSE", buflen);
- goto common2;
-
-#ifdef FORWARD
- case KRB_FORWARD: /* Forwarded credentials follow */
- strncpy((char *)buf, " FORWARD", buflen);
- goto common2;
-
- case KRB_FORWARD_ACCEPT: /* Forwarded credentials accepted */
- strncpy((char *)buf, " FORWARD_ACCEPT", buflen);
- goto common2;
-
- case KRB_FORWARD_REJECT: /* Forwarded credentials rejected */
- /* (reason might follow) */
- strncpy((char *)buf, " FORWARD_REJECT", buflen);
- goto common2;
-#endif /* FORWARD */
-
- default:
- snprintf(lbuf, sizeof(lbuf), " %d (unknown)", data[3]);
- strncpy((char *)buf, lbuf, buflen);
- common2:
- BUMP(buf, buflen);
- for (i = 4; i < cnt; i++) {
- snprintf(lbuf, sizeof(lbuf), " %d", data[i]);
- strncpy((char *)buf, lbuf, buflen);
- BUMP(buf, buflen);
- }
- break;
- }
-}
-
-#ifdef FORWARD
-
-static void
-kerberos5_forward(ap)
- Authenticator *ap;
-{
- krb5_error_code r;
- krb5_ccache ccache;
- krb5_principal client = 0;
- krb5_principal server = 0;
- krb5_data forw_creds;
-
- forw_creds.data = 0;
-
- if ((r = krb5_cc_default(telnet_context, &ccache))) {
- if (auth_debug_mode)
- printf("Kerberos V5: could not get default ccache - %s\r\n",
- error_message(r));
- return;
- }
-
- if ((r = krb5_cc_get_principal(telnet_context, ccache, &client))) {
- if (auth_debug_mode)
- printf("Kerberos V5: could not get default principal - %s\r\n",
- error_message(r));
- goto cleanup;
- }
-
- if ((r = krb5_sname_to_principal(telnet_context, RemoteHostName, "host",
- KRB5_NT_SRV_HST, &server))) {
- if (auth_debug_mode)
- printf("Kerberos V5: could not make server principal - %s\r\n",
- error_message(r));
- goto cleanup;
- }
-
- if ((r = krb5_auth_con_genaddrs(telnet_context, auth_context, net,
- KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR))) {
- if (auth_debug_mode)
- printf("Kerberos V5: could not gen local full address - %s\r\n",
- error_message(r));
- goto cleanup;
- }
-
- if ((r = krb5_fwd_tgt_creds(telnet_context, auth_context, 0, client,
- server, ccache,
- forward_flags & OPTS_FORWARDABLE_CREDS,
- &forw_creds))) {
- if (auth_debug_mode)
- printf("Kerberos V5: error getting forwarded creds - %s\r\n",
- error_message(r));
- goto cleanup;
- }
-
- /* Send forwarded credentials */
- if (!Data(ap, KRB_FORWARD, forw_creds.data, forw_creds.length)) {
- if (auth_debug_mode)
- printf("Not enough room for authentication data\r\n");
- } else {
- if (auth_debug_mode)
- printf("Forwarded local Kerberos V5 credentials to server\r\n");
- }
-
-cleanup:
- if (client)
- krb5_free_principal(telnet_context, client);
- if (server)
- krb5_free_principal(telnet_context, server);
- if (forw_creds.data)
- free(forw_creds.data);
- krb5_cc_close(telnet_context, ccache);
-}
-#endif /* FORWARD */
-
-#endif /* KRB5 */
+++ /dev/null
-/*-
- * Copyright (c) 1991, 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.
- *
- * @(#)key-proto.h 8.1 (Berkeley) 6/4/93
- */
-
-/*
- * Copyright (C) 1990 by the Massachusetts Institute of Technology
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- */
-
-#ifndef __KEY_PROTO__
-#define __KEY_PROTO__
-
-int key_file_exists (void);
-void key_lookup (unsigned char *, Block);
-void key_stream_init (Block, Block, int);
-unsigned char key_stream (int, int);
-#endif
+++ /dev/null
-extern krb5_error_code
-rd_and_store_for_creds(krb5_context, krb5_auth_context, krb5_data *,
- krb5_ticket *);
+++ /dev/null
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * 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.
- */
-
-/* based on:
- @(#)memcmp.c 8.1 (Berkeley) 6/4/93
- @(#)memset.c 8.1 (Berkeley) 6/4/93
- @(#)memcpy.c 8.1 (Berkeley) 6/4/93
- @(#)memmove.c 8.1 (Berkeley) 6/4/93
- */
-
-#ifndef __STDC__
-#define const
-#endif
-typedef int size_t;
-
-#include <sys/types.h>
-#include <sys/cdefs.h>
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#include <strings.h>
-#endif
-#include <limits.h>
-
-/*
- * Compare memory regions.
- */
-int
-memcmp(s1, s2, n)
- const void *s1, *s2;
- size_t n;
-{
- if (n != 0) {
- register const unsigned char *p1 = s1, *p2 = s2;
-
- do {
- if (*p1++ != *p2++)
- return (*--p1 - *--p2);
- } while (--n != 0);
- }
- return (0);
-}
-
-/*
- * Copy a block of memory.
- */
-void *
-memcpy(dst, src, n)
- void *dst;
- const void *src;
- size_t n;
-{
- bcopy((const char *)src, (char *)dst, n);
- return(dst);
-}
-
-/*
- * Copy a block of memory, handling overlap.
- */
-void *
-memmove(dst, src, length)
- void *dst;
- const void *src;
- register size_t length;
-{
- bcopy((const char *)src, (char *)dst, length);
- return(dst);
-}
-
-#define wsize sizeof(u_int)
-#define wmask (wsize - 1)
-
-#ifdef BZERO
-#define RETURN return
-#define VAL 0
-#define WIDEVAL 0
-
-void
-memset(dst0, 0, length)
- void *dst0;
- register size_t length;
-#else
-#define RETURN return (dst0)
-#define VAL c0
-#define WIDEVAL c
-
-void *
-memset(dst0, c0, length)
- void *dst0;
- register int c0;
- register size_t length;
-#endif
-{
- register size_t t;
- register u_int c;
- register u_char *dst;
-
- dst = dst0;
- /*
- * If not enough words, just fill bytes. A length >= 2 words
- * guarantees that at least one of them is `complete' after
- * any necessary alignment. For instance:
- *
- * |-----------|-----------|-----------|
- * |00|01|02|03|04|05|06|07|08|09|0A|00|
- * ^---------------------^
- * dst dst+length-1
- *
- * but we use a minimum of 3 here since the overhead of the code
- * to do word writes is substantial.
- */
- if (length < 3 * wsize) {
- while (length != 0) {
- *dst++ = VAL;
- --length;
- }
- RETURN;
- }
-
-#ifndef BZERO
- if ((c = (u_char)c0) != 0) { /* Fill the word. */
-#ifndef UINT_MAX
- UINT_MAX must be defined, try 0xFFFFFFFF;
-#endif
- c = (c << 8) | c; /* u_int is 16 bits. */
-#if UINT_MAX > 0xffff
- c = (c << 16) | c; /* u_int is 32 bits. */
-#endif
-#if UINT_MAX > 0xffffffff
- c = (c << 32) | c; /* u_int is 64 bits. */
-#endif
- }
-#endif
- /* Align destination by filling in bytes. */
- if ((t = (int)dst & wmask) != 0) {
- t = wsize - t;
- length -= t;
- do {
- *dst++ = VAL;
- } while (--t != 0);
- }
-
- /* Fill words. Length was >= 2*words so we know t >= 1 here. */
- t = length / wsize;
- do {
- *(u_int *)dst = WIDEVAL;
- dst += wsize;
- } while (--t != 0);
-
- /* Mop up trailing bytes, if any. */
- t = length & wmask;
- if (t != 0)
- do {
- *dst++ = VAL;
- } while (--t != 0);
- RETURN;
-}
+++ /dev/null
-/*-
- * Copyright (c) 1991, 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.
- *
- * @(#)misc-proto.h 8.1 (Berkeley) 6/4/93
- */
-
-/*
- * Copyright (C) 1990 by the Massachusetts Institute of Technology
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- */
-
-#ifndef __MISC_PROTO__
-#define __MISC_PROTO__
-
-void auth_encrypt_init (char *, char *, char *, int);
-void auth_encrypt_user (const char *);
-void auth_encrypt_connect (int);
-void printd (const unsigned char *, int);
-
-/*
- * These functions are imported from the application
- */
-int net_write (unsigned char *, int);
-void net_encrypt (void);
-int telnet_spin (void);
-char *telnet_getenv (char *);
-char *telnet_gets (char *, char *, int, int);
-
-
-#ifdef NEED_PARSETOS
-int parsetos(char *, char *);
-#endif
-
-#ifdef NEED_SETENV
-int setenv(const char *, const char *, int);
-#ifndef HAVE_UNSETENV
-void unsetenv(const char *);
-#endif
-#endif
-
-#endif
+++ /dev/null
-/*-
- * Copyright (c) 1991, 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.
- */
-
-/* based on @(#)misc.c 8.1 (Berkeley) 6/4/93 */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "misc.h"
-#include "auth.h"
-#include "encrypt.h"
-
-char *RemoteHostName;
-char *LocalHostName;
-char *UserNameRequested = 0;
-int ConnectedCount = 0;
-
- void
-auth_encrypt_init(local, remote, name, server)
- char *local;
- char *remote;
- char *name;
- int server;
-{
- RemoteHostName = remote;
- LocalHostName = local;
-#if defined(AUTHENTICATION)
- auth_init(name, server);
-#endif
-#ifdef ENCRYPTION
- encrypt_init(name, server);
-#endif /* ENCRYPTION */
- if (UserNameRequested) {
- free(UserNameRequested);
- UserNameRequested = 0;
- }
-}
-
- void
-auth_encrypt_user(name)
- const char *name;
-{
- extern char *strdup();
-
- if (UserNameRequested)
- free(UserNameRequested);
- UserNameRequested = name ? strdup(name) : 0;
-}
-
- void
-auth_encrypt_connect(cnt)
- int cnt;
-{
-}
-
- void
-printd(data, cnt)
- const unsigned char *data;
- int cnt;
-{
- if (cnt > 16)
- cnt = 16;
- while (cnt-- > 0) {
- printf(" %02x", *data);
- ++data;
- }
-}
+++ /dev/null
-/*-
- * Copyright (c) 1991, 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.
- *
- * @(#)misc.h 8.1 (Berkeley) 6/4/93
- */
-
-extern char *UserNameRequested;
-extern char *LocalHostName;
-extern char *RemoteHostName;
-extern int ConnectedCount;
-extern int ReservedPort;
-
-int isprefix (char *, char *);
-char **genget (char *, char **, int);
-int Ambiguous (void *);
-
-#include "misc-proto.h"
+++ /dev/null
-/*
- * The routine parsetos() for UNICOS 6.0/6.1, as well as more traditional
- * Unix systems. This is part of UNICOS 7.0 and later.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <netdb.h>
-#include <errno.h>
-#define NEED_PARSETOS
-#include "misc-proto.h"
-
-#define MIN_TOS 0
-#define MAX_TOS 255
-
-int
-parsetos(name, proto)
-char *name;
-char *proto;
-{
-#if 0
- register char *c;
-#endif
- int tos;
-
-#ifdef HAVE_GETTOSBYNAME
- struct tosent *tosp;
-
- tosp = gettosbyname(name, proto);
- if (tosp)
- tos = tosp->t_tos;
- else
-#endif
- tos = (int)strtol(name, (char **)NULL, 0);
-
- if (tos < MIN_TOS || tos > MAX_TOS) {
- return (-1);
- }
- return (tos);
-}
+++ /dev/null
-/*
- * Copyright (c) 1987, 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.
- */
-
-/* based on @(#)setenv.c 8.1 (Berkeley) 6/4/93 */
-/* based on @(#)getenv.c 8.1 (Berkeley) 6/4/93 */
-
-#ifndef __STDC__
-#define const
-#endif
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "misc-proto.h"
-
-static char *__findenv (const char *, int *);
-
-/*
- * setenv --
- * Set the value of the environmental variable "name" to be
- * "value". If rewrite is set, replace any current value.
- */
-#ifndef HAVE_SETENV
-int
-setenv(name, value, rewrite)
- register const char *name;
- register const char *value;
- int rewrite;
-{
- extern char **environ;
- static int alloced; /* if allocated space before */
- register char *c;
- const char *c2;
- int l_value, offset;
-
- if (*value == '=') /* no `=' in value */
- ++value;
- l_value = strlen(value);
- if ((c = __findenv(name, &offset))) { /* find if already exists */
- if (!rewrite)
- return (0);
- if (strlen(c) >= l_value) { /* old larger; copy over */
- while ((*c++ = *value++));
- return (0);
- }
- } else { /* create new slot */
- register int cnt;
- register char **p;
-
- for (p = environ, cnt = 0; *p; ++p, ++cnt);
- if (alloced) { /* just increase size */
- environ = (char **)realloc((char *)environ,
- (size_t)(sizeof(char *) * (cnt + 2)));
- if (!environ)
- return (-1);
- }
- else { /* get new space */
- alloced = 1; /* copy old entries into it */
- p = (char **)malloc((size_t)(sizeof(char *) * (cnt + 2)));
- if (!p)
- return (-1);
- memcpy(p, environ, cnt * sizeof(char *));
- environ = p;
- }
- environ[cnt + 1] = NULL;
- offset = cnt;
- }
- for (c2 = name; *c2 && *c2 != '='; ++c2); /* no `=' in name */
- if (!(environ[offset] = /* name + `=' + value */
- malloc((size_t)((int)(c2 - name) + l_value + 2))))
- return (-1);
- for (c = environ[offset]; (*c = *name++) && *c != '='; ++c);
- for (*c++ = '='; (*c++ = *value++););
- return (0);
-}
-#endif
-
-/*
- * unsetenv(name) --
- * Delete environmental variable "name".
- */
-#ifndef HAVE_UNSETENV
-void
-unsetenv(name)
- const char *name;
-{
- extern char **environ;
- register char **p;
- int offset;
-
- while (__findenv(name, &offset)) /* if set multiple times */
- for (p = &environ[offset];; ++p)
- if (!(*p = *(p + 1)))
- break;
-}
-#endif
-
-/*
- * getenv --
- * Returns ptr to value associated with name, if any, else NULL.
- */
-#ifndef HAVE_GETENV
-char *
-getenv(name)
- const char *name;
-{
- int offset;
-
- return (__findenv(name, &offset));
-}
-#endif
-
-/*
- * __findenv --
- * Returns pointer to value associated with name, if any, else NULL.
- * Sets offset to be the offset of the name/value combination in the
- * environmental array, for use by setenv(3) and unsetenv(3).
- * Explicitly removes '=' in argument name.
- */
-static char *
-__findenv(name, offset)
- register const char *name;
- int *offset;
-{
- extern char **environ;
- register unsigned int len;
- register const char *np;
- register char **p, *c;
-
- if (name == NULL || environ == NULL)
- return (NULL);
- for (np = name; *np && *np != '='; ++np)
- continue;
- len = np - name;
- for (p = environ; (c = *p) != NULL; ++p)
- if (strncmp(c, name, len) == 0 && c[len] == '=') {
- *offset = p - environ;
- return (c + len + 1);
- }
- return (NULL);
-}
+++ /dev/null
-/*
- * Copyright (c) 1991, 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.
- */
-
-/* based on @(#)setsid.c 8.1 (Berkeley) 6/4/93 */
-
-/*
- * Emulate the functionality of setsid(), called when forking
- * and execing the new process.
- */
-
-extern char *line;
-setsid()
-{
-#ifndef convex
- if (setpgrp(0, 0) < 0)
- return(-1);
-#endif
- return(0);
-}
+++ /dev/null
-/*-
- * Copyright (c) 1992, 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.
- */
-
-/* based on @(#)spx.c 8.1 (Berkeley) 6/4/93 */
-
-#ifdef SPX
-/*
- * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
- * ALL RIGHTS RESERVED
- *
- * "Digital Equipment Corporation authorizes the reproduction,
- * distribution and modification of this software subject to the following
- * restrictions:
- *
- * 1. Any partial or whole copy of this software, or any modification
- * thereof, must include this copyright notice in its entirety.
- *
- * 2. This software is supplied "as is" with no warranty of any kind,
- * expressed or implied, for any purpose, including any warranty of fitness
- * or merchantibility. DIGITAL assumes no responsibility for the use or
- * reliability of this software, nor promises to provide any form of
- * support for it on any basis.
- *
- * 3. Distribution of this software is authorized only if no profit or
- * remuneration of any kind is received in exchange for such distribution.
- *
- * 4. This software produces public key authentication certificates
- * bearing an expiration date established by DIGITAL and RSA Data
- * Security, Inc. It may cease to generate certificates after the expiration
- * date. Any modification of this software that changes or defeats
- * the expiration date or its effect is unauthorized.
- *
- * 5. Software that will renew or extend the expiration date of
- * authentication certificates produced by this software may be obtained
- * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
- * 94065, (415)595-8782, or from DIGITAL"
- *
- */
-
-#include <sys/types.h>
-#include <arpa/telnet.h>
-#include <stdio.h>
-#include "gssapi_defs.h"
-#include "k5-platform.h"
-#ifdef __STDC__
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#include <strings.h>
-#endif
-
-#include <pwd.h>
-#include "encrypt.h"
-#include "auth.h"
-#include "misc.h"
-
-extern auth_debug_mode;
-
-static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
- AUTHTYPE_SPX, };
-static unsigned char str_name[1024] = { IAC, SB, TELOPT_AUTHENTICATION,
- TELQUAL_NAME, };
-
-#define SPX_AUTH 0 /* Authentication data follows */
-#define SPX_REJECT 1 /* Rejected (reason might follow) */
-#define SPX_ACCEPT 2 /* Accepted */
-
-#ifdef ENCRYPTION
-static Block session_key = { 0 };
-#endif /* ENCRYPTION */
-static Schedule sched;
-static Block challenge = { 0 };
-
-
-/*******************************************************************/
-
-gss_OID_set actual_mechs;
-gss_OID actual_mech_type, output_name_type;
-int major_status, status, msg_ctx = 0, new_status;
-int req_flags = 0, ret_flags, lifetime_rec;
-gss_cred_id_t gss_cred_handle;
-gss_ctx_id_t actual_ctxhandle, context_handle;
-gss_buffer_desc output_token, input_token, input_name_buffer;
-gss_buffer_desc status_string;
-gss_name_t desired_targname, src_name;
-gss_channel_bindings input_chan_bindings;
-char lhostname[GSS_C_MAX_PRINTABLE_NAME];
-char targ_printable[GSS_C_MAX_PRINTABLE_NAME];
-int to_addr=0, from_addr=0;
-char *address;
-gss_buffer_desc fullname_buffer;
-gss_OID fullname_type;
-gss_cred_id_t gss_delegated_cred_handle;
-
-/*******************************************************************/
-
-
-
- static int
-Data(ap, type, d, c)
- Authenticator *ap;
- int type;
- void *d;
- int c;
-{
- unsigned char *p = str_data + 4;
- unsigned char *cd = (unsigned char *)d;
-
- if (c == -1)
- c = strlen((char *)cd);
-
- if (0) {
- printf("%s:%d: [%d] (%d)",
- str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY",
- str_data[3],
- type, c);
- printd(d, c);
- printf("\r\n");
- }
- *p++ = ap->type;
- *p++ = ap->way;
- *p++ = type;
- while (c-- > 0) {
- if ((*p++ = *cd++) == IAC)
- *p++ = IAC;
- }
- *p++ = IAC;
- *p++ = SE;
- if (str_data[3] == TELQUAL_IS)
- printsub('>', &str_data[2], p - (&str_data[2]));
- return(net_write(str_data, p - str_data));
-}
-
- int
-spx_init(ap, server)
- Authenticator *ap;
- int server;
-{
- gss_cred_id_t tmp_cred_handle;
-
- if (server) {
- str_data[3] = TELQUAL_REPLY;
- gethostname(lhostname, sizeof(lhostname));
- snprintf(targ_printable, sizeof(targ_printable),
- "SERVICE:rcmd@%s", lhostname);
- input_name_buffer.length = strlen(targ_printable);
- input_name_buffer.value = targ_printable;
- major_status = gss_import_name(&status,
- &input_name_buffer,
- GSS_C_NULL_OID,
- &desired_targname);
- major_status = gss_acquire_cred(&status,
- desired_targname,
- 0,
- GSS_C_NULL_OID_SET,
- GSS_C_ACCEPT,
- &tmp_cred_handle,
- &actual_mechs,
- &lifetime_rec);
- if (major_status != GSS_S_COMPLETE) return(0);
- } else {
- str_data[3] = TELQUAL_IS;
- }
- return(1);
-}
-
- int
-spx_send(ap)
- Authenticator *ap;
-{
- Block enckey;
- int r;
-
- gss_OID actual_mech_type, output_name_type;
- int msg_ctx = 0, new_status, status;
- int req_flags = 0, ret_flags, lifetime_rec, major_status;
- gss_buffer_desc output_token, input_token, input_name_buffer;
- gss_buffer_desc output_name_buffer, status_string;
- gss_name_t desired_targname;
- gss_channel_bindings input_chan_bindings;
- char targ_printable[GSS_C_MAX_PRINTABLE_NAME];
- int from_addr=0, to_addr=0, myhostlen, j;
- int deleg_flag=1, mutual_flag=0, replay_flag=0, seq_flag=0;
- char *address;
-
- printf("[ Trying SPX ... ]\n");
- snprintf(targ_printable, sizeof(targ_printable), "SERVICE:rcmd@%s",
- RemoteHostName);
-
- input_name_buffer.length = strlen(targ_printable);
- input_name_buffer.value = targ_printable;
-
- if (!UserNameRequested) {
- return(0);
- }
-
- major_status = gss_import_name(&status,
- &input_name_buffer,
- GSS_C_NULL_OID,
- &desired_targname);
-
-
- major_status = gss_display_name(&status,
- desired_targname,
- &output_name_buffer,
- &output_name_type);
-
- printf("target is '%s'\n", output_name_buffer.value); fflush(stdout);
-
- major_status = gss_release_buffer(&status, &output_name_buffer);
-
- input_chan_bindings = (gss_channel_bindings)
- malloc(sizeof(gss_channel_bindings_desc));
-
- input_chan_bindings->initiator_addrtype = GSS_C_AF_INET;
- input_chan_bindings->initiator_address.length = 4;
- address = (char *) malloc(4);
- input_chan_bindings->initiator_address.value = (char *) address;
- address[0] = ((from_addr & 0xff000000) >> 24);
- address[1] = ((from_addr & 0xff0000) >> 16);
- address[2] = ((from_addr & 0xff00) >> 8);
- address[3] = (from_addr & 0xff);
- input_chan_bindings->acceptor_addrtype = GSS_C_AF_INET;
- input_chan_bindings->acceptor_address.length = 4;
- address = (char *) malloc(4);
- input_chan_bindings->acceptor_address.value = (char *) address;
- address[0] = ((to_addr & 0xff000000) >> 24);
- address[1] = ((to_addr & 0xff0000) >> 16);
- address[2] = ((to_addr & 0xff00) >> 8);
- address[3] = (to_addr & 0xff);
- input_chan_bindings->application_data.length = 0;
-
- req_flags = 0;
- if (deleg_flag) req_flags = req_flags | 1;
- if (mutual_flag) req_flags = req_flags | 2;
- if (replay_flag) req_flags = req_flags | 4;
- if (seq_flag) req_flags = req_flags | 8;
-
- major_status = gss_init_sec_context(&status, /* minor status */
- GSS_C_NO_CREDENTIAL, /* cred handle */
- &actual_ctxhandle, /* ctx handle */
- desired_targname, /* target name */
- GSS_C_NULL_OID, /* mech type */
- req_flags, /* req flags */
- 0, /* time req */
- input_chan_bindings, /* chan binding */
- GSS_C_NO_BUFFER, /* input token */
- &actual_mech_type, /* actual mech */
- &output_token, /* output token */
- &ret_flags, /* ret flags */
- &lifetime_rec); /* time rec */
-
- if ((major_status != GSS_S_COMPLETE) &&
- (major_status != GSS_S_CONTINUE_NEEDED)) {
- gss_display_status(&new_status,
- status,
- GSS_C_MECH_CODE,
- GSS_C_NULL_OID,
- &msg_ctx,
- &status_string);
- printf("%s\n", status_string.value);
- return(0);
- }
-
- if (!auth_sendname(UserNameRequested, strlen(UserNameRequested))) {
- return(0);
- }
-
- if (!Data(ap, SPX_AUTH, (void *)output_token.value, output_token.length)) {
- return(0);
- }
-
- return(1);
-}
-
- void
-spx_is(ap, data, cnt)
- Authenticator *ap;
- unsigned char *data;
- int cnt;
-{
- Session_Key skey;
- Block datablock;
- int r;
-
- if (cnt-- < 1)
- return;
- switch (*data++) {
- case SPX_AUTH:
- input_token.length = cnt;
- input_token.value = (char *) data;
-
- gethostname(lhostname, sizeof(lhostname));
-
- snprintf(targ_printable, sizeof(targ_printable),
- "SERVICE:rcmd@%s", lhostname);
-
- input_name_buffer.length = strlen(targ_printable);
- input_name_buffer.value = targ_printable;
-
- major_status = gss_import_name(&status,
- &input_name_buffer,
- GSS_C_NULL_OID,
- &desired_targname);
-
- major_status = gss_acquire_cred(&status,
- desired_targname,
- 0,
- GSS_C_NULL_OID_SET,
- GSS_C_ACCEPT,
- &gss_cred_handle,
- &actual_mechs,
- &lifetime_rec);
-
- major_status = gss_release_name(&status, desired_targname);
-
- input_chan_bindings = (gss_channel_bindings)
- malloc(sizeof(gss_channel_bindings_desc));
-
- input_chan_bindings->initiator_addrtype = GSS_C_AF_INET;
- input_chan_bindings->initiator_address.length = 4;
- address = (char *) malloc(4);
- input_chan_bindings->initiator_address.value = (char *) address;
- address[0] = ((from_addr & 0xff000000) >> 24);
- address[1] = ((from_addr & 0xff0000) >> 16);
- address[2] = ((from_addr & 0xff00) >> 8);
- address[3] = (from_addr & 0xff);
- input_chan_bindings->acceptor_addrtype = GSS_C_AF_INET;
- input_chan_bindings->acceptor_address.length = 4;
- address = (char *) malloc(4);
- input_chan_bindings->acceptor_address.value = (char *) address;
- address[0] = ((to_addr & 0xff000000) >> 24);
- address[1] = ((to_addr & 0xff0000) >> 16);
- address[2] = ((to_addr & 0xff00) >> 8);
- address[3] = (to_addr & 0xff);
- input_chan_bindings->application_data.length = 0;
-
- major_status = gss_accept_sec_context(&status,
- &context_handle,
- gss_cred_handle,
- &input_token,
- input_chan_bindings,
- &src_name,
- &actual_mech_type,
- &output_token,
- &ret_flags,
- &lifetime_rec,
- &gss_delegated_cred_handle);
-
-
- if (major_status != GSS_S_COMPLETE) {
-
- major_status = gss_display_name(&status,
- src_name,
- &fullname_buffer,
- &fullname_type);
- Data(ap, SPX_REJECT, (void *)"auth failed", -1);
- auth_finished(ap, AUTH_REJECT);
- return;
- }
-
- major_status = gss_display_name(&status,
- src_name,
- &fullname_buffer,
- &fullname_type);
-
-
- Data(ap, SPX_ACCEPT, (void *)output_token.value, output_token.length);
- auth_finished(ap, AUTH_USER);
- break;
-
- default:
- Data(ap, SPX_REJECT, 0, 0);
- break;
- }
-}
-
-
- void
-spx_reply(ap, data, cnt)
- Authenticator *ap;
- unsigned char *data;
- int cnt;
-{
- Session_Key skey;
-
- if (cnt-- < 1)
- return;
- switch (*data++) {
- case SPX_REJECT:
- if (cnt > 0) {
- printf("[ SPX refuses authentication because %.*s ]\r\n",
- cnt, data);
- } else
- printf("[ SPX refuses authentication ]\r\n");
- auth_send_retry();
- return;
- case SPX_ACCEPT:
- printf("[ SPX accepts you ]\n");
- if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
- /*
- * Send over the encrypted challenge.
- */
- input_token.value = (char *) data;
- input_token.length = cnt;
-
- major_status = gss_init_sec_context(&status, /* minor stat */
- GSS_C_NO_CREDENTIAL, /* cred handle */
- &actual_ctxhandle, /* ctx handle */
- desired_targname, /* target name */
- GSS_C_NULL_OID, /* mech type */
- req_flags, /* req flags */
- 0, /* time req */
- input_chan_bindings, /* chan binding */
- &input_token, /* input token */
- &actual_mech_type, /* actual mech */
- &output_token, /* output token */
- &ret_flags, /* ret flags */
- &lifetime_rec); /* time rec */
-
- if (major_status != GSS_S_COMPLETE) {
- gss_display_status(&new_status,
- status,
- GSS_C_MECH_CODE,
- GSS_C_NULL_OID,
- &msg_ctx,
- &status_string);
- printf("[ SPX mutual response fails ... '%s' ]\r\n",
- status_string.value);
- auth_send_retry();
- return;
- }
- }
- auth_finished(ap, AUTH_USER);
- return;
-
- default:
- return;
- }
-}
-
- int
-spx_status(ap, name, level)
- Authenticator *ap;
- char *name;
- int level;
-{
-
- gss_buffer_desc fullname_buffer, acl_file_buffer;
- gss_OID fullname_type;
- char acl_file[MAXPATHLEN], fullname[160];
- int major_status, status = 0;
- struct passwd *pwd;
-
- /*
- * hard code fullname to
- * "SPX:/C=US/O=Digital/OU=LKG/OU=Sphinx/OU=Users/CN=Kannan Alagappan"
- * and acl_file to "~kannan/.sphinx"
- */
-
- pwd = getpwnam(UserNameRequested);
- if (pwd == NULL) {
- return(AUTH_USER); /* not authenticated */
- }
-
- acl_file[sizeof(acl_file) - 1] = '\0';
- strncpy(acl_file, pwd->pw_dir, sizeof(acl_file) - 1);
- strncat(acl_file, "/.sphinx", sizeof(acl_file) - 1 - strlen(acl_file));
- acl_file_buffer.value = acl_file;
- acl_file_buffer.length = strlen(acl_file);
-
- major_status = gss_display_name(&status,
- src_name,
- &fullname_buffer,
- &fullname_type);
-
- if (level < AUTH_USER)
- return(level);
-
- major_status = gss__check_acl(&status, &fullname_buffer,
- &acl_file_buffer);
-
- if (major_status == GSS_S_COMPLETE) {
- /* the name buffer comes from telnetd/telnetd{-ktd}.c */
- strncpy(name, UserNameRequested, 255);
- name[255] = '\0';
- return(AUTH_VALID);
- } else {
- return(AUTH_USER);
- }
-
-}
-
-#define BUMP(buf, len) while (*(buf)) {++(buf), --(len);}
-#define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);}
-
- void
-spx_printsub(data, cnt, buf, buflen)
- unsigned char *data, *buf;
- int cnt;
- unsigned int buflen;
-{
- char lbuf[32];
- register int i;
-
- buf[buflen-1] = '\0'; /* make sure its NULL terminated */
- buflen -= 1;
-
- switch(data[3]) {
- case SPX_REJECT: /* Rejected (reason might follow) */
- strncpy((char *)buf, " REJECT ", buflen);
- goto common;
-
- case SPX_ACCEPT: /* Accepted (name might follow) */
- strncpy((char *)buf, " ACCEPT ", buflen);
- common:
- BUMP(buf, buflen);
- if (cnt <= 4)
- break;
- ADDC(buf, buflen, '"');
- for (i = 4; i < cnt; i++)
- ADDC(buf, buflen, data[i]);
- ADDC(buf, buflen, '"');
- ADDC(buf, buflen, '\0');
- break;
-
- case SPX_AUTH: /* Authentication data follows */
- strncpy((char *)buf, " AUTH", buflen);
- goto common2;
-
- default:
- snprintf(lbuf, sizeof(lbuf), " %d (unknown)", data[3]);
- strncpy((char *)buf, lbuf, buflen);
- common2:
- BUMP(buf, buflen);
- for (i = 4; i < cnt; i++) {
- snprintf(lbuf, sizeof(lbuf), " %d", data[i]);
- strncpy((char *)buf, lbuf, buflen);
- BUMP(buf, buflen);
- }
- break;
- }
-}
-#else
-#include "misc-proto.h"
-#endif
-
-#ifdef notdef
-
-prkey(msg, key)
- char *msg;
- unsigned char *key;
-{
- register int i;
- printf("%s:", msg);
- for (i = 0; i < 8; i++)
- printf(" %3d", key[i]);
- printf("\r\n");
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 1987, 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 __STDC__
-#define const
-#endif
-
-#include <sys/types.h>
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#include <strings.h>
-#endif
-
-/* based on @(#)strcasecmp.c 8.1 (Berkeley) 6/4/93 */
-
-typedef unsigned char u_char;
-
-/*
- * This array is designed for mapping upper and lower case letter
- * together for a case independent comparison. The mappings are
- * based upon ascii character sequences.
- */
-static const u_char charmap[] = {
- '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
- '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
- '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
- '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
- '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
- '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
- '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
- '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
- '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
- '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
- '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
- '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
- '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
- '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
- '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
- '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
- '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
- '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
- '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
- '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
- '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
- '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
- '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
- '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
- '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
- '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
- '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
- '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
- '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
- '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
- '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
- '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
-};
-
-int
-strcasecmp(s1, s2)
- const char *s1, *s2;
-{
- register const u_char *cm = charmap,
- *us1 = (const u_char *)s1,
- *us2 = (const u_char *)s2;
-
- while (cm[*us1] == cm[*us2++])
- if (*us1++ == '\0')
- return (0);
- return (cm[*us1] - cm[*--us2]);
-}
-
-int
-strncasecmp(s1, s2, n)
- const char *s1, *s2;
- register size_t n;
-{
- if (n != 0) {
- register const u_char *cm = charmap,
- *us1 = (const u_char *)s1,
- *us2 = (const u_char *)s2;
-
- do {
- if (cm[*us1] != cm[*us2++])
- return (cm[*us1] - cm[*--us2]);
- if (*us1++ == '\0')
- break;
- } while (--n != 0);
- }
- return (0);
-}
+++ /dev/null
-/*
- * 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.
- */
-
-/* based on @(#)strchr.c 8.1 (Berkeley) 6/4/93 */
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#include <strings.h>
-#endif
-
-char *
-strchr(p, ch)
- char *p, ch;
-{
- return(index(p, ch));
-}
+++ /dev/null
-/*
- * 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.
- */
-
-/* based on @(#)strdup.c 8.1 (Berkeley) 6/4/93 */
-
-#ifndef __STDC__
-#define const
-#endif
-
-#include <sys/types.h>
-
-#include <stddef.h>
-#include <stdlib.h>
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#include <strings.h>
-#endif
-
-char *
-strdup(str)
- const char *str;
-{
- size_t len;
- char *copy;
-
- len = strlen(str) + 1;
- if (!(copy = malloc((u_int)len)))
- return (NULL);
- memcpy(copy, str, len);
- return (copy);
-}
+++ /dev/null
-/*
- * 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.
- */
-
-/* based on @(#)strerror.c 8.1 (Berkeley) 6/4/93 */
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#include <strings.h>
-#endif
-
-char *
-strerror(num)
- int num;
-{
- extern int sys_nerr;
- extern char *sys_errlist[];
-#define UPREFIX "Unknown error: "
- static char ebuf[40] = UPREFIX; /* 64-bit number + slop */
- register unsigned int errnum;
- register char *p, *t;
- char tmp[40];
-
- errnum = num; /* convert to unsigned */
- if (errnum < sys_nerr)
- return(sys_errlist[errnum]);
-
- /* Do this by hand, so we don't include stdio(3). */
- t = tmp;
- do {
- *t++ = "0123456789"[errnum % 10];
- } while (errnum /= 10);
- for (p = ebuf + sizeof(UPREFIX) - 1;;) {
- *p++ = *--t;
- if (t <= tmp)
- break;
- }
- return(ebuf);
-}
+++ /dev/null
-/*
- * Copyright (c) 1989, 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.
- */
-
-/* based on @(#)strftime.c 8.1 (Berkeley) 6/4/93 */
-
-#ifndef __STDC__
-#define const
-#endif
-
-#include <sys/types.h>
-#include <sys/time.h>
-#ifdef notdef
-#include <tzfile.h>
-#else
-#define TM_YEAR_BASE 1900 /* from <tzfile.h> */
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#include <strings.h>
-#endif
-
-static char *afmt[] = {
- "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
-};
-static char *Afmt[] = {
- "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
- "Saturday",
-};
-static char *bfmt[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
- "Oct", "Nov", "Dec",
-};
-static char *Bfmt[] = {
- "January", "February", "March", "April", "May", "June", "July",
- "August", "September", "October", "November", "December",
-};
-
-static size_t gsize;
-static char *pt;
-#ifndef __P
-#define __P(x) ()
-#endif
-static int _add __P((char *));
-static int _conv __P((int, int, int));
-static int _secs __P((const struct tm *));
-static size_t _fmt __P((const char *, const struct tm *));
-
-size_t
-strftime(s, maxsize, format, t)
- char *s;
- size_t maxsize;
- const char *format;
- const struct tm *t;
-{
-
- pt = s;
- if ((gsize = maxsize) < 1)
- return(0);
- if (_fmt(format, t)) {
- *pt = '\0';
- return(maxsize - gsize);
- }
- return(0);
-}
-
-static size_t
-_fmt(format, t)
- register const char *format;
- const struct tm *t;
-{
- for (; *format; ++format) {
- if (*format == '%')
- switch(*++format) {
- case '\0':
- --format;
- break;
- case 'A':
- if (t->tm_wday < 0 || t->tm_wday > 6)
- return(0);
- if (!_add(Afmt[t->tm_wday]))
- return(0);
- continue;
- case 'a':
- if (t->tm_wday < 0 || t->tm_wday > 6)
- return(0);
- if (!_add(afmt[t->tm_wday]))
- return(0);
- continue;
- case 'B':
- if (t->tm_mon < 0 || t->tm_mon > 11)
- return(0);
- if (!_add(Bfmt[t->tm_mon]))
- return(0);
- continue;
- case 'b':
- case 'h':
- if (t->tm_mon < 0 || t->tm_mon > 11)
- return(0);
- if (!_add(bfmt[t->tm_mon]))
- return(0);
- continue;
- case 'C':
- if (!_fmt("%a %b %e %H:%M:%S %Y", t))
- return(0);
- continue;
- case 'c':
- if (!_fmt("%m/%d/%y %H:%M:%S", t))
- return(0);
- continue;
- case 'D':
- if (!_fmt("%m/%d/%y", t))
- return(0);
- continue;
- case 'd':
- if (!_conv(t->tm_mday, 2, '0'))
- return(0);
- continue;
- case 'e':
- if (!_conv(t->tm_mday, 2, ' '))
- return(0);
- continue;
- case 'H':
- if (!_conv(t->tm_hour, 2, '0'))
- return(0);
- continue;
- case 'I':
- if (!_conv(t->tm_hour % 12 ?
- t->tm_hour % 12 : 12, 2, '0'))
- return(0);
- continue;
- case 'j':
- if (!_conv(t->tm_yday + 1, 3, '0'))
- return(0);
- continue;
- case 'k':
- if (!_conv(t->tm_hour, 2, ' '))
- return(0);
- continue;
- case 'l':
- if (!_conv(t->tm_hour % 12 ?
- t->tm_hour % 12 : 12, 2, ' '))
- return(0);
- continue;
- case 'M':
- if (!_conv(t->tm_min, 2, '0'))
- return(0);
- continue;
- case 'm':
- if (!_conv(t->tm_mon + 1, 2, '0'))
- return(0);
- continue;
- case 'n':
- if (!_add("\n"))
- return(0);
- continue;
- case 'p':
- if (!_add(t->tm_hour >= 12 ? "PM" : "AM"))
- return(0);
- continue;
- case 'R':
- if (!_fmt("%H:%M", t))
- return(0);
- continue;
- case 'r':
- if (!_fmt("%I:%M:%S %p", t))
- return(0);
- continue;
- case 'S':
- if (!_conv(t->tm_sec, 2, '0'))
- return(0);
- continue;
- case 's':
- if (!_secs(t))
- return(0);
- continue;
- case 'T':
- case 'X':
- if (!_fmt("%H:%M:%S", t))
- return(0);
- continue;
- case 't':
- if (!_add("\t"))
- return(0);
- continue;
- case 'U':
- if (!_conv((t->tm_yday + 7 - t->tm_wday) / 7,
- 2, '0'))
- return(0);
- continue;
- case 'W':
- if (!_conv((t->tm_yday + 7 -
- (t->tm_wday ? (t->tm_wday - 1) : 6))
- / 7, 2, '0'))
- return(0);
- continue;
- case 'w':
- if (!_conv(t->tm_wday, 1, '0'))
- return(0);
- continue;
- case 'x':
- if (!_fmt("%m/%d/%y", t))
- return(0);
- continue;
- case 'y':
- if (!_conv((t->tm_year + TM_YEAR_BASE)
- % 100, 2, '0'))
- return(0);
- continue;
- case 'Y':
- if (!_conv(t->tm_year + TM_YEAR_BASE, 4, '0'))
- return(0);
- continue;
-#ifdef notdef
- case 'Z':
- if (!t->tm_zone || !_add(t->tm_zone))
- return(0);
- continue;
-#endif
- case '%':
- /*
- * X311J/88-090 (4.12.3.5): if conversion char is
- * undefined, behavior is undefined. Print out the
- * character itself as printf(3) does.
- */
- default:
- break;
- }
- if (!gsize--)
- return(0);
- *pt++ = *format;
- }
- return(gsize);
-}
-
-static int
-_secs(t)
- const struct tm *t;
-{
- static char buf[15];
- register time_t s;
- register char *p;
- struct tm tmp;
-
- /* Make a copy, mktime(3) modifies the tm struct. */
- tmp = *t;
- s = mktime(&tmp);
- for (p = buf + sizeof(buf) - 2; s > 0 && p > buf; s /= 10)
- *p-- = s % 10 + '0';
- return(_add(++p));
-}
-
-static int
-_conv(n, digits, pad)
- int n, digits, pad;
-{
- static char buf[10];
- register char *p;
-
- for (p = buf + sizeof(buf) - 2; n > 0 && p > buf; n /= 10, --digits)
- *p-- = n % 10 + '0';
- while (p > buf && digits-- > 0)
- *p-- = pad;
- return(_add(++p));
-}
-
-static int
-_add(str)
- register char *str;
-{
- for (;; ++pt, --gsize) {
- if (!gsize)
- return(0);
- if (!(*pt = *str++))
- return(1);
- }
-}
+++ /dev/null
-/*
- * 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.
- */
-
-/* based on @(#)strrchr.c 8.1 (Berkeley) 6/4/93 */
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#include <strings.h>
-#endif
-
-char *
-strrchr(p, ch)
- char *p, ch;
-{
- return(rindex(p, ch));
-}
+++ /dev/null
-*** stty.c.old Tue May 23 13:54:29 1989
---- stty.c Wed Aug 23 13:42:32 1989
-***************
-*** 20,25 ****
---- 20,28 ----
-
- #include <stdio.h>
- #include <sys/ioctl.h>
-+ #include <sys/types.h>
-+ #define NO_T_CHARS_DEFINES
-+ #include <sys/tty.h>
-
- struct
- {
-***************
-*** 145,150 ****
---- 148,156 ----
- struct winsize win;
- int lmode;
- int oldisc, ldisc;
-+ #ifdef TIOCGSTATE
-+ int extproc;
-+ #endif
-
- struct special {
- char *name;
-***************
-*** 188,193 ****
---- 194,203 ----
- ioctl(1, TIOCLGET, &lmode);
- ioctl(1, TIOCGLTC, <c);
- ioctl(1, TIOCGWINSZ, &win);
-+ #ifdef TIOCGSTATE
-+ ioctl(1, TIOCGSTATE, &extproc);
-+ extproc &= TS_EXTPROC;
-+ #endif
- if(argc == 1) {
- prmodes(0);
- exit(0);
-***************
-*** 292,297 ****
---- 302,316 ----
- printf("%d %d\n", win.ws_row, win.ws_col);
- exit(0);
- }
-+ #if defined(TIOCEXT)
-+ if (eq("extproc") || eq("-extproc")) {
-+ if (**argv == '-')
-+ extproc = 0;
-+ else
-+ extproc = 1;
-+ ioctl(1, TIOCEXT, &extproc);
-+ }
-+ #endif
- for(i=0; speeds[i].string; i++)
- if(eq(speeds[i].string)) {
- mode.sg_ispeed = mode.sg_ospeed = speeds[i].speed;
-***************
-*** 438,443 ****
---- 457,468 ----
- lpit(LPENDIN, "-pendin ");
- lpit(LDECCTQ, "-decctlq ");
- lpit(LNOFLSH, "-noflsh ");
-+ #ifdef TIOCGSTATE
-+ if (all==2||extproc) {
-+ fprintf(stderr,"-extproc"+(extproc!=0));
-+ any++;
-+ }
-+ #endif
- if (any || nothing)
- fprintf(stderr,"\n");
- } else if (!all)
+++ /dev/null
-
- Three pieces of state need to be kept for each side of each option.
- (You need the localside, sending WILL/WONT & receiving DO/DONT, and
- the remoteside, sending DO/DONT and receiving WILL/WONT)
-
- MY_STATE: What state am I in?
- WANT_STATE: What state do I want?
- WANT_RESP: How many requests have I initiated?
-
- Default values:
- MY_STATE = WANT_STATE = DONT
- WANT_RESP = 0
-
- The local setup will change based on the state of the Telnet
- variables. When we are the originator, we can either make the
- local setup changes at option request time (in which case if
- the option is denied we need to change things back) or when
- the option is acknowledged.
-
- To initiate a switch to NEW_STATE:
-
- if ((WANT_RESP == 0 && NEW_STATE == MY_STATE) ||
- WANT_STATE == NEW_STATE) {
- do nothing;
- } else {
- /*
- * This is where the logic goes to change the local setup
- * if we are doing so at request initiation
- */
- WANT_STATE = NEW_STATE;
- send NEW_STATE;
- WANT_RESP += 1;
- }
-
- When receiving NEW_STATE:
-
- if (WANT_RESP) {
- --WANT_RESP;
- if (WANT_RESP && (NEW_STATE == MY_STATE))
- --WANT_RESP;
- }
- if (WANT_RESP == 0) {
- if (NEW_STATE != WANT_STATE) {
- /*
- * This is where the logic goes to decide if it is ok
- * to switch to NEW_STATE, and if so, do any necessary
- * local setup changes.
- */
- if (ok_to_switch_to NEW_STATE)
- WANT_STATE = NEW_STATE;
- else
- WANT_RESP++;
-* if (MY_STATE != WANT_STATE)
- reply with WANT_STATE;
- } else {
- /*
- * This is where the logic goes to change the local setup
- * if we are doing so at request acknowledgment
- */
- }
- }
- MY_STATE = NEW_STATE;
-
-* This if() line is not needed, it should be ok to always do the
- "reply with WANT_STATE". With the if() line, asking to turn on
- an option that the other side doesn't understand is:
- Send DO option
- Recv WONT option
- Without the if() line, it is:
- Send DO option
- Recv WONT option
- Send DONT option
- If the other side does not expect to receive the latter case,
- but generates the latter case, then there is a potential for
- option negotiation loops. An implementation that does not expect
- to get the second case should not generate it, an implementation
- that does expect to get it may or may not generate it, and things
- will still work. Being conservative in what we send, we have the
- if() statement in, but we expect the other side to generate the
- last response.
+++ /dev/null
-thisconfigdir=..
-myfulldir=appl/telnet/telnet
-mydir=telnet
-BUILDTOP=$(REL)..$(S)..$(S)..
-# derived from the original Makefile.generic
-#
-# 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.
-#
-# @(#)Makefile.generic 5.5 (Berkeley) 3/1/91
-#
-
-AUTH_DEF=-DAUTHENTICATION -DENCRYPTION -DKRB5 -DFORWARD -UNO_LOGIN_F -DLOGIN_CAP_F -DLOGIN_PROGRAM=KRB5_PATH_LOGIN
-OTHERDEFS=-DLINEMODE -DKLUDGELINEMODE -DDIAGNOSTICS -DENV_HACK -DOLD_ENVIRON
-LOCALINCLUDES=-I.. -I$(srcdir)/..
-DEFINES = -DTELNET_BUFSIZE=65535 $(AUTH_DEF) $(OTHERDEFS)
-ARPA_TELNET= $(srcdir)/../arpa/telnet.h
-
-PROG_LIBPATH=-L$(TOPLIBD)
-PROG_RPATH=$(KRB5_LIBDIR)
-
-LIBS= @TELNET_LIBS@
-
-SRCS= $(srcdir)/authenc.c $(srcdir)/commands.c $(srcdir)/main.c $(srcdir)/network.c $(srcdir)/ring.c \
- $(srcdir)/sys_bsd.c $(srcdir)/telnet.c $(srcdir)/terminal.c \
- $(srcdir)/utilities.c $(GETOPT_SRC)
-ALLHC= $(SRCS) \
- defines.h externs.h fdset.h general.h \
- ring.h types.h
-
-OBJS= authenc.o commands.o main.o network.o ring.o sys_bsd.o \
- telnet.o terminal.o utilities.o $(GETOPT_OBJ)
-
-all:: telnet
-
-telnet: $(OBJS) $(KRB5_BASE_DEPLIBS) ../libtelnet/libtelnet.a
- $(CC_LINK) -o $@ $(OBJS) ../libtelnet/libtelnet.a $(KRB5_BASE_LIBS)
-
-clean::
- $(RM) telnet
-
-install::
- for f in telnet; do \
- $(INSTALL_PROGRAM) $$f \
- $(DESTDIR)$(CLIENT_BINDIR)/`echo $$f|sed '$(transform)'`; \
- $(INSTALL_DATA) $(srcdir)/$$f.1 \
- ${DESTDIR}$(CLIENT_MANDIR)/`echo $$f|sed '$(transform)'`.1; \
- done
- $(INSTALL_DATA) $(srcdir)/tmac.doc ${DESTDIR}$(CLIENT_MANDIR)/tmac.doc
-
-authenc.o: defines.h externs.h general.h ring.h types.h $(ARPA_TELNET)
-commands.o: defines.h externs.h general.h ring.h types.h $(ARPA_TELNET)
-main.o: defines.h externs.h ring.h
-network.o: defines.h externs.h fdset.h ring.h $(ARPA_TELNET)
-ring.o: general.h ring.h
-sys_bsd.o: defines.h externs.h fdset.h ring.h types.h $(ARPA_TELNET)
-telnet.o: defines.h externs.h general.h ring.h types.h $(ARPA_TELNET)
-terminal.o: externs.h ring.h types.h $(ARPA_TELNET)
-tn3270.o: defines.h externs.h fdset.h general.h ring.h $(ARPA_TELNET)
-utilities.o: defines.h externs.h fdset.h general.h ring.h $(ARPA_TELNET)
+++ /dev/null
-/*-
- * Copyright (c) 1991, 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.
- */
-
-/* based on @(#)authenc.c 8.1 (Berkeley) 6/6/93 */
-
-#if defined(AUTHENTICATION) || defined(ENCRYPTION)
-#include <sys/types.h>
-#include <arpa/telnet.h>
-#include <libtelnet/encrypt.h>
-#include <libtelnet/misc.h>
-
-#include "general.h"
-#include "ring.h"
-#include "externs.h"
-#include "defines.h"
-#include "types.h"
-
- int
-net_write(str, len)
- unsigned char *str;
- int len;
-{
- if (NETROOM() > len) {
- ring_supply_data(&netoring, str, len);
- if (str[0] == IAC && str[1] == SE)
- printsub('>', &str[2], len-2);
- return(len);
- }
- return(0);
-}
-
- void
-net_encrypt()
-{
-#ifdef ENCRYPTION
- if (encrypt_output)
- ring_encrypt(&netoring, encrypt_output);
- else
- ring_clearto(&netoring);
-#endif /* ENCRYPTION */
-}
-
- int
-telnet_spin()
-{
- extern int scheduler_lockout_tty;
-
- scheduler_lockout_tty = 1;
- Scheduler(0);
- scheduler_lockout_tty = 0;
-
- return 0;
-}
-
- char *
-telnet_getenv(val)
- char *val;
-{
- return((char *)env_getvalue((unsigned char *)val));
-}
-
- char *
-telnet_gets(tprompt, result, length, echo)
- char *tprompt;
- char *result;
- int length;
- int echo;
-{
- extern char *getpass();
- extern int globalmode;
- int om = globalmode;
- char *res;
-
- TerminalNewMode(-1);
- if (echo) {
- printf("%s", tprompt);
- res = fgets(result, length, stdin);
- } else if ((res = getpass(tprompt))) {
- strncpy(result, res, (unsigned) length);
- res = result;
- }
- TerminalNewMode(om);
- return(res);
-}
-#endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */
+++ /dev/null
-/*
- * Copyright (c) 1988, 1990, 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.
- */
-
-/* based on @(#)commands.c 8.1 (Berkeley) 6/6/93 */
-
-#if defined(unix)
-#include <sys/param.h>
-#if defined(CRAY) || defined(sysV88)
-#include <sys/types.h>
-#endif
-#include <sys/file.h>
-#else
-#include <sys/types.h>
-#endif /* defined(unix) */
-#include <sys/socket.h>
-#include <netinet/in.h>
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif /* HAVE_ARPA_INET_H */
-#ifdef CRAY
-#include <fcntl.h>
-#endif /* CRAY */
-#include <sys/wait.h>
-
-#include <stdio.h>
-#include <string.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <signal.h>
-#include <netdb.h>
-#include <ctype.h>
-#include <pwd.h>
-#include <stdarg.h>
-#include <errno.h>
-#ifdef HAVE_VFORK_H
-#include <vfork.h>
-#endif
-
-#include <arpa/telnet.h>
-
-#include "general.h"
-
-#include "ring.h"
-
-#include "externs.h"
-#include "defines.h"
-#include "types.h"
-
-#if defined(AUTHENTICATION) || defined(FORWARD)
-#include <libtelnet/auth.h>
-#endif
-
-#ifdef ENCRYPTION
-#include <libtelnet/encrypt.h>
-#endif
-
-#if defined(AUTHENTICATION) || defined(ENCRYPTION)
-#include <libtelnet/misc-proto.h>
-#endif
-
-#if !defined(CRAY) && !defined(sysV88)
-#include <netinet/in_systm.h>
-# if (defined(vax) || defined(tahoe) || defined(hp300)) && !defined(ultrix)
-# include <machine/endian.h>
-# endif /* vax */
-#endif /* !defined(CRAY) && !defined(sysV88) */
-#include <netinet/ip.h>
-
-
-#if HAVE_ARPA_NAMESER_H
-#include <arpa/nameser.h>
-#endif
-#include <netdb.h>
-
-#ifndef MAXDNAME
-#define MAXDNAME 256 /*per the rfc*/
-#endif
-#ifndef INADDR_NONE
-#define INADDR_NONE 0xffffffff
-#endif
-
-#if defined(IPPROTO_IP) && defined(IP_TOS)
-int tos = -1;
-static unsigned long sourceroute(char *, char **, int *);
-#endif /* defined(IPPROTO_IP) && defined(IP_TOS) */
-
-#include "fake-addrinfo.h"
-
-#include <k5-platform.h>
-
-char *hostname;
-static char _hostname[MAXDNAME];
-static char hostaddrstring[NI_MAXHOST];
-
-extern char *getenv();
-
-extern int isprefix();
-extern char **genget();
-extern int Ambiguous();
-
-typedef int (*intrtn_t)();
-static int call (intrtn_t, ...);
-void cmdrc (char *, char *);
-static int
-send_tncmd (void (*func)(), char *, char *);
-static int help(int, char **);
-
-#ifdef NEED_HERROR_PROTO
-extern void herror(const char *);
-#endif
-
-typedef struct {
- char *name; /* command name */
- char *help; /* help string (NULL for no help) */
- int (*handler) /* routine which executes command */
- (int, char *[]);
- int needconnect; /* Do we need to be connected to execute? */
-} Command;
-
-static char line[256];
-static char saveline[256];
-static int margc;
-static char *margv[20];
-
- static void
-makeargv()
-{
- register char *cp, *cp2, c;
- register char **argp = margv;
-
- margc = 0;
- cp = line;
- if (*cp == '!') { /* Special case shell escape */
- strncpy(saveline, line, sizeof(saveline) - 1);
- /* save for shell command */
- saveline[sizeof(saveline) - 1] = '\0';
- *argp++ = "!"; /* No room in string to get this */
- margc++;
- cp++;
- }
- while ((c = *cp)) {
- register int inquote = 0;
- while (isspace((int) c))
- c = *++cp;
- if (c == '\0')
- break;
- *argp++ = cp;
- margc += 1;
- for (cp2 = cp; c != '\0'; c = *++cp) {
- if (inquote) {
- if (c == inquote) {
- inquote = 0;
- continue;
- }
- } else {
- if (c == '\\') {
- if ((c = *++cp) == '\0')
- break;
- } else if (c == '"') {
- inquote = '"';
- continue;
- } else if (c == '\'') {
- inquote = '\'';
- continue;
- } else if (isspace((int) c))
- break;
- }
- *cp2++ = c;
- }
- *cp2 = '\0';
- if (c == '\0')
- break;
- cp++;
- }
- *argp++ = 0;
-}
-
-/*
- * Make a character string into a number.
- *
- * Todo: 1. Could take random integers (12, 0x12, 012, 0b1).
- */
-
- static int
-special(s)
- register char *s;
-{
- register char c;
- char b;
-
- switch (*s) {
- case '^':
- b = *++s;
- if (b == '?') {
- c = b | 0x40; /* DEL */
- } else {
- c = b & 0x1f;
- }
- break;
- default:
- c = *s;
- break;
- }
- return c;
-}
-
-/*
- * Construct a control character sequence
- * for a special character.
- */
- static char *
-control(c)
- register cc_t c;
-{
- static char buf[5];
- /*
- * The only way I could get the Sun 3.5 compiler
- * to shut up about
- * if ((unsigned int)c >= 0x80)
- * was to assign "c" to an unsigned int variable...
- * Arggg....
- */
- register unsigned int uic = (unsigned int)c;
-
- if (uic == 0x7f)
- return ("^?");
- if (c == (cc_t)_POSIX_VDISABLE) {
- return "off";
- }
- if (uic >= 0x80) {
- buf[0] = '\\';
- buf[1] = ((c>>6)&07) + '0';
- buf[2] = ((c>>3)&07) + '0';
- buf[3] = (c&07) + '0';
- buf[4] = 0;
- } else if (uic >= 0x20) {
- buf[0] = c;
- buf[1] = 0;
- } else {
- buf[0] = '^';
- buf[1] = '@'+c;
- buf[2] = 0;
- }
- return (buf);
-}
-
-
-
-/*
- * The following are data structures and routines for
- * the "send" command.
- *
- */
-
-struct sendlist {
- char *name; /* How user refers to it (case independent) */
- char *help; /* Help information (0 ==> no help) */
- int needconnect; /* Need to be connected */
- int narg; /* Number of arguments */
- int (*handler) /* Routine to perform (for special ops) */
- (char *);
- int nbyte; /* Number of bytes to send this command */
- int what; /* Character to be sent (<0 ==> special) */
-};
-\f
-
-static int
- send_esc (char *),
- send_help (char *),
- send_docmd (char *),
- send_dontcmd (char *),
- send_willcmd (char *),
- send_wontcmd (char *);
-
-static struct sendlist Sendlist[] = {
- { "ao", "Send Telnet Abort output", 1, 0, 0, 2, AO },
- { "ayt", "Send Telnet 'Are You There'", 1, 0, 0, 2, AYT },
- { "brk", "Send Telnet Break", 1, 0, 0, 2, BREAK },
- { "break", 0, 1, 0, 0, 2, BREAK },
- { "ec", "Send Telnet Erase Character", 1, 0, 0, 2, EC },
- { "el", "Send Telnet Erase Line", 1, 0, 0, 2, EL },
- { "escape", "Send current escape character", 1, 0, send_esc, 1, 0 },
- { "ga", "Send Telnet 'Go Ahead' sequence", 1, 0, 0, 2, GA },
- { "ip", "Send Telnet Interrupt Process", 1, 0, 0, 2, IP },
- { "intp", 0, 1, 0, 0, 2, IP },
- { "interrupt", 0, 1, 0, 0, 2, IP },
- { "intr", 0, 1, 0, 0, 2, IP },
- { "nop", "Send Telnet 'No operation'", 1, 0, 0, 2, NOP },
- { "eor", "Send Telnet 'End of Record'", 1, 0, 0, 2, EOR },
- { "abort", "Send Telnet 'Abort Process'", 1, 0, 0, 2, ABORT },
- { "susp", "Send Telnet 'Suspend Process'", 1, 0, 0, 2, SUSP },
- { "eof", "Send Telnet End of File Character", 1, 0, 0, 2, xEOF },
- { "synch", "Perform Telnet 'Synch operation'", 1, 0, dosynch, 2, 0 },
- { "getstatus", "Send request for STATUS", 1, 0, get_status, 6, 0 },
- { "?", "Display send options", 0, 0, send_help, 0, 0 },
- { "help", 0, 0, 0, send_help, 0, 0 },
- { "do", 0, 0, 1, send_docmd, 3, 0 },
- { "dont", 0, 0, 1, send_dontcmd, 3, 0 },
- { "will", 0, 0, 1, send_willcmd, 3, 0 },
- { "wont", 0, 0, 1, send_wontcmd, 3, 0 },
- { 0 }
-};
-
-#define GETSEND(name) ((struct sendlist *) genget(name, (char **) Sendlist, \
- sizeof(struct sendlist)))
-
- static int
-sendcmd(argc, argv)
- int argc;
- char **argv;
-{
- int count; /* how many bytes we are going to need to send */
- int i;
- struct sendlist *s; /* pointer to current command */
- int success = 0;
- int needconnect = 0;
-
- if (argc < 2) {
- printf("need at least one argument for 'send' command\r\n");
- printf("'send ?' for help\n");
- return 0;
- }
- /*
- * First, validate all the send arguments.
- * In addition, we see how much space we are going to need, and
- * whether or not we will be doing a "SYNCH" operation (which
- * flushes the network queue).
- */
- count = 0;
- for (i = 1; i < argc; i++) {
- s = GETSEND(argv[i]);
- if (s == 0) {
- printf("Unknown send argument '%s'\n'send ?' for help.\r\n",
- argv[i]);
- return 0;
- } else if (Ambiguous(s)) {
- printf("Ambiguous send argument '%s'\n'send ?' for help.\r\n",
- argv[i]);
- return 0;
- }
- if (i + s->narg >= argc) {
- fprintf(stderr,
- "Need %d argument%s to 'send %s' command. 'send %s ?' for help.\n",
- s->narg, s->narg == 1 ? "" : "s", s->name, s->name);
- return 0;
- }
- count += s->nbyte;
- if (s->handler == send_help) {
- send_help(NULL);
- return 0;
- }
-
- i += s->narg;
- needconnect += s->needconnect;
- }
- if (!connected && needconnect) {
- printf("?Need to be connected first.\r\n");
- printf("'send ?' for help\r\n");
- return 0;
- }
- /* Now, do we have enough room? */
- if (NETROOM() < count) {
- printf("There is not enough room in the buffer TO the network\r\n");
- printf("to process your request. Nothing will be done.\r\n");
- printf("('send synch' will throw away most data in the network\r\n");
- printf("buffer, if this might help.)\r\n");
- return 0;
- }
- /* OK, they are all OK, now go through again and actually send */
- count = 0;
- for (i = 1; i < argc; i++) {
- if ((s = GETSEND(argv[i])) == 0) {
- fprintf(stderr, "Telnet 'send' error - argument disappeared!\n");
- (void) quit(0, NULL);
- /*NOTREACHED*/
- }
- if (s->handler) {
- count++;
- success += (*s->handler)(argv[i+1]);
- i += s->narg;
- } else {
- NET2ADD(IAC, s->what);
- printoption("SENT", IAC, s->what);
- }
- }
- return (count == success);
-}
-
- static int
-send_esc(s)
- char *s;
-{
- NETADD(escape);
- return 1;
-}
-
- static int
-send_docmd(name)
- char *name;
-{
- return(send_tncmd(send_do, "do", name));
-}
-
- static int
-send_dontcmd(name)
- char *name;
-{
- return(send_tncmd(send_dont, "dont", name));
-}
- static int
-send_willcmd(name)
- char *name;
-{
- return(send_tncmd(send_will, "will", name));
-}
- static int
-send_wontcmd(name)
- char *name;
-{
- return(send_tncmd(send_wont, "wont", name));
-}
-
-static int
-send_tncmd(func, cmd, name)
- void (*func)();
- char *cmd, *name;
-{
- char **cpp;
- extern char *telopts[];
- register int val = 0;
-
- if (isprefix(name, "help") || isprefix(name, "?")) {
- register int col, len;
-
- printf("Usage: send %s <value|option>\r\n", cmd);
- printf("\"value\" must be from 0 to 255\r\n");
- printf("Valid options are:\r\n\t");
-
- col = 8;
- for (cpp = telopts; *cpp; cpp++) {
- len = strlen(*cpp) + 3;
- if (col + len > 65) {
- printf("\r\n\t");
- col = 8;
- }
- printf(" \"%s\"", *cpp);
- col += len;
- }
- printf("\r\n");
- return 0;
- }
- cpp = (char **)genget(name, telopts, sizeof(char *));
- if (Ambiguous(cpp)) {
- fprintf(stderr,"'%s': ambiguous argument ('send %s ?' for help).\n",
- name, cmd);
- return 0;
- }
- if (cpp) {
- val = cpp - telopts;
- } else {
- register char *cp = name;
-
- while (*cp >= '0' && *cp <= '9') {
- val *= 10;
- val += *cp - '0';
- cp++;
- }
- if (*cp != 0) {
- fprintf(stderr, "'%s': unknown argument ('send %s ?' for help).\n",
- name, cmd);
- return 0;
- } else if (val < 0 || val > 255) {
- fprintf(stderr, "'%s': bad value ('send %s ?' for help).\n",
- name, cmd);
- return 0;
- }
- }
- if (!connected) {
- printf("?Need to be connected first.\r\n");
- return 0;
- }
- (*func)(val, 1);
- return 1;
-}
-
- static int
-send_help(n)
- char *n;
-{
- struct sendlist *s; /* pointer to current command */
- for (s = Sendlist; s->name; s++) {
- if (s->help)
- printf("%-15s %s\r\n", s->name, s->help);
- }
- return(0);
-}
-\f
-/*
- * The following are the routines and data structures referred
- * to by the arguments to the "toggle" command.
- */
-
- static int
-lclchars(s)
- int s;
-{
- donelclchars = 1;
- return 1;
-}
-
- static int
-togdebug(s)
- int s;
-{
-#ifndef NOT43
- if (net > 0 &&
- (SetSockOpt(net, SOL_SOCKET, SO_DEBUG, debug)) < 0) {
- perror("setsockopt (SO_DEBUG)");
- }
-#else /* NOT43 */
- if (debug) {
- if (net > 0 && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
- perror("setsockopt (SO_DEBUG)");
- } else
- printf("Cannot turn off socket debugging\r\n");
-#endif /* NOT43 */
- return 1;
-}
-
-
- static int
-togcrlf(s)
- int s;
-{
- if (crlf) {
- printf("Will send carriage returns as telnet <CR><LF>.\r\n");
- } else {
- printf("Will send carriage returns as telnet <CR><NUL>.\r\n");
- }
- return 1;
-}
-
-int binmode;
-
- static int
-togbinary(val)
- int val;
-{
- donebinarytoggle = 1;
-
- if (val >= 0) {
- binmode = val;
- } else {
- if (my_want_state_is_will(TELOPT_BINARY) &&
- my_want_state_is_do(TELOPT_BINARY)) {
- binmode = 1;
- } else if (my_want_state_is_wont(TELOPT_BINARY) &&
- my_want_state_is_dont(TELOPT_BINARY)) {
- binmode = 0;
- }
- val = binmode ? 0 : 1;
- }
-
- if (val == 1) {
- if (my_want_state_is_will(TELOPT_BINARY) &&
- my_want_state_is_do(TELOPT_BINARY)) {
- printf("Already operating in binary mode with remote host.\r\n");
- } else {
- printf("Negotiating binary mode with remote host.\r\n");
- tel_enter_binary(3);
- }
- } else {
- if (my_want_state_is_wont(TELOPT_BINARY) &&
- my_want_state_is_dont(TELOPT_BINARY)) {
- printf("Already in network ascii mode with remote host.\r\n");
- } else {
- printf("Negotiating network ascii mode with remote host.\r\n");
- tel_leave_binary(3);
- }
- }
- return 1;
-}
-
- static int
-togrbinary(val)
- int val;
-{
- donebinarytoggle = 1;
-
- if (val == -1)
- val = my_want_state_is_do(TELOPT_BINARY) ? 0 : 1;
-
- if (val == 1) {
- if (my_want_state_is_do(TELOPT_BINARY)) {
- printf("Already receiving in binary mode.\r\n");
- } else {
- printf("Negotiating binary mode on input.\r\n");
- tel_enter_binary(1);
- }
- } else {
- if (my_want_state_is_dont(TELOPT_BINARY)) {
- printf("Already receiving in network ascii mode.\r\n");
- } else {
- printf("Negotiating network ascii mode on input.\r\n");
- tel_leave_binary(1);
- }
- }
- return 1;
-}
-
- static int
-togxbinary(val)
- int val;
-{
- donebinarytoggle = 1;
-
- if (val == -1)
- val = my_want_state_is_will(TELOPT_BINARY) ? 0 : 1;
-
- if (val == 1) {
- if (my_want_state_is_will(TELOPT_BINARY)) {
- printf("Already transmitting in binary mode.\r\n");
- } else {
- printf("Negotiating binary mode on output.\r\n");
- tel_enter_binary(2);
- }
- } else {
- if (my_want_state_is_wont(TELOPT_BINARY)) {
- printf("Already transmitting in network ascii mode.\r\n");
- } else {
- printf("Negotiating network ascii mode on output.\r\n");
- tel_leave_binary(2);
- }
- }
- return 1;
-}
-
-
-static int togglehelp (int);
-#if defined(AUTHENTICATION)
-extern int auth_togdebug (int);
-#endif
-
-struct togglelist {
- char *name; /* name of toggle */
- char *help; /* help message */
- int (*handler) /* routine to do actual setting */
- (int);
- int *variable;
- char *actionexplanation;
-};
-
-static struct togglelist Togglelist[] = {
- { "autoflush",
- "flushing of output when sending interrupt characters",
- 0,
- &autoflush,
- "flush output when sending interrupt characters" },
- { "autosynch",
- "automatic sending of interrupt characters in urgent mode",
- 0,
- &autosynch,
- "send interrupt characters in urgent mode" },
-#if defined(AUTHENTICATION)
- { "autologin",
- "automatic sending of login and/or authentication info",
- 0,
- &autologin,
- "send login name and/or authentication information" },
- { "authdebug",
- "Toggle authentication debugging",
- auth_togdebug,
- 0,
- "print authentication debugging information" },
-#endif
-#ifdef ENCRYPTION
- { "autoencrypt",
- "automatic encryption of data stream",
- EncryptAutoEnc,
- 0,
- "automatically encrypt output" },
- { "autodecrypt",
- "automatic decryption of data stream",
- EncryptAutoDec,
- 0,
- "automatically decrypt input" },
- { "verbose_encrypt",
- "Toggle verbose encryption output",
- EncryptVerbose,
- 0,
- "print verbose encryption output" },
- { "encdebug",
- "Toggle encryption debugging",
- EncryptDebug,
- 0,
- "print encryption debugging information" },
-#endif /* ENCRYPTION */
- { "skiprc",
- "don't read ~/.telnetrc file",
- 0,
- &skiprc,
- "skip reading of ~/.telnetrc file" },
- { "binary",
- "sending and receiving of binary data",
- togbinary,
- 0,
- 0 },
- { "inbinary",
- "receiving of binary data",
- togrbinary,
- 0,
- 0 },
- { "outbinary",
- "sending of binary data",
- togxbinary,
- 0,
- 0 },
- { "crlf",
- "sending carriage returns as telnet <CR><LF>",
- togcrlf,
- &crlf,
- 0 },
- { "crmod",
- "mapping of received carriage returns",
- 0,
- &crmod,
- "map carriage return on output" },
- { "localchars",
- "local recognition of certain control characters",
- lclchars,
- &localchars,
- "recognize certain control characters" },
- { " ", "", 0 }, /* empty line */
-#if defined(unix) && defined(TN3270)
- { "apitrace",
- "(debugging) toggle tracing of API transactions",
- 0,
- &apitrace,
- "trace API transactions" },
- { "cursesdata",
- "(debugging) toggle printing of hexadecimal curses data",
- 0,
- &cursesdata,
- "print hexadecimal representation of curses data" },
-#endif /* defined(unix) && defined(TN3270) */
- { "debug",
- "debugging",
- togdebug,
- &debug,
- "turn on socket level debugging" },
- { "netdata",
- "printing of hexadecimal network data (debugging)",
- 0,
- &netdata,
- "print hexadecimal representation of network traffic" },
- { "prettydump",
- "output of \"netdata\" to user readable format (debugging)",
- 0,
- &prettydump,
- "print user readable output for \"netdata\"" },
- { "options",
- "viewing of options processing (debugging)",
- 0,
- &showoptions,
- "show option processing" },
- { "termdata",
- "(debugging) toggle printing of hexadecimal terminal data",
- 0,
- &termdata,
- "print hexadecimal representation of terminal traffic" },
- { "?",
- 0,
- togglehelp },
- { "help",
- 0,
- togglehelp },
- { 0 }
-};
-
- static int
-togglehelp(n)
- int n;
-{
- struct togglelist *c;
-
- for (c = Togglelist; c->name; c++) {
- if (c->help) {
- if (*c->help)
- printf("%-15s toggle %s\r\n", c->name, c->help);
- else
- printf("\r\n");
- }
- }
- printf("\r\n");
- printf("%-15s %s\r\n", "?", "display help information");
- return 0;
-}
-
- static void
-settogglehelp(set)
- int set;
-{
- struct togglelist *c;
-
- for (c = Togglelist; c->name; c++) {
- if (c->help) {
- if (*c->help)
- printf("%-15s %s %s\r\n", c->name, set ? "enable" : "disable",
- c->help);
- else
- printf("\r\n");
- }
- }
-}
-
-#define GETTOGGLE(name) (struct togglelist *) \
- genget(name, (char **) Togglelist, sizeof(struct togglelist))
-
- static int
-toggle(argc, argv)
- int argc;
- char *argv[];
-{
- int retval = 1;
- char *name;
- struct togglelist *c;
-
- if (argc < 2) {
- fprintf(stderr,
- "Need an argument to 'toggle' command. 'toggle ?' for help.\n");
- return 0;
- }
- argc--;
- argv++;
- while (argc--) {
- name = *argv++;
- c = GETTOGGLE(name);
- if (Ambiguous(c)) {
- fprintf(stderr, "'%s': ambiguous argument ('toggle ?' for help).\n",
- name);
- return 0;
- } else if (c == 0) {
- fprintf(stderr, "'%s': unknown argument ('toggle ?' for help).\n",
- name);
- return 0;
- } else {
- if (c->variable) {
- *c->variable = !*c->variable; /* invert it */
- if (c->actionexplanation) {
- printf("%s %s.\r\n", *c->variable? "Will" : "Won't",
- c->actionexplanation);
- }
- }
- if (c->handler) {
- retval &= (*c->handler)(-1);
- }
- }
- }
- return retval;
-}
-\f
-/*
- * The following perform the "set" command.
- */
-
-#ifdef USE_TERMIO
-struct termio new_tc = { 0 };
-#endif
-
-struct setlist {
- char *name; /* name */
- char *help; /* help information */
- void (*handler)();
- cc_t *charp; /* where it is located at */
-};
-
-static struct setlist Setlist[] = {
-#ifdef KLUDGELINEMODE
- { "echo", "character to toggle local echoing on/off", 0, &echoc },
-#endif
- { "escape", "character to escape back to telnet command mode", 0, &escape },
- { "rlogin", "rlogin escape character", 0, &rlogin },
- { "tracefile", "file to write trace information to", SetNetTrace, (cc_t *)NetTraceFile},
- { " ", "" },
- { " ", "The following need 'localchars' to be toggled true", 0, 0 },
- { "flushoutput", "character to cause an Abort Output", 0, termFlushCharp },
- { "interrupt", "character to cause an Interrupt Process", 0, termIntCharp },
- { "quit", "character to cause an Abort process", 0, termQuitCharp },
- { "eof", "character to cause an EOF ", 0, termEofCharp },
- { " ", "" },
- { " ", "The following are for local editing in linemode", 0, 0 },
- { "erase", "character to use to erase a character", 0, termEraseCharp },
- { "kill", "character to use to erase a line", 0, termKillCharp },
- { "lnext", "character to use for literal next", 0, termLiteralNextCharp },
- { "susp", "character to cause a Suspend Process", 0, termSuspCharp },
- { "reprint", "character to use for line reprint", 0, termRprntCharp },
- { "worderase", "character to use to erase a word", 0, termWerasCharp },
- { "start", "character to use for XON", 0, termStartCharp },
- { "stop", "character to use for XOFF", 0, termStopCharp },
- { "forw1", "alternate end of line character", 0, termForw1Charp },
- { "forw2", "alternate end of line character", 0, termForw2Charp },
- { "ayt", "alternate AYT character", 0, termAytCharp },
- { 0 }
-};
-
-#if defined(CRAY) && !defined(__STDC__)
-/* Work around compiler bug in pcc 4.1.5 */
- void
-_setlist_init()
-{
-#ifndef KLUDGELINEMODE
-#define N 5
-#else
-#define N 6
-#endif
- Setlist[N+0].charp = &termFlushChar;
- Setlist[N+1].charp = &termIntChar;
- Setlist[N+2].charp = &termQuitChar;
- Setlist[N+3].charp = &termEofChar;
- Setlist[N+6].charp = &termEraseChar;
- Setlist[N+7].charp = &termKillChar;
- Setlist[N+8].charp = &termLiteralNextChar;
- Setlist[N+9].charp = &termSuspChar;
- Setlist[N+10].charp = &termRprntChar;
- Setlist[N+11].charp = &termWerasChar;
- Setlist[N+12].charp = &termStartChar;
- Setlist[N+13].charp = &termStopChar;
- Setlist[N+14].charp = &termForw1Char;
- Setlist[N+15].charp = &termForw2Char;
- Setlist[N+16].charp = &termAytChar;
-#undef N
-}
-#endif /* defined(CRAY) && !defined(__STDC__) */
-
- static struct setlist *
-getset(name)
- char *name;
-{
- return (struct setlist *)
- genget(name, (char **) Setlist, sizeof(struct setlist));
-}
-
- void
-set_escape_char(s)
- char *s;
-{
- if (rlogin != _POSIX_VDISABLE) {
- rlogin = (s && *s) ? special(s) : _POSIX_VDISABLE;
- printf("Telnet rlogin escape character is '%s'.\r\n",
- control(rlogin));
- } else {
- escape = (s && *s) ? special(s) : _POSIX_VDISABLE;
- printf("Telnet escape character is '%s'.\r\n", control(escape));
- }
-}
-
- static int
-setcmd(argc, argv)
- int argc;
- char *argv[];
-{
- int value;
- struct setlist *ct;
- struct togglelist *c;
-
- if (argc < 2 || argc > 3) {
- printf("Format is 'set Name Value'\n'set ?' for help.\r\n");
- return 0;
- }
- if ((argc == 2) && (isprefix(argv[1], "?") || isprefix(argv[1], "help"))) {
- for (ct = Setlist; ct->name; ct++)
- printf("%-15s %s\r\n", ct->name, ct->help);
- printf("\r\n");
- settogglehelp(1);
- printf("%-15s %s\r\n", "?", "display help information");
- return 0;
- }
-
- ct = getset(argv[1]);
- if (ct == 0) {
- c = GETTOGGLE(argv[1]);
- if (c == 0) {
- fprintf(stderr, "'%s': unknown argument ('set ?' for help).\n",
- argv[1]);
- return 0;
- } else if (Ambiguous(c)) {
- fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\n",
- argv[1]);
- return 0;
- }
- if (c->variable) {
- if ((argc == 2) || (strcmp("on", argv[2]) == 0))
- *c->variable = 1;
- else if (strcmp("off", argv[2]) == 0)
- *c->variable = 0;
- else {
- printf("Format is 'set togglename [on|off]'\n'set ?' for help.\r\n");
- return 0;
- }
- if (c->actionexplanation) {
- printf("%s %s.\r\n", *c->variable? "Will" : "Won't",
- c->actionexplanation);
- }
- }
- if (c->handler)
- (*c->handler)(1);
- } else if (argc != 3) {
- printf("Format is 'set Name Value'\n'set ?' for help.\r\n");
- return 0;
- } else if (Ambiguous(ct)) {
- fprintf(stderr, "'%s': ambiguous argument ('set ?' for help).\n",
- argv[1]);
- return 0;
- } else if (ct->handler) {
- (*ct->handler)(argv[2]);
- printf("%s set to \"%s\".\r\n", ct->name, (char *)ct->charp);
- } else {
- if (strcmp("off", argv[2])) {
- value = special(argv[2]);
- } else {
- value = _POSIX_VDISABLE;
- }
- *(ct->charp) = (cc_t)value;
- printf("%s character is '%s'.\r\n", ct->name, control(*(ct->charp)));
- }
- slc_check();
- return 1;
-}
-
- static int
-unsetcmd(argc, argv)
- int argc;
- char *argv[];
-{
- struct setlist *ct;
- struct togglelist *c;
- register char *name;
-
- if (argc < 2) {
- fprintf(stderr,
- "Need an argument to 'unset' command. 'unset ?' for help.\n");
- return 0;
- }
- if (isprefix(argv[1], "?") || isprefix(argv[1], "help")) {
- for (ct = Setlist; ct->name; ct++)
- printf("%-15s %s\r\n", ct->name, ct->help);
- printf("\r\n");
- settogglehelp(0);
- printf("%-15s %s\r\n", "?", "display help information");
- return 0;
- }
-
- argc--;
- argv++;
- while (argc--) {
- name = *argv++;
- ct = getset(name);
- if (ct == 0) {
- c = GETTOGGLE(name);
- if (c == 0) {
- fprintf(stderr, "'%s': unknown argument ('unset ?' for help).\n",
- name);
- return 0;
- } else if (Ambiguous(c)) {
- fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\n",
- name);
- return 0;
- }
- if (c->variable) {
- *c->variable = 0;
- if (c->actionexplanation) {
- printf("%s %s.\r\n", *c->variable? "Will" : "Won't",
- c->actionexplanation);
- }
- }
- if (c->handler)
- (*c->handler)(0);
- } else if (Ambiguous(ct)) {
- fprintf(stderr, "'%s': ambiguous argument ('unset ?' for help).\n",
- name);
- return 0;
- } else if (ct->handler) {
- (*ct->handler)(0);
- printf("%s reset to \"%s\".\r\n", ct->name, (char *)ct->charp);
- } else {
- *(ct->charp) = _POSIX_VDISABLE;
- printf("%s character is '%s'.\r\n", ct->name, control(*(ct->charp)));
- }
- }
- return 1;
-}
-\f
-/*
- * The following are the data structures and routines for the
- * 'mode' command.
- */
-#ifdef KLUDGELINEMODE
-extern int kludgelinemode;
-
- static int
-dokludgemode()
-{
- kludgelinemode = 1;
- send_wont(TELOPT_LINEMODE, 1);
- send_dont(TELOPT_SGA, 1);
- send_dont(TELOPT_ECHO, 1);
- return 1; /* I'm guessing here -- eichin -- XXX */
-}
-#endif
-
- static int
-dolinemode()
-{
-#ifdef KLUDGELINEMODE
- if (kludgelinemode)
- send_dont(TELOPT_SGA, 1);
-#endif
- send_will(TELOPT_LINEMODE, 1);
- send_dont(TELOPT_ECHO, 1);
- return 1;
-}
-
- static int
-docharmode()
-{
-#ifdef KLUDGELINEMODE
- if (kludgelinemode)
- send_do(TELOPT_SGA, 1);
- else
-#endif
- send_wont(TELOPT_LINEMODE, 1);
- send_do(TELOPT_ECHO, 1);
- return 1;
-}
-
- static int
-dolmmode(bit, on)
- int bit, on;
-{
- unsigned char c;
- extern int linemode;
-
- if (my_want_state_is_wont(TELOPT_LINEMODE)) {
- printf("?Need to have LINEMODE option enabled first.\r\n");
- printf("'mode ?' for help.\r\n");
- return 0;
- }
-
- if (on)
- c = (linemode | bit);
- else
- c = (linemode & ~bit);
- lm_mode(&c, 1, 1);
- return 1;
-}
-
-static int
-tel_setmode(bit)
- int bit;
-{
- return dolmmode(bit, 1);
-}
-
-static int
-tel_clearmode(bit)
- int bit;
-{
- return dolmmode(bit, 0);
-}
-
-struct modelist {
- char *name; /* command name */
- char *help; /* help string */
- int (*handler)(); /* routine which executes command */
- int needconnect; /* Do we need to be connected to execute? */
- int arg1;
-};
-
-static int modehelp(void);
-
-static struct modelist ModeList[] = {
- { "character", "Disable LINEMODE option", docharmode, 1 },
-#ifdef KLUDGELINEMODE
- { "", "(or disable obsolete line-by-line mode)", 0 },
-#endif
- { "line", "Enable LINEMODE option", dolinemode, 1 },
-#ifdef KLUDGELINEMODE
- { "", "(or enable obsolete line-by-line mode)", 0 },
-#endif
- { "", "", 0 },
- { "", "These require the LINEMODE option to be enabled", 0 },
- { "isig", "Enable signal trapping", tel_setmode, 1, MODE_TRAPSIG },
- { "+isig", 0, tel_setmode, 1, MODE_TRAPSIG },
- { "-isig", "Disable signal trapping", tel_clearmode, 1, MODE_TRAPSIG },
- { "edit", "Enable character editing", tel_setmode, 1, MODE_EDIT },
- { "+edit", 0, tel_setmode, 1, MODE_EDIT },
- { "-edit", "Disable character editing", tel_clearmode, 1, MODE_EDIT },
- { "softtabs", "Enable tab expansion", tel_setmode, 1, MODE_SOFT_TAB },
- { "+softtabs", 0, tel_setmode, 1, MODE_SOFT_TAB },
- { "-softtabs", "Disable character editing", tel_clearmode, 1, MODE_SOFT_TAB },
- { "litecho", "Enable literal character echo", tel_setmode, 1, MODE_LIT_ECHO },
- { "+litecho", 0, tel_setmode, 1, MODE_LIT_ECHO },
- { "-litecho", "Disable literal character echo", tel_clearmode, 1, MODE_LIT_ECHO },
- { "help", 0, modehelp, 0 },
-#ifdef KLUDGELINEMODE
- { "kludgeline", 0, dokludgemode, 1 },
-#endif
- { "", "", 0 },
- { "?", "Print help information", modehelp, 0 },
- { 0 },
-};
-
-
-static int
-modehelp()
-{
- struct modelist *mt;
-
- printf("format is: 'mode Mode', where 'Mode' is one of:\r\n\r\n");
- for (mt = ModeList; mt->name; mt++) {
- if (mt->help) {
- if (*mt->help)
- printf("%-15s %s\r\n", mt->name, mt->help);
- else
- printf("\r\n");
- }
- }
- return 0;
-}
-
-#define GETMODECMD(name) (struct modelist *) \
- genget(name, (char **) ModeList, sizeof(struct modelist))
-
- static int
-modecmd(argc, argv)
- int argc;
- char *argv[];
-{
- struct modelist *mt;
-
- if (argc != 2) {
- printf("'mode' command requires an argument\r\n");
- printf("'mode ?' for help.\r\n");
- } else if ((mt = GETMODECMD(argv[1])) == 0) {
- fprintf(stderr, "Unknown mode '%s' ('mode ?' for help).\n", argv[1]);
- } else if (Ambiguous(mt)) {
- fprintf(stderr, "Ambiguous mode '%s' ('mode ?' for help).\n", argv[1]);
- } else if (mt->needconnect && !connected) {
- printf("?Need to be connected first.\r\n");
- printf("'mode ?' for help.\r\n");
- } else if (mt->handler) {
- return (*mt->handler)(mt->arg1);
- }
- return 0;
-}
-\f
-/*
- * The following data structures and routines implement the
- * "display" command.
- */
-
- static int
-display(argc, argv)
- int argc;
- char *argv[];
-{
- struct togglelist *tl;
- struct setlist *sl;
-
-#define dotog(tl) if (tl->variable && tl->actionexplanation) { \
- if (*tl->variable) { \
- printf("will"); \
- } else { \
- printf("won't"); \
- } \
- printf(" %s.\r\n", tl->actionexplanation); \
- }
-
-#define doset(sl) if (sl->name && *sl->name != ' ') { \
- if (sl->handler == 0) \
- printf("%-15s [%s]\r\n", sl->name, control(*sl->charp)); \
- else \
- printf("%-15s \"%s\"\r\n", sl->name, (char *)sl->charp); \
- }
-
- if (argc == 1) {
- for (tl = Togglelist; tl->name; tl++) {
- dotog(tl);
- }
- printf("\r\n");
- for (sl = Setlist; sl->name; sl++) {
- doset(sl);
- }
- } else {
- int i;
-
- for (i = 1; i < argc; i++) {
- sl = getset(argv[i]);
- tl = GETTOGGLE(argv[i]);
- if (Ambiguous(sl) || Ambiguous(tl)) {
- printf("?Ambiguous argument '%s'.\r\n", argv[i]);
- return 0;
- } else if (!sl && !tl) {
- printf("?Unknown argument '%s'.\r\n", argv[i]);
- return 0;
- } else {
- if (tl) {
- dotog(tl);
- }
- if (sl) {
- doset(sl);
- }
- }
- }
- }
- /*@*/optionstatus();
-#ifdef ENCRYPTION
- EncryptStatus();
-#endif /* ENCRYPTION */
- return 1;
-#undef doset
-#undef dotog
-}
-\f
-/*
- * The following are the data structures, and many of the routines,
- * relating to command processing.
- */
-
-/*
- * Set the escape character.
- */
- static int
-setescape(argc, argv)
- int argc;
- char *argv[];
-{
- register char *arg;
- char buf[50];
-
- printf(
- "Deprecated usage - please use 'set escape%s%s' in the future.\r\n",
- (argc > 2)? " ":"", (argc > 2)? argv[1]: "");
- if (argc > 2)
- arg = argv[1];
- else {
- printf("new escape character: ");
- (void) fgets(buf, sizeof(buf), stdin);
- arg = buf;
- }
- if (arg[0] != '\0')
- escape = arg[0];
- if (!In3270) {
- printf("Escape character is '%s'.\r\n", control(escape));
- }
- (void) fflush(stdout);
- return 1;
-}
-
- /*VARARGS*/
- static int
-togcrmod(argc, argv)
- int argc;
- char **argv;
-{
- crmod = !crmod;
- printf("Deprecated usage - please use 'toggle crmod' in the future.\r\n");
- printf("%s map carriage return on output.\r\n", crmod ? "Will" : "Won't");
- (void) fflush(stdout);
- return 1;
-}
-
- /*VARARGS*/
-static int
-suspend(argc, argv)
- int argc;
- char **argv;
-{
-#ifdef SIGTSTP
- setcommandmode();
- {
- long oldrows, oldcols, newrows, newcols, err;
-
- err = (TerminalWindowSize(&oldrows, &oldcols) == 0) ? 1 : 0;
- (void) kill(0, SIGTSTP);
- /*
- * If we didn't get the window size before the SUSPEND, but we
- * can get them now (???), then send the NAWS to make sure that
- * we are set up for the right window size.
- */
- if (TerminalWindowSize(&newrows, &newcols) && connected &&
- (err || ((oldrows != newrows) || (oldcols != newcols)))) {
- sendnaws();
- }
- }
- /* reget parameters in case they were changed */
- TerminalSaveState();
- setconnmode(0);
-#else
- printf("Suspend is not supported. Try the '!' command instead\r\n");
-#endif
- return 1;
-}
-
-#if !defined(TN3270)
- /*ARGSUSED*/
-static int
-shell(argc, argv)
- int argc;
- char *argv[];
-{
- long oldrows, oldcols, newrows, newcols, err;
-
- setcommandmode();
-
- err = (TerminalWindowSize(&oldrows, &oldcols) == 0) ? 1 : 0;
- switch(vfork()) {
- case -1:
- perror("Fork failed");
- break;
-
- case 0:
- {
- /*
- * Fire up the shell in the child.
- */
- register char *shellp, *shellname;
-
- shellp = getenv("SHELL");
- if (shellp == NULL)
- shellp = "/bin/sh";
- if ((shellname = strrchr(shellp, '/')) == 0)
- shellname = shellp;
- else
- shellname++;
- if (argc > 1)
- execl(shellp, shellname, "-c", &saveline[1], (char *)NULL);
- else
- execl(shellp, shellname, (char *)NULL);
- perror("Execl");
- _exit(1);
- }
- default:
- (void)wait((int *)0); /* Wait for the shell to complete */
-
- if (TerminalWindowSize(&newrows, &newcols) && connected &&
- (err || ((oldrows != newrows) || (oldcols != newcols)))) {
- sendnaws();
- }
- break;
- }
- return 1;
-}
-#else /* !defined(TN3270) */
-extern int shell();
-#endif /* !defined(TN3270) */
-
-/*VARARGS*/
-static int
-bye(argc, argv)
- int argc; /* Number of arguments */
- char *argv[]; /* arguments */
-{
- extern int resettermname;
-
- if (connected) {
- (void) shutdown(net, 2);
- printf("Connection closed.\r\n");
- (void) NetClose(net);
- connected = 0;
- resettermname = 1;
-#if defined(AUTHENTICATION) || defined(ENCRYPTION)
- auth_encrypt_connect(connected);
-#endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */
- /* reset options */
- tninit();
-#if defined(TN3270)
- SetIn3270(); /* Get out of 3270 mode */
-#endif /* defined(TN3270) */
- }
- if ((argc != 2) || (strcmp(argv[1], "fromquit") != 0)) {
- longjmp(toplevel, 1);
- /* NOTREACHED */
- }
- return 1; /* Keep lint, etc., happy */
-}
-
-/*VARARGS*/
-int
-quit(argc, argv)
- int argc;
- char *argv[];
-{
- (void) call(bye, "bye", "fromquit", 0);
- Exit(0);
- /*NOTREACHED*/
- return 0;
-}
-
-/*VARARGS*/
-static int
-logout(argc, argv)
- int argc;
- char **argv;
-{
- send_do(TELOPT_LOGOUT, 1);
- (void) netflush();
- return 1;
-}
-
-\f
-/*
- * The SLC command.
- */
-
-struct slclist {
- char *name;
- char *help;
- void (*handler)();
- int arg;
-};
-
-static void slc_help(void);
-
-struct slclist SlcList[] = {
- { "export", "Use local special character definitions",
- slc_mode_export, 0 },
- { "import", "Use remote special character definitions",
- slc_mode_import, 1 },
- { "check", "Verify remote special character definitions",
- slc_mode_import, 0 },
- { "help", 0, slc_help, 0 },
- { "?", "Print help information", slc_help, 0 },
- { 0 },
-};
-
- static void
-slc_help()
-{
- struct slclist *c;
-
- for (c = SlcList; c->name; c++) {
- if (c->help) {
- if (*c->help)
- printf("%-15s %s\r\n", c->name, c->help);
- else
- printf("\r\n");
- }
- }
-}
-
-static struct slclist *
-getslc(name)
- char *name;
-{
- return (struct slclist *)
- genget(name, (char **) SlcList, sizeof(struct slclist));
-}
-
-static int
-slccmd(argc, argv)
- int argc;
- char *argv[];
-{
- struct slclist *c;
-
- if (argc != 2) {
- fprintf(stderr,
- "Need an argument to 'slc' command. 'slc ?' for help.\n");
- return 0;
- }
- c = getslc(argv[1]);
- if (c == 0) {
- fprintf(stderr, "'%s': unknown argument ('slc ?' for help).\n",
- argv[1]);
- return 0;
- }
- if (Ambiguous(c)) {
- fprintf(stderr, "'%s': ambiguous argument ('slc ?' for help).\n",
- argv[1]);
- return 0;
- }
- (*c->handler)(c->arg);
- slcstate();
- return 1;
-}
-\f
-/*
- * The ENVIRON command.
- */
-
-struct envlist {
- char *name;
- char *help;
- void (*handler)();
- int narg;
-};
-
-extern struct env_lst *
- env_define (unsigned char *, unsigned char *);
-extern void
- env_undefine (unsigned char *),
- env_export (unsigned char *),
- env_unexport (unsigned char *),
- env_send (unsigned char *),
-#if defined(OLD_ENVIRON) && defined(ENV_HACK)
- env_varval (unsigned char *),
-#endif
- env_list (void);
-static void
- env_help (void);
-
-struct envlist EnvList[] = {
- { "define", "Define an environment variable",
- (void (*)())env_define, 2 },
- { "undefine", "Undefine an environment variable",
- env_undefine, 1 },
- { "export", "Mark an environment variable for automatic export",
- env_export, 1 },
- { "unexport", "Don't mark an environment variable for automatic export",
- env_unexport, 1 },
- { "send", "Send an environment variable", env_send, 1 },
- { "list", "List the current environment variables",
- env_list, 0 },
-#if defined(OLD_ENVIRON) && defined(ENV_HACK)
- { "varval", "Reverse VAR and VALUE (auto, right, wrong, status)",
- env_varval, 1 },
-#endif
- { "help", 0, env_help, 0 },
- { "?", "Print help information", env_help, 0 },
- { 0 },
-};
-
- static void
-env_help()
-{
- struct envlist *c;
-
- for (c = EnvList; c->name; c++) {
- if (c->help) {
- if (*c->help)
- printf("%-15s %s\r\n", c->name, c->help);
- else
- printf("\r\n");
- }
- }
-}
-
- static struct envlist *
-getenvcmd(name)
- char *name;
-{
- return (struct envlist *)
- genget(name, (char **) EnvList, sizeof(struct envlist));
-}
-
-static int
-env_cmd(argc, argv)
- int argc;
- char *argv[];
-{
- struct envlist *c;
-
- if (argc < 2) {
- fprintf(stderr,
- "Need an argument to 'environ' command. 'environ ?' for help.\n");
- return 0;
- }
- c = getenvcmd(argv[1]);
- if (c == 0) {
- fprintf(stderr, "'%s': unknown argument ('environ ?' for help).\n",
- argv[1]);
- return 0;
- }
- if (Ambiguous(c)) {
- fprintf(stderr, "'%s': ambiguous argument ('environ ?' for help).\n",
- argv[1]);
- return 0;
- }
- if (c->narg + 2 != argc) {
- fprintf(stderr,
- "Need %s%d argument%s to 'environ %s' command. 'environ ?' for help.\n",
- c->narg < argc - 2 ? "only " : "",
- c->narg, c->narg == 1 ? "" : "s", c->name);
- return 0;
- }
- (*c->handler)(argv[2], argv[3]);
- return 1;
-}
-
-struct env_lst {
- struct env_lst *next; /* pointer to next structure */
- struct env_lst *prev; /* pointer to previous structure */
- unsigned char *var; /* pointer to variable name */
- unsigned char *value; /* pointer to variable value */
- int export; /* 1 -> export with default list of variables */
- int welldefined; /* A well defined variable */
-};
-
-struct env_lst envlisthead;
-
-static struct env_lst *
-env_find(var)
- unsigned char *var;
-{
- register struct env_lst *ep;
-
- for (ep = envlisthead.next; ep; ep = ep->next) {
- if (strcmp((char *)ep->var, (char *)var) == 0)
- return(ep);
- }
- return(NULL);
-}
-
- void
-env_init()
-{
- extern char **environ;
- char **epp, *cp;
- struct env_lst *ep;
-
- for (epp = environ; *epp; epp++) {
- if ((cp = strchr(*epp, '='))) {
- *cp = '\0';
- ep = env_define((unsigned char *)*epp,
- (unsigned char *)cp+1);
- ep->export = 0;
- *cp = '=';
- }
- }
- /*
- * Special case for DISPLAY variable. If it is ":0.0" or
- * "unix:0.0", we have to get rid of "unix" and insert our
- * hostname.
- */
- if ((ep = env_find("DISPLAY"))
- && ((*ep->value == ':')
- || (strncmp((char *)ep->value, "unix:", 5) == 0))) {
- char hbuf[256+1];
- char *cp2 = strchr((char *)ep->value, ':');
-
- gethostname(hbuf, 256);
- hbuf[256] = '\0';
- asprintf(&cp, "%s%s", hbuf, cp2);
- free(ep->value);
- ep->value = (unsigned char *)cp;
- }
- /*
- * If USER is not defined, but LOGNAME is, then add
- * USER with the value from LOGNAME. By default, we
- * don't export the USER variable.
- */
- if ((env_find("USER") == NULL) && (ep = env_find("LOGNAME"))) {
- env_define((unsigned char *)"USER", ep->value);
- env_unexport((unsigned char *)"USER");
- }
- env_export((unsigned char *)"DISPLAY");
- env_export((unsigned char *)"PRINTER");
-}
-
- struct env_lst *
-env_define(var, value)
- unsigned char *var, *value;
-{
- register struct env_lst *ep;
-
- if ((ep = env_find(var))) {
- if (ep->var)
- free(ep->var);
- if (ep->value)
- free(ep->value);
- } else {
- ep = (struct env_lst *)malloc(sizeof(struct env_lst));
- ep->next = envlisthead.next;
- envlisthead.next = ep;
- ep->prev = &envlisthead;
- if (ep->next)
- ep->next->prev = ep;
- }
- ep->welldefined = opt_welldefined((char *)var);
- ep->export = 1;
- ep->var = (unsigned char *)strdup((char *)var);
- ep->value = (unsigned char *)strdup((char *)value);
- return(ep);
-}
-
- void
-env_undefine(var)
- unsigned char *var;
-{
- register struct env_lst *ep;
-
- if ((ep = env_find(var))) {
- ep->prev->next = ep->next;
- if (ep->next)
- ep->next->prev = ep->prev;
- if (ep->var)
- free(ep->var);
- if (ep->value)
- free(ep->value);
- free(ep);
- }
-}
-
- void
-env_export(var)
- unsigned char *var;
-{
- register struct env_lst *ep;
-
- if ((ep = env_find(var)))
- ep->export = 1;
-}
-
- void
-env_unexport(var)
- unsigned char *var;
-{
- register struct env_lst *ep;
-
- if ((ep = env_find(var)))
- ep->export = 0;
-}
-
- void
-env_send(var)
- unsigned char *var;
-{
- register struct env_lst *ep;
-
- if (my_state_is_wont(TELOPT_NEW_ENVIRON)
-#ifdef OLD_ENVIRON
- && my_state_is_wont(TELOPT_OLD_ENVIRON)
-#endif
- ) {
- fprintf(stderr,
- "Cannot send '%s': Telnet ENVIRON option not enabled\n",
- var);
- return;
- }
- ep = env_find(var);
- if (ep == 0) {
- fprintf(stderr, "Cannot send '%s': variable not defined\n",
- var);
- return;
- }
- env_opt_start_info();
- env_opt_add(ep->var);
- env_opt_end(0);
-}
-
- void
-env_list()
-{
- register struct env_lst *ep;
-
- for (ep = envlisthead.next; ep; ep = ep->next) {
- printf("%c %-20s %s\r\n", ep->export ? '*' : ' ',
- ep->var, ep->value);
- }
-}
-
- unsigned char *
-env_default(init, welldefined)
- int init;
-{
- static struct env_lst *nep = NULL;
-
- if (init) {
- nep = &envlisthead;
- return NULL; /* guessing here too -- eichin -- XXX */
- }
- if (nep) {
- while ((nep = nep->next)) {
- if (nep->export && (nep->welldefined == welldefined))
- return(nep->var);
- }
- }
- return(NULL);
-}
-
- unsigned char *
-env_getvalue(var)
- unsigned char *var;
-{
- register struct env_lst *ep;
-
- if ((ep = env_find(var)))
- return(ep->value);
- return(NULL);
-}
-
- int
-env_is_exported(var)
- unsigned char *var;
-{
- register struct env_lst *ep;
-
- if ((ep = env_find(var)))
- return ep->export;
- return 0;
-}
-
-#if defined(OLD_ENVIRON) && defined(ENV_HACK)
- void
-env_varval(what)
- unsigned char *what;
-{
- extern int old_env_var, old_env_value, env_auto;
- unsigned int len = strlen((char *)what);
-
- if (len == 0)
- goto unknown;
-
- if (strncasecmp((char *)what, "status", len) == 0) {
- if (env_auto)
- printf("%s%s", "VAR and VALUE are/will be ",
- "determined automatically\r\n");
- if (old_env_var == OLD_ENV_VAR)
- printf("VAR and VALUE set to correct definitions\r\n");
- else
- printf("VAR and VALUE definitions are reversed\r\n");
- } else if (strncasecmp((char *)what, "auto", len) == 0) {
- env_auto = 1;
- old_env_var = OLD_ENV_VALUE;
- old_env_value = OLD_ENV_VAR;
- } else if (strncasecmp((char *)what, "right", len) == 0) {
- env_auto = 0;
- old_env_var = OLD_ENV_VAR;
- old_env_value = OLD_ENV_VALUE;
- } else if (strncasecmp((char *)what, "wrong", len) == 0) {
- env_auto = 0;
- old_env_var = OLD_ENV_VALUE;
- old_env_value = OLD_ENV_VAR;
- } else {
-unknown:
- printf("Unknown \"varval\" command. (\"auto\", \"right\", \"wrong\", \"status\")\r\n");
- }
-}
-#endif
-
-#if defined(AUTHENTICATION)
-/*
- * The AUTHENTICATE command.
- */
-
-struct authlist {
- char *name;
- char *help;
- int (*handler)();
- int narg;
-};
-
-extern int
- auth_enable (char *),
- auth_disable (char *),
- auth_status (void);
-static int
- auth_help (void);
-
-struct authlist AuthList[] = {
- { "status", "Display current status of authentication information",
- auth_status, 0 },
- { "disable", "Disable an authentication type ('auth disable ?' for more)",
- auth_disable, 1 },
- { "enable", "Enable an authentication type ('auth enable ?' for more)",
- auth_enable, 1 },
- { "help", 0, auth_help, 0 },
- { "?", "Print help information", auth_help, 0 },
- { 0 },
-};
-
- static int
-auth_help()
-{
- struct authlist *c;
-
- for (c = AuthList; c->name; c++) {
- if (c->help) {
- if (*c->help)
- printf("%-15s %s\r\n", c->name, c->help);
- else
- printf("\r\n");
- }
- }
- return 0;
-}
-
-int
-auth_cmd(argc, argv)
- int argc;
- char *argv[];
-{
- struct authlist *c;
-
- if (argc < 2) {
- fprintf(stderr,
- "Need an argument to 'auth' command. 'auth ?' for help.\n");
- return 0;
- }
-
- c = (struct authlist *)
- genget(argv[1], (char **) AuthList, sizeof(struct authlist));
- if (c == 0) {
- fprintf(stderr, "'%s': unknown argument ('auth ?' for help).\n",
- argv[1]);
- return 0;
- }
- if (Ambiguous(c)) {
- fprintf(stderr, "'%s': ambiguous argument ('auth ?' for help).\n",
- argv[1]);
- return 0;
- }
- if (c->narg + 2 != argc) {
- fprintf(stderr,
- "Need %s%d argument%s to 'auth %s' command. 'auth ?' for help.\n",
- c->narg < argc + 2 ? "only " : "",
- c->narg, c->narg == 1 ? "" : "s", c->name);
- return 0;
- }
- return((*c->handler)(argv[2], argv[3]));
-}
-#endif
-
-#ifdef ENCRYPTION
-/*
- * The ENCRYPT command.
- */
-
-struct encryptlist {
- char *name;
- char *help;
- int (*handler)();
- int needconnect;
- int minarg;
- int maxarg;
-};
-
-extern int
- EncryptEnable (char *, char *),
- EncryptDisable (char *, char *),
- EncryptType (char *, char *),
- EncryptStart (char *),
- EncryptStartInput (void),
- EncryptStartOutput (void),
- EncryptStop (char *),
- EncryptStopInput (void),
- EncryptStopOutput (void),
- EncryptStatus (void);
-static int
- EncryptHelp (void);
-
-struct encryptlist EncryptList[] = {
- { "enable", "Enable encryption. ('encrypt enable ?' for more)",
- EncryptEnable, 1, 1, 2 },
- { "disable", "Disable encryption. ('encrypt enable ?' for more)",
- EncryptDisable, 0, 1, 2 },
- { "type", "Set encryption type. ('encrypt type ?' for more)",
- EncryptType, 0, 1, 1 },
- { "start", "Start encryption. ('encrypt start ?' for more)",
- EncryptStart, 1, 0, 1 },
- { "stop", "Stop encryption. ('encrypt stop ?' for more)",
- EncryptStop, 1, 0, 1 },
- { "input", "Start encrypting the input stream",
- EncryptStartInput, 1, 0, 0 },
- { "-input", "Stop encrypting the input stream",
- EncryptStopInput, 1, 0, 0 },
- { "output", "Start encrypting the output stream",
- EncryptStartOutput, 1, 0, 0 },
- { "-output", "Stop encrypting the output stream",
- EncryptStopOutput, 1, 0, 0 },
-
- { "status", "Display current status of authentication information",
- EncryptStatus, 0, 0, 0 },
- { "help", 0, EncryptHelp, 0, 0, 0 },
- { "?", "Print help information", EncryptHelp, 0, 0, 0 },
- { 0 },
-};
-
- static int
-EncryptHelp()
-{
- struct encryptlist *c;
-
- for (c = EncryptList; c->name; c++) {
- if (c->help) {
- if (*c->help)
- printf("%-15s %s\r\n", c->name, c->help);
- else
- printf("\r\n");
- }
- }
- return 0;
-}
-
-int
-encrypt_cmd(argc, argv)
- int argc;
- char *argv[];
-{
- struct encryptlist *c;
-
- if (argc < 2) {
- fprintf(stderr,
- "Need an argument to 'encrypt' command. 'encrypt ?' for help.\n");
- return 0;
- }
-
- c = (struct encryptlist *)
- genget(argv[1], (char **) EncryptList, sizeof(struct encryptlist));
- if (c == 0) {
- fprintf(stderr, "'%s': unknown argument ('encrypt ?' for help).\n",
- argv[1]);
- return 0;
- }
- if (Ambiguous(c)) {
- fprintf(stderr, "'%s': ambiguous argument ('encrypt ?' for help).\n",
- argv[1]);
- return 0;
- }
- argc -= 2;
- if (argc < c->minarg || argc > c->maxarg) {
- if (c->minarg == c->maxarg) {
- fprintf(stderr, "Need %s%d argument%s ",
- c->minarg < argc ? "only " : "", c->minarg,
- c->minarg == 1 ? "" : "s");
- } else {
- fprintf(stderr, "Need %s%d-%d arguments ",
- c->maxarg < argc ? "only " : "", c->minarg, c->maxarg);
- }
- fprintf(stderr, "to 'encrypt %s' command. 'encrypt ?' for help.\n",
- c->name);
- return 0;
- }
- if (c->needconnect && !connected) {
- if (!(argc && (isprefix(argv[2], "help") || isprefix(argv[2], "?")))) {
- printf("?Need to be connected first.\r\n");
- return 0;
- }
- }
- return ((*c->handler)(argc > 0 ? argv[2] : 0,
- argc > 1 ? argv[3] : 0,
- argc > 2 ? argv[4] : 0));
-}
-#endif /* ENCRYPTION */
-
-#if defined(FORWARD)
-
-/*
- * The FORWARD command.
- */
-
-
-extern int forward_flags;
-
-struct forwlist {
- char *name;
- char *help;
- int (*handler)();
- int f_flags;
-};
-
-static int
- forw_status (void),
- forw_set (int),
- forw_help (void);
-
-struct forwlist ForwList[] = {
- { "status", "Display current status of credential forwarding",
- forw_status, 0 },
- { "disable", "Disable credential forwarding",
- forw_set, 0 },
- { "enable", "Enable credential forwarding",
- forw_set,
- OPTS_FORWARD_CREDS },
- { "forwardable", "Enable credential forwarding of forwardable credentials",
- forw_set,
- OPTS_FORWARD_CREDS |
- OPTS_FORWARDABLE_CREDS },
- { "help", 0, forw_help, 0 },
- { "?", "Print help information", forw_help, 0 },
- { 0 },
-};
-
- static int
-forw_status()
-{
- if (forward_flags & OPTS_FORWARD_CREDS) {
- if (forward_flags & OPTS_FORWARDABLE_CREDS) {
- printf("Credential forwarding of forwardable credentials enabled\n");
- } else {
- printf("Credential forwarding enabled\n");
- }
- } else {
- printf("Credential forwarding disabled\n");
- }
- return(0);
-}
-
-int
-forw_set(f_flags)
- int f_flags;
-{
- forward_flags = f_flags;
- return(0);
-}
-
-static int
-forw_help()
-{
- struct forwlist *c;
-
- for (c = ForwList; c->name; c++) {
- if (c->help) {
- if (*c->help)
- printf("%-15s %s\n", c->name, c->help);
- else
- printf("\n");
- }
- }
- return 0;
-}
-
-static int
-forw_cmd(argc, argv)
- int argc;
- char *argv[];
-{
- struct forwlist *c;
-
- if (argc < 2) {
- fprintf(stderr,
- "Need an argument to 'forward' command. 'forward ?' for help.\n");
- return 0;
- }
-
- c = (struct forwlist *)
- genget(argv[1], (char **) ForwList, sizeof(struct forwlist));
- if (c == 0) {
- fprintf(stderr, "'%s': unknown argument ('forw ?' for help).\n",
- argv[1]);
- return 0;
- }
- if (Ambiguous(c)) {
- fprintf(stderr, "'%s': ambiguous argument ('forw ?' for help).\n",
- argv[1]);
- return 0;
- }
- if (argc != 2) {
- fprintf(stderr,
- "No arguments needed to 'forward %s' command. 'forward ?' for help.\n",
- c->name);
- return 0;
- }
- return((*c->handler)(c->f_flags));
-}
-#endif
-
-#if defined(unix) && defined(TN3270)
- static void
-filestuff(fd)
- int fd;
-{
- int res;
-
-#ifdef F_GETOWN
- setconnmode(0);
- res = fcntl(fd, F_GETOWN, 0);
- setcommandmode();
-
- if (res == -1) {
- perror("fcntl");
- return;
- }
- printf("\tOwner is %d.\r\n", res);
-#endif
-
- setconnmode(0);
- res = fcntl(fd, F_GETFL, 0);
- setcommandmode();
-
- if (res == -1) {
- perror("fcntl");
- return;
- }
-#ifdef notdef
- printf("\tFlags are 0x%x: %s\r\n", res, decodeflags(res));
-#endif
-}
-#endif /* defined(unix) && defined(TN3270) */
-
-/*
- * Print status about the connection.
- */
- /*ARGSUSED*/
-static int
-status(argc, argv)
- int argc;
- char *argv[];
-{
- if (connected) {
- printf("Connected to %s (%s).\r\n", hostname, hostaddrstring);
- if ((argc < 2) || strcmp(argv[1], "notmuch")) {
- int mode = getconnmode();
-
- if (my_want_state_is_will(TELOPT_LINEMODE)) {
- printf("Operating with LINEMODE option\r\n");
- printf("%s line editing\r\n", (mode&MODE_EDIT) ? "Local" : "No");
- printf("%s catching of signals\r\n",
- (mode&MODE_TRAPSIG) ? "Local" : "No");
- slcstate();
-#ifdef KLUDGELINEMODE
- } else if (kludgelinemode && my_want_state_is_dont(TELOPT_SGA)) {
- printf("Operating in obsolete linemode\r\n");
-#endif
- } else {
- printf("Operating in single character mode\r\n");
- if (localchars)
- printf("Catching signals locally\r\n");
- }
- printf("%s character echo\r\n", (mode&MODE_ECHO) ? "Local" : "Remote");
- if (my_want_state_is_will(TELOPT_LFLOW))
- printf("%s flow control\r\n", (mode&MODE_FLOW) ? "Local" : "No");
-#ifdef ENCRYPTION
- encrypt_display();
-#endif /* ENCRYPTION */
- }
- } else {
- printf("No connection.\r\n");
- }
-# if !defined(TN3270)
- printf("Escape character is '%s'.\r\n", control(escape));
- (void) fflush(stdout);
-# else /* !defined(TN3270) */
- if ((!In3270) && ((argc < 2) || strcmp(argv[1], "notmuch"))) {
- printf("Escape character is '%s'.\r\n", control(escape));
- }
-# if defined(unix)
- if ((argc >= 2) && !strcmp(argv[1], "everything")) {
- printf("SIGIO received %d time%s.\r\n",
- sigiocount, (sigiocount == 1)? "":"s");
- if (In3270) {
- printf("Process ID %d, process group %d.\r\n",
- getpid(), getpgrp(getpid()));
- printf("Terminal input:\r\n");
- filestuff(tin);
- printf("Terminal output:\r\n");
- filestuff(tout);
- printf("Network socket:\r\n");
- filestuff(net);
- }
- }
- if (In3270 && transcom) {
- printf("Transparent mode command is '%s'.\r\n", transcom);
- }
-# endif /* defined(unix) */
- (void) fflush(stdout);
- if (In3270) {
- return 0;
- }
-# endif /* defined(TN3270) */
- return 1;
-}
-
-#ifdef SIGINFO
-/*
- * Function that gets called when SIGINFO is received.
- */
-#if defined(CRAY) || (defined(USE_TERMIO) && !defined(SYSV_TERMIO))
-void
-ayt_status()
-{
- (void) call(status, "status", "notmuch", 0);
-}
-#else
-int
-ayt_status()
-{
- (void) call(status, "status", "notmuch", 0);
- return 0;
-}
-#endif
-#endif
-
- int
-tn(argc, argv)
- int argc;
- char *argv[];
-{
-#if defined(IP_OPTIONS) && defined(IPPROTO_IP)
- char *srp = 0;
- int srlen;
-#endif
- char *cmd, *hostp = 0, *portp = 0, *volatile user = 0;
- struct addrinfo *addrs = 0, *addrp;
- struct addrinfo hints;
- int error;
-
- if (connected) {
- printf("?Already connected to %s\r\n", hostname);
- return 0;
- }
- if (argc < 2) {
- (void) strlcpy(line, "open ", sizeof(line));
- printf("(to) ");
- (void) fgets(&line[strlen(line)], (int) (sizeof(line) - strlen(line)),
- stdin);
- makeargv();
- argc = margc;
- argv = margv;
- }
- cmd = *argv;
- --argc; ++argv;
- while (argc) {
- if (isprefix(*argv, "?"))
- goto usage;
- if (strcmp(*argv, "-l") == 0) {
- --argc; ++argv;
- if (argc == 0)
- goto usage;
- user = *argv++;
- --argc;
- continue;
- }
- if (strcmp(*argv, "-a") == 0) {
- --argc; ++argv;
- autologin = 1;
- continue;
- }
- if (hostp == 0) {
- hostp = *argv++;
- --argc;
- continue;
- }
- if (portp == 0) {
- portp = *argv++;
- --argc;
- continue;
- }
- usage:
- printf("usage: %s [-l user] [-a] host-name [port]\r\n", cmd);
- return 0;
- }
- if (hostp == 0)
- goto usage;
-
- if (portp) {
- if (*portp == '-') {
- portp++;
- telnetport = 1;
- } else
- telnetport = 0;
- } else {
- portp = "telnet";
- telnetport = 1;
- }
-
-#if defined(IP_OPTIONS) && defined(IPPROTO_IP)
- if (hostp[0] == '@' || hostp[0] == '!') {
- static struct sockaddr_in sr_sin4;
- static struct addrinfo sr_addr;
- unsigned long temp;
- if ((hostname = strrchr(hostp, ':')) == NULL)
- hostname = strrchr(hostp, '@');
- hostname++;
- srp = 0;
- temp = sourceroute(hostp, &srp, &srlen);
- if (temp == 0) {
- herror(srp);
- return 0;
- } else if (temp == -1) {
- printf("Bad source route option: %s\r\n", hostp);
- return 0;
- } else {
- sr_sin4.sin_addr.s_addr = temp;
- sr_sin4.sin_family = AF_INET;
-#ifdef HAVE_SA_LEN
- sr_sin4.sin_len = sizeof (sr_sin4);
-#endif
- sr_addr.ai_family = AF_INET;
- sr_addr.ai_addrlen = sizeof (sr_sin4);
- sr_addr.ai_addr = (struct sockaddr *) &sr_sin4;
- sr_addr.ai_next = 0;
- sr_addr.ai_canonname = hostname;
- addrs = &sr_addr;
- }
- } else {
-#endif
- memset (&hints, 0, sizeof (hints));
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_family = PF_UNSPEC;
-
-
- /* The GNU Libc (Red Hat Linux 6.1, on x86, which MIT is using
- at this time) implementation seems to completely ignore
- AI_NUMERICHOST, and contacts DNS anyways. But other
- versions will not, and we do want to treat the two cases a
- little differently. */
-#ifdef AF_INET6
-#define IS_NUMERIC_ADDR(P) \
- ('\0' == (P)[strspn((P), (strchr((P),':') ? "abcdefABCDEF:0123456789." : "0123456789."))])
-#else
-#define IS_NUMERIC_ADDR(P) \
- ('\0' == (P)[strspn((P), "0123456789.")])
-#endif
- if (! IS_NUMERIC_ADDR (hostp))
- goto not_numeric;
-
-
- hints.ai_flags = AI_NUMERICHOST;
- error = getaddrinfo (hostp, portp, &hints, &addrs);
- if (error == 0) {
- if (getnameinfo (addrs->ai_addr, addrs->ai_addrlen,
- _hostname, sizeof(_hostname), 0, 0, NI_NAMEREQD) != 0)
- strncpy(_hostname, hostp, sizeof (_hostname));
- hostname = _hostname;
- } else {
- not_numeric:
- hints.ai_flags = AI_CANONNAME;
- error = getaddrinfo (hostp, portp, &hints, &addrs);
- if (error == 0) {
-
- /* Stupid glibc lossage again. */
- if (! IS_NUMERIC_ADDR (addrs->ai_canonname)) {
- strncpy(_hostname, addrs->ai_canonname, sizeof(_hostname));
- } else {
- fprintf (stderr,
- "telnet: system library bug? getaddrinfo returns numeric address\n"
- "\tas canonical name of %s\n",
- hostp);
- strncpy(_hostname, hostp, sizeof (_hostname));
- }
-
- } else {
- strncpy(_hostname, hostp, sizeof (_hostname));
- }
- hostname = _hostname;
- }
- if (error) {
- fprintf (stderr, "%s/%s: %s\n", hostp, portp, gai_strerror (error));
- return 0;
- }
-#if defined(IP_OPTIONS) && defined(IPPROTO_IP)
- }
-#endif
- for (addrp = addrs; addrp && !connected; addrp = addrp->ai_next) {
- error = getnameinfo (addrp->ai_addr, addrp->ai_addrlen,
- hostaddrstring, sizeof (hostaddrstring),
- (char *) NULL, 0, NI_NUMERICHOST);
- if (error) {
- fprintf (stderr, "getnameinfo() error printing address: %s\n",
- gai_strerror (error));
- strlcpy (hostaddrstring, "[address unprintable]",
- sizeof(hostaddrstring));
- }
- printf("Trying %s...\r\n", hostaddrstring);
-#if defined(IP_OPTIONS) && defined(IPPROTO_IP)
- if (srp && addrp->ai_family != AF_INET) {
- printf ("source routing not supported (yet) for address family,"
- " trying another address\n");
- continue;
- }
-#endif
- net = socket(addrp->ai_family, SOCK_STREAM, 0);
- if (net < 0) {
- perror("telnet: socket");
- continue;
- }
-#if defined(IP_OPTIONS) && defined(IPPROTO_IP)
- if (srp) {
- if (addrp->ai_family != AF_INET)
- printf ("source routing not supported (yet)"
- " for address family\n");
- else if (setsockopt(net, IPPROTO_IP, IP_OPTIONS,
- (char *)srp, srlen) < 0)
- perror("setsockopt (IP_OPTIONS)");
- }
-#endif
-#if defined(IPPROTO_IP) && defined(IP_TOS)
- if (addrp->ai_family == AF_INET) {
-# if defined(HAVE_GETTOSBYNAME)
- struct tosent *tp;
- if (tos < 0 && (tp = gettosbyname("telnet", "tcp")))
- tos = tp->t_tos;
-# endif
- if (tos < 0)
- tos = 020; /* Low Delay bit */
- if (tos
- && (setsockopt(net, IPPROTO_IP, IP_TOS,
- (char *)&tos, sizeof(int)) < 0)
- && (errno != ENOPROTOOPT))
- perror("telnet: setsockopt (IP_TOS) (ignored)");
- }
-#endif /* defined(IPPROTO_IP) && defined(IP_TOS) */
-
- if (debug && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 1) < 0) {
- perror("setsockopt (SO_DEBUG)");
- }
-
- if (connect(net, addrp->ai_addr, addrp->ai_addrlen) < 0) {
- if (hostaddrstring[0]) {
- fprintf(stderr, "telnet: connect to address %s: %s\n",
- hostaddrstring, strerror (errno));
- (void) NetClose(net);
- continue;
- }
- }
- connected++;
-
-#if defined(AUTHENTICATION) || defined(ENCRYPTION)
- auth_encrypt_connect(connected);
-#endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */
- }
- if (!connected) {
- perror("telnet: Unable to connect to remote host");
- return 0;
- }
- if (user)
- user = strdup(user);
- if (hostp)
- hostp = strdup(hostp);
- cmdrc(hostp, hostname);
- if (hostp)
- free(hostp);
- if (autologin && user == NULL) {
- struct passwd *pw;
-
- user = getenv("USER");
- if (user == NULL ||
- ((pw = getpwnam(user)) && pw->pw_uid != getuid())) {
- pw = getpwuid(getuid());
- if (pw)
- user = pw->pw_name;
- else
- user = NULL;
- }
- if (user)
- user = strdup(user);
- }
- if (user) {
- env_define((unsigned char *)"USER", (unsigned char *)user);
- env_export((unsigned char *)"USER");
- }
- (void) call(status, "status", "notmuch", 0);
- if (setjmp(peerdied) == 0)
- telnet(user);
- if (user)
- free(user);
- (void) NetClose(net);
- ExitString("Connection closed by foreign host.\r\n",1);
- /*NOTREACHED*/
- return 0;
-}
-
-#define HELPINDENT ((int) sizeof ("connect"))
-
-static char
- openhelp[] = "connect to a site",
- closehelp[] = "close current connection",
- logouthelp[] = "forcibly logout remote user and close the connection",
- quithelp[] = "exit telnet",
- statushelp[] = "print status information",
- helphelp[] = "print help information",
- sendhelp[] = "transmit special characters ('send ?' for more)",
- sethelp[] = "set operating parameters ('set ?' for more)",
- unsethelp[] = "unset operating parameters ('unset ?' for more)",
- togglestring[] ="toggle operating parameters ('toggle ?' for more)",
- slchelp[] = "change state of special charaters ('slc ?' for more)",
- displayhelp[] = "display operating parameters",
-#if defined(TN3270) && defined(unix)
- transcomhelp[] = "specify Unix command for transparent mode pipe",
-#endif /* defined(TN3270) && defined(unix) */
-#if defined(AUTHENTICATION)
- authhelp[] = "turn on (off) authentication ('auth ?' for more)",
-#endif
-#ifdef ENCRYPTION
- encrypthelp[] = "turn on (off) encryption ('encrypt ?' for more)",
-#endif /* ENCRYPTION */
-#ifdef FORWARD
- forwardhelp[] = "turn on (off) credential forwarding ('forward ?' for more)",
-#endif
-#if defined(unix)
- zhelp[] = "suspend telnet",
-#endif /* defined(unix) */
- shellhelp[] = "invoke a subshell",
- envhelp[] = "change environment variables ('environ ?' for more)",
- modestring[] = "try to enter line or character mode ('mode ?' for more)";
-
-static int help();
-
-static Command cmdtab[] = {
- { "close", closehelp, bye, 1 },
- { "logout", logouthelp, logout, 1 },
- { "display", displayhelp, display, 0 },
- { "mode", modestring, modecmd, 0 },
- { "open", openhelp, tn, 0 },
- { "quit", quithelp, quit, 0 },
- { "send", sendhelp, sendcmd, 0 },
- { "set", sethelp, setcmd, 0 },
- { "unset", unsethelp, unsetcmd, 0 },
- { "status", statushelp, status, 0 },
- { "toggle", togglestring, toggle, 0 },
- { "slc", slchelp, slccmd, 0 },
-#if defined(TN3270) && defined(unix)
- { "transcom", transcomhelp, settranscom, 0 },
-#endif /* defined(TN3270) && defined(unix) */
-#if defined(AUTHENTICATION)
- { "auth", authhelp, auth_cmd, 0 },
-#endif
-#ifdef ENCRYPTION
- { "encrypt", encrypthelp, encrypt_cmd, 0 },
-#endif /* ENCRYPTION */
-#ifdef FORWARD
- { "forward", forwardhelp, forw_cmd, 0 },
-#endif
-#if defined(unix)
- { "z", zhelp, suspend, 0 },
-#endif /* defined(unix) */
-#if defined(TN3270)
- { "!", shellhelp, shell, 1 },
-#else
- { "!", shellhelp, shell, 0 },
-#endif
- { "environ", envhelp, env_cmd, 0 },
- { "?", helphelp, help, 0 },
- { 0, 0, 0, 0 }
-};
-
-static char crmodhelp[] = "deprecated command -- use 'toggle crmod' instead";
-static char escapehelp[] = "deprecated command -- use 'set escape' instead";
-
-static Command cmdtab2[] = {
- { "help", 0, help, 0 },
- { "escape", escapehelp, setescape, 0 },
- { "crmod", crmodhelp, togcrmod, 0 },
- { 0, 0, 0, 0 }
-};
-
-
-/*
- * Call routine with argc, argv set from args (terminated by 0).
- */
-
- /*VARARGS1*/
-static int
-#ifdef HAVE_STDARG_H
-call(intrtn_t routine, ...)
-#else
-call(routine, va_alist)
- intrtn_t routine;
- va_dcl
-#endif
-{
- va_list ap;
- char *args[100];
- int argno = 0;
-
-#ifdef HAVE_STDARG_H
- va_start(ap, routine);
-#else
- va_start(ap);
-#endif
-
- while ((args[argno++] = va_arg(ap, char *)) != 0) {
- ;
- }
- va_end(ap);
- return (*routine)(argno-1, args);
-}
-
-
- static Command *
-getcmd(name)
- char *name;
-{
- Command *cm;
-
- if ((cm = (Command *) genget(name, (char **) cmdtab, sizeof(Command))))
- return cm;
- return (Command *) genget(name, (char **) cmdtab2, sizeof(Command));
-}
-
- void
-command(top, tbuf, cnt)
- int top;
- char *tbuf;
- int cnt;
-{
- register Command *c;
-
- setcommandmode();
- if (!top) {
- putchar('\n');
-#if defined(unix)
- } else {
- (void) signal(SIGINT, SIG_DFL);
- (void) signal(SIGQUIT, SIG_DFL);
-#endif /* defined(unix) */
- }
- for (;;) {
- if (rlogin == _POSIX_VDISABLE)
- printf("%s> ", prompt);
- if (tbuf) {
- register char *cp;
- cp = line;
- while (cnt > 0 && (*cp++ = *tbuf++) != '\n')
- cnt--;
- tbuf = 0;
- if (cp == line || *--cp != '\n' || cp == line)
- goto getline;
- *cp = '\0';
- if (rlogin == _POSIX_VDISABLE)
- printf("%s\r\n", line);
- } else {
- getline:
- if (rlogin != _POSIX_VDISABLE)
- printf("%s> ", prompt);
- if (fgets(line, sizeof(line), stdin) == NULL) {
- if (feof(stdin) || ferror(stdin)) {
- (void) quit(0, NULL);
- /*NOTREACHED*/
- }
- break;
- }
- }
- if (line[0] == 0)
- break;
- makeargv();
- if (margv[0] == 0) {
- break;
- }
- c = getcmd(margv[0]);
- if (Ambiguous(c)) {
- printf("?Ambiguous command\r\n");
- continue;
- }
- if (c == 0) {
- printf("?Invalid command\r\n");
- continue;
- }
- if (c->needconnect && !connected) {
- printf("?Need to be connected first.\r\n");
- continue;
- }
- if ((*c->handler)(margc, margv)) {
- break;
- }
- }
- if (!top) {
- if (!connected) {
- longjmp(toplevel, 1);
- /*NOTREACHED*/
- }
-#if defined(TN3270)
- if (shell_active == 0) {
- setconnmode(0);
- }
-#else /* defined(TN3270) */
- setconnmode(0);
-#endif /* defined(TN3270) */
- }
-}
-\f
-/*
- * Help command.
- */
-static int
-help(argc, argv)
- int argc;
- char *argv[];
-{
- register Command *c;
-
- if (argc == 1) {
- printf("Commands may be abbreviated. Commands are:\r\n\r\n");
- for (c = cmdtab; c->name; c++)
- if (c->help) {
- printf("%-*s\t%s\r\n", HELPINDENT, c->name,
- c->help);
- }
- return 0;
- }
- while (--argc > 0) {
- register char *arg;
- arg = *++argv;
- c = getcmd(arg);
- if (Ambiguous(c))
- printf("?Ambiguous help command %s\r\n", arg);
- else if (c == (Command *)0)
- printf("?Invalid help command %s\r\n", arg);
- else
- printf("%s\r\n", c->help);
- }
- return 0;
-}
-
-static char *rcname = 0;
-static char rcbuf[128];
-
-void
-cmdrc(m1, m2)
- char *m1, *m2;
-{
- register Command *c;
- FILE *rcfile;
- int gotmachine = 0;
- unsigned int l1 = strlen(m1);
- unsigned int l2 = strlen(m2);
- char m1save[64];
-
- if (skiprc)
- return;
-
- strncpy(m1save, m1, sizeof(m1save) - 1);
- m1save[sizeof(m1save) - 1] = '\0';
- m1 = m1save;
-
- if (rcname == 0) {
- rcname = getenv("HOME");
- if (rcname)
- strncpy(rcbuf, rcname, sizeof(rcbuf) - 1);
- else
- rcbuf[0] = '\0';
- rcbuf[sizeof(rcbuf) - 1] = '\0';
- strncat(rcbuf, "/.telnetrc", sizeof(rcbuf) - 1 - strlen(rcbuf));
- rcname = rcbuf;
- }
-
- if ((rcfile = fopen(rcname, "r")) == 0) {
- return;
- }
-
- for (;;) {
- if (fgets(line, sizeof(line), rcfile) == NULL)
- break;
- if (line[0] == 0)
- break;
- if (line[0] == '#')
- continue;
- if (gotmachine) {
- if (!isspace((int) line[0]))
- gotmachine = 0;
- }
- if (gotmachine == 0) {
- if (isspace((int) line[0]))
- continue;
- if (strncasecmp(line, m1, l1) == 0)
- strncpy(line, &line[l1], sizeof(line) - l1);
- else if (strncasecmp(line, m2, l2) == 0)
- strncpy(line, &line[l2], sizeof(line) - l2);
- else if (strncasecmp(line, "DEFAULT", 7) == 0)
- strncpy(line, &line[7], sizeof(line) - 7);
- else
- continue;
- if (line[0] != ' ' && line[0] != '\t' && line[0] != '\n')
- continue;
- gotmachine = 1;
- }
- makeargv();
- if (margv[0] == 0)
- continue;
- c = getcmd(margv[0]);
- if (Ambiguous(c)) {
- printf("?Ambiguous command: %s\r\n", margv[0]);
- continue;
- }
- if (c == 0) {
- printf("?Invalid command: %s\r\n", margv[0]);
- continue;
- }
- /*
- * This should never happen...
- */
- if (c->needconnect && !connected) {
- printf("?Need to be connected first for %s.\r\n", margv[0]);
- continue;
- }
- (*c->handler)(margc, margv);
- }
- fclose(rcfile);
-}
-
-#if defined(IP_OPTIONS) && defined(IPPROTO_IP)
-
-/*
- * Source route is handed in as
- * [!]@hop1@hop2...[@|:]dst
- * If the leading ! is present, it is a
- * strict source route, otherwise it is
- * assmed to be a loose source route.
- *
- * We fill in the source route option as
- * hop1,hop2,hop3...dest
- * and return a pointer to hop1, which will
- * be the address to connect() to.
- *
- * Arguments:
- * arg: pointer to route list to decipher
- *
- * cpp: If *cpp is not equal to NULL, this is a
- * pointer to a pointer to a character array
- * that should be filled in with the option.
- *
- * lenp: pointer to an integer that contains the
- * length of *cpp if *cpp != NULL.
- *
- * Return values:
- *
- * Returns the address of the host to connect to. If the
- * return value is -1, there was a syntax error in the
- * option, either unknown characters, or too many hosts.
- * If the return value is 0, one of the hostnames in the
- * path is unknown, and *cpp is set to point to the bad
- * hostname.
- *
- * *cpp: If *cpp was equal to NULL, it will be filled
- * in with a pointer to our static area that has
- * the option filled in. This will be 32bit aligned.
- *
- * *lenp: This will be filled in with how long the option
- * pointed to by *cpp is.
- *
- */
-static unsigned long
-sourceroute(arg, cpp, lenp)
- char *arg;
- char **cpp;
- int *lenp;
-{
- static char lsr[44];
-#ifdef sysV88
- static IOPTN ipopt;
-#endif
- char *cp, *cp2, *lsrp, *lsrep;
- register int tmp;
- struct in_addr sin_addr;
- register struct hostent *host = 0;
- register char c;
-
- /*
- * Verify the arguments, and make sure we have
- * at least 7 bytes for the option.
- */
- if (cpp == NULL || lenp == NULL)
- return((unsigned long)-1);
- if (*cpp != NULL && *lenp < 7)
- return((unsigned long)-1);
- /*
- * Decide whether we have a buffer passed to us,
- * or if we need to use our own static buffer.
- */
- if (*cpp) {
- lsrp = *cpp;
- lsrep = lsrp + *lenp;
- } else {
- *cpp = lsrp = lsr;
- lsrep = lsrp + 44;
- }
-
- cp = arg;
-
- /*
- * Next, decide whether we have a loose source
- * route or a strict source route, and fill in
- * the begining of the option.
- */
-#ifndef sysV88
- if (*cp == '!') {
- cp++;
- *lsrp++ = IPOPT_SSRR;
- } else
- *lsrp++ = IPOPT_LSRR;
-#else
- if (*cp == '!') {
- cp++;
- ipopt.io_type = IPOPT_SSRR;
- } else
- ipopt.io_type = IPOPT_LSRR;
-#endif
-
- if (*cp != '@')
- return((unsigned long)-1);
-
-#ifndef sysV88
- lsrp++; /* skip over length, we'll fill it in later */
- *lsrp++ = 4;
-#endif
-
- cp++;
-
- sin_addr.s_addr = 0;
-
- for (c = 0;;) {
- if (c == ':')
- cp2 = 0;
- else for (cp2 = cp; (c = *cp2); cp2++) {
- if (c == ',') {
- *cp2++ = '\0';
- if (*cp2 == '@')
- cp2++;
- } else if (c == '@') {
- *cp2++ = '\0';
- } else if (c == ':') {
- *cp2++ = '\0';
- } else
- continue;
- break;
- }
- if (!c)
- cp2 = 0;
-
- if ((tmp = inet_addr(cp)) != -1) {
- sin_addr.s_addr = tmp;
- } else if ((host = gethostbyname(cp))) {
-#if defined(h_addr)
- memcpy(&sin_addr,
- host->h_addr_list[0], sizeof(sin_addr));
-#else
- memcpy(&sin_addr, host->h_addr, sizeof(sin_addr));
-#endif
- } else {
- *cpp = cp;
- return(0);
- }
- memcpy(lsrp, &sin_addr, 4);
- lsrp += 4;
- if (cp2)
- cp = cp2;
- else
- break;
- /*
- * Check to make sure there is space for next address
- */
- if (lsrp + 4 > lsrep)
- return((unsigned long)-1);
- }
-#ifndef sysV88
- if ((*(*cpp+IPOPT_OLEN) = lsrp - *cpp) <= 7) {
- *cpp = 0;
- *lenp = 0;
- return((unsigned long)-1);
- }
- *lsrp++ = IPOPT_NOP; /* 32 bit word align it */
- *lenp = lsrp - *cpp;
-#else
- ipopt.io_len = lsrp - *cpp;
- if (ipopt.io_len <= 5) { /* Is 3 better ? */
- *cpp = 0;
- *lenp = 0;
- return((unsigned long)-1);
- }
- *lenp = sizeof(ipopt);
- *cpp = (char *) &ipopt;
-#endif
- return(sin_addr.s_addr);
-}
-#endif
+++ /dev/null
-/*
- * 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.
- *
- * @(#)defines.h 8.1 (Berkeley) 6/6/93
- */
-
-#define settimer(x) clocks.x = clocks.system++
-
-#if !defined(TN3270)
-
-#define SetIn3270()
-
-#endif /* !defined(TN3270) */
-
-#define NETADD(c) { *netoring.supply = c; ring_supplied(&netoring, 1); }
-#define NET2ADD(c1,c2) { NETADD(c1); NETADD(c2); }
-#define NETBYTES() (ring_full_count(&netoring))
-#define NETROOM() (ring_empty_count(&netoring))
-
-#define TTYADD(c) if (!(SYNCHing||flushout)) { \
- *ttyoring.supply = c; \
- ring_supplied(&ttyoring, 1); \
- }
-#define TTYBYTES() (ring_full_count(&ttyoring))
-#define TTYROOM() (ring_empty_count(&ttyoring))
-
-/* Various modes */
-#define MODE_LOCAL_CHARS(m) ((m)&(MODE_EDIT|MODE_TRAPSIG))
-#define MODE_LOCAL_ECHO(m) ((m)&MODE_ECHO)
-#define MODE_COMMAND_LINE(m) ((m)==-1)
-
-#define CONTROL(x) ((x)&0x1f) /* CTRL(x) is not portable */
+++ /dev/null
-#
-# Generated makefile dependencies follow.
-#
-$(OUTPRE)authenc.$(OBJEXT): $(srcdir)/../arpa/telnet.h \
- $(srcdir)/../libtelnet/enc-proto.h $(srcdir)/../libtelnet/encrypt.h \
- $(srcdir)/../libtelnet/misc-proto.h $(srcdir)/../libtelnet/misc.h \
- authenc.c defines.h externs.h general.h ring.h types.h
-$(OUTPRE)commands.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(SRCTOP)/include/fake-addrinfo.h $(SRCTOP)/include/k5-platform.h \
- $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/port-sockets.h \
- $(SRCTOP)/include/socket-utils.h $(srcdir)/../arpa/telnet.h \
- $(srcdir)/../libtelnet/auth-proto.h $(srcdir)/../libtelnet/auth.h \
- $(srcdir)/../libtelnet/enc-proto.h $(srcdir)/../libtelnet/encrypt.h \
- $(srcdir)/../libtelnet/misc-proto.h commands.c defines.h \
- externs.h general.h ring.h types.h
-$(OUTPRE)main.$(OBJEXT): $(srcdir)/../libtelnet/auth-proto.h \
- $(srcdir)/../libtelnet/auth.h $(srcdir)/../libtelnet/enc-proto.h \
- $(srcdir)/../libtelnet/encrypt.h defines.h externs.h \
- main.c ring.h
-$(OUTPRE)network.$(OBJEXT): $(srcdir)/../arpa/telnet.h \
- defines.h externs.h fdset.h network.c ring.h
-$(OUTPRE)ring.$(OBJEXT): general.h ring.c ring.h
-$(OUTPRE)sys_bsd.$(OBJEXT): $(srcdir)/../arpa/telnet.h \
- defines.h externs.h fdset.h ring.h sys_bsd.c types.h
-$(OUTPRE)telnet.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \
- $(srcdir)/../arpa/telnet.h $(srcdir)/../libtelnet/auth-proto.h \
- $(srcdir)/../libtelnet/auth.h $(srcdir)/../libtelnet/enc-proto.h \
- $(srcdir)/../libtelnet/encrypt.h $(srcdir)/../libtelnet/misc-proto.h \
- defines.h externs.h general.h ring.h telnet.c types.h
-$(OUTPRE)terminal.$(OBJEXT): $(srcdir)/../arpa/telnet.h \
- $(srcdir)/../libtelnet/enc-proto.h $(srcdir)/../libtelnet/encrypt.h \
- externs.h ring.h terminal.c types.h
-$(OUTPRE)utilities.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \
- $(srcdir)/../arpa/telnet.h $(srcdir)/../libtelnet/auth-proto.h \
- $(srcdir)/../libtelnet/auth.h $(srcdir)/../libtelnet/enc-proto.h \
- $(srcdir)/../libtelnet/encrypt.h defines.h externs.h \
- fdset.h general.h ring.h utilities.c
+++ /dev/null
-/*
- * Copyright (c) 1988, 1990, 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.
- *
- * @(#)externs.h 8.1 (Berkeley) 6/6/93
- */
-
-#include <sys/param.h>
-
-#ifndef BSD
-# define BSD 43
-#endif
-
-/*
- * ucb stdio.h defines BSD as something wierd
- */
-#if defined(sun) && defined(__svr4__)
-#define BSD 43
-#endif
-
-#ifndef USE_TERMIO
-# if BSD > 43 || defined(SYSV_TERMIO)
-# define USE_TERMIO
-# endif
-#endif
-
-#include <stdio.h>
-#include <setjmp.h>
-#if defined(CRAY) && !defined(NO_BSD_SETJMP)
-#include <bsdsetjmp.h>
-#endif
-#include <sys/ioctl.h>
-#ifdef HAVE_SYS_FILIO_H
-#include <sys/filio.h>
-#endif
-#ifdef CRAY
-# include <errno.h>
-#endif /* CRAY */
-#ifdef USE_TERMIO
-# ifndef VINTR
-# ifdef SYSV_TERMIO
-# include <sys/termio.h>
-# else
-# include <termios.h>
-# endif
-# endif
-#endif
-#if defined(USE_TERMIO) && !defined(SYSV_TERMIO)
-# define termio termios
-#endif
-#if defined(NO_CC_T) || !defined(USE_TERMIO)
-# if !defined(USE_TERMIO)
-typedef char cc_t;
-# else
-typedef unsigned char cc_t;
-# endif
-#endif
-
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#else
-extern char *malloc(), *calloc(), *realloc();
-#endif
-
-#ifndef HAVE_STRING_H
-#include <strings.h>
-#else
-#include <string.h>
-#endif
-
-#ifndef _POSIX_VDISABLE
-# ifdef sun
-# include <sys/param.h> /* pick up VDISABLE definition, mayby */
-# endif
-# ifdef VDISABLE
-# define _POSIX_VDISABLE VDISABLE
-# else
-# define _POSIX_VDISABLE ((cc_t)'\377')
-# endif
-#endif
-
-#define SUBBUFSIZE 256
-
-extern int
- autologin, /* Autologin enabled */
- skiprc, /* Don't process the ~/.telnetrc file */
- eight, /* use eight bit mode (binary in and/or out */
- flushout, /* flush output */
- connected, /* Are we connected to the other side? */
- globalmode, /* Mode tty should be in */
- In3270, /* Are we in 3270 mode? */
- telnetport, /* Are we connected to the telnet port? */
- localflow, /* Flow control handled locally */
- restartany, /* If flow control, restart output on any character */
- localchars, /* we recognize interrupt/quit */
- donelclchars, /* the user has set "localchars" */
- showoptions,
- wantencryption, /* User has requested encryption */
- net, /* Network file descriptor */
- tin, /* Terminal input file descriptor */
- tout, /* Terminal output file descriptor */
- crlf, /* Should '\r' be mapped to <CR><LF> (or <CR><NUL>)? */
- autoflush, /* flush output when interrupting? */
- autosynch, /* send interrupt characters with SYNCH? */
- SYNCHing, /* Is the stream in telnet SYNCH mode? */
- donebinarytoggle, /* the user has put us in binary */
- dontlecho, /* do we suppress local echoing right now? */
- crmod,
- netdata, /* Print out network data flow */
- prettydump, /* Print "netdata" output in user readable format */
-#if defined(TN3270)
- cursesdata, /* Print out curses data flow */
- apitrace, /* Trace API transactions */
-#endif /* defined(TN3270) */
- termdata, /* Print out terminal data flow */
- debug; /* Debug level */
-
-extern int intr_happened, intr_waiting; /* for interrupt handling */
-
-extern cc_t escape; /* Escape to command mode */
-extern cc_t rlogin; /* Rlogin mode escape character */
-#ifdef KLUDGELINEMODE
-extern cc_t echoc; /* Toggle local echoing */
-#endif
-
-extern char
- *prompt; /* Prompt for command. */
-
-extern char
- doopt[],
- dont[],
- will[],
- wont[],
- options[], /* All the little options */
- *hostname; /* Who are we connected to? */
-#ifdef ENCRYPTION
-extern void (*encrypt_output) (unsigned char *, int);
-extern int (*decrypt_input) (int);
-#endif /* ENCRYPTION */
-
-/*
- * 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;}
-
-/*
- * 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
-
-
-extern FILE
- *NetTrace; /* Where debugging output goes */
-extern unsigned char
- NetTraceFile[]; /* Name of file where debugging output goes */
-extern void
- SetNetTrace (char *); /* Function to change where debugging goes */
-
-extern jmp_buf
- peerdied,
- toplevel; /* For error conditions. */
-
-extern void
- command (int, char *, int),
- Dump (int, unsigned char *, int),
- init_3270 (void),
- init_terminal (void),
- init_telnet (void),
- init_network (void),
- init_sys (void),
- printoption (char *, int, int),
- printsub (int, unsigned char *, int),
- sendnaws (void),
- sendabort (void),
- sendeof (void),
- sendayt (void),
- sendsusp (void),
- setconnmode (int),
- setcommandmode (void),
- setneturg (void),
- set_escape_char (char *),
- sys_telnet_init (void),
- telnet (char *),
- tel_enter_binary (int),
- tel_leave_binary (int),
- TerminalDefaultChars (void),
- TerminalFlushOutput (void),
- TerminalNewMode (int),
- TerminalRestoreState (void),
- TerminalSaveState (void),
- TerminalSpeeds (long *, long *),
- tninit (void),
- upcase (char *),
- willoption (int),
- wontoption (int);
-
-extern void
- send_do (int, int),
- send_dont (int, int),
- send_will (int, int),
- send_wont (int, int);
-
-extern void
- sendbrk (void),
- intp (void),
- xmitAO (void),
- xmitEL (void),
- xmitEC (void);
-
-extern void
- lm_will (unsigned char *, int),
- lm_wont (unsigned char *, int),
- lm_do (unsigned char *, int),
- lm_dont (unsigned char *, int),
- lm_mode (unsigned char *, int, int);
-
-extern void
- ExitString (char *, int),
- Exit (int),
- SetForExit (void),
- EmptyTerminal (void),
- slc_init (void),
- slcstate (void),
- slc_mode_export (void),
- slc_mode_import (int),
- slc_import (int),
- slc_export (void),
- slc (unsigned char *, int),
- slc_check (void),
- slc_start_reply (void),
- slc_add_reply (int, int, int),
- slc_end_reply (void);
-
-extern int
- quit (int, char *[]),
- ttyflush (int),
- rlogin_susp (void),
- tn (int, char **),
- getconnmode (void),
- netflush (void),
- NetClose (int),
- opt_welldefined (char *),
- process_rings (int, int, int, int, int, int),
- slc_update (void),
- Scheduler (int),
- SetSockOpt (int, int, int, int),
- stilloob (void),
- telrcv (void),
- telnet_spin (void),
- TerminalWrite (unsigned char *, int),
- TerminalRead (unsigned char *, int),
- TerminalAutoFlush (void),
- TerminalSpecialChars (int),
- TerminalWindowSize (long *, long *);
-
-
-extern void
- env_init (void),
- env_opt (unsigned char *, int),
- env_opt_start (void),
- env_opt_start_info (void),
- env_opt_add (unsigned char *),
- env_opt_end (int),
- optionstatus (void);
-
-extern unsigned char
- *env_default (int, int),
- *env_getvalue (unsigned char *);
-
-extern int
- env_is_exported (unsigned char *);
-
-extern int
- get_status (char *),
- dosynch (char *);
-
-extern cc_t
- *tcval (int);
-
-#ifndef USE_TERMIO
-
-extern struct tchars ntc;
-extern struct ltchars nltc;
-extern struct sgttyb nttyb;
-
-# define termEofChar ntc.t_eofc
-# define termEraseChar nttyb.sg_erase
-# define termFlushChar nltc.t_flushc
-# define termIntChar ntc.t_intrc
-# define termKillChar nttyb.sg_kill
-# define termLiteralNextChar nltc.t_lnextc
-# define termQuitChar ntc.t_quitc
-# define termSuspChar nltc.t_suspc
-# define termRprntChar nltc.t_rprntc
-# define termWerasChar nltc.t_werasc
-# define termStartChar ntc.t_startc
-# define termStopChar ntc.t_stopc
-# define termForw1Char ntc.t_brkc
-extern cc_t termForw2Char;
-extern cc_t termAytChar;
-
-# define termEofCharp (cc_t *)&ntc.t_eofc
-# define termEraseCharp (cc_t *)&nttyb.sg_erase
-# define termFlushCharp (cc_t *)&nltc.t_flushc
-# define termIntCharp (cc_t *)&ntc.t_intrc
-# define termKillCharp (cc_t *)&nttyb.sg_kill
-# define termLiteralNextCharp (cc_t *)&nltc.t_lnextc
-# define termQuitCharp (cc_t *)&ntc.t_quitc
-# define termSuspCharp (cc_t *)&nltc.t_suspc
-# define termRprntCharp (cc_t *)&nltc.t_rprntc
-# define termWerasCharp (cc_t *)&nltc.t_werasc
-# define termStartCharp (cc_t *)&ntc.t_startc
-# define termStopCharp (cc_t *)&ntc.t_stopc
-# define termForw1Charp (cc_t *)&ntc.t_brkc
-# define termForw2Charp (cc_t *)&termForw2Char
-# define termAytCharp (cc_t *)&termAytChar
-
-# else
-
-extern struct termio new_tc;
-
-# define termEofChar new_tc.c_cc[VEOF]
-# define termEraseChar new_tc.c_cc[VERASE]
-# define termIntChar new_tc.c_cc[VINTR]
-# define termKillChar new_tc.c_cc[VKILL]
-# define termQuitChar new_tc.c_cc[VQUIT]
-
-# ifndef VSUSP
-extern cc_t termSuspChar;
-# else
-# define termSuspChar new_tc.c_cc[VSUSP]
-# endif
-# if defined(VFLUSHO) && !defined(VDISCARD)
-# define VDISCARD VFLUSHO
-# endif
-# ifndef VDISCARD
-extern cc_t termFlushChar;
-# else
-# define termFlushChar new_tc.c_cc[VDISCARD]
-# endif
-# ifndef VWERASE
-extern cc_t termWerasChar;
-# else
-# define termWerasChar new_tc.c_cc[VWERASE]
-# endif
-# ifndef VREPRINT
-extern cc_t termRprntChar;
-# else
-# define termRprntChar new_tc.c_cc[VREPRINT]
-# endif
-# ifndef VLNEXT
-extern cc_t termLiteralNextChar;
-# else
-# define termLiteralNextChar new_tc.c_cc[VLNEXT]
-# endif
-# ifndef VSTART
-extern cc_t termStartChar;
-# else
-# define termStartChar new_tc.c_cc[VSTART]
-# endif
-# ifndef VSTOP
-extern cc_t termStopChar;
-# else
-# define termStopChar new_tc.c_cc[VSTOP]
-# endif
-# ifndef VEOL
-extern cc_t termForw1Char;
-# else
-# define termForw1Char new_tc.c_cc[VEOL]
-# endif
-# ifndef VEOL2
-extern cc_t termForw2Char;
-# else
-# define termForw2Char new_tc.c_cc[VEOL]
-# endif
-# ifndef VSTATUS
-extern cc_t termAytChar;
-#else
-# define termAytChar new_tc.c_cc[VSTATUS]
-#endif
-
-# if !defined(CRAY) || defined(__STDC__)
-# define termEofCharp &termEofChar
-# define termEraseCharp &termEraseChar
-# define termIntCharp &termIntChar
-# define termKillCharp &termKillChar
-# define termQuitCharp &termQuitChar
-# define termSuspCharp &termSuspChar
-# define termFlushCharp &termFlushChar
-# define termWerasCharp &termWerasChar
-# define termRprntCharp &termRprntChar
-# define termLiteralNextCharp &termLiteralNextChar
-# define termStartCharp &termStartChar
-# define termStopCharp &termStopChar
-# define termForw1Charp &termForw1Char
-# define termForw2Charp &termForw2Char
-# define termAytCharp &termAytChar
-# else
- /* Work around a compiler bug */
-# define termEofCharp 0
-# define termEraseCharp 0
-# define termIntCharp 0
-# define termKillCharp 0
-# define termQuitCharp 0
-# define termSuspCharp 0
-# define termFlushCharp 0
-# define termWerasCharp 0
-# define termRprntCharp 0
-# define termLiteralNextCharp 0
-# define termStartCharp 0
-# define termStopCharp 0
-# define termForw1Charp 0
-# define termForw2Charp 0
-# define termAytCharp 0
-# endif
-#endif
-
-
-/* Ring buffer structures which are shared */
-
-extern Ring
- netoring,
- netiring,
- ttyoring,
- ttyiring;
-
-/* Tn3270 section */
-#if defined(TN3270)
-
-extern int
- HaveInput, /* Whether an asynchronous I/O indication came in */
- noasynchtty, /* Don't do signals on I/O (SIGURG, SIGIO) */
- noasynchnet, /* Don't do signals on I/O (SIGURG, SIGIO) */
- sigiocount, /* Count of SIGIO receptions */
- shell_active; /* Subshell is active */
-
-extern char
- *Ibackp, /* Oldest byte of 3270 data */
- Ibuf[], /* 3270 buffer */
- *Ifrontp, /* Where next 3270 byte goes */
- tline[200],
- *transcom; /* Transparent command */
-
-extern int
- settranscom (int, char**);
-
-extern void
- inputAvailable (int);
-#endif /* defined(TN3270) */
+++ /dev/null
-/*
- * 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.
- *
- * @(#)fdset.h 8.1 (Berkeley) 6/6/93
- */
-
-/*
- * The following is defined just in case someone should want to run
- * this telnet on a 4.2 system.
- *
- */
-
-#ifndef FD_SETSIZE
-
-#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
+++ /dev/null
-/*
- * 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.
- *
- * @(#)general.h 8.1 (Berkeley) 6/6/93
- */
-
-/*
- * Some general definitions.
- */
-
-
-#define numberof(x) (sizeof x/sizeof x[0])
-#define highestof(x) (numberof(x)-1)
-
-#define ClearElement(x) memset(&x, 0, sizeof x)
-#define ClearArray(x) memset(x, 0, sizeof x)
+++ /dev/null
-/*
- * Copyright (c) 1988, 1990 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 lint
-char copyright[] =
-"@(#) Copyright (c) 1988, 1990 Regents of the University of California.\n\
- All rights reserved.\n";
-#endif /* not lint */
-
-/* based on @(#)main.c 5.5 (Berkeley) 12/18/92 */
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <sys/types.h>
-#include <libtelnet/auth.h>
-#ifdef ENCRYPTION
-#include <libtelnet/encrypt.h>
-#endif
-
-# include <netinet/in.h>
-
-#include "ring.h"
-#include "externs.h"
-#include "defines.h"
-
-#ifdef NEED_PARSETOS_PROTO
-extern int parsetos(char *, char *);
-#endif
-
-#if 0
-#define FORWARD
-#endif
-
-/*
- * Initialize variables.
- */
- void
-tninit()
-{
- init_terminal();
-
- init_network();
-
- init_telnet();
-
- init_sys();
-
-#if defined(TN3270)
- init_3270();
-#endif
-}
-
-static void
-usage()
-{
- fprintf(stderr, "Usage: %s %s%s%s%s\n",
- prompt,
-#ifdef AUTHENTICATION
- " [-8] [-E] [-K] [-L] [-X atype] [-a] [-d] [-e char] [-k realm]",
- "\n\t[-l user] [-f/-F] [-n tracefile] ",
-#else
- " [-8] [-E] [-L] [-a] [-d] [-e char] [-l user] [-n tracefile]",
- "\n\t",
-#endif
-#if defined(TN3270) && defined(unix)
-# ifdef AUTHENTICATION
- "[-noasynch] [-noasynctty] [-noasyncnet]\n\t[-r] [-t transcom] ",
-# else
- "[-noasynch] [-noasynctty] [-noasyncnet] [-r] [-t transcom]\n\t",
-# endif
-#else
- "[-r] ",
-#endif
-#ifdef ENCRYPTION
- "[-x] [host-name [port]]"
-#else
- "[host-name [port]]"
-#endif
- );
- exit(1);
-}
-
-/*
- * main. Parse arguments, invoke the protocol or command parser.
- */
-
-/* see forward.c -- indicate that we're in telnet, not telnetd. */
-char *line = 0;
-
-int
-main(argc, argv)
- int argc;
- char *argv[];
-{
- extern char *optarg;
- extern int optind;
- int ch;
- char *user;
-#ifdef FORWARD
- extern int forward_flags;
-#endif /* FORWARD */
-#ifdef ENCRYPTION
- extern int auth_enable_encrypt;
-#endif /* ENCRYPTION */
-
- tninit(); /* Clear out things */
-#if defined(CRAY) && !defined(__STDC__)
- _setlist_init(); /* Work around compiler bug */
-#endif
-
- TerminalSaveState();
-
- if ((prompt = strrchr(argv[0], '/')))
- ++prompt;
- else
- prompt = argv[0];
-
- user = NULL;
-
- rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
- autologin = -1;
-
- while ((ch = getopt(argc, argv, "8EKLS:X:acde:fFk:l:n:rt:x")) != -1) {
- switch(ch) {
- case '8':
- eight = 3; /* binary output and input */
- break;
- case 'E':
- rlogin = escape = _POSIX_VDISABLE;
- break;
- case 'K':
-#ifdef AUTHENTICATION
- autologin = 0;
-#endif
- break;
- case 'L':
- eight |= 2; /* binary output only */
- break;
- case 'S':
- {
-#if defined(HAVE_GETTOSBYNAME) || (defined(IPPROTO_IP) && defined(IP_TOS))
- extern int tos;
-
- if ((tos = parsetos(optarg, "tcp")) < 0)
- fprintf(stderr, "%s%s%s%s\n",
- prompt, ": Bad TOS argument '",
- optarg,
- "; will try to use default TOS");
-
- fprintf(stderr, "Setting TOS to 0x%x\n", tos);
-#else
- fprintf(stderr,
- "%s: Warning: -S ignored, no parsetos() support.\n",
- prompt);
-#endif
- }
- break;
- case 'X':
-#ifdef AUTHENTICATION
- auth_disable_name(optarg);
-#endif
- break;
- case 'a':
- autologin = 1;
- break;
- case 'c':
- skiprc = 1;
- break;
- case 'd':
- debug = 1;
- break;
- case 'e':
- set_escape_char(optarg);
- break;
- case 'f':
-#if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
- if (forward_flags & OPTS_FORWARD_CREDS) {
- fprintf(stderr,
- "%s: Only one of -f and -F allowed.\n",
- prompt);
- usage();
- }
- forward_flags |= OPTS_FORWARD_CREDS;
-#else
- fprintf(stderr,
- "%s: Warning: -f ignored, no Kerberos V5 support.\n",
- prompt);
-#endif
- break;
- case 'F':
-#if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
- if (forward_flags & OPTS_FORWARD_CREDS) {
- fprintf(stderr,
- "%s: Only one of -f and -F allowed.\n",
- prompt);
- usage();
- }
- forward_flags |= OPTS_FORWARD_CREDS;
- forward_flags |= OPTS_FORWARDABLE_CREDS;
-#else
- fprintf(stderr,
- "%s: Warning: -F ignored, no Kerberos V5 support.\n",
- prompt);
-#endif
- break;
- case 'k':
-#if defined(AUTHENTICATION) && defined(KRB5)
- {
- extern char *telnet_krb5_realm;
-
- telnet_krb5_realm = optarg;
- break;
- }
-#else
- fprintf(stderr,
- "%s: Warning: -k ignored, no Kerberos V4 support.\n",
- prompt);
-#endif
- break;
- case 'l':
- autologin = 1;
- user = optarg;
- break;
- case 'n':
-#if defined(TN3270) && defined(unix)
- /* distinguish between "-n oasynch" and "-noasynch" */
- if (argv[optind - 1][0] == '-' && argv[optind - 1][1]
- == 'n' && argv[optind - 1][2] == 'o') {
- if (!strcmp(optarg, "oasynch")) {
- noasynchtty = 1;
- noasynchnet = 1;
- } else if (!strcmp(optarg, "oasynchtty"))
- noasynchtty = 1;
- else if (!strcmp(optarg, "oasynchnet"))
- noasynchnet = 1;
- } else
-#endif /* defined(TN3270) && defined(unix) */
- SetNetTrace(optarg);
- break;
- case 'r':
- rlogin = '~';
- break;
- case 't':
-#if defined(TN3270) && defined(unix)
- transcom = tline;
- (void)strncpy(transcom, optarg, sizeof(tline) - 1);
- tline[sizeof(tline) - 1] = '\0';
-#else
- fprintf(stderr,
- "%s: Warning: -t ignored, no TN3270 support.\n",
- prompt);
-#endif
- break;
- case 'x':
-#ifdef ENCRYPTION
- encrypt_auto(1);
- decrypt_auto(1);
- wantencryption = 1;
- autologin = 1;
- auth_enable_encrypt = 1;
-#else
- fprintf(stderr,
- "%s: Warning: -x ignored, no ENCRYPT support.\n",
- prompt);
-#endif
- break;
- case '?':
- default:
- usage();
- /* NOTREACHED */
- }
- }
- if (autologin == -1)
- autologin = (rlogin == _POSIX_VDISABLE) ? 0 : 1;
-
- argc -= optind;
- argv += optind;
-
- if (argc) {
- char *args[7], **volatile argp = args;
-
- if (argc > 2)
- usage();
- *argp++ = prompt;
- if (user) {
- *argp++ = "-l";
- *argp++ = user;
- }
- *argp++ = argv[0]; /* host */
- if (argc > 1)
- *argp++ = argv[1]; /* port */
- *argp = 0;
-
- if (setjmp(toplevel) != 0)
- Exit(0);
- if (tn(argp - args, args) == 1)
- return (0);
- else
- return (1);
- }
- (void)setjmp(toplevel);
- for (;;) {
-#ifdef TN3270
- if (shell_active)
- shell_continue();
- else
-#endif
- command(1, 0, 0);
- }
-}
+++ /dev/null
-/*
- * 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.
- */
-
-/* based on @(#)network.c 8.1 (Berkeley) 6/6/93 */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-#include <errno.h>
-
-#include <arpa/telnet.h>
-
-#include "ring.h"
-
-#include "defines.h"
-#include "externs.h"
-#include "fdset.h"
-
-Ring netoring, netiring;
-unsigned char netobuf[2*TELNET_BUFSIZE], netibuf[TELNET_BUFSIZE];
-
-/*
- * Initialize internal network data structures.
- */
-
- void
-init_network()
-{
- if (ring_init(&netoring, netobuf, sizeof netobuf) != 1) {
- exit(1);
- }
- if (ring_init(&netiring, netibuf, sizeof netibuf) != 1) {
- exit(1);
- }
- NetTrace = stdout;
-}
-
-
-/*
- * Check to see if any out-of-band data exists on a socket (for
- * Telnet "synch" processing).
- */
-
- int
-stilloob()
-{
- static struct timeval timeout = { 0 };
- fd_set excepts;
- int value;
-
- do {
- FD_ZERO(&excepts);
- FD_SET(net, &excepts);
- value = select(net+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout);
- } while ((value == -1) && (errno == EINTR));
-
- if (value < 0) {
- perror("select");
- (void) quit(0, NULL);
- /* NOTREACHED */
- }
- if (FD_ISSET(net, &excepts)) {
- return 1;
- } else {
- return 0;
- }
-}
-
-
-/*
- * setneturg()
- *
- * Sets "neturg" to the current location.
- */
-
- void
-setneturg()
-{
- ring_mark(&netoring);
-}
-
-
-/*
- * netflush
- * Send as much data as possible to the network,
- * handling requests for urgent data.
- *
- * The return value indicates whether we did any
- * useful work.
- */
-
-
- int
-netflush()
-{
- register int n, n1;
-
-#ifdef ENCRYPTION
- if (encrypt_output)
- ring_encrypt(&netoring, encrypt_output);
-#endif /* ENCRYPTION */
- if ((n1 = n = ring_full_consecutive(&netoring)) > 0) {
- if (!ring_at_mark(&netoring)) {
- n = send(net, (char *)netoring.consume, n, 0); /* normal write */
- } else {
- /*
- * In 4.2 (and 4.3) systems, there is some question about
- * what byte in a sendOOB operation is the "OOB" data.
- * To make ourselves compatible, we only send ONE byte
- * out of band, the one WE THINK should be OOB (though
- * we really have more the TCP philosophy of urgent data
- * rather than the Unix philosophy of OOB data).
- */
- n = send(net, (char *)netoring.consume, 1, MSG_OOB);/* URGENT data */
- }
- }
- if (n < 0) {
- if (errno != ENOBUFS && errno != EWOULDBLOCK) {
- setcommandmode();
- perror(hostname);
- (void)NetClose(net);
- ring_clear_mark(&netoring);
- longjmp(peerdied, -1);
- /*NOTREACHED*/
- }
- n = 0;
- }
- if (netdata && n) {
- Dump('>', netoring.consume, n);
- }
- if (n) {
- ring_consumed(&netoring, n);
- /*
- * If we sent all, and more to send, then recurse to pick
- * up the other half.
- */
- if ((n1 == n) && ring_full_consecutive(&netoring)) {
- (void) netflush();
- }
- return 1;
- } else {
- return 0;
- }
-}
+++ /dev/null
-/*
- * 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.
- */
-
-/* based on @(#)ring.c 8.1 (Berkeley) 6/6/93 */
-
-/*
- * This defines a structure for a ring buffer.
- *
- * The circular buffer has two parts:
- *(((
- * full: [consume, supply)
- * empty: [supply, consume)
- *]]]
- *
- */
-
-#include <stdio.h>
-#include <errno.h>
-
-#ifdef size_t
-#undef size_t
-#endif
-
-#include <sys/types.h>
-#ifndef HAVE_SYS_FILIO_H
-#include <sys/ioctl.h>
-#endif
-#include <sys/socket.h>
-
-#include "ring.h"
-#include "general.h"
-
-#ifndef NO_STRING_H
-#include <string.h>
-#else
-#include <strings.h>
-#endif
-
-/* Internal macros */
-
-#if !defined(MIN)
-#define MIN(a,b) (((a)<(b))? (a):(b))
-#endif /* !defined(MIN) */
-
-#define ring_subtract(d,a,b) (((a)-(b) >= 0)? \
- (a)-(b): (((a)-(b))+(d)->size))
-
-#define ring_increment(d,a,c) (((a)+(c) < (d)->top)? \
- (a)+(c) : (((a)+(c))-(d)->size))
-
-#define ring_decrement(d,a,c) (((a)-(c) >= (d)->bottom)? \
- (a)-(c) : (((a)-(c))-(d)->size))
-
-
-/*
- * The following is a clock, used to determine full, empty, etc.
- *
- * There is some trickiness here. Since the ring buffers are initialized
- * to ZERO on allocation, we need to make sure, when interpreting the
- * clock, that when the times are EQUAL, then the buffer is FULL.
- */
-static u_long ring_clock = 0;
-
-
-#define ring_empty(d) (((d)->consume == (d)->supply) && \
- ((d)->consumetime >= (d)->supplytime))
-#define ring_full(d) (((d)->supply == (d)->consume) && \
- ((d)->supplytime > (d)->consumetime))
-
-
-
-
-
-/* Buffer state transition routines */
-
-int
-ring_init(ring, buffer, count)
-Ring *ring;
- unsigned char *buffer;
- int count;
-{
- memset(ring, 0, sizeof *ring);
-
- ring->size = count;
-
- ring->supply = ring->consume = ring->bottom = buffer;
-
- ring->top = ring->bottom+ring->size;
-
-#ifdef ENCRYPTION
- ring->clearto = 0;
-#endif /* ENCRYPTION */
-
- return 1;
-}
-
-/* Mark routines */
-
-/*
- * Mark the most recently supplied byte.
- */
-
- void
-ring_mark(ring)
- Ring *ring;
-{
- ring->mark = ring_decrement(ring, ring->supply, 1);
-}
-
-/*
- * Is the ring pointing to the mark?
- */
-
- int
-ring_at_mark(ring)
- Ring *ring;
-{
- if (ring->mark == ring->consume) {
- return 1;
- } else {
- return 0;
- }
-}
-
-/*
- * Clear any mark set on the ring.
- */
-
- void
-ring_clear_mark(ring)
- Ring *ring;
-{
- ring->mark = 0;
-}
-
-/*
- * Add characters from current segment to ring buffer.
- */
- void
-ring_supplied(ring, count)
- Ring *ring;
- int count;
-{
- ring->supply = ring_increment(ring, ring->supply, count);
- ring->supplytime = ++ring_clock;
-}
-
-/*
- * We have just consumed "c" bytes.
- */
- void
-ring_consumed(ring, count)
- Ring *ring;
- int count;
-{
- if (count == 0) /* don't update anything */
- return;
-
- if (ring->mark &&
- (ring_subtract(ring, ring->mark, ring->consume) < count)) {
- ring->mark = 0;
- }
-#ifdef ENCRYPTION
- if (ring->consume < ring->clearto &&
- ring->clearto <= ring->consume + count)
- ring->clearto = 0;
- else if (ring->consume + count > ring->top &&
- ring->bottom <= ring->clearto &&
- ring->bottom + ((ring->consume + count) - ring->top))
- ring->clearto = 0;
-#endif /* ENCRYPTION */
- ring->consume = ring_increment(ring, ring->consume, count);
- ring->consumetime = ++ring_clock;
- /*
- * Try to encourage "ring_empty_consecutive()" to be large.
- */
- if (ring_empty(ring)) {
- ring->consume = ring->supply = ring->bottom;
- }
-}
-
-
-
-/* Buffer state query routines */
-
-
-/* Number of bytes that may be supplied */
- int
-ring_empty_count(ring)
- Ring *ring;
-{
- if (ring_empty(ring)) { /* if empty */
- return ring->size;
- } else {
- return ring_subtract(ring, ring->consume, ring->supply);
- }
-}
-
-/* number of CONSECUTIVE bytes that may be supplied */
- int
-ring_empty_consecutive(ring)
- Ring *ring;
-{
- if ((ring->consume < ring->supply) || ring_empty(ring)) {
- /*
- * if consume is "below" supply, or empty, then
- * return distance to the top
- */
- return ring_subtract(ring, ring->top, ring->supply);
- } else {
- /*
- * else, return what we may.
- */
- return ring_subtract(ring, ring->consume, ring->supply);
- }
-}
-
-/* Return the number of bytes that are available for consuming
- * (but don't give more than enough to get to cross over set mark)
- */
-
- int
-ring_full_count(ring)
- Ring *ring;
-{
- if ((ring->mark == 0) || (ring->mark == ring->consume)) {
- if (ring_full(ring)) {
- return ring->size; /* nothing consumed, but full */
- } else {
- return ring_subtract(ring, ring->supply, ring->consume);
- }
- } else {
- return ring_subtract(ring, ring->mark, ring->consume);
- }
-}
-
-/*
- * Return the number of CONSECUTIVE bytes available for consuming.
- * However, don't return more than enough to cross over set mark.
- */
- int
-ring_full_consecutive(ring)
- Ring *ring;
-{
- if ((ring->mark == 0) || (ring->mark == ring->consume)) {
- if ((ring->supply < ring->consume) || ring_full(ring)) {
- return ring_subtract(ring, ring->top, ring->consume);
- } else {
- return ring_subtract(ring, ring->supply, ring->consume);
- }
- } else {
- if (ring->mark < ring->consume) {
- return ring_subtract(ring, ring->top, ring->consume);
- } else { /* Else, distance to mark */
- return ring_subtract(ring, ring->mark, ring->consume);
- }
- }
-}
-
-/*
- * Move data into the "supply" portion of of the ring buffer.
- */
- void
-ring_supply_data(ring, buffer, count)
- Ring *ring;
- unsigned char *buffer;
- int count;
-{
- int i;
-
- while (count) {
- i = MIN(count, ring_empty_consecutive(ring));
- memcpy(ring->supply, buffer, i);
- ring_supplied(ring, i);
- count -= i;
- buffer += i;
- }
-}
-
-#ifdef notdef
-
-/*
- * Move data from the "consume" portion of the ring buffer
- */
- void
-ring_consume_data(ring, buffer, count)
- Ring *ring;
- unsigned char *buffer;
- int count;
-{
- int i;
-
- while (count) {
- i = MIN(count, ring_full_consecutive(ring));
- memcpy(buffer, ring->consume, i);
- ring_consumed(ring, i);
- count -= i;
- buffer += i;
- }
-}
-#endif
-
-#ifdef ENCRYPTION
- void
-ring_encrypt(ring, encryptor)
- Ring *ring;
- void (*encryptor)();
-{
- unsigned char *s, *c;
-
- if (ring_empty(ring) || ring->clearto == ring->supply)
- return;
-
- if (!(c = ring->clearto))
- c = ring->consume;
-
- s = ring->supply;
-
- if (s <= c) {
- (*encryptor)(c, ring->top - c);
- (*encryptor)(ring->bottom, s - ring->bottom);
- } else
- (*encryptor)(c, s - c);
-
- ring->clearto = ring->supply;
-}
-
- void
-ring_clearto(ring)
- Ring *ring;
-{
- if (!ring_empty(ring))
- ring->clearto = ring->supply;
- else
- ring->clearto = 0;
-}
-#endif /* ENCRYPTION */
+++ /dev/null
-/*
- * 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.
- *
- * @(#)ring.h 8.1 (Berkeley) 6/6/93
- */
-
-/*
- * This defines a structure for a ring buffer.
- *
- * The circular buffer has two parts:
- *(((
- * full: [consume, supply)
- * empty: [supply, consume)
- *]]]
- *
- */
-typedef struct {
- unsigned char *consume, /* where data comes out of */
- *supply, /* where data comes in to */
- *bottom, /* lowest address in buffer */
- *top, /* highest address+1 in buffer */
- *mark; /* marker (user defined) */
-#ifdef ENCRYPTION
- unsigned char *clearto; /* Data to this point is clear text */
- unsigned char *encryyptedto; /* Data is encrypted to here */
-#endif /* ENCRYPTION */
- int size; /* size in bytes of buffer */
- u_long consumetime, /* help us keep straight full, empty, etc. */
- supplytime;
-} Ring;
-
-/* Here are some functions and macros to deal with the ring buffer */
-
-/* Initialization routine */
-extern int
- ring_init (Ring *ring, unsigned char *buffer, int count);
-
-/* Data movement routines */
-extern void
- ring_supply_data (Ring *ring, unsigned char *buffer, int count);
-#ifdef notdef
-extern void
- ring_consume_data (Ring *ring, unsigned char *buffer, int count);
-#endif
-
-/* Buffer state transition routines */
-extern void
- ring_supplied (Ring *ring, int count),
- ring_consumed (Ring *ring, int count);
-
-/* Buffer state query routines */
-extern int
- ring_empty_count (Ring *ring),
- ring_empty_consecutive (Ring *ring),
- ring_full_count (Ring *ring),
- ring_full_consecutive (Ring *ring);
-
-#ifdef ENCRYPTION
-extern void
- ring_encrypt (Ring *ring, void (*func)()),
- ring_clearto (Ring *ring);
-#endif /* ENCRYPTION */
-
-extern void
- ring_clear_mark (Ring *ring),
- ring_mark (Ring *ring);
-
-extern int
- ring_at_mark (Ring *);
+++ /dev/null
-/*
- * Copyright (c) 1988, 1990, 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.
- */
-
-/* based on @(#)sys_bsd.c 8.1 (Berkeley) 6/6/93 */
-
-/*
- * The following routines try to encapsulate what is system dependent
- * (at least between 4.x and dos) which is used in telnet.c.
- */
-
-
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-#include <signal.h>
-#ifdef POSIX_SIGNALS
-#include <unistd.h>
-#endif /* POSIX_SIGNALS */
-#include <errno.h>
-#include <arpa/telnet.h>
-
-#include "ring.h"
-
-#include "fdset.h"
-
-#include "defines.h"
-#include "externs.h"
-#include "types.h"
-
-#if defined(CRAY) || (defined(USE_TERMIO) && !defined(SYSV_TERMIO))
-#define SIG_FUNC_RET void
-#else
-#define SIG_FUNC_RET int
-#endif
-
-#ifdef SIGTSTP
-static SIG_FUNC_RET susp(int);
-#endif /* SIGTSTP */
-#ifdef SIGINFO
-SIG_FUNC_RET ayt(int);
-#endif
-#ifdef SIGINFO
-extern SIG_FUNC_RET ayt_status();
-#endif
-
-#ifdef POSIX_SIGNALS
-static struct sigaction new_sa_rec, old_sa_rec;
-
-#ifdef SA_INTERRUPT
-#define SIGACTION_INTERRUPT SA_INTERRUPT
-#else
-#define SIGACTION_INTERRUPT 0
-#endif
-
-#ifdef SA_NOMASK
-#define SIGACTION_NOMASK SA_NOMASK
-#else
-#define SIGACTION_NOMASK 0
-#endif
-
-#define signal(sig, func) ((new_sa_rec.sa_handler = func), \
- sigemptyset(&new_sa_rec.sa_mask), \
- (new_sa_rec.sa_flags = SIGACTION_INTERRUPT | \
- SIGACTION_NOMASK), \
- sigaction(sig, &new_sa_rec, &old_sa_rec), \
- old_sa_rec.sa_handler)
-
-#endif /* POSIX_SIGNALS */
-
-int
- tout, /* Output file descriptor */
- tin, /* Input file descriptor */
- net;
-
-#ifndef USE_TERMIO
-struct tchars otc = { 0 }, ntc = { 0 };
-struct ltchars oltc = { 0 }, nltc = { 0 };
-struct sgttyb ottyb = { 0 }, nttyb = { 0 };
-int olmode = 0;
-# define cfgetispeed(ptr) (ptr)->sg_ispeed
-# define cfgetospeed(ptr) (ptr)->sg_ospeed
-# define old_tc ottyb
-
-#else /* USE_TERMIO */
-struct termio old_tc = { 0 };
-extern struct termio new_tc;
-
-# ifndef TCSANOW
-# ifdef TCSETS
-# define TCSANOW TCSETS
-# define TCSADRAIN TCSETSW
-# define tcgetattr(f, t) ioctl(f, TCGETS, (char *)t)
-# else
-# ifdef TCSETA
-# define TCSANOW TCSETA
-# define TCSADRAIN TCSETAW
-# define tcgetattr(f, t) ioctl(f, TCGETA, (char *)t)
-# else
-# define TCSANOW TIOCSETA
-# define TCSADRAIN TIOCSETAW
-# define tcgetattr(f, t) ioctl(f, TIOCGETA, (char *)t)
-# endif
-# endif
-# define tcsetattr(f, a, t) ioctl(f, a, (char *)t)
-# define cfgetospeed(ptr) ((ptr)->c_cflag&CBAUD)
-# ifdef CIBAUD
-# define cfgetispeed(ptr) (((ptr)->c_cflag&CIBAUD) >> IBSHIFT)
-# else
-# define cfgetispeed(ptr) cfgetospeed(ptr)
-# endif
-# endif /* TCSANOW */
-# ifdef sysV88
-# define TIOCFLUSH TC_PX_DRAIN
-# endif
-#endif /* USE_TERMIO */
-
-static fd_set ibits, obits, xbits;
-
-
- void
-init_sys()
-{
- tout = fileno(stdout);
- tin = fileno(stdin);
- FD_ZERO(&ibits);
- FD_ZERO(&obits);
- FD_ZERO(&xbits);
-
- errno = 0;
-}
-
-
- int
-TerminalWrite(buf, n)
- unsigned char *buf;
- int n;
-{
- return write(tout, buf, n);
-}
-
- int
-TerminalRead(buf, n)
- unsigned char *buf;
- int n;
-{
- return read(tin, buf, n);
-}
-
-/*
- *
- */
-
- int
-TerminalAutoFlush()
-{
-#if defined(LNOFLSH)
- int flush;
-
- ioctl(0, TIOCLGET, (char *)&flush);
- return !(flush&LNOFLSH); /* if LNOFLSH, no autoflush */
-#else /* LNOFLSH */
- return 1;
-#endif /* LNOFLSH */
-}
-
-#ifdef KLUDGELINEMODE
-extern int kludgelinemode;
-#endif
-/*
- * TerminalSpecialChars()
- *
- * Look at an input character to see if it is a special character
- * and decide what to do.
- *
- * Output:
- *
- * 0 Don't add this character.
- * 1 Do add this character
- */
-
- int
-TerminalSpecialChars(c)
- int c;
-{
- if (c == termIntChar) {
- intp();
- return 0;
- } else if (c == termQuitChar) {
-#ifdef KLUDGELINEMODE
- if (kludgelinemode)
- sendbrk();
- else
-#endif
- sendabort();
- return 0;
- } else if (c == termEofChar) {
- if (my_want_state_is_will(TELOPT_LINEMODE)) {
- sendeof();
- return 0;
- }
- return 1;
- } else if (c == termSuspChar) {
- sendsusp();
- return(0);
- } else if (c == termFlushChar) {
- xmitAO(); /* Transmit Abort Output */
- return 0;
- } else if (!MODE_LOCAL_CHARS(globalmode)) {
- if (c == termKillChar) {
- xmitEL();
- return 0;
- } else if (c == termEraseChar) {
- xmitEC(); /* Transmit Erase Character */
- return 0;
- }
- }
- return 1;
-}
-
-
-/*
- * Flush output to the terminal
- */
- void
-TerminalFlushOutput()
-{
-#ifdef TIOCFLUSH
- (void) ioctl(fileno(stdout), TIOCFLUSH, (char *) 0);
-#else
- (void) ioctl(fileno(stdout), TCFLSH, (char *) 0);
-#endif
-}
-
- void
-TerminalSaveState()
-{
-#ifndef USE_TERMIO
- ioctl(0, TIOCGETP, (char *)&ottyb);
- ioctl(0, TIOCGETC, (char *)&otc);
- ioctl(0, TIOCGLTC, (char *)&oltc);
- ioctl(0, TIOCLGET, (char *)&olmode);
-
- ntc = otc;
- nltc = oltc;
- nttyb = ottyb;
-
-#else /* USE_TERMIO */
- tcgetattr(0, &old_tc);
-
- new_tc = old_tc;
-
-#ifndef VDISCARD
- termFlushChar = CONTROL('O');
-#endif
-#ifndef VWERASE
- termWerasChar = CONTROL('W');
-#endif
-#ifndef VREPRINT
- termRprntChar = CONTROL('R');
-#endif
-#ifndef VLNEXT
- termLiteralNextChar = CONTROL('V');
-#endif
-#ifndef VSTART
- termStartChar = CONTROL('Q');
-#endif
-#ifndef VSTOP
- termStopChar = CONTROL('S');
-#endif
-#ifndef VSTATUS
- termAytChar = CONTROL('T');
-#endif
-#endif /* USE_TERMIO */
-}
-
- cc_t *
-tcval(func)
- register int func;
-{
- switch(func) {
- case SLC_IP: return(&termIntChar);
- case SLC_ABORT: return(&termQuitChar);
- case SLC_EOF: return(&termEofChar);
- case SLC_EC: return(&termEraseChar);
- case SLC_EL: return(&termKillChar);
- case SLC_XON: return(&termStartChar);
- case SLC_XOFF: return(&termStopChar);
- case SLC_FORW1: return(&termForw1Char);
-#ifdef USE_TERMIO
- case SLC_FORW2: return(&termForw2Char);
-# ifdef VDISCARD
- case SLC_AO: return(&termFlushChar);
-# endif
-# ifdef VSUSP
- case SLC_SUSP: return(&termSuspChar);
-# endif
-# ifdef VWERASE
- case SLC_EW: return(&termWerasChar);
-# endif
-# ifdef VREPRINT
- case SLC_RP: return(&termRprntChar);
-# endif
-# ifdef VLNEXT
- case SLC_LNEXT: return(&termLiteralNextChar);
-# endif
-# ifdef VSTATUS
- case SLC_AYT: return(&termAytChar);
-# endif
-#endif
-
- case SLC_SYNCH:
- case SLC_BRK:
- case SLC_EOR:
- default:
- return((cc_t *)0);
- }
-}
-
- void
-TerminalDefaultChars()
-{
-#ifndef USE_TERMIO
- ntc = otc;
- nltc = oltc;
- nttyb.sg_kill = ottyb.sg_kill;
- nttyb.sg_erase = ottyb.sg_erase;
-#else /* USE_TERMIO */
- memcpy(new_tc.c_cc, old_tc.c_cc, sizeof(old_tc.c_cc));
-# ifndef VDISCARD
- termFlushChar = CONTROL('O');
-# endif
-# ifndef VWERASE
- termWerasChar = CONTROL('W');
-# endif
-# ifndef VREPRINT
- termRprntChar = CONTROL('R');
-# endif
-# ifndef VLNEXT
- termLiteralNextChar = CONTROL('V');
-# endif
-# ifndef VSTART
- termStartChar = CONTROL('Q');
-# endif
-# ifndef VSTOP
- termStopChar = CONTROL('S');
-# endif
-# ifndef VSTATUS
- termAytChar = CONTROL('T');
-# endif
-#endif /* USE_TERMIO */
-}
-
-#ifdef notdef
-void
-TerminalRestoreState()
-{
-}
-#endif
-
-/*
- * TerminalNewMode - set up terminal to a specific mode.
- * MODE_ECHO: do local terminal echo
- * MODE_FLOW: do local flow control
- * MODE_TRAPSIG: do local mapping to TELNET IAC sequences
- * MODE_EDIT: do local line editing
- *
- * Command mode:
- * MODE_ECHO|MODE_EDIT|MODE_FLOW|MODE_TRAPSIG
- * local echo
- * local editing
- * local xon/xoff
- * local signal mapping
- *
- * Linemode:
- * local/no editing
- * Both Linemode and Single Character mode:
- * local/remote echo
- * local/no xon/xoff
- * local/no signal mapping
- */
-
-
- void
-TerminalNewMode(f)
- register int f;
-{
- static int prevmode = 0;
-#ifndef USE_TERMIO
- struct tchars tc;
- struct ltchars ltc;
- struct sgttyb sb;
- int lmode;
-#else /* USE_TERMIO */
- struct termio tmp_tc;
-#endif /* USE_TERMIO */
- int onoff;
- int old;
- cc_t esc;
-
- globalmode = f&~MODE_FORCE;
- if (prevmode == f)
- return;
-
- /*
- * Write any outstanding data before switching modes
- * ttyflush() returns 0 only when there is no more data
- * left to write out, it returns -1 if it couldn't do
- * anything at all, otherwise it returns 1 + the number
- * of characters left to write.
-#ifndef USE_TERMIO
- * We would really like ask the kernel to wait for the output
- * to drain, like we can do with the TCSADRAIN, but we don't have
- * that option. The only ioctl that waits for the output to
- * drain, TIOCSETP, also flushes the input queue, which is NOT
- * what we want (TIOCSETP is like TCSADFLUSH).
-#endif
- */
- old = ttyflush(SYNCHing|flushout);
- if (old < 0 || old > 1) {
-#ifdef USE_TERMIO
- tcgetattr(tin, &tmp_tc);
-#endif /* USE_TERMIO */
- do {
- /*
- * Wait for data to drain, then flush again.
- */
-#ifdef USE_TERMIO
- tcsetattr(tin, TCSADRAIN, &tmp_tc);
-#endif /* USE_TERMIO */
- old = ttyflush(SYNCHing|flushout);
- } while (old < 0 || old > 1);
- }
-
- old = prevmode;
- prevmode = f&~MODE_FORCE;
-#ifndef USE_TERMIO
- sb = nttyb;
- tc = ntc;
- ltc = nltc;
- lmode = olmode;
-#else
- tmp_tc = new_tc;
-#endif
-
- if (f&MODE_ECHO) {
-#ifndef USE_TERMIO
- sb.sg_flags |= ECHO;
-#else
- tmp_tc.c_lflag |= ECHO;
- tmp_tc.c_oflag |= ONLCR;
- if (crlf)
- tmp_tc.c_iflag |= ICRNL;
-#endif
- } else {
-#ifndef USE_TERMIO
- sb.sg_flags &= ~ECHO;
-#else
- tmp_tc.c_lflag &= ~ECHO;
- tmp_tc.c_oflag &= ~ONLCR;
-# ifdef notdef
- if (crlf)
- tmp_tc.c_iflag &= ~ICRNL;
-# endif
-#endif
- }
-
- if ((f&MODE_FLOW) == 0) {
-#ifndef USE_TERMIO
- tc.t_startc = _POSIX_VDISABLE;
- tc.t_stopc = _POSIX_VDISABLE;
-#else
- tmp_tc.c_iflag &= ~(IXOFF|IXON); /* Leave the IXANY bit alone */
- } else {
- if (restartany < 0) {
- tmp_tc.c_iflag |= IXOFF|IXON; /* Leave the IXANY bit alone */
- } else if (restartany > 0) {
- tmp_tc.c_iflag |= IXOFF|IXON|IXANY;
- } else {
- tmp_tc.c_iflag |= IXOFF|IXON;
- tmp_tc.c_iflag &= ~IXANY;
- }
-#endif
- }
-
- if ((f&MODE_TRAPSIG) == 0) {
-#ifndef USE_TERMIO
- tc.t_intrc = _POSIX_VDISABLE;
- tc.t_quitc = _POSIX_VDISABLE;
- tc.t_eofc = _POSIX_VDISABLE;
- ltc.t_suspc = _POSIX_VDISABLE;
- ltc.t_dsuspc = _POSIX_VDISABLE;
-#else
- tmp_tc.c_lflag &= ~ISIG;
-#endif
- localchars = 0;
- } else {
-#ifdef USE_TERMIO
- tmp_tc.c_lflag |= ISIG;
-#endif
- localchars = 1;
- }
-
- if (f&MODE_EDIT) {
-#ifndef USE_TERMIO
- sb.sg_flags &= ~CBREAK;
- sb.sg_flags |= CRMOD;
-#else
- tmp_tc.c_lflag |= ICANON;
-#endif
- } else {
-#ifndef USE_TERMIO
- sb.sg_flags |= CBREAK;
- if (f&MODE_ECHO)
- sb.sg_flags |= CRMOD;
- else
- sb.sg_flags &= ~CRMOD;
-#else
- tmp_tc.c_lflag &= ~ICANON;
- tmp_tc.c_iflag &= ~ICRNL;
- tmp_tc.c_cc[VMIN] = 1;
- tmp_tc.c_cc[VTIME] = 0;
-#endif
- }
-
- if ((f&(MODE_EDIT|MODE_TRAPSIG)) == 0) {
-#ifndef USE_TERMIO
- ltc.t_lnextc = _POSIX_VDISABLE;
-#else
-# ifdef VLNEXT
- tmp_tc.c_cc[VLNEXT] = (cc_t)(_POSIX_VDISABLE);
-# endif
-#endif
- }
-
- if (f&MODE_SOFT_TAB) {
-#ifndef USE_TERMIO
- sb.sg_flags |= XTABS;
-#else
-# ifdef OXTABS
- tmp_tc.c_oflag |= OXTABS;
-# endif
-# ifdef TABDLY
- tmp_tc.c_oflag &= ~TABDLY;
- tmp_tc.c_oflag |= TAB3;
-# endif
-#endif
- } else {
-#ifndef USE_TERMIO
- sb.sg_flags &= ~XTABS;
-#else
-# ifdef OXTABS
- tmp_tc.c_oflag &= ~OXTABS;
-# endif
-# ifdef TABDLY
- tmp_tc.c_oflag &= ~TABDLY;
-# endif
-#endif
- }
-
- if (f&MODE_LIT_ECHO) {
-#ifndef USE_TERMIO
- lmode &= ~LCTLECH;
-#else
-# ifdef ECHOCTL
- tmp_tc.c_lflag &= ~ECHOCTL;
-# endif
-#endif
- } else {
-#ifndef USE_TERMIO
- lmode |= LCTLECH;
-#else
-# ifdef ECHOCTL
- tmp_tc.c_lflag |= ECHOCTL;
-# endif
-#endif
- }
-
- if (f == -1) {
- onoff = 0;
- } else {
-#ifndef USE_TERMIO
- if (f & MODE_OUTBIN)
- lmode |= LLITOUT;
- else
- lmode &= ~LLITOUT;
-
- if (f & MODE_INBIN)
- lmode |= LPASS8;
- else
- lmode &= ~LPASS8;
-#else
- if (f & MODE_INBIN)
- tmp_tc.c_iflag &= ~ISTRIP;
- else
- tmp_tc.c_iflag |= ISTRIP;
- if (f & MODE_OUTBIN) {
- tmp_tc.c_cflag &= ~(CSIZE|PARENB);
- tmp_tc.c_cflag |= CS8;
- tmp_tc.c_oflag &= ~OPOST;
- } else {
- tmp_tc.c_cflag &= ~(CSIZE|PARENB);
- tmp_tc.c_cflag |= old_tc.c_cflag & (CSIZE|PARENB);
- tmp_tc.c_oflag |= OPOST;
- }
-#endif
- onoff = 1;
- }
-
- if (f != -1) {
-
-#ifdef SIGTSTP
- (void) signal(SIGTSTP, susp);
-#endif /* SIGTSTP */
-#ifdef SIGINFO
- (void) signal(SIGINFO, ayt);
-#endif
-#if defined(USE_TERMIO) && defined(NOKERNINFO)
- tmp_tc.c_lflag |= NOKERNINFO;
-#endif
- /*
- * We don't want to process ^Y here. It's just another
- * character that we'll pass on to the back end. It has
- * to process it because it will be processed when the
- * user attempts to read it, not when we send it.
- */
-#ifndef USE_TERMIO
- ltc.t_dsuspc = _POSIX_VDISABLE;
-#else
-# ifdef VDSUSP
- tmp_tc.c_cc[VDSUSP] = (cc_t)(_POSIX_VDISABLE);
-# endif
-#endif
-#ifdef USE_TERMIO
- /*
- * If the VEOL character is already set, then use VEOL2,
- * otherwise use VEOL.
- */
- esc = (rlogin != _POSIX_VDISABLE) ? rlogin : escape;
- if ((tmp_tc.c_cc[VEOL] != esc)
-# ifdef VEOL2
- && (tmp_tc.c_cc[VEOL2] != esc)
-# endif
- ) {
- if (tmp_tc.c_cc[VEOL] == (cc_t)(_POSIX_VDISABLE))
- tmp_tc.c_cc[VEOL] = esc;
-# ifdef VEOL2
- else if (tmp_tc.c_cc[VEOL2] == (cc_t)(_POSIX_VDISABLE))
- tmp_tc.c_cc[VEOL2] = esc;
-# endif
- }
-#else
- if (tc.t_brkc == (cc_t)(_POSIX_VDISABLE))
- tc.t_brkc = esc;
-#endif
- } else {
-#ifdef SIGINFO
- SIG_FUNC_RET ayt_status();
-
- (void) signal(SIGINFO, ayt_status);
-#endif
-#ifdef SIGTSTP
- (void) signal(SIGTSTP, SIG_DFL);
-#ifdef POSIX_SIGNALS
- {
- sigset_t tmask;
- sigemptyset(&tmask);
- sigaddset(&tmask, SIGTSTP);
- sigprocmask(SIG_UNBLOCK, &tmask, (sigset_t*)0);
- }
-#else
- (void) sigsetmask(sigblock(0) & ~(1<<(SIGTSTP-1)));
-#endif
-#endif /* SIGTSTP */
-#ifndef USE_TERMIO
- ltc = oltc;
- tc = otc;
- sb = ottyb;
- lmode = olmode;
-#else
- tmp_tc = old_tc;
-#endif
- }
-#ifndef USE_TERMIO
- ioctl(tin, TIOCLSET, (char *)&lmode);
- ioctl(tin, TIOCSLTC, (char *)<c);
- ioctl(tin, TIOCSETC, (char *)&tc);
- ioctl(tin, TIOCSETN, (char *)&sb);
-#else
- if (tcsetattr(tin, TCSADRAIN, &tmp_tc) < 0)
- tcsetattr(tin, TCSANOW, &tmp_tc);
-#endif
-
-#if (!defined(TN3270)) || ((!defined(NOT43)) || defined(PUTCHAR))
-# if !defined(sysV88)
- ioctl(tin, FIONBIO, (char *)&onoff);
- ioctl(tout, FIONBIO, (char *)&onoff);
-# endif
-#endif /* (!defined(TN3270)) || ((!defined(NOT43)) || defined(PUTCHAR)) */
-#if defined(TN3270)
- if (noasynchtty == 0) {
- ioctl(tin, FIOASYNC, (char *)&onoff);
- }
-#endif /* defined(TN3270) */
-
-}
-
-#ifndef B19200
-# define B19200 B9600
-#endif
-
-#ifndef B38400
-# define B38400 B19200
-#endif
-
-/*
- * This code assumes that the values B0, B50, B75...
- * are in ascending order. They do not have to be
- * contiguous.
- */
-struct termspeeds {
- long speed;
- long value;
-} termspeeds[] = {
- { 0, B0 }, { 50, B50 }, { 75, B75 },
- { 110, B110 }, { 134, B134 }, { 150, B150 },
- { 200, B200 }, { 300, B300 }, { 600, B600 },
- { 1200, B1200 }, { 1800, B1800 }, { 2400, B2400 },
- { 4800, B4800 }, { 9600, B9600 }, { 19200, B19200 },
- { 38400, B38400 }, { -1, B38400 }
-};
-
- void
-TerminalSpeeds(ispeed, ospeed)
- long *ispeed;
- long *ospeed;
-{
- register struct termspeeds *tp;
- register long in, out;
-
- out = cfgetospeed(&old_tc);
- in = cfgetispeed(&old_tc);
- if (in == 0)
- in = out;
-
- tp = termspeeds;
- while ((tp->speed != -1) && (tp->value < in))
- tp++;
- *ispeed = tp->speed;
-
- tp = termspeeds;
- while ((tp->speed != -1) && (tp->value < out))
- tp++;
- *ospeed = tp->speed;
-}
-
- int
-TerminalWindowSize(rows, cols)
- long *rows, *cols;
-{
-#ifdef TIOCGWINSZ
- struct winsize ws;
-
- if (ioctl(fileno(stdin), TIOCGWINSZ, (char *)&ws) >= 0) {
- *rows = ws.ws_row;
- *cols = ws.ws_col;
- return 1;
- }
-#endif /* TIOCGWINSZ */
- return 0;
-}
-
- int
-NetClose(fd)
- int fd;
-{
- return close(fd);
-}
-
-
-static void
-NetNonblockingIO(fd, onoff)
- int fd;
- int onoff;
-{
- ioctl(fd, FIONBIO, (char *)&onoff);
-}
-
-#if defined(TN3270)
- void
-NetSigIO(fd, onoff)
- int fd;
- int onoff;
-{
- ioctl(fd, FIOASYNC, (char *)&onoff); /* hear about input */
-}
-
- void
-NetSetPgrp(fd)
- int fd;
-{
- int myPid;
-
- myPid = getpid();
- fcntl(fd, F_SETOWN, myPid);
-}
-#endif /*defined(TN3270)*/
-\f
-/*
- * Various signal handling routines.
- */
-
- /* ARGSUSED */
-static SIG_FUNC_RET
-deadpeer(sig)
- int sig;
-{
- setcommandmode();
- longjmp(peerdied, -1);
-}
-
-int intr_happened = 0;
-int intr_waiting = 0;
-
- /* ARGSUSED */
-static SIG_FUNC_RET
-intr(sig)
- int sig;
-{
- if (intr_waiting) {
- intr_happened = 1;
- return;
- }
- if (localchars) {
- intp();
- return;
- }
- setcommandmode();
- longjmp(toplevel, -1);
-}
-
- /* ARGSUSED */
-static SIG_FUNC_RET
-intr2(sig)
- int sig;
-{
- if (localchars) {
-#ifdef KLUDGELINEMODE
- if (kludgelinemode)
- sendbrk();
- else
-#endif
- sendabort();
- return;
- }
-}
-
-#ifdef SIGTSTP
- /* ARGSUSED */
-static SIG_FUNC_RET
-susp(sig)
- int sig;
-{
- if ((rlogin != _POSIX_VDISABLE) && rlogin_susp())
- return;
- if (localchars)
- sendsusp();
-}
-#endif
-
-#ifdef SIGWINCH
- /* ARGSUSED */
-static SIG_FUNC_RET
-sendwin(sig)
- int sig;
-{
- if (connected) {
- sendnaws();
- }
-}
-#endif
-
-#ifdef SIGINFO
- /* ARGSUSED */
- SIG_FUNC_RET
-ayt(sig)
- int sig;
-{
- if (connected)
- sendayt();
- else
- ayt_status();
-}
-#endif
-
-\f
- void
-sys_telnet_init()
-{
- (void) signal(SIGINT, intr);
- (void) signal(SIGQUIT, intr2);
- (void) signal(SIGPIPE, deadpeer);
-#ifdef SIGWINCH
- (void) signal(SIGWINCH, sendwin);
-#endif
-#ifdef SIGTSTP
- (void) signal(SIGTSTP, susp);
-#endif
-#ifdef SIGINFO
- (void) signal(SIGINFO, ayt);
-#endif
-
- setconnmode(0);
-
- NetNonblockingIO(net, 1);
-
-#if defined(TN3270)
- if (noasynchnet == 0) { /* DBX can't handle! */
- NetSigIO(net, 1);
- NetSetPgrp(net);
- }
-#endif /* defined(TN3270) */
-
-#if defined(SO_OOBINLINE)
- if (SetSockOpt(net, SOL_SOCKET, SO_OOBINLINE, 1) == -1) {
- perror("SetSockOpt");
- }
-#endif /* defined(SO_OOBINLINE) */
-}
-
-/*
- * Process rings -
- *
- * This routine tries to fill up/empty our various rings.
- *
- * The parameter specifies whether this is a poll operation,
- * or a block-until-something-happens operation.
- *
- * The return value is 1 if something happened, 0 if not.
- */
-
- int
-process_rings(netin, netout, netex, ttyin, ttyout, poll)
- int poll; /* If 0, then block until something to do */
-{
- register int c;
- /* One wants to be a bit careful about setting returnValue
- * to one, since a one implies we did some useful work,
- * and therefore probably won't be called to block next
- * time (TN3270 mode only).
- */
- int returnValue = 0;
- static struct timeval TimeValue = { 0 };
-
- if (netout) {
- FD_SET(net, &obits);
- }
- if (ttyout) {
- FD_SET(tout, &obits);
- }
-#if defined(TN3270)
- if (ttyin) {
- FD_SET(tin, &ibits);
- }
-#else /* defined(TN3270) */
- if (ttyin) {
- FD_SET(tin, &ibits);
- }
-#endif /* defined(TN3270) */
-#if defined(TN3270)
- if (netin) {
- FD_SET(net, &ibits);
- }
-# else /* !defined(TN3270) */
- if (netin) {
- FD_SET(net, &ibits);
- }
-# endif /* !defined(TN3270) */
- if (netex) {
- FD_SET(net, &xbits);
- }
- if ((c = select(16, &ibits, &obits, &xbits,
- (poll == 0)? (struct timeval *)0 : &TimeValue)) < 0) {
- if (c == -1) {
- /*
- * we can get EINTR if we are in line mode,
- * and the user does an escape (TSTP), or
- * some other signal generator.
- */
- if (errno == EINTR) {
- return 0;
- }
-# if defined(TN3270)
- /*
- * we can get EBADF if we were in transparent
- * mode, and the transcom process died.
- */
- if (errno == EBADF) {
- /*
- * zero the bits (even though kernel does it)
- * to make sure we are selecting on the right
- * ones.
- */
- FD_ZERO(&ibits);
- FD_ZERO(&obits);
- FD_ZERO(&xbits);
- return 0;
- }
-# endif /* defined(TN3270) */
- /* I don't like this, does it ever happen? */
- printf("sleep(5) from telnet, after select\r\n");
- sleep(5);
- }
- return 0;
- }
-
- /*
- * Any urgent data?
- */
- if (FD_ISSET(net, &xbits)) {
- FD_CLR(net, &xbits);
- SYNCHing = 1;
- (void) ttyflush(1); /* flush already enqueued data */
- }
-
- /*
- * Something to read from the network...
- */
- if (FD_ISSET(net, &ibits)) {
- int canread;
-
- FD_CLR(net, &ibits);
- canread = ring_empty_consecutive(&netiring);
-#if !defined(SO_OOBINLINE)
- /*
- * In 4.2 (and some early 4.3) systems, the
- * OOB indication and data handling in the kernel
- * is such that if two separate TCP Urgent requests
- * come in, one byte of TCP data will be overlaid.
- * This is fatal for Telnet, but we try to live
- * with it.
- *
- * In addition, in 4.2 (and...), a special protocol
- * is needed to pick up the TCP Urgent data in
- * the correct sequence.
- *
- * What we do is: if we think we are in urgent
- * mode, we look to see if we are "at the mark".
- * If we are, we do an OOB receive. If we run
- * this twice, we will do the OOB receive twice,
- * but the second will fail, since the second
- * time we were "at the mark", but there wasn't
- * any data there (the kernel doesn't reset
- * "at the mark" until we do a normal read).
- * Once we've read the OOB data, we go ahead
- * and do normal reads.
- *
- * There is also another problem, which is that
- * since the OOB byte we read doesn't put us
- * out of OOB state, and since that byte is most
- * likely the TELNET DM (data mark), we would
- * stay in the TELNET SYNCH (SYNCHing) state.
- * So, clocks to the rescue. If we've "just"
- * received a DM, then we test for the
- * presence of OOB data when the receive OOB
- * fails (and AFTER we did the normal mode read
- * to clear "at the mark").
- */
- if (SYNCHing) {
- int atmark;
- static int bogus_oob = 0, first = 1;
-
- ioctl(net, SIOCATMARK, (char *)&atmark);
- if (atmark) {
- c = recv(net, netiring.supply, canread, MSG_OOB);
- if ((c == -1) && (errno == EINVAL)) {
- c = recv(net, netiring.supply, canread, 0);
- if (clocks.didnetreceive < clocks.gotDM) {
- SYNCHing = stilloob(net);
- }
- } else if (first && c > 0) {
- /*
- * Bogosity check. Systems based on 4.2BSD
- * do not return an error if you do a second
- * recv(MSG_OOB). So, we do one. If it
- * succeeds and returns exactly the same
- * data, then assume that we are running
- * on a broken system and set the bogus_oob
- * flag. (If the data was different, then
- * we probably got some valid new data, so
- * increment the count...)
- */
- int i;
- i = recv(net, netiring.supply + c, canread - c, MSG_OOB);
- if (i == c &&
- memcmp(netiring.supply, netiring.supply + c, i) == 0) {
- bogus_oob = 1;
- first = 0;
- } else if (i < 0) {
- bogus_oob = 0;
- first = 0;
- } else
- c += i;
- }
- if (bogus_oob && c > 0) {
- int i;
- /*
- * Bogosity. We have to do the read
- * to clear the atmark to get out of
- * an infinate loop.
- */
- i = read(net, netiring.supply + c, canread - c);
- if (i > 0)
- c += i;
- }
- } else {
- c = recv(net, netiring.supply, canread, 0);
- }
- } else {
- c = recv(net, netiring.supply, canread, 0);
- }
- settimer(didnetreceive);
-#else /* !defined(SO_OOBINLINE) */
- c = recv(net, (char *)netiring.supply, canread, 0);
-#endif /* !defined(SO_OOBINLINE) */
- if (c < 0 && errno == EWOULDBLOCK) {
- c = 0;
- } else if (c <= 0) {
- return -1;
- }
- if (netdata) {
- Dump('<', netiring.supply, c);
- }
- if (c)
- ring_supplied(&netiring, c);
- returnValue = 1;
- }
-
- /*
- * Something to read from the tty...
- */
- if (FD_ISSET(tin, &ibits)) {
- FD_CLR(tin, &ibits);
- c = TerminalRead(ttyiring.supply, ring_empty_consecutive(&ttyiring));
- if (c < 0 && errno == EWOULDBLOCK) {
- c = 0;
- } else {
- /* EOF detection for line mode!!!! */
- if ((c == 0) && MODE_LOCAL_CHARS(globalmode) && isatty(tin)) {
- /* must be an EOF... */
- *ttyiring.supply = termEofChar;
- c = 1;
- }
- if (c <= 0) {
- return -1;
- }
- if (termdata) {
- Dump('<', ttyiring.supply, c);
- }
- ring_supplied(&ttyiring, c);
- }
- returnValue = 1; /* did something useful */
- }
-
- if (FD_ISSET(net, &obits)) {
- FD_CLR(net, &obits);
- returnValue |= netflush();
- }
- if (FD_ISSET(tout, &obits)) {
- FD_CLR(tout, &obits);
- returnValue |= (ttyflush(SYNCHing|flushout) > 0);
- }
-
- return returnValue;
-}
+++ /dev/null
-%!PS-Adobe-3.0
-%%Creator: groff version 1.08
-%%DocumentNeededResources: font Times-Roman
-%%+ font Times-Bold
-%%+ font Courier-Bold
-%%+ font Courier-Oblique
-%%+ font Courier
-%%+ font Symbol
-%%+ font Times-Italic
-%%DocumentSuppliedResources: procset grops 1.08 0
-%%Pages: 10
-%%PageOrder: Ascend
-%%Orientation: Portrait
-%%EndComments
-%%BeginProlog
-%%BeginResource: procset grops 1.08 0
-/setpacking where{
-pop
-currentpacking
-true setpacking
-}if
-/grops 120 dict dup begin
-/SC 32 def
-/A/show load def
-/B{0 SC 3 -1 roll widthshow}bind def
-/C{0 exch ashow}bind def
-/D{0 exch 0 SC 5 2 roll awidthshow}bind def
-/E{0 rmoveto show}bind def
-/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def
-/G{0 rmoveto 0 exch ashow}bind def
-/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/I{0 exch rmoveto show}bind def
-/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def
-/K{0 exch rmoveto 0 exch ashow}bind def
-/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/M{rmoveto show}bind def
-/N{rmoveto 0 SC 3 -1 roll widthshow}bind def
-/O{rmoveto 0 exch ashow}bind def
-/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/Q{moveto show}bind def
-/R{moveto 0 SC 3 -1 roll widthshow}bind def
-/S{moveto 0 exch ashow}bind def
-/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/SF{
-findfont exch
-[exch dup 0 exch 0 exch neg 0 0]makefont
-dup setfont
-[exch/setfont cvx]cvx bind def
-}bind def
-/MF{
-findfont
-[5 2 roll
-0 3 1 roll
-neg 0 0]makefont
-dup setfont
-[exch/setfont cvx]cvx bind def
-}bind def
-/level0 0 def
-/RES 0 def
-/PL 0 def
-/LS 0 def
-/PLG{
-gsave newpath clippath pathbbox grestore
-exch pop add exch pop
-}bind def
-/BP{
-/level0 save def
-1 setlinecap
-1 setlinejoin
-72 RES div dup scale
-LS{
-90 rotate
-}{
-0 PL translate
-}ifelse
-1 -1 scale
-}bind def
-/EP{
-level0 restore
-showpage
-}bind def
-/DA{
-newpath arcn stroke
-}bind def
-/SN{
-transform
-.25 sub exch .25 sub exch
-round .25 add exch round .25 add exch
-itransform
-}bind def
-/DL{
-SN
-moveto
-SN
-lineto stroke
-}bind def
-/DC{
-newpath 0 360 arc closepath
-}bind def
-/TM matrix def
-/DE{
-TM currentmatrix pop
-translate scale newpath 0 0 .5 0 360 arc closepath
-TM setmatrix
-}bind def
-/RC/rcurveto load def
-/RL/rlineto load def
-/ST/stroke load def
-/MT/moveto load def
-/CL/closepath load def
-/FL{
-currentgray exch setgray fill setgray
-}bind def
-/BL/fill load def
-/LW/setlinewidth load def
-/RE{
-findfont
-dup maxlength 1 index/FontName known not{1 add}if dict begin
-{
-1 index/FID ne{def}{pop pop}ifelse
-}forall
-/Encoding exch def
-dup/FontName exch def
-currentdict end definefont pop
-}bind def
-/DEFS 0 def
-/EBEGIN{
-moveto
-DEFS begin
-}bind def
-/EEND/end load def
-/CNT 0 def
-/level1 0 def
-/PBEGIN{
-/level1 save def
-translate
-div 3 1 roll div exch scale
-neg exch neg exch translate
-0 setgray
-0 setlinecap
-1 setlinewidth
-0 setlinejoin
-10 setmiterlimit
-[]0 setdash
-/setstrokeadjust where{
-pop
-false setstrokeadjust
-}if
-/setoverprint where{
-pop
-false setoverprint
-}if
-newpath
-/CNT countdictstack def
-userdict begin
-/showpage{}def
-}bind def
-/PEND{
-clear
-countdictstack CNT sub{end}repeat
-level1 restore
-}bind def
-end def
-/setpacking where{
-pop
-setpacking
-}if
-%%EndResource
-%%IncludeResource: font Times-Roman
-%%IncludeResource: font Times-Bold
-%%IncludeResource: font Courier-Bold
-%%IncludeResource: font Courier-Oblique
-%%IncludeResource: font Courier
-%%IncludeResource: font Symbol
-%%IncludeResource: font Times-Italic
-grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL
-792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron
-/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef
-/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space
-/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft
-/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four
-/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C
-/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash
-/bracketright/circumflex/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q
-/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase
-/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger
-/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut
-/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash
-/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar
-/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus
-/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu
-/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright
-/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde
-/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute
-/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
-/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
-/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute
-/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve
-/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex
-/udieresis/yacute/thorn/ydieresis]def/Times-Italic@0 ENC0/Times-Italic RE
-/Courier@0 ENC0/Courier RE/Courier-Oblique@0 ENC0/Courier-Oblique RE
-/Courier-Bold@0 ENC0/Courier-Bold RE/Times-Bold@0 ENC0/Times-Bold RE
-/Times-Roman@0 ENC0/Times-Roman RE
-%%EndProlog
-%%Page: 1 1
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF -.834(TELNET \( 1 \))72 48 R(BSD Reference Manual)
-258.235 48 Q -.834(TELNET \( 1 \))485.572 48 R/F1 10/Times-Bold@0 SF -.2(NA)72
-108 S(ME).2 E/F2 10/Courier-Bold@0 SF(telnet)102 120 Q F0 2.5<ad75>2.5 G
-(ser interf)153.64 120 Q(ace to the)-.1 E/F3 9/Times-Roman@0 SF(TELNET)2.5 E F0
-(protocol)2.5 E F1(SYNOPSIS)72 144 Q F2(telnet)102 156 Q F0([)3.333 E F2<ad38>
-2.499 E F0 3.333(][).833 G F2<ad45>-.834 E F0 3.333(][).833 G F2<ad46>-.834 E
-F0 3.333(][).833 G F2<ad4b>-.834 E F0 3.333(][).833 G F2<ad4c>-.834 E F0 3.333
-(][).833 G F2<ad53>-.834 E/F4 10/Courier-Oblique@0 SF(tos)6 E F0 3.333(][).833
-G F2<ad58>-.834 E F4(authtype)6 E F0 3.333(][).833 G F2<ad61>-.834 E F0 3.333
-(][).833 G F2<ad63>-.834 E F0 3.333(][).833 G F2<ad64>-.834 E F0 3.333(][).833
-G F2<ad65>-.834 E F4(escapechar)144 168 Q F0 3.333(][).833 G F2<ad66>-.834 E F0
-3.333(][).833 G F2<ad6b>-.834 E F4(realm)6 E F0 3.333(][).833 G F2<ad6c>-.834 E
-F4(user)6 E F0 3.333(][).833 G F2<ad6e>-.834 E F4(tracefile)6 E F0 3.333(][)
-.833 G F2<ad72>-.834 E F0 3.333(][).833 G F2<ad78>-.834 E F0 2.5(][).833 G F4
-(host)491.943 168 Q F0 .833([p)144.833 180 S -1.667(ort ]])-.833 F F1
-(DESCRIPTION)72 204 Q F0(The)102 216 Q F2(telnet)2.523 E F0 .023
-(command is used to communicate with another host using the)2.523 F F3(TELNET)
-2.523 E F0 2.523(protocol. If)2.523 F F2(telnet)2.523 E F0(is)2.522 E(in)102
-228 Q -.2(vo)-.4 G -.1(ke).2 G 2.693(dw).1 G .193(ithout the)143.433 228 R F4
-(host)2.693 E F0(ar)2.693 E .194
-(gument, it enters command mode, indicated by its prompt)-.18 F(\()4.36 E F2
-(telnet>)1.666 E F0 -3.138 1.666(\). I)1.666 H 2.694(nt)-1.666 G(his)528.33 228
-Q 1.07(mode, it accepts and e)102 240 R -.15(xe)-.15 G 1.07
-(cutes the commands listed belo).15 F 4.87 -.65(w. I)-.25 H 3.57(fi).65 G 3.57
-(ti)361.18 240 S 3.57(si)370.31 240 S -1.9 -.4(nv o)380.55 240 T -.1(ke).4 G
-3.57(dw).1 G 1.07(ith ar)420.08 240 R 1.07(guments, it performs an)-.18 F F2
-(open)102 252 Q F0(command with those ar)2.5 E(guments.)-.18 E(Options:)102 270
-Q F2<ad38>103.666 288 Q F0 .352(Speci\214es an 8-bit data path.)143 288 R .353
-(This causes an attempt to ne)5.352 F .353(gotiate the)-.15 F/F5 10/Courier@0
-SF .353(TELNET BINARY)2.853 F F0 .353(option on)2.853 F(both input and output.)
-143 300 Q F2<ad45>103.666 318 Q F0(Stops an)143 318 Q 2.5(yc)-.15 G
-(haracter from being recognized as an escape character)188.96 318 Q(.)-.55 E F2
-<ad46>103.666 336 Q F0 .691(If K)143 336 R .691
-(erberos V5 authentication is being used, the)-.25 F F2<ad46>4.856 E F0 .69
-(option allo)3.19 F .69(ws the local credentials to be for)-.25 F(-)-.2 E -.1
-(wa)143 348 S .615(rded to the remote system, including an).1 F 3.116(yc)-.15 G
-.616(redentials that ha)328.698 348 R .916 -.15(ve a)-.2 H .616
-(lready been forw).15 F .616(arded into the)-.1 F(local en)143 360 Q
-(vironment.)-.4 E F2<ad4b>103.666 378 Q F0
-(Speci\214es no automatic login to the remote system.)143 378 Q F2<ad4c>103.666
-396 Q F0 .147(Speci\214es an 8-bit data path on output.)143 396 R .146
-(This causes the BIN)5.146 F(AR)-.35 E 2.646(Yo)-.65 G .146(ption to be ne)
-409.42 396 R .146(gotiated on output.)-.15 F F2<ad53>103.666 414 Q F4(tos)6 E
-F0 .288(Sets the IP type-of-service \(T)143 426 R .288
-(OS\) option for the telnet connection to the v)-.18 F(alue)-.25 E F4(tos,)
-2.788 E F0 .289(which can be)2.788 F 3.12(an)143 438 S .62(umeric T)155.56 438
-R .62(OS v)-.18 F .62(alue or)-.25 F 3.12(,o)-.4 G 3.12(ns)251.36 438 S .619
-(ystems that support it, a symbolic T)263.37 438 R .619
-(OS name found in the /etc/iptos)-.18 F(\214le.)143 450 Q F2<ad58>103.666 468 Q
-F4(atype)6 E F0(Disables the)143 480 Q F4(atype)2.5 E F0
-(type of authentication.)2.5 E F2<ad61>103.666 498 Q F0 2.562
-(Attempt automatic login.)143 498 R(Currently)7.563 E 5.063(,t)-.65 G 2.563
-(his sends the user name via the)303.99 498 R F5(USER)5.063 E F0 -.25(va)5.063
-G 2.563(riable of the).25 F F5(ENVIRON)143 510 Q F0 .444
-(option if supported by the remote system.)2.945 F .444
-(The name used is that of the current user as)5.444 F .168(returned by)143 522
-R F5(getlogin)2.668 E F0 .168(\(2\) if it agrees with the current user ID, oth\
-erwise it is the name associated)B(with the user ID.)143 534 Q F2<ad63>103.666
-552 Q F0 .022(Disables the reading of the user')143 552 R(s)-.55 E F5
-(.telnetrc)2.522 E F0 2.522(\214le. \(See)2.522 F(the)2.522 E F2 .022
-(toggle skiprc)2.522 F F0 .022(command on this)2.522 F(man page.\))143 564 Q F2
-<ad64>103.666 582 Q F0(Sets the initial v)143 582 Q(alue of the)-.25 E F2
-(debug)2.5 E F0(toggle to)2.5 E F5(TRUE)2.5 E F2<ad65>103.666 600 Q F4
-(escape char)6 E F0 1.759(Sets the initial)143 612 R F2 -1.741(telnet telnet)
-4.259 F F0 1.759(escape character to)4.259 F F4 1.759(escape char.)4.259 F F0
-(If)4.259 E F4 1.76(escape char)4.26 F F0(is)4.26 E
-(omitted, then there will be no escape character)143 624 Q(.)-.55 E F2<ad66>
-103.666 642 Q F0 .691(If K)143 642 R .691
-(erberos V5 authentication is being used, the)-.25 F F2<ad66>4.856 E F0 .69
-(option allo)3.19 F .69(ws the local credentials to be for)-.25 F(-)-.2 E -.1
-(wa)143 654 S(rded to the remote system.).1 E F2<ad6b>103.666 672 Q F4(realm)6
-E F0 .008(If K)143 684 R .008(erberos authentication is being used, the)-.25 F
-F2<ad6b>4.174 E F0 .009(option requests that telnet obtain tick)2.508 F .009
-(ets for the re-)-.1 F 6.61
-(mote host in realm realm instead of the remote host')143 696 R 9.11(sr)-.55 G
-6.61(ealm, as determined by)427.41 696 R(4.2 Berk)72 750 Q(ele)-.1 E 2.5(yD)
--.15 G(istrib)132.57 750 Q 95.71(ution February)-.2 F(3, 1994)2.5 E(1)535 750 Q
-EP
-%%Page: 2 2
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF -.834(TELNET \( 1 \))72 48 R(BSD Reference Manual)
-258.235 48 Q -.834(TELNET \( 1 \))485.572 48 R/F1 10/Courier@0 SF
-(krb_realmofhost)143 96 Q F0(\(3\).)A/F2 10/Courier-Bold@0 SF<ad6c>103.666 114
-Q/F3 10/Courier-Oblique@0 SF(user)6 E F0 1.135
-(When connecting to the remote system, if the remote system understands the)143
-126 R F1(ENVIRON)3.636 E F0(option,)3.636 E(then)143 138 Q F3(user)2.974 E F0
-.474(will be sent to the remote system as the v)2.974 F .474(alue for the v)
--.25 F .474(ariable USER.)-.25 F .473(This option im-)5.474 F(plies the)143 150
-Q F2<ad61>4.166 E F0 2.5(option. This)2.5 F(option may also be used with the)
-2.5 E F2(open)2.5 E F0(command.)2.5 E F2<ad6e>103.666 168 Q F3(tracefile)6 E F0
-(Opens)143 180 Q F3(tracefile)2.561 E F0 .062(for recording trace information.)
-2.561 F .062(See the)5.062 F F2 .062(set tracefile)2.562 F F0 .062
-(command belo)2.562 F -.65(w.)-.25 G F2<ad72>103.666 198 Q F0 .936
-(Speci\214es a user interf)143 198 R .936(ace similar to)-.1 F F1(rlogin)3.435
-E F0 4.37(\(1\). In)B .935(this mode, the escape character is set to the)3.435
-F(tilde \(~\) character)143 210 Q 2.5(,u)-.4 G
-(nless modi\214ed by the -e option.)222.01 210 Q F2<ad78>103.666 228 Q F0 -.45
-(Tu)143 228 S .123(rns on encryption of the data stream if possible.).45 F .124
-(This option is not a)5.124 F -.25(va)-.2 G .124(ilable outside of the Unit-)
-.25 F(ed States and Canada.)143 240 Q F3(host)102 258 Q F0(Indicates the of)143
-258 Q(\214cial name, an alias, or the Internet address of a remote host.)-.25 E
-F3(port)102 276 Q F0 1.96
-(Indicates a port number \(address of an application\).)143 276 R 1.96
-(If a number is not speci\214ed, the def)6.96 F(ault)-.1 E F2(telnet)143 288 Q
-F0(port is used.)2.5 E .237(When in rlogin mode, a line of the form ~.)102 306
-R .238(disconnects from the remote host; ~ is the telnet escape character)5.237
-F(.)-.55 E(Similarly)102 318 Q 2.5(,t)-.65 G
-(he line ~^Z suspends the telnet session.)146.36 318 Q
-(The line ~^] escapes to the normal telnet escape prompt.)5 E 1.008
-(Once a connection has been opened,)102 336 R F2(telnet)3.507 E F0 1.007
-(will attempt to enable the)3.507 F F1 1.007(TELNET LINEMODE)3.507 F F0 3.507
-(option. If)3.507 F .73(this f)102 348 R .73(ails, then)-.1 F F2(telnet)3.23 E
-F0 .73(will re)3.23 F -.15(ve)-.25 G .73(rt to one of tw).15 F 3.23(oi)-.1 G
-.731(nput modes: either `)308.3 348 R .731(`character at a time')-.74 F 3.231
-('o)-.74 G 3.231(r`)483.277 348 S .731(`old line by)492.428 348 R(line')102 360
-Q 2.5('d)-.74 G(epending on what the remote system supports.)130.42 360 Q(When)
-102 378 Q F1(LINEMODE)3.143 E F0 .642(is enabled, character processing is done\
- on the local system, under the control of the re-)3.143 F .123(mote system.)
-102 390 R .123(When input editing or character echoing is to be disabled, the \
-remote system will relay that in-)5.123 F 3.397(formation. The)102 402 R .897
-(remote system will also relay changes to an)3.397 F 3.397(ys)-.15 G .897
-(pecial characters that happen on the remote)361.34 402 R(system, so that the)
-102 414 Q 2.5(yc)-.15 G(an tak)187.68 414 Q 2.5(ee)-.1 G -.25(ff)223.12 414 S
-(ect on the local system.).25 E(In `)102 432 Q(`character at a time')-.74 E 2.5
-('m)-.74 G(ode, most te)208.53 432 Q
-(xt typed is immediately sent to the remote host for processing.)-.15 E .323
-(In `)102 450 R .323(`old line by line')-.74 F 2.823('m)-.74 G .323
-(ode, all te)196.845 450 R .323(xt is echoed locally)-.15 F 2.823(,a)-.65 G
-.323(nd \(normally\) only completed lines are sent to the re-)324.073 450 R
-.757(mote host.)102 462 R .757(The `)5.757 F .757(`local echo character')-.74 F
-3.257('\()-.74 G .756(initially `)268.892 462 R(`^E')-.74 E .756
-('\) may be used to turn of)-.74 F 3.256(fa)-.25 G .756
-(nd on the local echo \(this)435.4 462 R -.1(wo)102 474 S
-(uld mostly be used to enter passw).1 E(ords without the passw)-.1 E
-(ord being echoed\).)-.1 E 1.076(If the)102 492 R F1(LINEMODE)3.576 E F0 1.076
-(option is enabled, or if the)3.576 F F2(localchars)3.577 E F0 1.077(toggle is)
-3.577 F F1(TRUE)3.577 E F0 1.077(\(the def)3.577 F 1.077(ault for `)-.1 F 1.077
-(`old line by)-.74 F(line`)102 504 Q .866(`; see belo)-.74 F .866
-(w\), the user')-.25 F(s)-.55 E F2(quit)3.366 E F0(,)A F2(intr)3.366 E F0 3.366
-(,a)C(nd)285.042 504 Q F2(flush)3.365 E F0 .865(characters are trapped locally)
-3.365 F 3.365(,a)-.65 G .865(nd sent as)461.472 504 R/F4 9/Times-Roman@0 SF
-(TELNET)3.365 E F0 .368(protocol sequences to the remote side.)102 516 R(If)
-5.368 E F1(LINEMODE)2.868 E F0 .368(has e)2.868 F -.15(ve)-.25 G 2.868(rb).15 G
-.368(een enabled, then the user')363.23 516 R(s)-.55 E F2(susp)2.869 E F0(and)
-2.869 E F2(eof)2.869 E F0 1.308(are also sent as)102 528 R F4(TELNET)3.808 E F0
-1.308(protocol sequences, and)3.808 F F2(quit)3.808 E F0 1.307(is sent as a)
-3.807 F F1 1.307(TELNET ABORT)3.807 F F0 1.307(instead of)3.807 F F1(BREAK)
-3.807 E F0 .474(There are options \(see)102 540 R F2 -3.026(toggle autoflush)
-2.974 F F0(and)2.974 E F2 -3.026(toggle autosynch)2.974 F F0(belo)2.974 E .475
-(w\) which cause this action to)-.25 F .194
-(\215ush subsequent output to the terminal \(until the remote host ackno)102
-552 R .194(wledges the)-.25 F F4(TELNET)2.694 E F0 .193(sequence\) and \215ush)
-2.693 F(pre)102 564 Q(vious terminal input \(in the case of)-.25 E F2(quit)2.5
-E F0(and)2.5 E F2(intr)2.5 E F0(\).)A .235(While connected to a remote host,)
-102 582 R F2(telnet)2.735 E F0 .235(command mode may be entered by typing the)
-2.735 F F2(telnet)2.735 E F0 -.74(``)2.735 G(escape).74 E(character')102 594 Q
-2.5('\()-.74 G(initially `)150.39 594 Q(`^]')-.74 E 2.5('\). When)-.74 F
-(in command mode, the normal terminal editing con)2.5 E -.15(ve)-.4 G
-(ntions are a).15 E -.25(va)-.2 G(ilable.).25 E .018(The follo)102 612 R(wing)
--.25 E F2(telnet)2.518 E F0 .018(commands are a)2.518 F -.25(va)-.2 G 2.517
-(ilable. Only).25 F .017(enough of each command to uniquely identify it need)
-2.517 F 2.478(be typed \(this is also true for ar)102 624 R 2.478
-(guments to the)-.18 F F2(mode)4.978 E F0(,)A F2(set)4.978 E F0(,)A F2(toggle)
-4.978 E F0(,)A F2(unset)4.978 E F0(,)A F2(slc)4.978 E F0(,)A F2(environ)4.979 E
-F0 4.979(,a)C(nd)530 624 Q F2(display)102 636 Q F0(commands\).)2.5 E F2(auth)
-102 654 Q F3(argument ...)6 E F0 .308
-(The auth command manipulates the information sent through the)161 666 R F1
-.308(TELNET AUTHENTICATE)2.808 F F0 2.5(option. V)161 678 R(alid ar)-1.11 E
-(guments for the auth command are as follo)-.18 E(ws:)-.25 E(4.2 Berk)72 750 Q
-(ele)-.1 E 2.5(yD)-.15 G(istrib)132.57 750 Q 95.71(ution February)-.2 F
-(3, 1994)2.5 E(2)535 750 Q EP
-%%Page: 3 3
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF -.834(TELNET \( 1 \))72 48 R(BSD Reference Manual)
-258.235 48 Q -.834(TELNET \( 1 \))485.572 48 R/F1 10/Courier-Bold@0 SF(disable)
-161 96 Q/F2 10/Courier-Oblique@0 SF(type)6.76 E F0 .76
-(Disables the speci\214ed type of authentication.)5 F 2.36 -.8(To o)5.76 H .76
-(btain a list of a).8 F -.25(va)-.2 G(ilable).25 E(types, use the)238 108 Q F1
-(auth disable ?)2.5 E F0(command.)2.5 E F1(enable)161 126 Q F2(type)6.992 E F0
-.992(Enables the speci\214ed type of authentication.)238.992 126 R 2.592 -.8
-(To o)5.992 H .991(btain a list of a).8 F -.25(va)-.2 G(ilable).25 E
-(types, use the)238 138 Q F1(auth enable ?)2.5 E F0(command.)2.5 E F1(status)
-161 156 Q F0(Lists the current status of the v)238 156 Q
-(arious types of authentication.)-.25 E F1(close)102 174 Q F0(Close a)161 174 Q
-/F3 9/Times-Roman@0 SF(TELNET)2.5 E F0(session and return to command mode.)2.5
-E F1(display)102 192 Q F2(argument ...)6 E F0(Displays all, or some, of the)161
-204 Q F1(set)2.5 E F0(and)2.5 E F1(toggle)2.5 E F0 -.25(va)2.5 G
-(lues \(see belo).25 E(w\).)-.25 E F1(encrypt)102 222 Q F2(argument ...)6 E F0
-.407(The encrypt command manipulates the information sent through the)161 234 R
-/F4 10/Courier@0 SF .408(TELNET ENCRYPT)2.908 F F0(op-)2.908 E(tion.)161 246 Q
-2.856(Note: Because)161 264 R .356(of e)2.856 F .356(xport controls, the)-.15 F
-F4 .355(TELNET ENCRYPT)2.855 F F0 .355(option is not supported outside of)2.855
-F(the United States and Canada.)161 276 Q -1.11(Va)161 294 S(lid ar)1.11 E
-(guments for the encrypt command are as follo)-.18 E(ws:)-.25 E F1(disable)161
-312 Q F2(type)6 E F1([input|output])6 E F0 1.099
-(Disables the speci\214ed type of encryption.)226 324 R 1.099
-(If you omit the input and output,)6.099 F .357
-(both input and output are disabled.)226 336 R 1.957 -.8(To o)5.357 H .357
-(btain a list of a).8 F -.25(va)-.2 G .357(ilable types, use the).25 F F1
-(encrypt disable ?)226 348 Q F0(command.)2.5 E F1(enable)161 366 Q F2(type)6 E
-F1([input|output])6 E F0 .867(Enables the speci\214ed type of encryption.)226
-378 R .868(If you omit input and output, both)5.867 F 2.117
-(input and output are enabled.)226 390 R 3.716 -.8(To o)7.116 H 2.116
-(btain a list of a).8 F -.25(va)-.2 G 2.116(ilable types, use the).25 F F1
-(encrypt enable ?)226 402 Q F0(command.)2.5 E F1(input)161 420 Q F0
-(This is the same as the)226 420 Q F1(encrypt start input)2.5 E F0(command.)2.5
-E F1(-input)161 438 Q F0(This is the same as the)226 438 Q F1
-(encrypt stop input)2.5 E F0(command.)2.5 E F1(output)161 456 Q F0
-(This is the same as the)226 456 Q F1(encrypt start output)2.5 E F0(command.)
-2.5 E F1(-output)161 474 Q F0(This is the same as the)226 474 Q F1
-(encrypt stop output)2.5 E F0(command.)2.5 E F1(start [input|output])161 492 Q
-F0 1.116(Attempts to start encryption.)226 504 R 1.116(If you omit)6.116 F F1
-(input)3.616 E F0(and)3.617 E F1(output,)3.617 E F0 1.117(both input)3.617 F
-.467(and output are enabled.)226 516 R 2.067 -.8(To o)5.467 H .467
-(btain a list of a).8 F -.25(va)-.2 G .467(ilable types, use the).25 F F1
-(encrypt)2.966 E(enable ?)226 528 Q F0(command.)2.5 E F1(status)161 546 Q F0
-(Lists the current status of encryption.)226 546 Q F1(stop [input|output])161
-564 Q F0 1.096(Stops encryption.)226 576 R 1.097
-(If you omit input and output, encryption is on both input)6.096 F(and output.)
-226 588 Q F1(type)161 606 Q F2(type)6.121 E F0 .121(Sets the def)226.121 606 R
-.121(ault type of encryption to be used with later)-.1 F F1 .12(encrypt start)
-2.62 F F0(or)2.62 E F1(encrypt stop)226 618 Q F0(commands.)2.5 E F1(environ)102
-636 Q F2(arguments...)6 E F0(The)161 648 Q F1(environ)3.189 E F0 .689
-(command is used to manipulate the the v)3.189 F .69
-(ariables that my be sent through the)-.25 F F4 .552(TELNET ENVIRON)161 660 R
-F0 3.052(option. The)3.052 F .552(initial set of v)3.052 F .551
-(ariables is tak)-.25 F .551(en from the users en)-.1 F(vironment,)-.4 E .501
-(with only the)161 672 R F4(DISPLAY)3.001 E F0(and)3.001 E F4(PRINTER)3.001 E
-F0 -.25(va)3.001 G .502(riables being e).25 F .502(xported by def)-.15 F 3.002
-(ault. The)-.1 F F4(USER)3.002 E F0 -.25(va)3.002 G(ri-).25 E(able is also e)
-161 684 Q(xported if the)-.15 E F1<ad61>4.166 E F0(or)2.5 E F1<ad6c>4.166 E F0
-(options are used.)2.5 E(4.2 Berk)72 750 Q(ele)-.1 E 2.5(yD)-.15 G(istrib)
-132.57 750 Q 95.71(ution February)-.2 F(3, 1994)2.5 E(3)535 750 Q EP
-%%Page: 4 4
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF -.834(TELNET \( 1 \))72 48 R(BSD Reference Manual)
-258.235 48 Q -.834(TELNET \( 1 \))485.572 48 R -1.11(Va)161 96 S(lid ar)1.11 E
-(guments for the)-.18 E/F1 10/Courier-Bold@0 SF(environ)2.5 E F0(command are:)
-2.5 E F1(define)161 114 Q/F2 10/Courier-Oblique@0 SF(variable value)6 E F0
-1.082(De\214ne the v)216 126 R(ariable)-.25 E F2(variable)3.582 E F0 1.082
-(to ha)3.582 F 1.382 -.15(ve a v)-.2 H 1.082(alue of)-.1 F F2(value.)3.581 E F0
-(An)3.581 E 3.581(yv)-.15 G 1.081(ariables de-)492.549 126 R 1.922
-(\214ned by this command are automatically e)216 138 R 4.422(xported. The)-.15
-F F2(value)4.422 E F0 1.922(may be en-)4.422 F
-(closed in single or double quotes so that tabs and spaces may be included.)216
-150 Q F1(undefine)161 168 Q F2(variable)6 E F0(Remo)216 180 Q -.15(ve)-.15 G F2
-(variable)2.65 E F0(from the list of en)2.5 E(vironment v)-.4 E(ariables.)-.25
-E F1(export)161 198 Q F2(variable)6 E F0(Mark the v)216 210 Q(ariable)-.25 E F2
-(variable)2.5 E F0(to be e)2.5 E(xported to the remote side.)-.15 E F1
-(unexport)161 228 Q F2(variable)6 E F0 .697(Mark the v)216 240 R(ariable)-.25 E
-F2(variable)3.197 E F0 .697(to not be e)3.197 F .697(xported unless e)-.15 F
-.696(xplicitly ask)-.15 F .696(ed for by)-.1 F(the remote side.)216 252 Q F1
-(list)161 270 Q F0 1.416(List the current set of en)216 270 R 1.416
-(vironment v)-.4 F 3.916(ariables. Those)-.25 F(mark)3.916 E 1.416(ed with a)
--.1 F/F3 10/Symbol SF(*)3.916 E F0 1.417(will be)3.917 F(sent automatically)216
-282 Q 2.5(,o)-.65 G(ther v)298.4 282 Q(ariables will only be sent if e)-.25 E
-(xplicitly requested.)-.15 E F1(?)161 300 Q F0
-(Prints out help information for the)216 300 Q F1(environ)2.5 E F0(command.)2.5
-E F1(logout)102 318 Q F0 .104(Sends the)161 318 R/F4 10/Courier@0 SF .104
-(TELNET LOGOUT)2.604 F F0 .104(option to the remote side.)2.604 F .104
-(This command is similar to a)5.104 F F1(close)2.604 E F0 .228(command; ho)161
-330 R(we)-.25 E -.15(ve)-.25 G 1.028 -.4(r, i).15 H 2.728(ft).4 G .228
-(he remote side does not support the)256.174 330 R F4(LOGOUT)2.729 E F0 .229
-(option, nothing happens.)2.729 F .233(If, ho)161 342 R(we)-.25 E -.15(ve)-.25
-G 1.033 -.4(r, t).15 H .233(he remote side does support the).4 F F4(LOGOUT)
-2.733 E F0 .233(option, this command should cause the)2.733 F .652
-(remote side to close the)161 354 R/F5 9/Times-Roman@0 SF(TELNET)3.152 E F0
-3.152(connection. If)3.152 F .653(the remote side also supports the concept of)
-3.152 F 1.904(suspending a user')161 366 R 4.404(ss)-.55 G 1.903
-(ession for later reattachment, the logout ar)250.872 366 R 1.903
-(gument indicates that you)-.18 F(should terminate the session immediately)161
-378 Q(.)-.65 E F1(mode)102 396 Q F2 -1(type Type)6.889 F F0 .889(is one of se)
-3.389 F -.15(ve)-.25 G .889(ral options, depending on the state of the).15 F F5
-(TELNET)3.389 E F0 3.39(session. The)3.39 F(remote)3.39 E .882(host is ask)161
-408 R .881(ed for permission to go into the requested mode.)-.1 F .881
-(If the remote host is capable of)5.881 F
-(entering that mode, the requested mode will be entered.)161 420 Q F1
-(character)161 438 Q F0 .715(Disable the)226 438 R F4 .716(TELNET LINEMODE)
-3.215 F F0 .716(option, or)3.216 F 3.216(,i)-.4 G 3.216(ft)416.834 438 S .716
-(he remote side does not un-)426.16 438 R(derstand the)226 450 Q F4(LINEMODE)
-2.5 E F0(option, then enter `)2.5 E(`character at a time`)-.74 E 2.5(`m)-.74 G
-(ode.)496.07 450 Q F1(line)161 468 Q F0 .948(Enable the)226 468 R F4 .948
-(TELNET LINEMODE)3.448 F F0 .948(option, or)3.448 F 3.448(,i)-.4 G 3.447(ft)
-415.448 468 S .947(he remote side does not un-)425.005 468 R 2.78(derstand the)
-226 480 R F4(LINEMODE)5.28 E F0 2.78(option, then attempt to enter `)5.28 F
-(`old-line-by-line`)-.74 E(`)-.74 E(mode.)226 492 Q F1(isig)161 510 Q F0(\()
-7.666 E F1(\255isig)1.666 E F0(\))1.666 E 1.43
-(Attempt to enable \(disable\) the)226 522 R F4(TRAPSIG)3.93 E F0 1.43
-(mode of the)3.93 F F4(LINEMODE)3.93 E F0(option.)3.93 E
-(This requires that the)226 534 Q F4(LINEMODE)2.5 E F0(option be enabled.)2.5 E
-F1(edit)161 552 Q F0(\()7.666 E F1(\255edit)1.666 E F0(\))1.666 E .865
-(Attempt to enable \(disable\) the)226 564 R F4(EDIT)3.365 E F0 .866
-(mode of the)3.365 F F4(LINEMODE)3.366 E F0 3.366(option. This)3.366 F
-(requires that the)226 576 Q F4(LINEMODE)2.5 E F0(option be enabled.)2.5 E F1
-(softtabs)161 594 Q F0(\()7.666 E F1(\255softtabs)1.666 E F0(\))1.666 E .83
-(Attempt to enable \(disable\) the)226 606 R F4(SOFT_TAB)3.33 E F0 .83
-(mode of the)3.33 F F4(LINEMODE)3.33 E F0(option.)3.33 E
-(This requires that the)226 618 Q F4(LINEMODE)2.5 E F0(option be enabled.)2.5 E
-F1(litecho)161 636 Q F0(\()7.666 E F1(\255litecho)1.666 E F0(\))1.666 E .83
-(Attempt to enable \(disable\) the)226 648 R F4(LIT_ECHO)3.33 E F0 .83
-(mode of the)3.33 F F4(LINEMODE)3.33 E F0(option.)3.33 E
-(This requires that the)226 660 Q F4(LINEMODE)2.5 E F0(option be enabled.)2.5 E
-F1(?)161 678 Q F0(Prints out help information for the)226 678 Q F1(mode)2.5 E
-F0(command.)2.5 E(4.2 Berk)72 750 Q(ele)-.1 E 2.5(yD)-.15 G(istrib)132.57 750 Q
-95.71(ution February)-.2 F(3, 1994)2.5 E(4)535 750 Q EP
-%%Page: 5 5
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF -.834(TELNET \( 1 \))72 48 R(BSD Reference Manual)
-258.235 48 Q -.834(TELNET \( 1 \))485.572 48 R/F1 10/Courier-Bold@0 SF(open)102
-102 Q/F2 10/Courier-Oblique@0 SF(host)6 E F0 .833([[)2.5 G F1<ad6c>1.666 E F0
-(]).833 E F2(user)6 E F0(][)A F1<ad>1.666 E F2(port)A F0(])A .207
-(Open a connection to the named host.)161 114 R .207
-(If no port number is speci\214ed,)5.207 F F1(telnet)2.707 E F0 .206
-(will attempt to)2.707 F .263(contact a)161 126 R/F3 9/Times-Roman@0 SF(TELNET)
-2.763 E F0(serv)2.763 E .263(er at the def)-.15 F .263(ault port.)-.1 F .264
-(The host speci\214cation may be either a host name)5.264 F(\(see)161 138 Q/F4
-10/Courier@0 SF(hosts)3.531 E F0 4.562(\(5\)\) or)B 1.031
-(an Internet address speci\214ed in the `)3.531 F 1.03(`dot notation')-.74 F
-3.53('\()-.74 G(see)459.6 138 Q F4(inet)3.53 E F0 4.56(\(3\)\). The)B([)161.833
-150 Q F1<ad6c>2.499 E F0 3.03(]o).833 G .531(ption may be used to specify the \
-user name to be passed to the remote system via the)191.855 150 R F4(ENVIRON)
-161 162 Q F0 3.971(option. When)3.971 F 1.471
-(connecting to a non-standard port,)3.971 F F1(telnet)3.971 E F0 1.471
-(omits an)3.971 F 3.97(ya)-.15 G(utomatic)505 162 Q .631(initiation of)161 174
-R F3(TELNET)3.131 E F0 3.131(options. When)3.131 F .631
-(the port number is preceded by a minus sign, the initial)3.131 F .441
-(option ne)161 186 R .441(gotiation is done.)-.15 F .441
-(After establishing a connection, the \214le)5.441 F F4(.telnetrc)2.941 E F0
-.44(in the users)2.94 F .928(home directory is opened.)161 198 R .928(Lines be)
-5.928 F .928(ginning with a # are comment lines.)-.15 F .928
-(Blank lines are ig-)5.928 F 3.255(nored. Lines)161 210 R .755(that be)3.255 F
-.755(gin without white space are the start of a machine entry)-.15 F 5.755(.T)
--.65 G .755(he \214rst thing)487.93 210 R .022
-(on the line is the name of the machine that is being connected to.)161 222 R
-.023(The rest of the line, and suc-)5.023 F(cessi)161 234 Q .856 -.15(ve l)-.25
-H .556(ines that be).15 F .556(gin with white space are assumed to be)-.15 F F1
-(telnet)3.056 E F0 .556(commands and are pro-)3.056 F(cessed as if the)161 246
-Q 2.5(yh)-.15 G(ad been typed in manually to the)233.61 246 Q F1(telnet)2.5 E
-F0(command prompt.)2.5 E F1(quit)102 264 Q F0 .114(Close an)161 264 R 2.614(yo)
--.15 G(pen)208.298 264 Q F3(TELNET)2.614 E F0 .115(session and e)2.615 F(xit)
--.15 E F1(telnet)2.615 E F0 2.615(.A)C 2.615(ne)376.32 264 S .115
-(nd of \214le \(in command mode\) will al-)388.375 264 R
-(so close a session and e)161 276 Q(xit.)-.15 E F1(send)102 294 Q F2(arguments)
-6 E F0 .024(Sends one or more special character sequences to the remote host.)
-161 306 R .024(The follo)5.024 F .024(wing are the ar)-.25 F(gu-)-.18 E
-(ments which may be speci\214ed \(more than one ar)161 318 Q
-(gument may be speci\214ed at a time\):)-.18 E F1(abort)161 336 Q F0(Sends the)
-202 336 Q F4(TELNET ABORT)2.5 E F0(\(Abort processes\) sequence.)2.5 E F1(ao)
-161 354 Q F0 1.15(Sends the)202 354 R F4 1.151(TELNET AO)3.651 F F0 1.151
-(\(Abort Output\) sequence, which should cause the remote)3.651 F
-(system to \215ush all output)202 366 Q/F5 10/Times-Italic@0 SF(fr)2.5 E(om)
--.45 E F0(the remote system)2.5 E F5(to)2.5 E F0(the user')2.5 E 2.5(st)-.55 G
-(erminal.)454.89 366 Q F1(ayt)161 384 Q F0 1.18(Sends the)202 384 R F4 1.18
-(TELNET AYT)3.68 F F0 1.18(\(Are Y)3.68 F 1.18
-(ou There\) sequence, to which the remote system)-1.1 F
-(may or may not choose to respond.)202 396 Q F1(brk)161 414 Q F0 .47(Sends the)
-202 414 R F4 .47(TELNET BRK)2.97 F F0 .47(\(Break\) sequence, which may ha)2.97
-F .77 -.15(ve s)-.2 H .47(igni\214cance to the re-).15 F(mote system.)202 426 Q
-F1(ec)161 444 Q F0 .245(Sends the)202 444 R F4 .245(TELNET EC)2.745 F F0 .244
-(\(Erase Character\) sequence, which should cause the remote)2.745 F
-(system to erase the last character entered.)202 456 Q F1(el)161 474 Q F0 .385
-(Sends the)202 474 R F4 .385(TELNET EL)2.885 F F0 .385
-(\(Erase Line\) sequence, which should cause the remote sys-)2.885 F
-(tem to erase the line currently being entered.)202 486 Q F1(eof)161 504 Q F0
-(Sends the)202 504 Q F4(TELNET EOF)2.5 E F0(\(End Of File\) sequence.)2.5 E F1
-(eor)161 522 Q F0(Sends the)202 522 Q F4(TELNET EOR)2.5 E F0
-(\(End of Record\) sequence.)2.5 E F1(escape)161 540 Q F0(Sends the current)5 E
-F1(telnet)2.5 E F0(escape character \(initially `)2.5 E(`^')-.74 E('\).)-.74 E
-F1(ga)161 558 Q F0 .855(Sends the)202 558 R F4 .855(TELNET GA)3.355 F F0 .855
-(\(Go Ahead\) sequence, which lik)3.355 F .855(ely has no signi\214cance to)-.1
-F(the remote system.)202 570 Q F1(getstatus)161 588 Q F0 1.713
-(If the remote side supports the)202 600 R F4 1.713(TELNET STATUS)4.213 F F0
-(command,)4.213 E F1(getstatus)4.213 E F0(will)4.213 E(send the subne)202 612 Q
-(gotiation to request that the serv)-.15 E(er send its current option status.)
--.15 E F1(ip)161 630 Q F0 1.355(Sends the)202 630 R F4 1.355(TELNET IP)3.855 F
-F0 1.354(\(Interrupt Process\) sequence, which should cause the re-)3.855 F
-(mote system to abort the currently running process.)202 642 Q F1(nop)161 660 Q
-F0(Sends the)202 660 Q F4(TELNET NOP)2.5 E F0(\(No OPeration\) sequence.)2.5 E
-F1(susp)161 678 Q F0(Sends the)202 678 Q F4(TELNET SUSP)2.5 E F0
-(\(SUSPend process\) sequence.)2.5 E(4.2 Berk)72 750 Q(ele)-.1 E 2.5(yD)-.15 G
-(istrib)132.57 750 Q 95.71(ution February)-.2 F(3, 1994)2.5 E(5)535 750 Q EP
-%%Page: 6 6
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF -.834(TELNET \( 1 \))72 48 R(BSD Reference Manual)
-258.235 48 Q -.834(TELNET \( 1 \))485.572 48 R/F1 10/Courier-Bold@0 SF(synch)
-161 96 Q F0 .65(Sends the)202 96 R/F2 10/Courier@0 SF .651(TELNET SYNCH)3.151 F
-F0 3.151(sequence. This)3.151 F .651(sequence causes the remote system to)3.151
-F .777(discard all pre)202 108 R .777(viously typed \(b)-.25 F .777
-(ut not yet read\) input.)-.2 F .776(This sequence is sent as)5.777 F/F3 9
-/Times-Roman@0 SF(TCP)3.276 E F0(ur)202 120 Q 1.665(gent data \(and may not w)
--.18 F 1.665(ork if the remote system is a 4.2)-.1 F F3(BSD)A F0 1.666
-(system -- if it)4.166 F(doesn')202 132 Q 2.5(tw)-.18 G(ork, a lo)240.88 132 Q
-(wer case `)-.25 E(`r')-.74 E 2.5('m)-.74 G(ay be echoed on the terminal\).)
-336.33 132 Q F1(do)161 150 Q/F4 10/Courier-Oblique@0 SF(cmd)6 E F1(dont)161 168
-Q F4(cmd)6 E F1(will)161 186 Q F4(cmd)6 E F1(wont)161 204 Q F4(cmd)6 E F0 1.134
-(Sends the)202 216 R F2 1.133(TELNET DO)3.633 F F4(cmd)3.633 E F0(sequence.)
-3.633 E F4(Cmd)6.133 E F0 1.133(can be either a decimal number be-)3.633 F .865
-(tween 0 and 255, or a symbolic name for a speci\214c)202 228 R F2(TELNET)3.365
-E F0(command.)3.365 E F4(Cmd)5.865 E F0(can)3.365 E 1.181(also be either)202
-240 R F1(help)3.681 E F0(or)3.681 E F1(?)3.681 E F0 1.18
-(to print out help information, including a list of kno)3.681 F(wn)-.25 E
-(symbolic names.)202 252 Q F1(?)161 270 Q F0
-(Prints out help information for the)202 270 Q F1(send)2.5 E F0(command.)2.5 E
-F1(set)102 288 Q F4(argument value)6 E F1(unset)102 306 Q F4(argument value)6 E
-F0(The)161 318 Q F1(set)2.601 E F0 .101(command will set an)2.601 F 2.601(yo)
--.15 G .101(ne of a number of)295.556 318 R F1(telnet)2.601 E F0 -.25(va)2.601
-G .101(riables to a speci\214c v).25 F .102(alue or to)-.25 F F2(TRUE)161 330 Q
-F0 2.722(.T)C .222(he special v)196.332 330 R(alue)-.25 E F1(off)2.722 E F0
-.222(turns of)2.722 F 2.722(ft)-.25 G .222(he function associated with the v)
-323.474 330 R .222(ariable, this is equi)-.25 F(v-)-.25 E .37
-(alent to using the)161 342 R F1(unset)2.87 E F0 2.871(command. The)2.87 F F1
-(unset)2.871 E F0 .371(command will disable or set to)2.871 F F2(FALSE)2.871 E
-F0(an)2.871 E(y)-.15 E 1.248(of the speci\214ed functions.)161 354 R 1.248
-(The v)6.248 F 1.248(alues of v)-.25 F 1.248(ariables may be interrog)-.25 F
-1.247(ated with the)-.05 F F1(display)3.747 E F0 2.886(command. The)161 366 R
--.25(va)2.886 G .386(riables which may be set or unset, b).25 F .386
-(ut not toggled, are listed here.)-.2 F .387(In addi-)5.387 F .763(tion, an)161
-378 R 3.263(yo)-.15 G 3.263(ft)204.876 378 S .763(he v)214.249 378 R .763
-(ariables for the)-.25 F F1(toggle)3.263 E F0 .762(command may be e)3.263 F
-.762(xplicitly set or unset using the)-.15 F F1(set)161 390 Q F0(and)2.5 E F1
-(unset)2.5 E F0(commands.)2.5 E F1(ayt)161 408 Q F0(If)202 408 Q F3(TELNET)
-2.689 E F0 .189(is in localchars mode, or)2.689 F F2(LINEMODE)2.689 E F0 .189
-(is enabled, and the status character)2.689 F 1.056(is typed, a)202 420 R F2
-1.056(TELNET AYT)3.556 F F0 1.056(sequence \(see)3.556 F F1 1.056(send ayt)
-3.556 F F0 1.055(preceding\) is sent to the re-)3.556 F .327(mote host.)202 432
-R .328(The initial v)5.327 F .328(alue for the "Are Y)-.25 F .328
-(ou There" character is the terminal')-1.1 F 2.828(ss)-.55 G(ta-)529.45 432 Q
-(tus character)202 444 Q(.)-.55 E F1(echo)161 462 Q F0 .805(This is the v)202
-462 R .805(alue \(initially `)-.25 F(`^E')-.74 E .804('\) which, when in `)-.74
-F .804(`line by line')-.74 F 3.304('m)-.74 G .804(ode, toggles be-)474.792 462
-R .988(tween doing local echoing of entered characters \(for normal processing\
-\), and sup-)202 474 R
-(pressing echoing of entered characters \(for entering, say)202 486 Q 2.5(,ap)
--.65 G(assw)442.66 486 Q(ord\).)-.1 E F1(eof)161 504 Q F0(If)202 504 Q F1
-(telnet)3.864 E F0 1.364(is operating in)3.864 F F2(LINEMODE)3.864 E F0 1.364
-(or `)3.864 F 1.364(`old line by line')-.74 F 3.864('m)-.74 G 1.363
-(ode, entering this)468.114 504 R .199(character as the \214rst character on a\
- line will cause this character to be sent to the re-)202 516 R .12
-(mote system.)202 528 R .12(The initial v)5.12 F .119
-(alue of the eof character is tak)-.25 F .119(en to be the terminal')-.1 F(s)
--.55 E F1(eof)2.619 E F0(character)202 540 Q(.)-.55 E F1(erase)161 558 Q F0(If)
-202 558 Q F1(telnet)3.12 E F0 .62(is in)3.12 F F1(localchars)3.12 E F0 .62
-(mode \(see)3.12 F F1 -2.88(toggle localchars)3.12 F F0(belo)3.12 E(w\),)-.25 E
-/F5 10/Times-Bold@0 SF(and)3.12 E F0(if)3.12 E F1(telnet)202 570 Q F0 1.385
-(is operating in `)3.885 F 1.385(`character at a time')-.74 F 3.885('m)-.74 G
-1.384(ode, then when this character is)407 570 R .417(typed, a)202 582 R F2
-.418(TELNET EC)2.917 F F0 .418(sequence \(see)2.918 F F1 -3.082(send ec)2.918 F
-F0(abo)2.918 E -.15(ve)-.15 G 2.918(\)i).15 G 2.918(ss)427.36 582 S .418
-(ent to the remote system.)438.058 582 R .325(The initial v)202 594 R .325
-(alue for the erase character is tak)-.25 F .325(en to be the terminal')-.1 F
-(s)-.55 E F1(erase)2.825 E F0(charac-)2.825 E(ter)202 606 Q(.)-.55 E F1(escape)
-161 624 Q F0 2.873(This is the)5 F F1(telnet)5.373 E F0 2.874
-(escape character \(initially `)5.373 F(`^[')-.74 E 2.874
-('\) which causes entry into)-.74 F F1(telnet)202 636 Q F0
-(command mode \(when connected to a remote system\).)2.5 E F1(flushoutput)161
-654 Q F0(If)202 666 Q F1(telnet)2.945 E F0 .445(is in)2.945 F F1(localchars)
-2.945 E F0 .445(mode \(see)2.945 F F1 -3.056(toggle localchars)2.944 F F0(belo)
-2.944 E .444(w\) and the)-.25 F F1(flushoutput)202 678 Q F0 .442
-(character is typed, a)2.942 F F2 .443(TELNET AO)2.943 F F0 .443
-(sequence \(see)2.943 F F1 -3.057(send ao)2.943 F F0(abo)2.943 E -.15(ve)-.15 G
-(\)).15 E .314(is sent to the remote host.)202 690 R .314(The initial v)5.314 F
-.314(alue for the \215ush character is tak)-.25 F .314(en to be the)-.1 F
-(4.2 Berk)72 750 Q(ele)-.1 E 2.5(yD)-.15 G(istrib)132.57 750 Q 95.71
-(ution February)-.2 F(3, 1994)2.5 E(6)535 750 Q EP
-%%Page: 7 7
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF -.834(TELNET \( 1 \))72 48 R(BSD Reference Manual)
-258.235 48 Q -.834(TELNET \( 1 \))485.572 48 R(terminal')202 96 Q(s)-.55 E/F1
-10/Courier-Bold@0 SF(flush)2.5 E F0(character)2.5 E(.)-.55 E F1(forw1)161 114 Q
-(forw2)161 132 Q F0(If)202 132 Q/F2 9/Times-Roman@0 SF(TELNET)3.769 E F0 1.269
-(is operating in)3.769 F/F3 10/Courier@0 SF(LINEMODE)3.77 E F0 3.77(,t)C 1.27
-(hese are the characters that, when typed,)370.77 132 R .958
-(cause partial lines to be forw)202 144 R .958(arded to the remote system.)-.1
-F .958(The initial v)5.958 F .957(alue for the)-.25 F(forw)202 156 Q
-(arding characters are tak)-.1 E(en from the terminal')-.1 E 2.5(se)-.55 G
-(ol and eol2 characters.)414.23 156 Q F1(interrupt)161 174 Q F0(If)202 186 Q F1
-(telnet)2.944 E F0 .444(is in)2.944 F F1(localchars)2.944 E F0 .445(mode \(see)
-2.944 F F1 -3.055(toggle localchars)2.945 F F0(belo)2.945 E .445(w\) and the)
--.25 F F1(interrupt)202 198 Q F0 .642(character is typed, a)3.142 F F3 .642
-(TELNET IP)3.142 F F0 .642(sequence \(see)3.142 F F1 -2.859(send ip)3.141 F F0
-(abo)3.141 E -.15(ve)-.15 G 3.141(\)i).15 G(s)536.11 198 Q .949
-(sent to the remote host.)202 210 R .949(The initial v)5.949 F .949
-(alue for the interrupt character is tak)-.25 F .95(en to be)-.1 F
-(the terminal')202 222 Q(s)-.55 E F1(intr)2.5 E F0(character)2.5 E(.)-.55 E F1
-(kill)161 240 Q F0(If)202 240 Q F1(telnet)2.95 E F0 .449(is in)2.949 F F1
-(localchars)2.949 E F0 .449(mode \(see)2.949 F F1 -3.051(toggle localchars)
-2.949 F F0(belo)2.949 E(w\),)-.25 E F1(and)2.949 E F0(if)2.949 E F1(telnet)202
-252 Q F0 1.384(is operating in `)3.884 F 1.385(`character at a time')-.74 F
-3.885('m)-.74 G 1.385(ode, then when this character is)406.995 252 R .418
-(typed, a)202 264 R F3 .418(TELNET EL)2.918 F F0 .418(sequence \(see)2.918 F F1
--3.082(send el)2.918 F F0(abo)2.918 E -.15(ve)-.15 G 2.918(\)i).15 G 2.918(ss)
-427.362 264 S .418(ent to the remote system.)438.06 264 R(The initial v)202 276
-Q(alue for the kill character is tak)-.25 E(en to be the terminal')-.1 E(s)-.55
-E F1(kill)2.5 E F0(character)2.5 E(.)-.55 E F1(lnext)161 294 Q F0(If)202 294 Q
-F1(telnet)2.597 E F0 .097(is operating in)2.597 F F3(LINEMODE)2.597 E F0 .097
-(or `)2.597 F .097(`old line by line`)-.74 F 2.597(`m)-.74 G .098
-(ode, then this charac-)454.177 294 R 1.405(ter is tak)202 306 R 1.405
-(en to be the terminal')-.1 F(s)-.55 E F1(lnext)3.904 E F0(character)3.904 E
-6.404(.T)-.55 G 1.404(he initial v)422.56 306 R 1.404(alue for the lne)-.25 F
-(xt)-.15 E(character is tak)202 318 Q(en to be the terminal')-.1 E(s)-.55 E F1
-(lnext)2.5 E F0(character)2.5 E(.)-.55 E F1(quit)161 336 Q F0(If)202 336 Q F1
-(telnet)2.944 E F0 .444(is in)2.944 F F1(localchars)2.944 E F0 .445(mode \(see)
-2.944 F F1 -3.055(toggle localchars)2.945 F F0(belo)2.945 E .445(w\) and the)
--.25 F F1(quit)202 348 Q F0 .546(character is typed, a)3.046 F F3 .545
-(TELNET BRK)3.046 F F0 .545(sequence \(see)3.045 F F1 -2.955(send brk)3.045 F
-F0(abo)3.045 E -.15(ve)-.15 G 3.045(\)i).15 G 3.045(ss)516.955 348 S(ent)527.78
-348 Q .629(to the remote host.)202 360 R .629(The initial v)5.629 F .629
-(alue for the quit character is tak)-.25 F .63(en to be the termi-)-.1 F(nal')
-202 372 Q(s)-.55 E F1(quit)2.5 E F0(character)2.5 E(.)-.55 E F1(reprint)161 390
-Q F0(If)202 402 Q F1(telnet)2.598 E F0 .097(is operating in)2.598 F F3
-(LINEMODE)2.597 E F0 .097(or `)2.597 F .097(`old line by line`)-.74 F 2.597(`m)
--.74 G .097(ode, then this charac-)454.179 402 R .06(ter is tak)202 414 R .06
-(en to be the terminal')-.1 F(s)-.55 E F1(reprint)2.561 E F0(character)2.561 E
-5.061(.T)-.55 G .061(he initial v)422.465 414 R .061(alue for the reprint)-.25
-F(character is tak)202 426 Q(en to be the terminal')-.1 E(s)-.55 E F1(reprint)
-2.5 E F0(character)2.5 E(.)-.55 E F1(rlogin)161 444 Q F0 .956
-(This is the rlogin escape character)5 F 5.956(.I)-.55 G 3.456(fs)354.366 444 S
-.956(et, the normal)365.042 444 R F2(TELNET)3.456 E F0 .956
-(escape character is)3.456 F .357
-(ignored unless it is preceded by this character at the be)202 456 R .358
-(ginning of a line.)-.15 F .358(This char)5.358 F(-)-.2 E(acter)202 468 Q 3.14
-(,a)-.4 G 3.14(tt)231.11 468 S .64(he be)239.81 468 R .64
-(ginning of a line follo)-.15 F .639(wed by a ".")-.25 F .639
-(closes the connection; when fol-)5.639 F(lo)202 480 Q 1.31
-(wed by a ^Z it suspends the telnet command.)-.25 F 1.311
-(The initial state is to disable the)6.311 F(rlogin escape character)202 492 Q
-(.)-.55 E F1(start)161 510 Q F0 2.232(If the)202 510 R F3 2.231
-(TELNET TOGGLE-FLOW-CONTROL)4.731 F F0 2.231
-(option has been enabled, then this)4.731 F .005(character is tak)202 522 R
-.005(en to be the terminal')-.1 F(s)-.55 E F1(start)2.506 E F0(character)2.506
-E 5.006(.T)-.55 G .006(he initial v)436.06 522 R .006(alue for the kill)-.25 F
-(character is tak)202 534 Q(en to be the terminal')-.1 E(s)-.55 E F1(start)2.5
-E F0(character)2.5 E(.)-.55 E F1(stop)161 552 Q F0 2.232(If the)202 552 R F3
-2.231(TELNET TOGGLE-FLOW-CONTROL)4.731 F F0 2.231
-(option has been enabled, then this)4.731 F .434(character is tak)202 564 R
-.434(en to be the terminal')-.1 F(s)-.55 E F1(stop)2.934 E F0(character)2.934 E
-5.434(.T)-.55 G .434(he initial v)433.916 564 R .435(alue for the kill)-.25 F
-(character is tak)202 576 Q(en to be the terminal')-.1 E(s)-.55 E F1(stop)2.5 E
-F0(character)2.5 E(.)-.55 E F1(susp)161 594 Q F0(If)202 594 Q F1(telnet)2.576 E
-F0 .076(is in)2.576 F F1(localchars)2.576 E F0 .076(mode, or)2.576 F F3
-(LINEMODE)2.576 E F0 .076(is enabled, and the)2.576 F F1(suspend)2.575 E F0 .87
-(character is typed, a)202 606 R F3 .87(TELNET SUSP)3.37 F F0 .87
-(sequence \(see)3.37 F F1 -2.63(send susp)3.37 F F0(abo)3.37 E -.15(ve)-.15 G
-3.37(\)i).15 G 3.37(ss)505.48 606 S .87(ent to)516.63 606 R .246
-(the remote host.)202 618 R .246(The initial v)5.246 F .246
-(alue for the suspend character is tak)-.25 F .246(en to be the termi-)-.1 F
-(nal')202 630 Q(s)-.55 E F1(suspend)2.5 E F0(character)2.5 E(.)-.55 E F1
-(tracefile)161 648 Q F0 .537(This is the \214le to which the output, caused by)
-202 660 R F1(netdata)3.037 E F0(or)3.037 E F1(option)3.037 E F0 .538
-(tracing being)3.038 F F3(TRUE)202 672 Q F0 3.079(,w)C .579(ill be written.)
-238.799 672 R .579(If it is set to `)5.579 F(`)-.74 E F1<ad>1.666 E F0 -.74('')
-1.666 G 3.078(,t).74 G .578(hen tracing information will be written)381.85 672
-R(4.2 Berk)72 750 Q(ele)-.1 E 2.5(yD)-.15 G(istrib)132.57 750 Q 95.71
-(ution February)-.2 F(3, 1994)2.5 E(7)535 750 Q EP
-%%Page: 8 8
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF -.834(TELNET \( 1 \))72 48 R(BSD Reference Manual)
-258.235 48 Q -.834(TELNET \( 1 \))485.572 48 R(to standard output \(the def)202
-96 Q(ault\).)-.1 E/F1 10/Courier-Bold@0 SF(worderase)161 114 Q F0(If)202 126 Q
-F1(telnet)2.597 E F0 .097(is operating in)2.597 F/F2 10/Courier@0 SF(LINEMODE)
-2.597 E F0 .097(or `)2.597 F .097(`old line by line`)-.74 F 2.597(`m)-.74 G
-.098(ode, then this charac-)454.177 126 R 1.386(ter is tak)202 138 R 1.386
-(en to be the terminal')-.1 F(s)-.55 E F1(worderase)3.885 E F0(character)3.885
-E 6.385(.T)-.55 G 1.385(he initial v)446.39 138 R 1.385(alue for the)-.25 F -.1
-(wo)202 150 S(rderase character is tak).1 E(en to be the terminal')-.1 E(s)-.55
-E F1(worderase)2.5 E F0(character)2.5 E(.)-.55 E F1(?)161 168 Q F0
-(Displays the le)202 168 Q -.05(ga)-.15 G(l).05 E F1(set)2.5 E F0(\()4.166 E F1
-(unset)1.666 E F0 4.166(\)c)1.666 G(ommands.)346.724 168 Q F1(slc)102 186 Q/F3
-10/Courier-Oblique@0 SF(state)6.383 E F0(The)5 E F1(slc)2.883 E F0 .384(comman\
-d \(Set Local Characters\) is used to set or change the state of the the speci\
-al)2.884 F 1.231(characters when the)161 198 R F2 1.231(TELNET LINEMODE)3.731 F
-F0 1.231(option has been enabled.)3.731 F 1.231(Special characters are)6.231 F
-.139(characters that get mapped to)161 210 R/F4 9/Times-Roman@0 SF(TELNET)2.639
-E F0 .139(commands sequences \(lik)2.639 F(e)-.1 E F1(ip)2.639 E F0(or)2.639 E
-F1(quit)2.639 E F0 2.639(\)o)C 2.639(rl)488.611 210 S .14(ine editing)497.36
-210 R(characters \(lik)161 222 Q(e)-.1 E F1(erase)2.5 E F0(and)2.5 E F1(kill)
-2.5 E F0(\). By def)A(ault, the local special characters are e)-.1 E(xported.)
--.15 E F1(check)161 240 Q F0 -1.11(Ve)216 240 S .526
-(rify the current settings for the current special characters.)1.11 F .525
-(The remote side is)5.526 F .925(requested to send all the current special cha\
-racter settings, and if there are an)216 252 R(y)-.15 E
-(discrepancies with the local side, the local side will switch to the remote v)
-216 264 Q(alue.)-.25 E F1(export)161 282 Q F0 .497(Switch to the local def)216
-282 R .497(aults for the special characters.)-.1 F .496(The local def)5.496 F
-.496(ault charac-)-.1 F(ters are those of the local terminal at the time when)
-216 294 Q F1(telnet)2.5 E F0 -.1(wa)2.5 G 2.5(ss).1 G(tarted.)483.8 294 Q F1
-(import)161 312 Q F0 1.929(Switch to the remote def)216 312 R 1.929
-(aults for the special characters.)-.1 F 1.929(The remote def)6.929 F(ault)-.1
-E .37(characters are those of the remote system at the time when the)216 324 R
-F4(TELNET)2.869 E F0(connec-)2.869 E(tion w)216 336 Q(as established.)-.1 E F1
-(?)161 354 Q F0(Prints out help information for the)216 354 Q F1(slc)2.5 E F0
-(command.)2.5 E F1(status)102 372 Q F0(Sho)161 372 Q 2.808(wt)-.25 G .308
-(he current status of)189.118 372 R F1(telnet)2.809 E F0 2.809(.T)C .309
-(his includes the peer one is connected to, as well as the)316.641 372 R
-(current mode.)161 384 Q F1(toggle)102 402 Q F3(arguments ...)6 E F0 -.8(To)161
-414 S 2.112(ggle \(between).8 F F2(TRUE)4.612 E F0(and)4.612 E F2(FALSE)4.612 E
-F0 4.612(\)v)C 2.112(arious \215ags that control ho)324.76 414 R(w)-.25 E F1
-(telnet)4.611 E F0 2.111(responds to)4.611 F -2.15 -.25(ev e)161 426 T 2.73
-(nts. These).25 F .23(\215ags may be set e)2.73 F .231(xplicitly to)-.15 F F2
-(TRUE)2.731 E F0(or)2.731 E F2(FALSE)2.731 E F0 .231(using the)2.731 F F1(set)
-2.731 E F0(and)2.731 E F1(unset)2.731 E F0(com-)2.731 E .544(mands listed abo)
-161 438 R -.15(ve)-.15 G 5.544(.M).15 G .544(ore than one ar)255.382 438 R .543
-(gument may be speci\214ed.)-.18 F .543(The state of these \215ags may)5.543 F
-(be interrog)161 450 Q(ated with the)-.05 E F1(display)2.5 E F0 2.5(command. V)
-2.5 F(alid ar)-1.11 E(guments are:)-.18 E F1(authdebug)161 468 Q F0 -.45(Tu)226
-468 S(rns on deb).45 E(ugging information for the authentication code.)-.2 E F1
-(autoflush)161 486 Q F0(If)226 486 Q F1(autoflush)4.407 E F0(and)4.407 E F1
-(localchars)4.407 E F0 1.907(are both)4.407 F F2(TRUE)4.407 E F0 4.407(,t)C
-1.907(hen when the)451.219 486 R F1(ao)4.408 E F0 4.408(,o)C(r)536.67 486 Q F1
-(quit)226 498 Q F0 1.803(characters are recognized \(and transformed into)4.304
-F F4(TELNET)4.303 E F0(sequences;)4.303 E(see)226 510 Q F1(set)2.966 E F0(abo)
-2.966 E .766 -.15(ve f)-.15 H .466(or details\),).15 F F1(telnet)2.966 E F0
-.466(refuses to display an)2.966 F 2.966(yd)-.15 G .467(ata on the user')473.89
-510 R(s)-.55 E 2.241(terminal until the remote system ackno)226 522 R 2.241
-(wledges \(via a)-.25 F F2 2.241(TELNET TIMING)4.741 F(MARK)226 534 Q F0 .496
-(option\) that it has processed those)2.996 F F4(TELNET)2.996 E F0 2.996
-(sequences. The)2.996 F .497(initial v)2.996 F(al-)-.25 E .754
-(ue for this toggle is)226 546 R F2(TRUE)3.254 E F0 .753
-(if the terminal user had not done an "stty no\215sh",)3.253 F(otherwise)226
-558 Q F2(FALSE)2.5 E F0(\(see)2.5 E F2(stty)2.5 E F0(\(1\)\).)A F1(autodecrypt)
-161 576 Q F0 .556(When the)226 588 R F2 .556(TELNET ENCRYPT)3.056 F F0 .556
-(option is ne)3.056 F .556(gotiated, by def)-.15 F .557(ault the actual en-)-.1
-F .403(cryption \(decryption\) of the data stream does not start automatically)
-226 600 R 5.402(.T)-.65 G .402(he au-)514.888 600 R .789(toencrypt \(autodecry\
-pt\) command states that encryption of the output \(input\))226 612 R
-(stream should be enabled as soon as possible.)226 624 Q 2.87(Note: Because)226
-642 R .369(of e)2.869 F .369(xport controls, the)-.15 F F2 .369(TELNET ENCRYPT)
-2.869 F F0 .369(option is not sup-)2.869 F
-(ported outside the United States and Canada.)226 654 Q F1(autologin)161 672 Q
-F0 4.509(If the remote side supports the)226 672 R F2 4.509
-(TELNET AUTHENTICATION)7.009 F F0(option)7.009 E F4(TELNET)226 684 Q F0 3.448
-(attempts to use it to perform automatic authentication.)5.948 F 3.447(If the)
-8.447 F F2(AUTHENTICATION)226 696 Q F0 .197(option is not supported, the user')
-2.697 F 2.697(sl)-.55 G .197(ogin name are propa-)454.159 696 R -.05(ga)226 708
-S .41(ted through the).05 F F2 .41(TELNET ENVIRON)2.91 F F0 2.91(option. This)
-2.91 F .41(command is the same as)2.91 F(4.2 Berk)72 756 Q(ele)-.1 E 2.5(yD)
--.15 G(istrib)132.57 756 Q 95.71(ution February)-.2 F(3, 1994)2.5 E(8)535 756 Q
-EP
-%%Page: 9 9
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF -.834(TELNET \( 1 \))72 48 R(BSD Reference Manual)
-258.235 48 Q -.834(TELNET \( 1 \))485.572 48 R(specifying)226 96 Q/F1 10
-/Courier-Oblique@0 SF(a)2.5 E F0(option on the)2.5 E/F2 10/Courier-Bold@0 SF
-(open)2.5 E F0(command.)2.5 E F2(autosynch)161 114 Q F0(If)226 114 Q F2
-(autosynch)4.854 E F0(and)4.854 E F2(localchars)4.854 E F0 2.354(are both)4.854
-F/F3 10/Courier@0 SF(TRUE)4.854 E F0 4.854(,t)C 2.354(hen when either the)
-454.348 114 R F2(intr)226 126 Q F0(or)4.17 E F2(quit)4.17 E F0 1.669
-(characters is typed \(see)4.169 F F2(set)4.169 E F0(abo)4.169 E 1.969 -.15
-(ve f)-.15 H 1.669(or descriptions of the).15 F F2(intr)226 138 Q F0(and)2.925
-E F2(quit)2.925 E F0 .426(characters\), the resulting)2.925 F/F4 9
-/Times-Roman@0 SF(TELNET)2.926 E F0 .426(sequence sent is follo)2.926 F(wed)
--.25 E 1.634(by the)226 150 R F3 1.634(TELNET SYNCH)4.134 F F0 4.134
-(sequence. This)4.134 F(procedure)4.134 E F2(should)4.134 E F0 1.634
-(cause the re-)4.134 F .871(mote system to be)226 162 R .871(gin thro)-.15 F
-.872(wing a)-.25 F -.1(wa)-.15 G 3.372(ya).1 G .872(ll pre)385.008 162 R .872
-(viously typed input until both of)-.25 F(the)226 174 Q F4(TELNET)3.622 E F0
-1.122(sequences ha)3.622 F 1.422 -.15(ve b)-.2 H 1.121
-(een read and acted upon.).15 F 1.121(The initial v)6.121 F 1.121(alue of)-.25
-F(this toggle is)226 186 Q F3(FALSE)2.5 E F0(.)A F2(binary)161 204 Q F0
-(Enable or disable the)226 204 Q F3(TELNET BINARY)2.5 E F0
-(option on both input and output.)2.5 E F2(inbinary)161 222 Q F0
-(Enable or disable the)226 222 Q F3(TELNET BINARY)2.5 E F0(option on input.)2.5
-E F2(outbinary)161 240 Q F0(Enable or disable the)226 240 Q F3(TELNET BINARY)
-2.5 E F0(option on output.)2.5 E F2(crlf)161 258 Q F0 1.415(If this is)226 258
-R F3(TRUE)3.915 E F0 3.915(,t)C 1.415(hen carriage returns will be sent as)
-298.72 258 R F3(<CR><LF>)3.915 E F0 3.915(.I)C 3.915(ft)507.72 258 S 1.415
-(his is)517.745 258 R F3(FALSE)226 270 Q F0 3.26(,t)C .759
-(hen carriage returns will be send as)264.54 270 R F3(<CR><NUL>)3.259 E F0
-3.259(.T)C .759(he initial v)479.292 270 R(alue)-.25 E(for this toggle is)226
-282 Q F3(FALSE)2.5 E F0(.)A F2(crmod)161 300 Q F0 -.8(To)226 300 S 1.1
-(ggle carriage return mode.).8 F 1.1
-(When this mode is enabled, most carriage re-)6.1 F .745(turn characters recei)
-226 312 R -.15(ve)-.25 G 3.244(df).15 G .744
-(rom the remote host will be mapped into a carriage)329.174 312 R 1.492
-(return follo)226 324 R 1.492(wed by a line feed.)-.25 F 1.493
-(This mode does not af)6.492 F 1.493(fect those characters)-.25 F .207
-(typed by the user)226 336 R 2.707(,o)-.4 G .207(nly those recei)305.028 336 R
--.15(ve)-.25 G 2.706(df).15 G .206(rom the remote host.)383.838 336 R .206
-(This mode is not)5.206 F -.15(ve)226 348 S 1.026
-(ry useful unless the remote host only sends carriage return, b).15 F 1.026
-(ut ne)-.2 F -.15(ve)-.25 G 3.526(rl).15 G(ine)527.78 348 Q 2.5(feed. The)226
-360 R(initial v)2.5 E(alue for this toggle is)-.25 E F3(FALSE)2.5 E F0(.)A F2
-(debug)161 378 Q F0 -.8(To)226 378 S .073(ggles sock).8 F .073(et le)-.1 F -.15
-(ve)-.25 G 2.573(ld).15 G(eb)314.629 378 Q .073(ugging \(useful only to the)-.2
-F F2 .072(super user)2.573 F F0 .072(\). The initial)B -.25(va)226 390 S
-(lue for this toggle is).25 E F3(FALSE)2.5 E F0(.)A F2(encdebug)161 408 Q F0
--.45(Tu)226 408 S(rns on deb).45 E(ugging information for the encryption code.)
--.2 E F2(localchars)161 426 Q F0 1.485(If this is)5 F F3(TRUE)3.985 E F0 3.985
-(,t)C 1.485(hen the)299 426 R F2(flush)3.985 E F0(,)A F2(interrupt)3.986 E F0
-(,)A F2(quit)3.986 E F0(,)A F2(erase)3.986 E F0 3.986(,a)C(nd)502.014 426 Q F2
-(kill)3.986 E F0 2.944(characters \(see)226 438 R F2(set)5.444 E F0(abo)5.444 E
--.15(ve)-.15 G 5.443(\)a).15 G 2.943(re recognized locally)353.755 438 R 5.443
-(,a)-.65 G 2.943(nd transformed into)455.234 438 R 3.265
-(\(hopefully\) appropriate)226 450 R F4(TELNET)5.765 E F0 3.265
-(control sequences \(respecti)5.765 F -.15(ve)-.25 G(ly).15 E F2(ao)5.766 E F0
-(,)A F2(ip)5.766 E F0(,)A F2(brk)226 462 Q F0(,)A F2(ec)2.788 E F0 2.788(,a)C
-(nd)271.016 462 Q F2(el)2.787 E F0 2.787(;s)C(ee)305.26 462 Q F2(send)2.787 E
-F0(abo)2.787 E -.15(ve)-.15 G 2.787(\). The).15 F .287(initial v)2.787 F .287
-(alue for this toggle is)-.25 F F3(TRUE)2.787 E F0 .045(in `)226 474 R .045
-(`old line by line')-.74 F 2.546('m)-.74 G .046(ode, and)318.906 474 R F3
-(FALSE)2.546 E F0 .046(in `)2.546 F .046(`character at a time')-.74 F 2.546('m)
--.74 G 2.546(ode. When)494.134 474 R(the)226 486 Q F3(LINEMODE)2.894 E F0 .394
-(option is enabled, the v)2.894 F .394(alue of)-.25 F F2(localchars)2.893 E F0
-.393(is ignored, and)2.893 F 2.388(assumed to al)226 498 R -.1(wa)-.1 G 2.388
-(ys be).1 F F3(TRUE)4.888 E F0 4.888(.I)C(f)359.5 498 Q F3(LINEMODE)4.888 E F0
-2.388(has e)4.888 F -.15(ve)-.25 G 4.888(rb).15 G 2.389(een enabled, then)
-465.522 498 R F2(quit)226 510 Q F0 1.574(is sent as)4.074 F F2(abort)4.074 E F0
-4.074(,a)C(nd)338.42 510 Q F2 1.574(eof and)4.074 F F0 1.573(are sent as)4.074
-F F2 1.573(eof and)4.073 F(susp)4.073 E F0 4.073(,s)C(ee)531.12 510 Q F2(send)
-226 522 Q F0(abo)2.5 E -.15(ve)-.15 G(\).).15 E F2(netdata)161 540 Q F0 -.8(To)
-226 540 S .993(ggles the display of all netw).8 F .994(ork data \(in he)-.1 F
-.994(xadecimal format\).)-.15 F .994(The initial)5.994 F -.25(va)226 552 S
-(lue for this toggle is).25 E F3(FALSE)2.5 E F0(.)A F2(options)161 570 Q F0 -.8
-(To)226 570 S .625(ggles the display of some internal).8 F F2(telnet)3.125 E F0
-.625(protocol processing \(ha)3.125 F .625(ving to)-.2 F(do with)226 582 Q F4
-(TELNET)2.5 E F0 2.5(options\). The)2.5 F(initial v)2.5 E
-(alue for this toggle is)-.25 E F3(FALSE)2.5 E F0(.)A F2(prettydump)161 600 Q
-F0 .133(When the)5 F F2(netdata)2.633 E F0 .134(toggle is enabled, if)2.633 F
-F2(prettydump)2.634 E F0 .134(is enabled the output)2.634 F .745(from the)226
-612 R F2(netdata)3.245 E F0 .744
-(command will be formatted in a more user readable for)3.244 F(-)-.2 E 3.199
-(mat. Spaces)226 624 R .699
-(are put between each character in the output, and the be)3.199 F(ginning)-.15
-E(of an)226 636 Q(y)-.15 E F4(TELNET)2.5 E F0
-(escape sequence is preceded by a ')2.5 E/F5 10/Symbol SF(*)A F0 2.5('t)C 2.5
-(oa)442.553 636 S(id in locating them.)454.493 636 Q F2(skiprc)161 654 Q F0
-4.589(When the skiprc toggle is)226 654 R F3(TRUE)7.089 E F0(,)A F4(TELNET)
-7.089 E F0 4.589(skips the reading of the)7.089 F F3(.telnetrc)226 666 Q F0
-1.033(\214le in the users home directory when connections are opened.)3.533 F
-(The initial v)226 678 Q(alue for this toggle is)-.25 E F3(FALSE.)2.5 E F0
-(4.2 Berk)72 750 Q(ele)-.1 E 2.5(yD)-.15 G(istrib)132.57 750 Q 95.71
-(ution February)-.2 F(3, 1994)2.5 E(9)535 750 Q EP
-%%Page: 10 10
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF -.834(TELNET \( 1 \))72 48 R(BSD Reference Manual)
-258.235 48 Q -.834(TELNET \( 1 \))485.572 48 R/F1 10/Courier-Bold@0 SF
-(termdata)161 96 Q F0 -.8(To)226 96 S .934
-(ggles the display of all terminal data \(in he).8 F .933(xadecimal format\).)
--.15 F .933(The initial)5.933 F -.25(va)226 108 S(lue for this toggle is).25 E
-/F2 10/Courier@0 SF(FALSE)2.5 E F0(.)A F1(verbose_encrypt)161 126 Q F0 1.129
-(When the)226 138 R F1(verbose_encrypt)3.629 E F0 1.13(toggle is)3.629 F F2
-(TRUE)3.63 E F0(,)A/F3 9/Times-Roman@0 SF(TELNET)3.63 E F0 1.13
-(prints out a mes-)3.63 F 1.377
-(sage each time encryption is enabled or disabled.)226 150 R 1.376
-(The initial v)6.377 F 1.376(alue for this)-.25 F 1.223(toggle is)226 162 R F2
-(FALSE.)3.723 E F0 3.723(Note: Because)3.723 F 1.224(of e)3.724 F 1.224
-(xport controls, data encryption is not)-.15 F
-(supported outside of the United States and Canada.)226 174 Q F1(?)161 192 Q F0
-(Displays the le)226 192 Q -.05(ga)-.15 G(l).05 E F1(toggle)2.5 E F0(commands.)
-2.5 E F1(z)102 210 Q F0(Suspend)161 210 Q F1(telnet)2.5 E F0 2.5(.T)C
-(his command only w)244.5 210 Q(orks when the user is using the)-.1 E F2(csh)
-2.5 E F0(\(1\).)A F1(!)102 228 Q F0([)6.833 E/F4 10/Courier-Oblique@0 SF
-(command).833 E F0(]).833 E(Ex)161 240 Q .293
-(ecute a single command in a subshell on the local system.)-.15 F(If)5.292 E F1
-(command)2.792 E F0 .292(is omitted, then an)2.792 F(interacti)161 252 Q .3
--.15(ve s)-.25 H(ubshell is in).15 E -.2(vo)-.4 G -.1(ke).2 G(d.).1 E F1(?)102
-270 Q F0([)6.833 E F4(command).833 E F0(]).833 E 1.177(Get help.)161 282 R -.4
-(Wi)6.177 G 1.178(th no ar).4 F(guments,)-.18 E F1(telnet)3.678 E F0 1.178
-(prints a help summary)3.678 F 6.178(.I)-.65 G 3.678(fac)433.358 282 S 1.178
-(ommand is speci\214ed,)452.924 282 R F1(telnet)161 294 Q F0
-(will print the help information for just that command.)2.5 E/F5 10
-/Times-Bold@0 SF(ENVIR)72 318 Q(ONMENT)-.3 E F1(Telnet)102 330 Q F0 .666
-(uses at least the)3.166 F F2(HOME)3.166 E F0(,)A F2(SHELL)3.165 E F0(,)A F2
-(DISPLAY)3.165 E F0 3.165(,a)C(nd)326.255 330 Q F2(TERM)3.165 E F0(en)3.165 E
-.665(vironment v)-.4 F 3.165(ariables. Other)-.25 F(en)3.165 E(vironment)-.4 E
--.25(va)102 342 S(riables may be propag).25 E(ated to the other side via the)
--.05 E F2(TELNET ENVIRON)2.5 E F0(option.)2.5 E F5(FILES)72 366 Q F2
-(~/.telnetrc)102 378 Q F0(user customized telnet startup v)5 E(alues)-.25 E F5
-(HIST)72 402 Q(OR)-.18 E(Y)-.35 E F0(The)102 414 Q F1(Telnet)2.5 E F0
-(command appeared in 4.2)2.5 E F3(BSD)A F0(.)A F5(NO)72 438 Q(TES)-.4 E F0
-(On some remote systems, echo has to be turned of)102 450 Q 2.5(fm)-.25 G
-(anually when in `)316.44 450 Q(`old line by line')-.74 E 2.5('m)-.74 G(ode.)
-465.22 450 Q .691(In `)102 468 R .691(`old line by line')-.74 F 3.191('m)-.74 G
-.691(ode or)198.685 468 R F2(LINEMODE)3.191 E F0 .691(the terminal')3.191 F(s)
--.55 E F1(eof)3.191 E F0 .691(character is only recognized \(and sent to the)
-3.191 F(remote system\) when it is the \214rst character on a line.)102 480 Q
-(4.2 Berk)72 750 Q(ele)-.1 E 2.5(yD)-.15 G(istrib)132.57 750 Q 95.71
-(ution February)-.2 F(3, 1994)2.5 E(10)530 750 Q EP
-%%Trailer
-end
-%%EOF
+++ /dev/null
-TELNET(1) BSD Reference Manual TELNET(1)
-
-N\bNA\bAM\bME\bE
- t\bte\bel\bln\bne\bet\bt - user interface to the TELNET protocol
-
-S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS
- t\bte\bel\bln\bne\bet\bt [-\b-8\b8] [-\b-E\bE] [-\b-F\bF] [-\b-K\bK] [-\b-L\bL] [-\b-S\bS _\bt_\bo_\bs] [-\b-X\bX _\ba_\bu_\bt_\bh_\bt_\by_\bp_\be] [-\b-a\ba] [-\b-c\bc] [-\b-d\bd] [-\b-e\be
- _\be_\bs_\bc_\ba_\bp_\be_\bc_\bh_\ba_\br] [-\b-f\bf] [-\b-k\bk _\br_\be_\ba_\bl_\bm] [-\b-l\bl _\bu_\bs_\be_\br] [-\b-n\bn _\bt_\br_\ba_\bc_\be_\bf_\bi_\bl_\be] [-\b-r\br] [-\b-x\bx]
- [_\bh_\bo_\bs_\bt [port]]
-
-D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
- The t\bte\bel\bln\bne\bet\bt command is used to communicate with another host using the
- TELNET protocol. If t\bte\bel\bln\bne\bet\bt is invoked without the _\bh_\bo_\bs_\bt argument, it en-
- ters command mode, indicated by its prompt (t\bte\bel\bln\bne\bet\bt>\b>). In this mode, it
- accepts and executes the commands listed below. If it is invoked with
- arguments, it performs an o\bop\bpe\ben\bn command with those arguments.
-
- Options:
-
- -\b-8\b8 Specifies an 8-bit data path. This causes an attempt to negoti-
- ate the TELNET BINARY option on both input and output.
-
- -\b-E\bE Stops any character from being recognized as an escape character.
-
- -\b-F\bF If Kerberos V5 authentication is being used, the -\b-F\bF option allows
- the local credentials to be forwarded to the remote system, in-
- cluding any credentials that have already been forwarded into the
- local environment.
-
- -\b-K\bK Specifies no automatic login to the remote system.
-
- -\b-L\bL Specifies an 8-bit data path on output. This causes the BINARY
- option to be negotiated on output.
-
- -\b-S\bS _\bt_\bo_\bs Sets the IP type-of-service (TOS) option for the telnet connec-
- tion to the value _\bt_\bo_\bs_\b, which can be a numeric TOS value or, on
- systems that support it, a symbolic TOS name found in the
- /etc/iptos file.
-
- -\b-X\bX _\ba_\bt_\by_\bp_\be
- Disables the _\ba_\bt_\by_\bp_\be type of authentication.
-
- -\b-a\ba Attempt automatic login. Currently, this sends the user name via
- the USER variable of the ENVIRON option if supported by the re-
- mote system. The name used is that of the current user as re-
- turned by getlogin(2) if it agrees with the current user ID, oth-
- erwise it is the name associated with the user ID.
-
- -\b-c\bc Disables the reading of the user's _\b._\bt_\be_\bl_\bn_\be_\bt_\br_\bc file. (See the
- t\bto\bog\bgg\bgl\ble\be s\bsk\bki\bip\bpr\brc\bc command on this man page.)
-
- -\b-d\bd Sets the initial value of the d\bde\beb\bbu\bug\bg toggle to TRUE
-
- -\b-e\be _\be_\bs_\bc_\ba_\bp_\be _\bc_\bh_\ba_\br
- Sets the initial t\bte\bel\bln\bne\bet\bt t\bte\bel\bln\bne\bet\bt escape character to _\be_\bs_\bc_\ba_\bp_\be _\bc_\bh_\ba_\br_\b.
- If _\be_\bs_\bc_\ba_\bp_\be _\bc_\bh_\ba_\br is omitted, then there will be no escape charac-
- ter.
-
- -\b-f\bf If Kerberos V5 authentication is being used, the -\b-f\bf option allows
- the local credentials to be forwarded to the remote system.
-
- -\b-k\bk _\br_\be_\ba_\bl_\bm
- If Kerberos authentication is being used, the -\b-k\bk option requests
- that telnet obtain tickets for the remote host in realm realm in-
- stead of the remote host's realm, as determined by
-
- krb_realmofhost(3).
-
- -\b-l\bl _\bu_\bs_\be_\br
- When connecting to the remote system, if the remote system under-
- stands the ENVIRON option, then _\bu_\bs_\be_\br will be sent to the remote
- system as the value for the variable USER. This option implies
- the -\b-a\ba option. This option may also be used with the o\bop\bpe\ben\bn com-
- mand.
-
- -\b-n\bn _\bt_\br_\ba_\bc_\be_\bf_\bi_\bl_\be
- Opens _\bt_\br_\ba_\bc_\be_\bf_\bi_\bl_\be for recording trace information. See the s\bse\bet\bt
- t\btr\bra\bac\bce\bef\bfi\bil\ble\be command below.
-
- -\b-r\br Specifies a user interface similar to rlogin(1). In this mode,
- the escape character is set to the tilde (~) character, unless
- modified by the -e option.
-
- -\b-x\bx Turns on encryption of the data stream if possible. This option
- is not available outside of the United States and Canada.
-
- _\bh_\bo_\bs_\bt Indicates the official name, an alias, or the Internet address of
- a remote host.
-
- _\bp_\bo_\br_\bt Indicates a port number (address of an application). If a number
- is not specified, the default t\bte\bel\bln\bne\bet\bt port is used.
-
- When in rlogin mode, a line of the form ~. disconnects from the remote
- host; ~ is the telnet escape character. Similarly, the line ~^Z suspends
- the telnet session. The line ~^] escapes to the normal telnet escape
- prompt.
-
- Once a connection has been opened, t\bte\bel\bln\bne\bet\bt will attempt to enable the
- TELNET LINEMODE option. If this fails, then t\bte\bel\bln\bne\bet\bt will revert to one of
- two input modes: either ``character at a time'' or ``old line by line''
- depending on what the remote system supports.
-
- When LINEMODE is enabled, character processing is done on the local sys-
- tem, under the control of the remote system. When input editing or char-
- acter echoing is to be disabled, the remote system will relay that infor-
- mation. The remote system will also relay changes to any special charac-
- ters that happen on the remote system, so that they can take effect on
- the local system.
-
- In ``character at a time'' mode, most text typed is immediately sent to
- the remote host for processing.
-
- In ``old line by line'' mode, all text is echoed locally, and (normally)
- only completed lines are sent to the remote host. The ``local echo char-
- acter'' (initially ``^E'') may be used to turn off and on the local echo
- (this would mostly be used to enter passwords without the password being
- echoed).
-
- If the LINEMODE option is enabled, or if the l\blo\boc\bca\bal\blc\bch\bha\bar\brs\bs toggle is TRUE
- (the default for ``old line by line``; see below), the user's q\bqu\bui\bit\bt, i\bin\bnt\btr\br,
- and f\bfl\blu\bus\bsh\bh characters are trapped locally, and sent as TELNET protocol se-
- quences to the remote side. If LINEMODE has ever been enabled, then the
- user's s\bsu\bus\bsp\bp and e\beo\bof\bf are also sent as TELNET protocol sequences, and q\bqu\bui\bit\bt
- is sent as a TELNET ABORT instead of BREAK There are options (see t\bto\bog\bgg\bgl\ble\be
- a\bau\but\bto\bof\bfl\blu\bus\bsh\bh and t\bto\bog\bgg\bgl\ble\be a\bau\but\bto\bos\bsy\byn\bnc\bch\bh below) which cause this action to flush
- subsequent output to the terminal (until the remote host acknowledges the
- TELNET sequence) and flush previous terminal input (in the case of q\bqu\bui\bit\bt
- and i\bin\bnt\btr\br).
-
- While connected to a remote host, t\bte\bel\bln\bne\bet\bt command mode may be entered by
- typing the t\bte\bel\bln\bne\bet\bt ``escape character'' (initially ``^]''). When in com-
- mand mode, the normal terminal editing conventions are available.
-
- The following t\bte\bel\bln\bne\bet\bt commands are available. Only enough of each command
- to uniquely identify it need be typed (this is also true for arguments to
- the m\bmo\bod\bde\be, s\bse\bet\bt, t\bto\bog\bgg\bgl\ble\be, u\bun\bns\bse\bet\bt, s\bsl\blc\bc, e\ben\bnv\bvi\bir\bro\bon\bn, and d\bdi\bis\bsp\bpl\bla\bay\by commands).
-
- a\bau\but\bth\bh _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt _\b._\b._\b.
- The auth command manipulates the information sent through the
- TELNET AUTHENTICATE option. Valid arguments for the auth com-
- mand are as follows:
-
- d\bdi\bis\bsa\bab\bbl\ble\be _\bt_\by_\bp_\be Disables the specified type of authentication.
- To obtain a list of available types, use the
- a\bau\but\bth\bh d\bdi\bis\bsa\bab\bbl\ble\be ?\b? command.
-
- e\ben\bna\bab\bbl\ble\be _\bt_\by_\bp_\be Enables the specified type of authentication.
- To obtain a list of available types, use the
- a\bau\but\bth\bh e\ben\bna\bab\bbl\ble\be ?\b? command.
-
- s\bst\bta\bat\btu\bus\bs Lists the current status of the various types of
- authentication.
-
- c\bcl\blo\bos\bse\be Close a TELNET session and return to command mode.
-
- d\bdi\bis\bsp\bpl\bla\bay\by _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt _\b._\b._\b.
- Displays all, or some, of the s\bse\bet\bt and t\bto\bog\bgg\bgl\ble\be values (see be-
- low).
-
- e\ben\bnc\bcr\bry\byp\bpt\bt _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt _\b._\b._\b.
- The encrypt command manipulates the information sent through
- the TELNET ENCRYPT option.
-
- Note: Because of export controls, the TELNET ENCRYPT option
- is not supported outside of the United States and Canada.
-
- Valid arguments for the encrypt command are as follows:
-
- d\bdi\bis\bsa\bab\bbl\ble\be _\bt_\by_\bp_\be [\b[i\bin\bnp\bpu\but\bt|\b|o\bou\but\btp\bpu\but\bt]\b]
- Disables the specified type of encryption. If
- you omit the input and output, both input and
- output are disabled. To obtain a list of avail-
- able types, use the e\ben\bnc\bcr\bry\byp\bpt\bt d\bdi\bis\bsa\bab\bbl\ble\be ?\b? command.
-
- e\ben\bna\bab\bbl\ble\be _\bt_\by_\bp_\be [\b[i\bin\bnp\bpu\but\bt|\b|o\bou\but\btp\bpu\but\bt]\b]
- Enables the specified type of encryption. If
- you omit input and output, both input and output
- are enabled. To obtain a list of available
- types, use the e\ben\bnc\bcr\bry\byp\bpt\bt e\ben\bna\bab\bbl\ble\be ?\b? command.
-
- i\bin\bnp\bpu\but\bt This is the same as the e\ben\bnc\bcr\bry\byp\bpt\bt s\bst\bta\bar\brt\bt i\bin\bnp\bpu\but\bt com-
- mand.
-
- -\b-i\bin\bnp\bpu\but\bt This is the same as the e\ben\bnc\bcr\bry\byp\bpt\bt s\bst\bto\bop\bp i\bin\bnp\bpu\but\bt com-
- mand.
-
- o\bou\but\btp\bpu\but\bt This is the same as the e\ben\bnc\bcr\bry\byp\bpt\bt s\bst\bta\bar\brt\bt o\bou\but\btp\bpu\but\bt
- command.
-
- -\b-o\bou\but\btp\bpu\but\bt This is the same as the e\ben\bnc\bcr\bry\byp\bpt\bt s\bst\bto\bop\bp o\bou\but\btp\bpu\but\bt com-
- mand.
-
- s\bst\bta\bar\brt\bt [\b[i\bin\bnp\bpu\but\bt|\b|o\bou\but\btp\bpu\but\bt]\b]
- Attempts to start encryption. If you omit i\bin\bnp\bpu\but\bt
- and o\bou\but\btp\bpu\but\bt,\b, both input and output are enabled.
- To obtain a list of available types, use the
-
- e\ben\bnc\bcr\bry\byp\bpt\bt e\ben\bna\bab\bbl\ble\be ?\b? command.
-
- s\bst\bta\bat\btu\bus\bs Lists the current status of encryption.
-
- s\bst\bto\bop\bp [\b[i\bin\bnp\bpu\but\bt|\b|o\bou\but\btp\bpu\but\bt]\b]
- Stops encryption. If you omit input and output,
- encryption is on both input and output.
-
- t\bty\byp\bpe\be _\bt_\by_\bp_\be Sets the default type of encryption to be used
- with later e\ben\bnc\bcr\bry\byp\bpt\bt s\bst\bta\bar\brt\bt or e\ben\bnc\bcr\bry\byp\bpt\bt s\bst\bto\bop\bp com-
- mands.
-
- e\ben\bnv\bvi\bir\bro\bon\bn _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt_\bs_\b._\b._\b.
- The e\ben\bnv\bvi\bir\bro\bon\bn command is used to manipulate the the variables
- that my be sent through the TELNET ENVIRON option. The ini-
- tial set of variables is taken from the users environment,
- with only the DISPLAY and PRINTER variables being exported by
- default. The USER variable is also exported if the -\b-a\ba or -\b-l\bl
- options are used.
- Valid arguments for the e\ben\bnv\bvi\bir\bro\bon\bn command are:
-
- d\bde\bef\bfi\bin\bne\be _\bv_\ba_\br_\bi_\ba_\bb_\bl_\be _\bv_\ba_\bl_\bu_\be
- Define the variable _\bv_\ba_\br_\bi_\ba_\bb_\bl_\be to have a value of
- _\bv_\ba_\bl_\bu_\be_\b. Any variables defined by this command are
- automatically exported. The _\bv_\ba_\bl_\bu_\be may be enclosed
- in single or double quotes so that tabs and spaces
- may be included.
-
- u\bun\bnd\bde\bef\bfi\bin\bne\be _\bv_\ba_\br_\bi_\ba_\bb_\bl_\be
- Remove _\bv_\ba_\br_\bi_\ba_\bb_\bl_\be from the list of environment vari-
- ables.
-
- e\bex\bxp\bpo\bor\brt\bt _\bv_\ba_\br_\bi_\ba_\bb_\bl_\be
- Mark the variable _\bv_\ba_\br_\bi_\ba_\bb_\bl_\be to be exported to the
- remote side.
-
- u\bun\bne\bex\bxp\bpo\bor\brt\bt _\bv_\ba_\br_\bi_\ba_\bb_\bl_\be
- Mark the variable _\bv_\ba_\br_\bi_\ba_\bb_\bl_\be to not be exported un-
- less explicitly asked for by the remote side.
-
- l\bli\bis\bst\bt List the current set of environment variables.
- Those marked with a *\b* will be sent automatically,
- other variables will only be sent if explicitly
- requested.
-
- ?\b? Prints out help information for the e\ben\bnv\bvi\bir\bro\bon\bn com-
- mand.
-
- l\blo\bog\bgo\bou\but\bt Sends the TELNET LOGOUT option to the remote side. This com-
- mand is similar to a c\bcl\blo\bos\bse\be command; however, if the remote
- side does not support the LOGOUT option, nothing happens. If,
- however, the remote side does support the LOGOUT option, this
- command should cause the remote side to close the TELNET con-
- nection. If the remote side also supports the concept of sus-
- pending a user's session for later reattachment, the logout
- argument indicates that you should terminate the session imme-
- diately.
-
- m\bmo\bod\bde\be _\bt_\by_\bp_\be _\bT_\by_\bp_\be is one of several options, depending on the state of the
- TELNET session. The remote host is asked for permission to go
- into the requested mode. If the remote host is capable of en-
- tering that mode, the requested mode will be entered.
-
- c\bch\bha\bar\bra\bac\bct\bte\ber\br Disable the TELNET LINEMODE option, or, if the
- remote side does not understand the LINEMODE op-
-
- tion, then enter ``character at a time`` mode.
-
- l\bli\bin\bne\be Enable the TELNET LINEMODE option, or, if the
- remote side does not understand the LINEMODE op-
- tion, then attempt to enter ``old-line-by-line``
- mode.
-
- i\bis\bsi\big\bg (-\b-i\bis\bsi\big\bg) Attempt to enable (disable) the TRAPSIG mode of
- the LINEMODE option. This requires that the
- LINEMODE option be enabled.
-
- e\bed\bdi\bit\bt (-\b-e\bed\bdi\bit\bt) Attempt to enable (disable) the EDIT mode of the
- LINEMODE option. This requires that the
- LINEMODE option be enabled.
-
- s\bso\bof\bft\btt\bta\bab\bbs\bs (-\b-s\bso\bof\bft\btt\bta\bab\bbs\bs)
- Attempt to enable (disable) the SOFT_TAB mode of
- the LINEMODE option. This requires that the
- LINEMODE option be enabled.
-
- l\bli\bit\bte\bec\bch\bho\bo (-\b-l\bli\bit\bte\bec\bch\bho\bo)
- Attempt to enable (disable) the LIT_ECHO mode of
- the LINEMODE option. This requires that the
- LINEMODE option be enabled.
-
- ?\b? Prints out help information for the m\bmo\bod\bde\be com-
- mand.
-
- o\bop\bpe\ben\bn _\bh_\bo_\bs_\bt [[-\b-l\bl] _\bu_\bs_\be_\br][-\b-_\bp_\bo_\br_\bt]
- Open a connection to the named host. If no port number is
- specified, t\bte\bel\bln\bne\bet\bt will attempt to contact a TELNET server at
- the default port. The host specification may be either a host
- name (see hosts(5)) or an Internet address specified in the
- ``dot notation'' (see inet(3)). The [-\b-l\bl] option may be used
- to specify the user name to be passed to the remote system via
- the ENVIRON option. When connecting to a non-standard port,
- t\bte\bel\bln\bne\bet\bt omits any automatic initiation of TELNET options. When
- the port number is preceded by a minus sign, the initial op-
- tion negotiation is done. After establishing a connection,
- the file _\b._\bt_\be_\bl_\bn_\be_\bt_\br_\bc in the users home directory is opened.
- Lines beginning with a # are comment lines. Blank lines are
- ignored. Lines that begin without white space are the start
- of a machine entry. The first thing on the line is the name
- of the machine that is being connected to. The rest of the
- line, and successive lines that begin with white space are as-
- sumed to be t\bte\bel\bln\bne\bet\bt commands and are processed as if they had
- been typed in manually to the t\bte\bel\bln\bne\bet\bt command prompt.
-
- q\bqu\bui\bit\bt Close any open TELNET session and exit t\bte\bel\bln\bne\bet\bt. An end of file
- (in command mode) will also close a session and exit.
-
- s\bse\ben\bnd\bd _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt_\bs
- Sends one or more special character sequences to the remote
- host. The following are the arguments which may be specified
- (more than one argument may be specified at a time):
-
- a\bab\bbo\bor\brt\bt Sends the TELNET ABORT (Abort processes) sequence.
-
- a\bao\bo Sends the TELNET AO (Abort Output) sequence, which
- should cause the remote system to flush all output
- _\bf_\br_\bo_\bm the remote system _\bt_\bo the user's terminal.
-
- a\bay\byt\bt Sends the TELNET AYT (Are You There) sequence, to
- which the remote system may or may not choose to re-
-
-
- spond.
-
- b\bbr\brk\bk Sends the TELNET BRK (Break) sequence, which may have
- significance to the remote system.
-
- e\bec\bc Sends the TELNET EC (Erase Character) sequence, which
- should cause the remote system to erase the last char-
- acter entered.
-
- e\bel\bl Sends the TELNET EL (Erase Line) sequence, which
- should cause the remote system to erase the line cur-
- rently being entered.
-
- e\beo\bof\bf Sends the TELNET EOF (End Of File) sequence.
-
- e\beo\bor\br Sends the TELNET EOR (End of Record) sequence.
-
- e\bes\bsc\bca\bap\bpe\be Sends the current t\bte\bel\bln\bne\bet\bt escape character (initially
- ``^'').
-
- g\bga\ba Sends the TELNET GA (Go Ahead) sequence, which likely
- has no significance to the remote system.
-
- g\bge\bet\bts\bst\bta\bat\btu\bus\bs
- If the remote side supports the TELNET STATUS command,
- g\bge\bet\bts\bst\bta\bat\btu\bus\bs will send the subnegotiation to request that
- the server send its current option status.
-
- i\bip\bp Sends the TELNET IP (Interrupt Process) sequence,
- which should cause the remote system to abort the cur-
- rently running process.
-
- n\bno\bop\bp Sends the TELNET NOP (No OPeration) sequence.
-
- s\bsu\bus\bsp\bp Sends the TELNET SUSP (SUSPend process) sequence.
-
- s\bsy\byn\bnc\bch\bh Sends the TELNET SYNCH sequence. This sequence causes
- the remote system to discard all previously typed (but
- not yet read) input. This sequence is sent as TCP ur-
- gent data (and may not work if the remote system is a
- 4.2BSD system -- if it doesn't work, a lower case
- ``r'' may be echoed on the terminal).
-
- d\bdo\bo _\bc_\bm_\bd
-
- d\bdo\bon\bnt\bt _\bc_\bm_\bd
-
- w\bwi\bil\bll\bl _\bc_\bm_\bd
-
- w\bwo\bon\bnt\bt _\bc_\bm_\bd
- Sends the TELNET DO _\bc_\bm_\bd sequence. _\bC_\bm_\bd can be either a
- decimal number between 0 and 255, or a symbolic name
- for a specific TELNET command. _\bC_\bm_\bd can also be either
- h\bhe\bel\blp\bp or ?\b? to print out help information, including a
- list of known symbolic names.
-
- ?\b? Prints out help information for the s\bse\ben\bnd\bd command.
-
- s\bse\bet\bt _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt _\bv_\ba_\bl_\bu_\be
-
- u\bun\bns\bse\bet\bt _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt _\bv_\ba_\bl_\bu_\be
- The s\bse\bet\bt command will set any one of a number of t\bte\bel\bln\bne\bet\bt vari-
- ables to a specific value or to TRUE. The special value o\bof\bff\bf
- turns off the function associated with the variable, this is
- equivalent to using the u\bun\bns\bse\bet\bt command. The u\bun\bns\bse\bet\bt command will
- disable or set to FALSE any of the specified functions. The
- values of variables may be interrogated with the d\bdi\bis\bsp\bpl\bla\bay\by com-
- mand. The variables which may be set or unset, but not tog-
- gled, are listed here. In addition, any of the variables for
- the t\bto\bog\bgg\bgl\ble\be command may be explicitly set or unset using the
- s\bse\bet\bt and u\bun\bns\bse\bet\bt commands.
-
- a\bay\byt\bt If TELNET is in localchars mode, or LINEMODE is en-
- abled, and the status character is typed, a TELNET AYT
- sequence (see s\bse\ben\bnd\bd a\bay\byt\bt preceding) is sent to the re-
- mote host. The initial value for the "Are You There"
- character is the terminal's status character.
-
- e\bec\bch\bho\bo This is the value (initially ``^E'') which, when in
- ``line by line'' mode, toggles between doing local
- echoing of entered characters (for normal processing),
- and suppressing echoing of entered characters (for en-
- tering, say, a password).
-
- e\beo\bof\bf If t\bte\bel\bln\bne\bet\bt is operating in LINEMODE or ``old line by
- line'' mode, entering this character as the first
- character on a line will cause this character to be
- sent to the remote system. The initial value of the
- eof character is taken to be the terminal's e\beo\bof\bf char-
- acter.
-
- e\ber\bra\bas\bse\be If t\bte\bel\bln\bne\bet\bt is in l\blo\boc\bca\bal\blc\bch\bha\bar\brs\bs mode (see t\bto\bog\bgg\bgl\ble\be l\blo\boc\bca\bal\blc\bch\bha\bar\brs\bs
- below), a\ban\bnd\bd if t\bte\bel\bln\bne\bet\bt is operating in ``character at a
- time'' mode, then when this character is typed, a
- TELNET EC sequence (see s\bse\ben\bnd\bd e\bec\bc above) is sent to the
- remote system. The initial value for the erase char-
- acter is taken to be the terminal's e\ber\bra\bas\bse\be character.
-
- e\bes\bsc\bca\bap\bpe\be This is the t\bte\bel\bln\bne\bet\bt escape character (initially ``^['')
- which causes entry into t\bte\bel\bln\bne\bet\bt command mode (when con-
- nected to a remote system).
-
- f\bfl\blu\bus\bsh\bho\bou\but\btp\bpu\but\bt
- If t\bte\bel\bln\bne\bet\bt is in l\blo\boc\bca\bal\blc\bch\bha\bar\brs\bs mode (see t\bto\bog\bgg\bgl\ble\be l\blo\boc\bca\bal\blc\bch\bha\bar\brs\bs
- below) and the f\bfl\blu\bus\bsh\bho\bou\but\btp\bpu\but\bt character is typed, a
- TELNET AO sequence (see s\bse\ben\bnd\bd a\bao\bo above) is sent to the
- remote host. The initial value for the flush charac-
- ter is taken to be the terminal's f\bfl\blu\bus\bsh\bh character.
-
- f\bfo\bor\brw\bw1\b1
-
- f\bfo\bor\brw\bw2\b2 If TELNET is operating in LINEMODE, these are the
- characters that, when typed, cause partial lines to be
- forwarded to the remote system. The initial value for
- the forwarding characters are taken from the termi-
- nal's eol and eol2 characters.
-
- i\bin\bnt\bte\ber\brr\bru\bup\bpt\bt
- If t\bte\bel\bln\bne\bet\bt is in l\blo\boc\bca\bal\blc\bch\bha\bar\brs\bs mode (see t\bto\bog\bgg\bgl\ble\be l\blo\boc\bca\bal\blc\bch\bha\bar\brs\bs
- below) and the i\bin\bnt\bte\ber\brr\bru\bup\bpt\bt character is typed, a TELNET
- IP sequence (see s\bse\ben\bnd\bd i\bip\bp above) is sent to the remote
- host. The initial value for the interrupt character
- is taken to be the terminal's i\bin\bnt\btr\br character.
-
- k\bki\bil\bll\bl If t\bte\bel\bln\bne\bet\bt is in l\blo\boc\bca\bal\blc\bch\bha\bar\brs\bs mode (see t\bto\bog\bgg\bgl\ble\be l\blo\boc\bca\bal\blc\bch\bha\bar\brs\bs
- below), a\ban\bnd\bd if t\bte\bel\bln\bne\bet\bt is operating in ``character at a
- time'' mode, then when this character is typed, a
- TELNET EL sequence (see s\bse\ben\bnd\bd e\bel\bl above) is sent to the
- remote system. The initial value for the kill charac-
- ter is taken to be the terminal's k\bki\bil\bll\bl character.
-
- l\bln\bne\bex\bxt\bt If t\bte\bel\bln\bne\bet\bt is operating in LINEMODE or ``old line by
- line`` mode, then this character is taken to be the
- terminal's l\bln\bne\bex\bxt\bt character. The initial value for the
- lnext character is taken to be the terminal's l\bln\bne\bex\bxt\bt
- character.
-
- q\bqu\bui\bit\bt If t\bte\bel\bln\bne\bet\bt is in l\blo\boc\bca\bal\blc\bch\bha\bar\brs\bs mode (see t\bto\bog\bgg\bgl\ble\be l\blo\boc\bca\bal\blc\bch\bha\bar\brs\bs
- below) and the q\bqu\bui\bit\bt character is typed, a TELNET BRK
- sequence (see s\bse\ben\bnd\bd b\bbr\brk\bk above) is sent to the remote
- host. The initial value for the quit character is
- taken to be the terminal's q\bqu\bui\bit\bt character.
-
- r\bre\bep\bpr\bri\bin\bnt\bt
- If t\bte\bel\bln\bne\bet\bt is operating in LINEMODE or ``old line by
- line`` mode, then this character is taken to be the
- terminal's r\bre\bep\bpr\bri\bin\bnt\bt character. The initial value for
- the reprint character is taken to be the terminal's
- r\bre\bep\bpr\bri\bin\bnt\bt character.
-
- r\brl\blo\bog\bgi\bin\bn This is the rlogin escape character. If set, the nor-
- mal TELNET escape character is ignored unless it is
- preceded by this character at the beginning of a line.
- This character, at the beginning of a line followed by
- a "." closes the connection; when followed by a ^Z it
- suspends the telnet command. The initial state is to
- disable the rlogin escape character.
-
- s\bst\bta\bar\brt\bt If the TELNET TOGGLE-FLOW-CONTROL option has been en-
- abled, then this character is taken to be the termi-
- nal's s\bst\bta\bar\brt\bt character. The initial value for the kill
- character is taken to be the terminal's s\bst\bta\bar\brt\bt charac-
- ter.
-
- s\bst\bto\bop\bp If the TELNET TOGGLE-FLOW-CONTROL option has been en-
- abled, then this character is taken to be the termi-
- nal's s\bst\bto\bop\bp character. The initial value for the kill
- character is taken to be the terminal's s\bst\bto\bop\bp charac-
- ter.
-
- s\bsu\bus\bsp\bp If t\bte\bel\bln\bne\bet\bt is in l\blo\boc\bca\bal\blc\bch\bha\bar\brs\bs mode, or LINEMODE is en-
- abled, and the s\bsu\bus\bsp\bpe\ben\bnd\bd character is typed, a TELNET
- SUSP sequence (see s\bse\ben\bnd\bd s\bsu\bus\bsp\bp above) is sent to the re-
- mote host. The initial value for the suspend charac-
- ter is taken to be the terminal's s\bsu\bus\bsp\bpe\ben\bnd\bd character.
-
- t\btr\bra\bac\bce\bef\bfi\bil\ble\be
- This is the file to which the output, caused by
- n\bne\bet\btd\bda\bat\bta\ba or o\bop\bpt\bti\bio\bon\bn tracing being TRUE, will be written.
- If it is set to ``-\b-'', then tracing information will
- be written to standard output (the default).
-
- w\bwo\bor\brd\bde\ber\bra\bas\bse\be
- If t\bte\bel\bln\bne\bet\bt is operating in LINEMODE or ``old line by
- line`` mode, then this character is taken to be the
- terminal's w\bwo\bor\brd\bde\ber\bra\bas\bse\be character. The initial value for
- the worderase character is taken to be the terminal's
- w\bwo\bor\brd\bde\ber\bra\bas\bse\be character.
-
- ?\b? Displays the legal s\bse\bet\bt (u\bun\bns\bse\bet\bt) commands.
-
- s\bsl\blc\bc _\bs_\bt_\ba_\bt_\be The s\bsl\blc\bc command (Set Local Characters) is used to set or
- change the state of the the special characters when the TELNET
- LINEMODE option has been enabled. Special characters are
- characters that get mapped to TELNET commands sequences (like
- i\bip\bp or q\bqu\bui\bit\bt) or line editing characters (like e\ber\bra\bas\bse\be and k\bki\bil\bll\bl).
-
-
- By default, the local special characters are exported.
-
- c\bch\bhe\bec\bck\bk Verify the current settings for the current spe-
- cial characters. The remote side is requested to
- send all the current special character settings,
- and if there are any discrepancies with the local
- side, the local side will switch to the remote
- value.
-
- e\bex\bxp\bpo\bor\brt\bt Switch to the local defaults for the special char-
- acters. The local default characters are those of
- the local terminal at the time when t\bte\bel\bln\bne\bet\bt was
- started.
-
- i\bim\bmp\bpo\bor\brt\bt Switch to the remote defaults for the special
- characters. The remote default characters are
- those of the remote system at the time when the
- TELNET connection was established.
-
- ?\b? Prints out help information for the s\bsl\blc\bc command.
-
- s\bst\bta\bat\btu\bus\bs Show the current status of t\bte\bel\bln\bne\bet\bt. This includes the peer one
- is connected to, as well as the current mode.
-
- t\bto\bog\bgg\bgl\ble\be _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt_\bs _\b._\b._\b.
- Toggle (between TRUE and FALSE) various flags that control how
- t\bte\bel\bln\bne\bet\bt responds to events. These flags may be set explicitly
- to TRUE or FALSE using the s\bse\bet\bt and u\bun\bns\bse\bet\bt commands listed
- above. More than one argument may be specified. The state of
- these flags may be interrogated with the d\bdi\bis\bsp\bpl\bla\bay\by command.
- Valid arguments are:
-
- a\bau\but\bth\bhd\bde\beb\bbu\bug\bg Turns on debugging information for the authenti-
- cation code.
-
- a\bau\but\bto\bof\bfl\blu\bus\bsh\bh If a\bau\but\bto\bof\bfl\blu\bus\bsh\bh and l\blo\boc\bca\bal\blc\bch\bha\bar\brs\bs are both TRUE, then
- when the a\bao\bo, or q\bqu\bui\bit\bt characters are recognized
- (and transformed into TELNET sequences; see s\bse\bet\bt
- above for details), t\bte\bel\bln\bne\bet\bt refuses to display
- any data on the user's terminal until the remote
- system acknowledges (via a TELNET TIMING MARK
- option) that it has processed those TELNET se-
- quences. The initial value for this toggle is
- TRUE if the terminal user had not done an "stty
- noflsh", otherwise FALSE (see stty(1)).
-
- a\bau\but\bto\bod\bde\bec\bcr\bry\byp\bpt\bt When the TELNET ENCRYPT option is negotiated, by
- default the actual encryption (decryption) of
- the data stream does not start automatically.
- The autoencrypt (autodecrypt) command states
- that encryption of the output (input) stream
- should be enabled as soon as possible.
-
- Note: Because of export controls, the TELNET
- ENCRYPT option is not supported outside the
- United States and Canada.
-
- a\bau\but\bto\bol\blo\bog\bgi\bin\bn If the remote side supports the TELNET
- AUTHENTICATION option TELNET attempts to use it
- to perform automatic authentication. If the
- AUTHENTICATION option is not supported, the us-
- er's login name are propagated through the
- TELNET ENVIRON option. This command is the same
- as specifying _\ba option on the o\bop\bpe\ben\bn command.
-
- a\bau\but\bto\bos\bsy\byn\bnc\bch\bh If a\bau\but\bto\bos\bsy\byn\bnc\bch\bh and l\blo\boc\bca\bal\blc\bch\bha\bar\brs\bs are both TRUE, then
- when either the i\bin\bnt\btr\br or q\bqu\bui\bit\bt characters is typed
- (see s\bse\bet\bt above for descriptions of the i\bin\bnt\btr\br and
- q\bqu\bui\bit\bt characters), the resulting TELNET sequence
- sent is followed by the TELNET SYNCH sequence.
- This procedure s\bsh\bho\bou\bul\bld\bd cause the remote system to
- begin throwing away all previously typed input
- until both of the TELNET sequences have been
- read and acted upon. The initial value of this
- toggle is FALSE.
-
- b\bbi\bin\bna\bar\bry\by Enable or disable the TELNET BINARY option on
- both input and output.
-
- i\bin\bnb\bbi\bin\bna\bar\bry\by Enable or disable the TELNET BINARY option on
- input.
-
- o\bou\but\btb\bbi\bin\bna\bar\bry\by Enable or disable the TELNET BINARY option on
- output.
-
- c\bcr\brl\blf\bf If this is TRUE, then carriage returns will be
- sent as <CR><LF>. If this is FALSE, then car-
- riage returns will be send as <CR><NUL>. The
- initial value for this toggle is FALSE.
-
- c\bcr\brm\bmo\bod\bd Toggle carriage return mode. When this mode is
- enabled, most carriage return characters re-
- ceived from the remote host will be mapped into
- a carriage return followed by a line feed. This
- mode does not affect those characters typed by
- the user, only those received from the remote
- host. This mode is not very useful unless the
- remote host only sends carriage return, but nev-
- er line feed. The initial value for this toggle
- is FALSE.
-
- d\bde\beb\bbu\bug\bg Toggles socket level debugging (useful only to
- the s\bsu\bup\bpe\ber\br u\bus\bse\ber\br). The initial value for this tog-
- gle is FALSE.
-
- e\ben\bnc\bcd\bde\beb\bbu\bug\bg Turns on debugging information for the encryp-
- tion code.
-
- l\blo\boc\bca\bal\blc\bch\bha\bar\brs\bs If this is TRUE, then the f\bfl\blu\bus\bsh\bh, i\bin\bnt\bte\ber\brr\bru\bup\bpt\bt,
- q\bqu\bui\bit\bt, e\ber\bra\bas\bse\be, and k\bki\bil\bll\bl characters (see s\bse\bet\bt above)
- are recognized locally, and transformed into
- (hopefully) appropriate TELNET control sequences
- (respectively a\bao\bo, i\bip\bp, b\bbr\brk\bk, e\bec\bc, and e\bel\bl; see s\bse\ben\bnd\bd
- above). The initial value for this toggle is
- TRUE in ``old line by line'' mode, and FALSE in
- ``character at a time'' mode. When the LINEMODE
- option is enabled, the value of l\blo\boc\bca\bal\blc\bch\bha\bar\brs\bs is
- ignored, and assumed to always be TRUE. If
- LINEMODE has ever been enabled, then q\bqu\bui\bit\bt is
- sent as a\bab\bbo\bor\brt\bt, and e\beo\bof\bf a\ban\bnd\bd are sent as e\beo\bof\bf a\ban\bnd\bd
- s\bsu\bus\bsp\bp, see s\bse\ben\bnd\bd above).
-
- n\bne\bet\btd\bda\bat\bta\ba Toggles the display of all network data (in hex-
- adecimal format). The initial value for this
- toggle is FALSE.
-
- o\bop\bpt\bti\bio\bon\bns\bs Toggles the display of some internal t\bte\bel\bln\bne\bet\bt pro-
- tocol processing (having to do with TELNET op-
- tions). The initial value for this toggle is
- FALSE.
-
- p\bpr\bre\bet\btt\bty\byd\bdu\bum\bmp\bp When the n\bne\bet\btd\bda\bat\bta\ba toggle is enabled, if
- p\bpr\bre\bet\btt\bty\byd\bdu\bum\bmp\bp is enabled the output from the
- n\bne\bet\btd\bda\bat\bta\ba command will be formatted in a more user
- readable format. Spaces are put between each
- character in the output, and the beginning of
- any TELNET escape sequence is preceded by a '*'
- to aid in locating them.
-
- s\bsk\bki\bip\bpr\brc\bc When the skiprc toggle is TRUE, TELNET skips the
- reading of the _\b._\bt_\be_\bl_\bn_\be_\bt_\br_\bc file in the users home
- directory when connections are opened. The ini-
- tial value for this toggle is FALSE.
-
- t\bte\ber\brm\bmd\bda\bat\bta\ba Toggles the display of all terminal data (in
- hexadecimal format). The initial value for this
- toggle is FALSE.
-
- v\bve\ber\brb\bbo\bos\bse\be_\b_e\ben\bnc\bcr\bry\byp\bpt\bt
- When the v\bve\ber\brb\bbo\bos\bse\be_\b_e\ben\bnc\bcr\bry\byp\bpt\bt toggle is TRUE, TELNET
- prints out a message each time encryption is en-
- abled or disabled. The initial value for this
- toggle is FALSE. Note: Because of export con-
- trols, data encryption is not supported outside
- of the United States and Canada.
-
- ?\b? Displays the legal t\bto\bog\bgg\bgl\ble\be commands.
-
- z\bz Suspend t\bte\bel\bln\bne\bet\bt. This command only works when the user is using
- the csh(1).
-
- !\b! [_\bc_\bo_\bm_\bm_\ba_\bn_\bd]
- Execute a single command in a subshell on the local system.
- If c\bco\bom\bmm\bma\ban\bnd\bd is omitted, then an interactive subshell is in-
- voked.
-
- ?\b? [_\bc_\bo_\bm_\bm_\ba_\bn_\bd]
- Get help. With no arguments, t\bte\bel\bln\bne\bet\bt prints a help summary.
- If a command is specified, t\bte\bel\bln\bne\bet\bt will print the help informa-
- tion for just that command.
-
-E\bEN\bNV\bVI\bIR\bRO\bON\bNM\bME\bEN\bNT\bT
- T\bTe\bel\bln\bne\bet\bt uses at least the HOME, SHELL, DISPLAY, and TERM environment vari-
- ables. Other environment variables may be propagated to the other side
- via the TELNET ENVIRON option.
-
-F\bFI\bIL\bLE\bES\bS
- ~/.telnetrc user customized telnet startup values
-
-H\bHI\bIS\bST\bTO\bOR\bRY\bY
- The T\bTe\bel\bln\bne\bet\bt command appeared in 4.2BSD.
-
-N\bNO\bOT\bTE\bES\bS
- On some remote systems, echo has to be turned off manually when in ``old
- line by line'' mode.
-
- In ``old line by line'' mode or LINEMODE the terminal's e\beo\bof\bf character is
- only recognized (and sent to the remote system) when it is the first
- character on a line.
-
-4.2 Berkeley Distribution February 3, 1994 11
+++ /dev/null
-.\" Copyright (c) 1983, 1990, 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.
-.\"
-.\" @(#)telnet.1 8.4 (Berkeley) 2/3/94
-.\" "
-.TH TELNET 1
-.SH NAME
-telnet \- user interface to the TELNET protocol
-.SH SYNOPSIS
-.B telnet
-[\fB\-8\fP] [\fB\-E\fP] [\fB\-F\fP] [\fB\-K\fP] [\fB\-L\fP] [\fB\-S\fP
-\fItos\fP] [\fB\-X\fP \fIauthtype\fP] [\fB\-a\fP] [\fB\-c\fP]
-[\fB\-d\fP] [\fB\-e\fP \fIescapechar\fP] [\fB\-f\fP] [\fB\-k\fP
-\fIrealm\fP] [\fB\-l\fP \fIuser\fP] [\fB\-n\fP \fItracefile\fP]
-[\fB\-r\fP] [\fB\-x\fP] [\fIhost\fP [\fIport\fP]]
-.SH DESCRIPTION
-The
-.B telnet
-command is used to communicate with another host using the
-.SM TELNET
-protocol. If
-.B telnet
-is invoked without the
-.I host
-argument, it enters command mode, indicated by its prompt (
-.BR telnet\&> ).
-In this mode, it accepts and executes the commands listed below. If it
-is invoked with arguments, it performs an
-.B open
-command with those arguments.
-.SH OPTIONS
-.TP
-.B \-8
-Specify an 8-bit data path. This causes an attempt to negotiate the
-.SM TELNET BINARY
-option on both input and output.
-.TP
-.B \-E
-Stop any character from being recognized as an escape character.
-.TP
-\fB\-F\fP
-forward a
-.I forwardable
-copy of the local credentials to the remote system.
-.TP
-\fB\-K\fP
-Specify no automatic login to the remote system.
-.TP
-.B \-L
-Specify an 8-bit data path on output. This causes the BINARY option to
-be negotiated on output.
-.TP
-\fB\-S\fP \fItos\fP
-Set the IP type-of-service (TOS) option for the telnet connection to the
-value
-.I tos,
-which can be a numeric TOS value (in decimal, or a hex value preceded
-by 0x, or an octal value preceded by a leading 0) or, on systems that support it, a
-symbolic TOS name found in the /etc/iptos file.
-.TP
-\fB\-X\fP \fIatype\fP
-Disable the
-.I atype
-type of authentication.
-.TP
-\fB\-a\fP
-Attempt automatic login. This sends the user name via the
-.SM USER
-variable of the
-.SM ENVIRON
-option, if supported by the remote system. The name used is that of the
-current user as returned by
-.IR getlogin (2)
-if it agrees with the current user ID; otherwise it is the name
-associated with the user ID.
-.TP
-.B \-c
-Disable the reading of the user's
-.B \&.telnetrc
-file. (See the
-.B toggle skiprc
-command on this man page.)
-.TP
-.B \-d
-Set the initial value of the
-.B debug
-flag to TRUE
-.TP
-\fB\-e\fP \fIescape char\fP
-Set the initial
-.B telnet
-escape character to
-.I escape char.
-If
-.I escape char
-is omitted, then there will be no escape character.
-.TP
-\fB\-f\fP
-forward a copy of the local credentials to the remote system.
-.TP
-\fB\-k\fP \fIrealm\fP
-If Kerberos authentication is being used, request that telnet obtain
-tickets for the remote host in realm
-.I realm
-instead of the remote host's realm, as determined by
-.IR krb_realmofhost (3).
-.TP
-\fB\-l\fP \fIuser\fP
-If the remote system understands the
-.SM ENVIRON
-option, then
-.I user
-will be sent to the remote system as the value for the variable
-.SM USER.
-This option implies the
-.B \-a
-option. This option may also be used with the
-.B open
-command.
-.TP
-\fB\-n\fP \fItracefile\fP
-Open
-.I tracefile
-for recording trace information. See the
-.B set tracefile
-command below.
-.TP
-.B \-r
-Specify a user interface similar to
-.IR rlogin (1).
-In this mode, the escape character is set to the tilde (~) character,
-unless modified by the
-.B \-e
-option.
-.TP
-\fB\-x\fP
-Turn on encryption of the data stream. When this option is turned on,
-.B telnet
-will exit with an error if authentication cannot be negotiated or if
-encryption cannot be turned on.
-.TP
-.I host
-Indicates the name, alias, or Internet address of the remote host.
-.TP
-.I port
-Indicates a port number (address of an application). If the port is not
-specified, the default
-.B telnet
-port (23) is used.
-.PP
-When in rlogin mode, ~ is the telnet escape character; a line of the
-form ~. disconnects from the remote host. Similarly, the line ~^Z
-suspends the telnet session. The line ~^] escapes to the normal telnet
-escape prompt.
-.PP
-Once a connection has been opened,
-.B telnet
-will attempt to enable the
-.SM TELNET LINEMODE
-option. If this fails, then
-.B telnet
-will revert to one of two input modes: either ``character at a time'' or
-``old line by line,'' depending on what the remote system supports.
-.PP
-When
-.SM LINEMODE
-is enabled, character processing is done on the local system, under the
-control of the remote system. When input editing or character echoing
-is to be disabled, the remote system will relay that information. The
-remote system will also relay changes to any special characters that
-happen on the remote system, so that they can take effect on the local
-system.
-.PP
-In ``character at a time'' mode, most text typed is immediately sent to
-the remote host for processing.
-.PP
-In ``old line by line'' mode, all text is echoed locally, and (normally)
-only completed lines are sent to the remote host. The ``local echo
-character'' (initially ``^E'') may be used to turn off and on the local
-echo. (This would mostly be used to enter passwords without the
-password being echoed).
-.PP
-If the LINEMODE option is enabled, or if the
-.B localchars
-flag is TRUE (the default for ``old line by line''; see below), the
-user's
-.BR quit ,
-.BR intr ,
-and
-.BR flush
-characters are trapped locally, and sent as
-.SM TELNET
-protocol sequences to the remote side. If
-.SM LINEMODE
-has ever been enabled, then the user's
-.B susp
-and
-.B eof
-are also sent as
-.SM TELNET
-protocol sequences, and
-.B quit
-is sent as a
-.SM TELNET ABORT
-instead of
-.SM BREAK.
-There are options (see
-.B toggle autoflush
-and
-.B toggle autosynch
-below) which cause this action to flush subsequent output to the
-terminal (until the remote host acknowledges the
-.SM TELNET
-sequence) and flush previous terminal input (in the case of
-.B quit
-and
-.BR intr ).
-.PP
-While connected to a remote host,
-.B telnet
-command mode may be entered by typing the
-.B telnet
-``escape character'' (initially ``^]''). When in command mode, the
-normal terminal editing conventions are available.
-.PP
-The following
-.B telnet
-commands are available. Only enough of each command to uniquely
-identify it need be typed (this is also true for arguments to the
-.BR mode ,
-.BR set ,
-.BR toggle ,
-.BR unset ,
-.BR slc ,
-.BR environ ,
-and
-.B display
-commands).
-.PP
-.TP
-\fBauth\fP \fIargument ...\fP
-The auth command manipulates the information sent through the
-.SM TELNET AUTHENTICATE
-option. Valid arguments for the auth command are as
-follows:
-.RS
-.TP
-\fBdisable\fP \fItype\fP
-Disables the specified type of authentication. To obtain a list of
-available types, use the
-.B auth disable \&?
-command.
-.TP
-\fBenable\fP \fItype\fP
-Enables the specified type of authentication. To obtain a list of
-available types, use the
-.B auth enable \&?
-command.
-.TP
-.B status
-Lists the current status of the various types of authentication.
-.RE
-.TP
-.B close
-Close a
-.SM TELNET
-session and return to command mode.
-.TP
-\fBdisplay\fP \fIargument ...\fP
-Displays some or all of the
-.B set
-and
-.B toggle
-values (see below).
-.TP
-\fBencrypt\fP \fIargument ...\fP
-The encrypt command manipulates the information sent through the
-.SM TELNET ENCRYPT
-option.
-.PP
-Note: Because of export controls, the
-.SM TELNET ENCRYPT
-option is not supported outside of the United States and Canada.
-.PP
-Valid arguments for the encrypt command are as follows:
-.RS
-.TP
-\fBdisable\fP \fItype\fP [\fBinput\fP|\fBoutput\fP]
-Disables the specified type of encryption. If you omit the input and
-output, both input and output are disabled. To obtain a list of
-available types, use the
-.B encrypt disable \&?
-command.
-.TP
-\fBenable\fP \fItype]fP [\fBinput\fP|\fBoutput\fP]
-Enables the specified type of encryption. If you omit input and output,
-both input and output are enabled. To obtain a list of available types,
-use the
-.B encrypt enable \&?
-command.
-.TP
-.B input
-This is the same as the
-.B encrypt start input
-command.
-.TP
-.B \-input
-This is the same as the
-.B encrypt stop input
-command.
-.TP
-.B output
-This is the same as the
-.B encrypt start output
-command.
-.TP
-.B \-output
-This is the same as the
-.B encrypt stop output
-command.
-.TP
-\fBstart\fP [\fBinput\fP|\fBoutput\fP]
-Attempts to start encryption. If you omit
-.B input
-and
-.BR output ,
-both input and output are enabled. To obtain a list of available types,
-use the
-.B encrypt enable \&?
-command.
-.TP
-.B status
-Lists the current status of encryption.
-.TP
-\fBstop\fP [\fBinput\fP|\fBoutput\fP]
-Stops encryption. If you omit input and output, encryption is on both
-input and output.
-.TP
-\fBtype\fP \fItype\fP
-Sets the default type of encryption to be used with later
-.B encrypt start
-or
-.B encrypt stop
-commands.
-.RE
-.TP
-\fBenviron\fP \fIarguments ...\fP
-The
-.B environ
-command is used to manipulate the the variables that my be sent through
-the
-.SM TELNET ENVIRON
-option. The initial set of variables is taken from the users
-environment, with only the
-.SM DISPLAY
-and
-.SM PRINTER
-variables being exported by default. The
-.SM USER
-variable is also exported if the
-.B \-a
-or
-.B \-l
-options are used.
-.PP
-Valid arguments for the
-.B environ
-command are:
-.RS
-.TP
-\fBdefine\fP \fIvariable value\fP
-Define the variable
-.I variable
-to have a value of
-.IR value .
-Any variables defined by this command are automatically exported. The
-.I value
-may be enclosed in single or double quotes so that tabs and spaces may
-be included.
-.TP
-\fBundefine\fP \fIvariable\fP
-Remove
-.I variable
-from the list of environment variables.
-.TP
-\fBexport\fP \fIvariable\fP
-Mark the variable
-.I variable
-to be exported to the remote side.
-.TP
-\fBunexport\fP \fIvariable\fP
-Mark the variable
-.I variable
-to not be exported unless explicitly asked for by the remote side.
-.TP
-.B list
-List the current set of environment variables. Those marked with a \&*
-will be sent automatically; other variables will only be sent if
-explicitly requested.
-.TP
-.B \&?
-Prints out help information for the
-.B environ
-command.
-.RE
-.TP
-.B logout
-Sends the
-.SM TELNET LOGOUT
-option to the remote side. This command is similar to a
-.B close
-command; however, if the remote side does not support the
-.SM LOGOUT
-option, nothing happens. If, however, the remote side does support the
-.SM LOGOUT
-option, this command should cause the remote side to close the
-.SM TELNET
-connection. If the remote side also supports the concept of suspending
-a user's session for later reattachment, the logout argument indicates
-that you should terminate the session immediately.
-.TP
-\fBmode\fP \fItype\fP
-.I Type
-is one of several options, depending on the state of the
-.SM TELNET
-session. The remote host is asked for permission to go into the
-requested mode. If the remote host is capable of entering that mode,
-the requested mode will be entered.
-.RS
-.TP
-.B character
-Disable the
-.SM TELNET LINEMODE
-option, or, if the remote side does not understand the
-.SM LINEMODE
-option, then enter ``character at a time'' mode.
-.TP
-.B line
-Enable the
-.SM TELNET LINEMODE
-option, or, if the remote side does not understand the
-.SM LINEMODE
-option, then attempt to enter ``old-line-by-line'' mode.
-.TP
-\fBisig\fP (\fI\-isig\fP)
-Attempt to enable (disable) the
-.SM TRAPSIG
-mode of the
-.SM LINEMODE
-option. This requires that the
-.SM LINEMODE
-option be enabled.
-.TP
-\fBedit\fP (\fB\-edit\fP)
-Attempt to enable (disable) the
-.SM EDIT
-mode of the
-.SM LINEMODE
-option. This requires that the
-.SM LINEMODE
-option be enabled.
-.TP
-\fBsofttabs\fP (\fB\-softtabs\fP)
-Attempt to enable (disable) the
-.SM SOFT_TAB
-mode of the
-.SM LINEMODE
-option. This requires that the
-.SM LINEMODE
-option be enabled.
-.TP
-\fBlitecho\fP (\fB\-litecho\fP)
-Attempt to enable (disable) the
-.SM LIT_ECHO
-mode of the
-.SM LINEMODE
-option. This requires that the
-.SM LINEMODE
-option be enabled.
-.TP
-.B \&?
-Prints out help information for the
-.B mode
-command.
-.RE
-.TP
-\fBopen\fP \fIhost\fP [\fB-a\fP] [[\fB\-l\fP] \fIuser\fP] [\fB\-\fP\fIport\fP]
-Open a connection to the named host. If no port number is specified,
-.B telnet
-will attempt to contact a
-.SM TELNET
-server at the default port. The host specification may be either a host
-name (see
-.IR hosts (5)
-or an Internet address specified in the ``dot notation'' (see
-.IR inet (3).
-After establishing a connection, the file
-.B \&.telnetrc
-in the user's home directory is opened. Lines beginning with a # are
-comment lines. Blank lines are ignored. Lines that begin without white
-space are the start of a machine entry. The first thing on the line is
-the name of the machine that is being connected to. The rest of the
-line, and successive lines that begin with white space are assumed to be
-.B telnet
-commands and are processed as if they had been typed in manually to the
-.B telnet
-command prompt.
-.RS
-.TP
-.B \-a
-Attempt automatic login. This sends the user name via the
-.SM USER
-variable of the
-.SM ENVIRON
-option, if supported by the remote system. The name used is that of the
-current user as returned by
-.IR getlogin (2)
-if it agrees with the current user ID; otherwise it is the name
-associated with the user ID.
-.TP
-[\fB\-l\fP] \fIuser\fP
-may be used to specify the user name to be passed to the remote system
-via the
-.SM ENVIRON
-option.
-.TP
-\fB\-\fP\fIport\fP
-When connecting to a non-standard port,
-.B telnet
-omits any automatic initiation of
-.SM TELNET
-options. When the port number is preceded by a minus sign, the initial
-option negotiation is done.
-.RE
-.TP
-.B quit
-Close any open
-.SM TELNET
-session and exit
-.BR telnet .
-An end of file (in command mode) will also close a session and exit.
-.TP
-\fBsend\fP \fIarguments\fP
-Sends one or more special character sequences to the remote host. The
-following are the arguments which may be specified (more than one
-argument may be specified at a time):
-.PP
-.RS
-.TP
-.B abort
-Sends the
-.SM TELNET ABORT
-(Abort processes) sequence.
-.TP
-.B ao
-Sends the
-.SM TELNET AO
-(Abort Output) sequence, which should cause the remote system to flush
-all output
-.I from
-the remote system
-.I to
-the user's terminal.
-.TP
-.B ayt
-Sends the
-.SM TELNET AYT
-(Are You There) sequence, to which the remote system may or may not
-choose to respond.
-.TP
-.B brk
-Sends the
-.SM TELNET BRK
-(Break) sequence, which may have significance to the remote system.
-.TP
-.B ec
-Sends the
-.SM TELNET EC
-(Erase Character) sequence, which should cause the remote system to
-erase the last character entered.
-.TP
-.B el
-Sends the
-.SM TELNET EL
-(Erase Line) sequence, which should cause the remote system to erase the
-line currently being entered.
-.TP
-.B eof
-Sends the
-.SM TELNET EOF
-(End Of File) sequence.
-.TP
-.B eor
-Sends the
-.SM TELNET EOR
-(End of Record) sequence.
-.TP
-.B escape
-Sends the current
-.B telnet
-escape character (initially ``^''.
-.TP
-.B ga
-Sends the
-.SM TELNET GA
-(Go Ahead) sequence, which likely has no significance to the remote
-system.
-.TP
-.B getstatus
-If the remote side supports the
-.SM TELNET STATUS
-command,
-.B getstatus
-will send the subnegotiation to request that the server send its current
-option status.
-.TP
-.B ip
-Sends the
-.SM TELNET IP
-(Interrupt Process) sequence, which should cause the remote system to
-abort the currently running process.
-.TP
-.B nop
-Sends the
-.SM TELNET NOP
-(No OPeration) sequence.
-.TP
-.B susp
-Sends the
-.SM TELNET SUSP
-(SUSPend process) sequence.
-.TP
-.B synch
-Sends the
-.SM TELNET SYNCH
-sequence. This sequence causes the remote system to discard all
-previously typed (but not yet read) input. This sequence is sent as
-.SM TCP
-urgent data (and may not work if the remote system is a 4.2BSD system --
-if it doesn't work, a lower case ``r'' may be echoed on the terminal).
-.TP
-\fBdo\fP \fIcmd\fP
-.TP
-\fBdont\fP \fIcmd\fP
-.TP
-\fBwill\fP \fIcmd\fP
-.TP
-\fBwont\fP \fIcmd\fP
-Sends the
-.SM TELNET DO
-.I cmd
-sequence.
-.I Cmd
-can be either a decimal number between 0 and 255, or a symbolic name for
-a specific
-.SM TELNET
-command.
-.I Cmd
-can also be either
-.B help
-or
-.B \&?
-to print out help information, including a list of known symbolic names.
-.TP
-.B \&?
-Prints out help information for the
-.B send
-command.
-.RE
-.TP
-\fBset\fP \fIargument value\fP
-.TP
-\fBunset\fP \fIargument value\fP
-The
-.B set
-command will set any one of a number of
-.B telnet
-variables to a specific value or to
-.SM TRUE.
-The special value
-.B off
-turns off the function associated with the variable; this is equivalent
-to using the
-.B unset
-command. The
-.B unset
-command will disable or set to
-.SM FALSE
-any of the specified functions. The values of variables may be
-interrogated with the
-.B display
-command. The variables which may be set or unset, but not toggled, are
-listed here. In addition, any of the variables for the
-.B toggle
-command may be explicitly set or unset using the
-.B set
-and
-.B unset
-commands.
-.RS
-.TP
-.B ayt
-If
-.B telnet
-is in localchars mode, or
-.SM LINEMODE
-is enabled, and the status character is typed, a
-.SM TELNET AYT
-sequence (see
-.B send ayt
-preceding) is sent to the remote host. The initial value for the "Are
-You There" character is the terminal's status character.
-.TP
-.B echo
-This is the value (initially ``^E'') which, when in ``line by line''
-mode, toggles between doing local echoing of entered characters (for
-normal processing), and suppressing echoing of entered characters (for
-entering, say, a password).
-.TP
-.B eof
-If
-.B telnet
-is operating in
-.SM LINEMODE
-or ``old line by line'' mode, entering this character as the first
-character on a line will cause this character to be sent to the remote
-system. The initial value of the eof character is taken to be the
-terminal's
-.B eof
-character.
-.TP
-.B erase
-If
-.B telnet
-is in
-.B localchars
-mode (see
-.B toggle localchars
-below),
-.I and
-if
-.B telnet
-is operating in ``character at a time'' mode, then when this character
-is typed, a
-.SM TELNET EC
-sequence (see
-.B send ec
-above) is sent to the remote system. The initial value for the erase
-character is taken to be the terminal's
-.B erase
-character.
-.TP
-.B escape
-This is the
-.B telnet
-escape character (initially ``^['') which causes entry into
-.B telnet
-command mode (when connected to a remote system).
-.TP
-.B flushoutput
-If
-.B telnet
-is in
-.B localchars
-mode (see
-.B toggle localchars
-below) and the
-.B flushoutput
-character is typed, a
-.SM TELNET AO
-sequence (see
-.B send ao
-above) is sent to the remote host. The initial value for the flush
-character is taken to be the terminal's
-.B flush
-character.
-.TP
-.B forw1
-.TP
-.B forw2
-If
-.B telnet
-is operating in
-.SM LINEMODE,
-these are the characters that, when typed, cause partial lines to be
-forwarded to the remote system. The initial value for the forwarding
-characters are taken from the terminal's eol and eol2 characters.
-.TP
-.B interrupt
-If
-.B telnet
-is in
-.B localchars
-mode (see
-.B toggle localchars
-below) and the
-.B interrupt
-character is typed, a
-.SM TELNET IP
-sequence (see
-.B send ip
-above) is sent to the remote host. The initial value for the interrupt
-character is taken to be the terminal's
-.B intr
-character.
-.TP
-.B kill
-If
-.B telnet
-is in
-.B localchars
-mode (see
-.B toggle localchars
-below),
-.I and
-if
-.B telnet
-is operating in ``character at a time'' mode, then when this character
-is typed, a
-.SM TELNET EL
-sequence (see
-.B send el
-above) is sent to the remote system. The initial value for the kill
-character is taken to be the terminal's
-.B kill
-character.
-.TP
-.B lnext
-If
-.B telnet
-is operating in
-.SM LINEMODE
-or ``old line by line'' mode, then this character is taken to be the
-terminal's
-.B lnext
-character. The initial value for the lnext character is taken to be the
-terminal's
-.B lnext
-character.
-.TP
-.B quit
-If
-.B telnet
-is in
-.B localchars
-mode (see
-.B toggle localchars
-below) and the
-.B quit
-character is typed, a
-.SM TELNET BRK
-sequence (see
-.B send brk
-above) is sent to the remote host. The initial value for the quit
-character is taken to be the terminal's
-.B quit
-character.
-.TP
-.B reprint
-If
-.B telnet
-is operating in
-.SM LINEMODE
-or ``old line by line'' mode, then this character is taken to be the
-terminal's
-.B reprint
-character. The initial value for the reprint character is taken to be
-the terminal's
-.B reprint
-character.
-.TP
-.B rlogin
-This is the rlogin escape character. If set, the normal
-.B TELNET
-escape character is ignored unless it is preceded by this character at
-the beginning of a line. This character, at the beginning of a line
-followed by a "." closes the connection; when followed by a ^Z it
-suspends the telnet command. The initial state is to disable the rlogin
-escape character.
-.TP
-.B start
-If the
-.SM TELNET TOGGLE-FLOW-CONTROL
-option has been enabled, then this character is taken to be the
-terminal's
-.B start
-character. The initial value for the kill character is taken to be the
-terminal's
-.B start
-character.
-.TP
-.B stop
-If the
-.SM TELNET TOGGLE-FLOW-CONTROL
-option has been enabled, then this character is taken to be the
-terminal's
-.B stop
-character. The initial value for the kill character is taken to be the
-terminal's
-.B stop
-character.
-.TP
-.B susp
-If
-.B telnet
-is in
-.B localchars
-mode, or
-.SM LINEMODE
-is enabled, and the
-.B suspend
-character is typed, a
-.SM TELNET SUSP
-sequence (see
-.B send susp
-above) is sent to the remote host. The initial value for the suspend
-character is taken to be the terminal's
-.B suspend
-character.
-.TP
-.B tracefile
-This is the file to which the output, caused by
-.B netdata
-or
-.B option
-tracing being
-.SM TRUE,
-will be written. If it is set to ``\fB\-\fP'', then tracing information
-will be written to standard output (the default).
-.TP
-.B worderase
-If
-.B telnet
-is operating in
-.SM LINEMODE
-or ``old line by line'' mode, then this character is taken to be the
-terminal's
-.B worderase
-character. The initial value for the worderase character is taken to be
-the terminal's
-.B worderase
-character.
-.TP
-.B \&?
-Displays the legal \fBset\fP (\fBunset\fP) commands.
-.RE
-.TP
-\fBslc\fP \fIstate\fP
-The
-.B slc
-command (Set Local Characters) is used to set or change the state of the
-the special characters when the
-.SM TELNET LINEMODE
-option has been enabled. Special characters are characters that get
-mapped to
-.B telnet
-commands sequences (like
-.B ip
-or
-.B quit )
-or line editing characters (like
-.B erase
-and
-.BR kill ).
-By default, the local special characters are exported.
-.RS
-.TP
-.B check
-Verify the current settings for the current special characters. The
-remote side is requested to send all the current special character
-settings, and if there are any discrepancies with the local side, the
-local side will switch to the remote value.
-.TP
-.B export
-Switch to the local defaults for the special characters. The local
-default characters are those of the local terminal at the time when
-.B telnet
-was started.
-.TP
-.B import
-Switch to the remote defaults for the special characters. The remote
-default characters are those of the remote system at the time when the
-.SM TELNET
-connection was established.
-.TP
-.B \&?
-Prints out help information for the
-.B slc
-command.
-.RE
-.TP
-.B status
-Show the current status of
-.BR telnet .
-This includes the peer one is connected to, as well as the current mode.
-.TP
-\fBtoggle\fP \fIarguments ...\fP
-Toggle (between
-.SM TRUE
-and
-.SM FALSE)
-various flags that control how
-.B telnet
-responds to events. These flags may be set explicitly to
-.SM TRUE
-or
-.SM FALSE
-using the
-.B set
-and
-.B unset
-commands listed above. More than one argument may be specified. The
-state of these flags may be interrogated with the
-.B display
-command. Valid arguments are:
-.RS
-.TP
-.B authdebug
-Turns on debugging information for the authentication code.
-.TP
-.B autoflush
-If
-.B autoflush
-and
-.B localchars
-are both
-.SM TRUE ,
-then when the
-.BR ao ,
-or
-.B quit
-characters are recognized (and transformed into
-.SM TELNET
-sequences; see
-.B set
-above for details),
-.B telnet
-refuses to display any data on the user's terminal until the remote
-system acknowledges (via a
-.SM TELNET TIMING MARK
-option) that it has processed those
-.SM TELNET
-sequences. The initial value for this toggle is
-.SM TRUE
-if the terminal user had not done an "stty noflsh", otherwise
-.SM FALSE
-(see
-.BR stty (1).
-.TP
-.B autodecrypt
-When the
-.SM TELNET ENCRYPT
-option is negotiated, by default the actual encryption (decryption) of
-the data stream does not start automatically. The autoencrypt
-(autodecrypt) command states that encryption of the output (input)
-stream should be enabled as soon as possible.
-.PP
-Note: Because of export controls, the
-.SM TELNET ENCRYPT
-option is not supported outside the United States and Canada.
-.TP
-.B autologin
-If the remote side supports the
-.SM TELNET AUTHENTICATION
-option
-.B telnet
-attempts to use it to perform automatic authentication. If the
-.SM AUTHENTICATION
-option is not supported, the user's login name are propagated through
-the
-.SM TELNET ENVIRON
-option. This command is the same as specifying the
-.B \-a
-option on the
-.B open
-command.
-.TP
-.B autosynch
-If
-.B autosynch
-and
-.B localchars
-are both
-.SM TRUE,
-then when either the
-.B intr
-or
-.B quit
-characters is typed (see
-.B set
-above for descriptions of the
-.B intr
-and
-.B quit
-characters), the resulting
-.SM TELNET
-sequence sent is followed by the
-.SM TELNET SYNCH
-sequence. This procedure
-.I should
-cause the remote system to begin throwing away all previously typed
-input until both of the
-.SM TELNET
-sequences have been read and acted upon. The initial value of this
-toggle is
-.SM FALSE.
-.TP
-.B binary
-Enable or disable the
-.SM TELNET BINARY
-option on both input and output.
-.TP
-.B inbinary
-Enable or disable the
-.SM TELNET BINARY
-option on input.
-.TP
-.B outbinary
-Enable or disable the
-.SM TELNET BINARY
-option on output.
-.TP
-.B crlf
-If this is
-.SM TRUE,
-then carriage returns will be sent as <CR><LF>. If this is
-.SM FALSE,
-then carriage returns will be send as <CR><NUL>. The initial value for
-this toggle is
-.SM FALSE.
-.TP
-.B crmod
-Toggle carriage return mode. When this mode is enabled, most carriage
-return characters received from the remote host will be mapped into a
-carriage return followed by a line feed. This mode does not affect
-those characters typed by the user, only those received from the remote
-host. This mode is not very useful unless the remote host only sends
-carriage return, but never line feed. The initial value for this toggle
-is
-.SM FALSE .
-.TP
-.B debug
-Toggles socket level debugging (useful only to the \fBsuper user\fP).
-The initial value for this toggle is
-.SM FALSE .
-.TP
-.B encdebug
-Turns on debugging information for the encryption code.
-.TP
-.B localchars
-If this is
-.SM TRUE ,
-then the
-.BR flush ,
-.BR interrupt ,
-.BR quit ,
-.BR erase ,
-and
-.B kill
-characters (see
-.B set
-above) are recognized locally, and transformed into (hopefully)
-appropriate
-.SM TELNET
-control sequences (respectively
-.BR ao ,
-.BR ip ,
-.BR brk ,
-.BR ec ,
-and
-.BR el ;
-see
-.B send
-above). The initial value for this toggle is
-.SM TRUE
-in ``old line by line'' mode, and
-.SM FALSE
-in ``character at a time'' mode. When the
-.SM LINEMODE
-option is enabled, the value of
-.B localchars
-is ignored, and assumed to always be
-.SM TRUE.
-If
-.SM LINEMODE
-has ever been enabled, then
-.B quit
-is sent as
-.BR abort ,
-and
-.B eof
-and
-.B suspend
-are sent as
-.B eof
-and
-.BR susp ,
-see
-.B send
-above).
-.TP
-.B netdata
-Toggles the display of all network data (in hexadecimal format). The
-initial value for this toggle is
-.SM FALSE.
-.TP
-.B options
-Toggles the display of some internal
-.B telnet
-protocol processing (having to do with
-.SM TELNET
-options). The initial value for this flag is
-.SM FALSE .
-.TP
-.B prettydump
-When the
-.B netdata
-flag is enabled, if
-.B prettydump
-is enabled the output from the
-.B netdata
-command will be formatted in a more user-readable format. Spaces are
-put between each character in the output, and the beginning of any
-.SM TELNET
-escape sequence is preceded by a '*' to aid in locating them.
-.TP
-.B skiprc
-When the skiprc flag is
-.SM TRUE,
-.SM TELNET
-skips the reading of the \&.telnetrc file in the user's home directory
-when connections are opened. The initial value for this flag is
-.SM FALSE.
-.TP
-.B termdata
-Toggles the display of all terminal data (in hexadecimal format). The
-initial value for this flag is
-.SM FALSE.
-.TP
-.B verbose_encrypt
-When the
-.B verbose_encrypt
-flag is
-.SM TRUE,
-.SM TELNET
-prints out a message each time encryption is enabled or disabled. The
-initial value for this toggle is
-.SM FALSE.
-Note: Because of export controls, data encryption is not supported
-outside of the United States and Canada.
-.TP
-.B \&?
-Displays the legal
-.B toggle
-commands.
-.RE
-.TP
-.B z
-Suspend
-.BR telnet .
-This command only works when the user's shell is
-.IR csh (1).
-.TP
-\fB\&!\fP [\fIcommand\fP]
-Execute a single command in a subshell on the local system. If
-.B command
-is omitted, then an interactive subshell is invoked.
-.TP
-\fB\&?\fP \fIcommand\fP
-Get help. With no arguments,
-.B telnet
-prints a help summary. If a command is specified,
-.B telnet
-will print the help information for just that command.
-.SH ENVIRONMENT
-.B Telnet
-uses at least the
-.SM HOME,
-.SM SHELL,
-.SM DISPLAY,
-and
-.SM TERM
-environment variables. Other environment variables may be propagated to
-the other side via the
-.SM TELNET ENVIRON
-option.
-.SH FILES
-.TP "\w'~/.telnetrc\ \ 'u"
-.TP
-~/.telnetrc
-user-customized telnet startup values
-.sp -1v
-.TP
-~/.k5login
-(on remote host) - file containing Kerberos principals that are allowed
-access.
-.SH HISTORY
-The
-.B Telnet
-command appeared in 4.2BSD.
-.SH NOTES
-.PP
-On some remote systems, echo has to be turned off manually when in ``old
-line by line'' mode.
-.PP
-In ``old line by line'' mode or
-.SM LINEMODE
-the terminal's
-.B eof
-character is only recognized (and sent to the remote system) when it is
-the first character on a line.
+++ /dev/null
-/*
- * Copyright (c) 1988, 1990, 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.
- */
-
-/* based on @(#)telnet.c 8.1 (Berkeley) 6/6/93 */
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include <sys/types.h>
-#include <time.h>
-
-#if defined(unix)
-#include <signal.h>
-/* By the way, we need to include curses.h before telnet.h since,
- * among other things, telnet.h #defines 'DO', which is a variable
- * declared in curses.h.
- */
-#endif /* defined(unix) */
-
-#ifdef HAVE_CURSES_H
-#include <curses.h>
-#endif
-
-#ifdef HAVE_TERM_H
-#include <term.h>
-#endif
-
-#include <arpa/telnet.h>
-
-#include <ctype.h>
-
-#include "ring.h"
-
-#include "defines.h"
-#include "externs.h"
-#include "types.h"
-#include "general.h"
-
-#ifdef AUTHENTICATION
-#include <libtelnet/auth.h>
-#endif
-
-#ifdef ENCRYPTION
-#include <libtelnet/encrypt.h>
-#endif
-
-#if defined(AUTHENTICATION) || defined(ENCRYPTION)
-#include <libtelnet/misc-proto.h>
-#endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */
-
-#include <k5-platform.h>
-
-static int is_unique (char *, char **, char **);
-
-\f
-#define strip(x) ((x)&0x7f)
-
-static unsigned char subbuffer[SUBBUFSIZE],
- *subpointer, *subend; /* buffer for sub-options */
-#define SB_CLEAR() subpointer = subbuffer;
-#define SB_TERM() { subend = subpointer; SB_CLEAR(); }
-#define SB_ACCUM(c) if (subpointer < (subbuffer+sizeof subbuffer)) { \
- *subpointer++ = (c); \
- }
-
-#define SB_GET() ((*subpointer++)&0xff)
-#define SB_PEEK() ((*subpointer)&0xff)
-#define SB_EOF() (subpointer >= subend)
-#define SB_LEN() (subend - subpointer)
-
-char options[256]; /* The combined options */
-char do_dont_resp[256];
-char will_wont_resp[256];
-
-int
- eight = 0,
- autologin = 0, /* Autologin anyone? */
- skiprc = 0,
- connected,
- showoptions,
- In3270, /* Are we in 3270 mode? */
- ISend, /* trying to send network data in */
- debug = 0,
- crmod,
- netdata, /* Print out network data flow */
- crlf, /* Should '\r' be mapped to <CR><LF> (or <CR><NUL>)? */
-#if defined(TN3270)
- noasynchtty = 0,/* User specified "-noasynch" on command line */
- noasynchnet = 0,/* User specified "-noasynch" on command line */
- askedSGA = 0, /* We have talked about suppress go ahead */
-#endif /* defined(TN3270) */
- telnetport,
- wantencryption = 0,
- SYNCHing, /* we are in TELNET SYNCH mode */
- flushout, /* flush output */
- autoflush = 0, /* flush output when interrupting? */
- autosynch, /* send interrupt characters with SYNCH? */
- localflow, /* we handle flow control locally */
- restartany, /* if flow control enabled, restart on any character */
- localchars, /* we recognize interrupt/quit */
- donelclchars, /* the user has set "localchars" */
- donebinarytoggle, /* the user has put us in binary */
- dontlecho, /* do we suppress local echoing right now? */
- globalmode;
-
-char *prompt = 0;
-
-int scheduler_lockout_tty = 0;
-
-cc_t escape;
-cc_t rlogin;
-#ifdef KLUDGELINEMODE
-cc_t echoc;
-#endif
-
-/*
- * Telnet receiver states for fsm
- */
-#define TS_DATA 0
-#define TS_IAC 1
-#define TS_WILL 2
-#define TS_WONT 3
-#define TS_DO 4
-#define TS_DONT 5
-#define TS_CR 6
-#define TS_SB 7 /* sub-option collection */
-#define TS_SE 8 /* looking for sub-option end */
-
-static int telrcv_state;
-#ifdef OLD_ENVIRON
-unsigned char telopt_environ = TELOPT_NEW_ENVIRON;
-#else
-# define telopt_environ TELOPT_NEW_ENVIRON
-#endif
-
-jmp_buf toplevel = { 0 };
-jmp_buf peerdied;
-
-int flushline;
-int linemode;
-
-#ifdef KLUDGELINEMODE
-int kludgelinemode = 1;
-#endif
-
-/*
- * The following are some clocks used to decide how to interpret
- * the relationship between various variables.
- */
-
-Clocks clocks;
-\f
-#ifdef notdef
-Modelist modelist[] = {
- { "telnet command mode", COMMAND_LINE },
- { "character-at-a-time mode", 0 },
- { "character-at-a-time mode (local echo)", LOCAL_ECHO|LOCAL_CHARS },
- { "line-by-line mode (remote echo)", LINE | LOCAL_CHARS },
- { "line-by-line mode", LINE | LOCAL_ECHO | LOCAL_CHARS },
- { "line-by-line mode (local echoing suppressed)", LINE | LOCAL_CHARS },
- { "3270 mode", 0 },
-};
-#endif
-
-\f
-/*
- * Initialize telnet environment.
- */
-
- void
-init_telnet()
-{
- env_init();
-
- SB_CLEAR();
- ClearArray(options);
-
- connected = In3270 = ISend = localflow = donebinarytoggle = 0;
-#if defined(AUTHENTICATION) || defined(ENCRYPTION)
- auth_encrypt_connect(connected);
-#endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */
- restartany = -1;
-
- SYNCHing = 0;
-
- /* Don't change NetTrace */
-
- escape = CONTROL(']');
- rlogin = _POSIX_VDISABLE;
-#ifdef KLUDGELINEMODE
- echoc = CONTROL('E');
-#endif
-
- flushline = 1;
- telrcv_state = TS_DATA;
-}
-\f
-
-#ifdef notdef
-#include <varargs.h>
-
- /*VARARGS*/
- static void
-printring(va_alist)
- va_dcl
-{
- va_list ap;
- char buffer[100]; /* where things go */
- char *ptr;
- char *format;
- char *string;
- Ring *ring;
- int i;
-
- va_start(ap);
-
- ring = va_arg(ap, Ring *);
- format = va_arg(ap, char *);
- ptr = buffer;
-
- while ((i = *format++) != 0) {
- if (i == '%') {
- i = *format++;
- switch (i) {
- case 'c':
- *ptr++ = va_arg(ap, int);
- break;
- case 's':
- string = va_arg(ap, char *);
- ring_supply_data(ring, buffer, ptr-buffer);
- ring_supply_data(ring, string, strlen(string));
- ptr = buffer;
- break;
- case 0:
- ExitString("printring: trailing %%.\n", 1);
- /*NOTREACHED*/
- default:
- ExitString("printring: unknown format character.\n", 1);
- /*NOTREACHED*/
- }
- } else {
- *ptr++ = i;
- }
- }
- ring_supply_data(ring, buffer, ptr-buffer);
-}
-#endif
-
-/*
- * These routines are in charge of sending option negotiations
- * to the other side.
- *
- * The basic idea is that we send the negotiation if either side
- * is in disagreement as to what the current state should be.
- */
-
- void
-send_do(c, init)
- register int c, init;
-{
- if (init) {
- if (((do_dont_resp[c] == 0) && my_state_is_do(c)) ||
- my_want_state_is_do(c))
- return;
- set_my_want_state_do(c);
- do_dont_resp[c]++;
- }
- NET2ADD(IAC, DO);
- NETADD(c);
- printoption("SENT", DO, c);
-}
-
- void
-send_dont(c, init)
- register int c, init;
-{
- if (init) {
- if (((do_dont_resp[c] == 0) && my_state_is_dont(c)) ||
- my_want_state_is_dont(c))
- return;
- set_my_want_state_dont(c);
- do_dont_resp[c]++;
- }
- NET2ADD(IAC, DONT);
- NETADD(c);
- printoption("SENT", DONT, c);
-}
-
- void
-send_will(c, init)
- register int c, init;
-{
- if (init) {
- if (((will_wont_resp[c] == 0) && my_state_is_will(c)) ||
- my_want_state_is_will(c))
- return;
- set_my_want_state_will(c);
- will_wont_resp[c]++;
- }
- NET2ADD(IAC, WILL);
- NETADD(c);
- printoption("SENT", WILL, c);
-}
-
- void
-send_wont(c, init)
- register int c, init;
-{
- if (init) {
- if (((will_wont_resp[c] == 0) && my_state_is_wont(c)) ||
- my_want_state_is_wont(c))
- return;
- set_my_want_state_wont(c);
- will_wont_resp[c]++;
- }
- NET2ADD(IAC, WONT);
- NETADD(c);
- printoption("SENT", WONT, c);
-}
-
-
- void
-willoption(option)
- int option;
-{
- int new_state_ok = 0;
-
- if (do_dont_resp[option]) {
- --do_dont_resp[option];
- if (do_dont_resp[option] && my_state_is_do(option))
- --do_dont_resp[option];
- }
-
- if ((do_dont_resp[option] == 0) && my_want_state_is_dont(option)) {
-
- switch (option) {
-
- case TELOPT_ECHO:
-# if defined(TN3270)
- /*
- * The following is a pain in the rear-end.
- * Various IBM servers (some versions of Wiscnet,
- * possibly Fibronics/Spartacus, and who knows who
- * else) will NOT allow us to send "DO SGA" too early
- * in the setup proceedings. On the other hand,
- * 4.2 servers (telnetd) won't set SGA correctly.
- * So, we are stuck. Empirically (but, based on
- * a VERY small sample), the IBM servers don't send
- * out anything about ECHO, so we postpone our sending
- * "DO SGA" until we see "WILL ECHO" (which 4.2 servers
- * DO send).
- */
- {
- if (askedSGA == 0) {
- askedSGA = 1;
- if (my_want_state_is_dont(TELOPT_SGA))
- send_do(TELOPT_SGA, 1);
- }
- }
- /* Fall through */
- case TELOPT_EOR:
-#endif /* defined(TN3270) */
- case TELOPT_BINARY:
- case TELOPT_SGA:
- settimer(modenegotiated);
- /* FALL THROUGH */
- case TELOPT_STATUS:
-#if defined(AUTHENTICATION)
- case TELOPT_AUTHENTICATION:
-#endif
-#ifdef ENCRYPTION
- case TELOPT_ENCRYPT:
-#endif /* ENCRYPTION */
- new_state_ok = 1;
- break;
-
- case TELOPT_TM:
- if (flushout)
- flushout = 0;
- /*
- * Special case for TM. If we get back a WILL,
- * pretend we got back a WONT.
- */
- set_my_want_state_dont(option);
- set_my_state_dont(option);
- return; /* Never reply to TM will's/wont's */
-
- case TELOPT_LINEMODE:
- default:
- break;
- }
-
- if (new_state_ok) {
- set_my_want_state_do(option);
- send_do(option, 0);
- setconnmode(0); /* possibly set new tty mode */
- } else {
- do_dont_resp[option]++;
- send_dont(option, 0);
- }
- }
- set_my_state_do(option);
-#ifdef ENCRYPTION
- if (option == TELOPT_ENCRYPT)
- encrypt_send_support();
-#endif /* ENCRYPTION */
-}
-
- void
-wontoption(option)
- int option;
-{
- if (do_dont_resp[option]) {
- --do_dont_resp[option];
- if (do_dont_resp[option] && my_state_is_dont(option))
- --do_dont_resp[option];
- }
-
- if ((do_dont_resp[option] == 0) && my_want_state_is_do(option)) {
-
- switch (option) {
-
-#ifdef KLUDGELINEMODE
- case TELOPT_SGA:
- if (!kludgelinemode)
- break;
- /* FALL THROUGH */
-#endif
- case TELOPT_ECHO:
- settimer(modenegotiated);
- break;
-
- case TELOPT_TM:
- if (flushout)
- flushout = 0;
- set_my_want_state_dont(option);
- set_my_state_dont(option);
- return; /* Never reply to TM will's/wont's */
-
- default:
- break;
- }
- set_my_want_state_dont(option);
- if (my_state_is_do(option))
- send_dont(option, 0);
- setconnmode(0); /* Set new tty mode */
- } else if (option == TELOPT_TM) {
- /*
- * Special case for TM.
- */
- if (flushout)
- flushout = 0;
- set_my_want_state_dont(option);
- }
- set_my_state_dont(option);
-}
-
- static void
-dooption(option)
- int option;
-{
- int new_state_ok = 0;
-
- if (will_wont_resp[option]) {
- --will_wont_resp[option];
- if (will_wont_resp[option] && my_state_is_will(option))
- --will_wont_resp[option];
- }
-
- if (will_wont_resp[option] == 0) {
- if (my_want_state_is_wont(option)) {
-
- switch (option) {
-
- case TELOPT_TM:
- /*
- * Special case for TM. We send a WILL, but pretend
- * we sent WONT.
- */
- send_will(option, 0);
- set_my_want_state_wont(TELOPT_TM);
- set_my_state_wont(TELOPT_TM);
- return;
-
-# if defined(TN3270)
- case TELOPT_EOR: /* end of record */
-# endif /* defined(TN3270) */
- case TELOPT_BINARY: /* binary mode */
- case TELOPT_NAWS: /* window size */
- case TELOPT_TSPEED: /* terminal speed */
- case TELOPT_LFLOW: /* local flow control */
- case TELOPT_TTYPE: /* terminal type option */
- case TELOPT_SGA: /* no big deal */
-#ifdef ENCRYPTION
- case TELOPT_ENCRYPT: /* encryption variable option */
-#endif /* ENCRYPTION */
- new_state_ok = 1;
- break;
-
- case TELOPT_NEW_ENVIRON: /* New environment variable option */
-#ifdef OLD_ENVIRON
- if (my_state_is_will(TELOPT_OLD_ENVIRON))
- send_wont(TELOPT_OLD_ENVIRON, 1); /* turn off the old */
- goto env_common;
- case TELOPT_OLD_ENVIRON: /* Old environment variable option */
- if (my_state_is_will(TELOPT_NEW_ENVIRON))
- break; /* Don't enable if new one is in use! */
- env_common:
- telopt_environ = option;
-#endif
- new_state_ok = 1;
- break;
-
-#if defined(AUTHENTICATION)
- case TELOPT_AUTHENTICATION:
- if (autologin)
- new_state_ok = 1;
- break;
-#endif
-
- case TELOPT_XDISPLOC: /* X Display location */
- if (env_getvalue((unsigned char *)"DISPLAY") &&
- env_is_exported((unsigned char *)"DISPLAY"))
- new_state_ok = 1;
- break;
-
- case TELOPT_LINEMODE:
-#ifdef KLUDGELINEMODE
- kludgelinemode = 0;
- send_do(TELOPT_SGA, 1);
-#endif
- set_my_want_state_will(TELOPT_LINEMODE);
- send_will(option, 0);
- set_my_state_will(TELOPT_LINEMODE);
- slc_init();
- return;
-
- case TELOPT_ECHO: /* We're never going to echo... */
- default:
- break;
- }
-
- if (new_state_ok) {
- set_my_want_state_will(option);
- send_will(option, 0);
- setconnmode(0); /* Set new tty mode */
- } else {
- will_wont_resp[option]++;
- send_wont(option, 0);
- }
- } else {
- /*
- * Handle options that need more things done after the
- * other side has acknowledged the option.
- */
- switch (option) {
- case TELOPT_LINEMODE:
-#ifdef KLUDGELINEMODE
- kludgelinemode = 0;
- send_do(TELOPT_SGA, 1);
-#endif
- set_my_state_will(option);
- slc_init();
- send_do(TELOPT_SGA, 0);
- return;
- }
- }
- }
- set_my_state_will(option);
-}
-
- static void
-dontoption(option)
- int option;
-{
-
- if (will_wont_resp[option]) {
- --will_wont_resp[option];
- if (will_wont_resp[option] && my_state_is_wont(option))
- --will_wont_resp[option];
- }
-
- if ((will_wont_resp[option] == 0) && my_want_state_is_will(option)) {
- switch (option) {
- case TELOPT_LINEMODE:
- linemode = 0; /* put us back to the default state */
- break;
-#ifdef OLD_ENVIRON
- case TELOPT_NEW_ENVIRON:
- /*
- * The new environ option wasn't recognized, try
- * the old one.
- */
- send_will(TELOPT_OLD_ENVIRON, 1);
- telopt_environ = TELOPT_OLD_ENVIRON;
- break;
-#endif
- }
- /* we always accept a DONT */
- set_my_want_state_wont(option);
- if (my_state_is_will(option))
- send_wont(option, 0);
- setconnmode(0); /* Set new tty mode */
- }
- set_my_state_wont(option);
-}
-
-/*
- * Given a buffer returned by tgetent(), this routine will turn
- * the pipe seperated list of names in the buffer into an array
- * of pointers to null terminated names. We toss out any bad,
- * duplicate, or verbose names (names with spaces).
- */
-
-static char *name_unknown = "UNKNOWN";
-static char *unknown[] = { 0, 0 };
-
-static char **
-mklist(buf, name)
- char *buf, *name;
-{
- register int n;
- register char c, *cp, **argvp, *cp2, **argv, **avt;
-
- if (name) {
- if (strlen(name) > 40) {
- name = 0;
- unknown[0] = name_unknown;
- } else {
- unknown[0] = name;
- upcase(name);
- }
- } else
- unknown[0] = name_unknown;
- /*
- * Count up the number of names.
- */
- for (n = 1, cp = buf; *cp && *cp != ':'; cp++) {
- if (*cp == '|')
- n++;
- }
- /*
- * Allocate an array to put the name pointers into
- */
- argv = (char **)malloc((n+3)*sizeof(char *));
- if (argv == 0)
- return(unknown);
- while (--n >= 0)
- argv[n] = 0;
-
- /*
- * Fill up the array of pointers to names.
- */
- *argv = 0;
- argvp = argv+1;
- n = 0;
- for (cp = cp2 = buf; (c = *cp); cp++) {
- if (c == '|' || c == ':') {
- *cp++ = '\0';
- /*
- * Skip entries that have spaces or are over 40
- * characters long. If this is our environment
- * name, then put it up front. Otherwise, as
- * long as this is not a duplicate name (case
- * insensitive) add it to the list.
- */
- if (n || (cp - cp2 > 41))
- ;
- else if (name && (strncasecmp(name, cp2,
- (unsigned) (cp-cp2))
- == 0))
- *argv = cp2;
- else if (is_unique(cp2, argv+1, argvp))
- *argvp++ = cp2;
- if (c == ':')
- break;
- /*
- * Skip multiple delimiters. Reset cp2 to
- * the beginning of the next name. Reset n,
- * the flag for names with spaces.
- */
- while ((c = *cp) == '|')
- cp++;
- cp2 = cp;
- n = 0;
- }
- /*
- * Skip entries with spaces or non-ascii values.
- * Convert lower case letters to upper case.
- */
- if ((c == ' ') || !isascii(c))
- n = 1;
- else if (islower((unsigned char) c))
- *cp = toupper((unsigned char) c);
- }
-
- /*
- * Check for an old V6 2 character name. If the second
- * name points to the beginning of the buffer, and is
- * only 2 characters long, move it to the end of the array.
- */
- if ((argv[1] == buf) && (strlen(argv[1]) == 2)) {
- --argvp;
- for (avt = &argv[1]; avt < argvp; avt++)
- *avt = *(avt+1);
- *argvp++ = buf;
- }
-
- /*
- * Duplicate last name, for TTYPE option, and null
- * terminate the array. If we didn't find a match on
- * our terminal name, put that name at the beginning.
- */
- cp = *(argvp-1);
- *argvp++ = cp;
- *argvp = 0;
-
- if (*argv == 0) {
- if (name)
- *argv = name;
- else {
- --argvp;
- for (avt = argv; avt < argvp; avt++)
- *avt = *(avt+1);
- }
- }
- if (*argv)
- return(argv);
- else
- return(unknown);
-}
-
-static int
-is_unique(name, as, ae)
- register char *name, **as, **ae;
-{
- register char **ap;
- register unsigned int n;
-
- n = strlen(name) + 1;
- for (ap = as; ap < ae; ap++)
- if (strncasecmp(*ap, name, n) == 0)
- return(0);
- return (1);
-}
-
-#ifndef HAVE_SETUPTERM
-char termbuf[1024];
-
- /*ARGSUSED*/
-static int
-setupterm(tname, fd, errp)
- char *tname;
- int fd, *errp;
-{
- if (tgetent(termbuf, tname) == 1) {
- termbuf[1023] = '\0';
- if (errp)
- *errp = 1;
- return(0);
- }
- if (errp)
- *errp = 0;
- return(-1);
-}
-#else
-#define termbuf ttytype
-extern char ttytype[];
-#endif
-
-int resettermname = 1;
-
-static char *
-gettermname()
-{
- char *tname;
- static char **tnamep = 0;
- static char **next;
- int err;
-
- if (resettermname) {
- resettermname = 0;
- if (tnamep && tnamep != unknown)
- free(tnamep);
- if ((tname = (char *)env_getvalue((unsigned char *)"TERM")) &&
- (setupterm(tname, 1, &err) == 0)) {
- tnamep = mklist(termbuf, tname);
- } else {
- if (tname && (strlen(tname) <= 40)) {
- unknown[0] = tname;
- upcase(tname);
- } else
- unknown[0] = name_unknown;
- tnamep = unknown;
- }
- next = tnamep;
- }
- if (*next == 0)
- next = tnamep;
- return(*next++);
-}
-/*
- * suboption()
- *
- * Look at the sub-option buffer, and try to be helpful to the other
- * side.
- *
- * Currently we recognize:
- *
- * Terminal type, send request.
- * Terminal speed (send request).
- * Local flow control (is request).
- * Linemode
- */
-
- static void
-suboption()
-{
- unsigned char subchar;
-
- printsub('<', subbuffer, SB_LEN()+2);
- switch (subchar = SB_GET()) {
- case TELOPT_TTYPE:
- if (my_want_state_is_wont(TELOPT_TTYPE))
- return;
- if (SB_EOF() || SB_GET() != TELQUAL_SEND) {
- return;
- } else {
- char *name;
- unsigned char temp[50];
- int len;
-
-#if defined(TN3270)
- if (tn3270_ttype()) {
- return;
- }
-#endif /* defined(TN3270) */
- name = gettermname();
- len = strlen(name) + 4 + 2;
- if (len < NETROOM()) {
- snprintf((char *)temp, sizeof(temp), "%c%c%c%c%s%c%c",
- IAC, SB, TELOPT_TTYPE, TELQUAL_IS, name, IAC, SE);
- ring_supply_data(&netoring, temp, len);
- printsub('>', &temp[2], len-2);
- } else {
- ExitString("No room in buffer for terminal type.\n", 1);
- /*NOTREACHED*/
- }
- }
- break;
- case TELOPT_TSPEED:
- if (my_want_state_is_wont(TELOPT_TSPEED))
- return;
- if (SB_EOF())
- return;
- if (SB_GET() == TELQUAL_SEND) {
- long o_speed, ispeed;
- unsigned char temp[50];
- int len;
-
- TerminalSpeeds(&ispeed, &o_speed);
-
- snprintf((char *)temp, sizeof(temp), "%c%c%c%c%ld,%ld%c%c", IAC,
- SB, TELOPT_TSPEED, TELQUAL_IS, o_speed, ispeed, IAC, SE);
- len = strlen((char *)temp+4) + 4; /* temp[3] is 0 ... */
-
- if (len < NETROOM()) {
- ring_supply_data(&netoring, temp, len);
- printsub('>', temp+2, len - 2);
- }
-/*@*/ else printf("lm_will: not enough room in buffer\n");
- }
- break;
- case TELOPT_LFLOW:
- if (my_want_state_is_wont(TELOPT_LFLOW))
- return;
- if (SB_EOF())
- return;
- switch(SB_GET()) {
- case LFLOW_RESTART_ANY:
- restartany = 1;
- break;
- case LFLOW_RESTART_XON:
- restartany = 0;
- break;
- case LFLOW_ON:
- localflow = 1;
- break;
- case LFLOW_OFF:
- localflow = 0;
- break;
- default:
- return;
- }
- setcommandmode();
- setconnmode(0);
- break;
-
- case TELOPT_LINEMODE:
- if (my_want_state_is_wont(TELOPT_LINEMODE))
- return;
- if (SB_EOF())
- return;
- switch (SB_GET()) {
- case WILL:
- lm_will(subpointer, SB_LEN());
- break;
- case WONT:
- lm_wont(subpointer, SB_LEN());
- break;
- case DO:
- lm_do(subpointer, SB_LEN());
- break;
- case DONT:
- lm_dont(subpointer, SB_LEN());
- break;
- case LM_SLC:
- slc(subpointer, SB_LEN());
- break;
- case LM_MODE:
- lm_mode(subpointer, SB_LEN(), 0);
- break;
- default:
- break;
- }
- break;
-
-#ifdef OLD_ENVIRON
- case TELOPT_OLD_ENVIRON:
-#endif
- case TELOPT_NEW_ENVIRON:
- if (SB_EOF())
- return;
- switch(SB_PEEK()) {
- case TELQUAL_IS:
- case TELQUAL_INFO:
- if (my_want_state_is_dont(subchar))
- return;
- break;
- case TELQUAL_SEND:
- if (my_want_state_is_wont(subchar)) {
- return;
- }
- break;
- default:
- return;
- }
- env_opt(subpointer, SB_LEN());
- break;
-
- case TELOPT_XDISPLOC:
- if (my_want_state_is_wont(TELOPT_XDISPLOC))
- return;
- if (SB_EOF())
- return;
- if (SB_GET() == TELQUAL_SEND) {
- unsigned char temp[50], *dp;
- int len;
-
- if (((dp = env_getvalue((unsigned char *)"DISPLAY")) == NULL) ||
- (! env_is_exported((unsigned char *)"DISPLAY"))) {
- /*
- * Something happened, we no longer have a DISPLAY
- * variable. So, turn off the option.
- */
- send_wont(TELOPT_XDISPLOC, 1);
- break;
- }
- snprintf((char *)temp, sizeof(temp), "%c%c%c%c%s%c%c",
- IAC, SB, TELOPT_XDISPLOC, TELQUAL_IS, dp, IAC, SE);
- len = strlen((char *)temp+4) + 4; /* temp[3] is 0 ... */
-
- if (len < NETROOM()) {
- ring_supply_data(&netoring, temp, len);
- printsub('>', temp+2, len - 2);
- }
-/*@*/ else printf("lm_will: not enough room in buffer\n");
- }
- break;
-
-#if defined(AUTHENTICATION)
- case TELOPT_AUTHENTICATION: {
- if (!autologin)
- break;
- if (SB_EOF())
- return;
- switch(SB_GET()) {
- case TELQUAL_IS:
- if (my_want_state_is_dont(TELOPT_AUTHENTICATION))
- return;
- auth_is(subpointer, SB_LEN());
- break;
- case TELQUAL_SEND:
- if (my_want_state_is_wont(TELOPT_AUTHENTICATION))
- return;
- auth_send(subpointer, SB_LEN());
- break;
- case TELQUAL_REPLY:
- if (my_want_state_is_wont(TELOPT_AUTHENTICATION))
- return;
- auth_reply(subpointer, SB_LEN());
- break;
- case TELQUAL_NAME:
- if (my_want_state_is_dont(TELOPT_AUTHENTICATION))
- return;
- auth_name(subpointer, SB_LEN());
- break;
- }
- }
- break;
-#endif
-#ifdef ENCRYPTION
- case TELOPT_ENCRYPT:
- if (SB_EOF())
- return;
- switch(SB_GET()) {
- case ENCRYPT_START:
- if (my_want_state_is_dont(TELOPT_ENCRYPT))
- return;
- encrypt_start(subpointer, SB_LEN());
- break;
- case ENCRYPT_END:
- if (my_want_state_is_dont(TELOPT_ENCRYPT))
- return;
- encrypt_end();
- break;
- case ENCRYPT_SUPPORT:
- if (my_want_state_is_wont(TELOPT_ENCRYPT))
- return;
- encrypt_support(subpointer, SB_LEN());
- break;
- case ENCRYPT_REQSTART:
- if (my_want_state_is_wont(TELOPT_ENCRYPT))
- return;
- encrypt_request_start(subpointer, SB_LEN());
- break;
- case ENCRYPT_REQEND:
- if (my_want_state_is_wont(TELOPT_ENCRYPT))
- return;
- /*
- * We can always send an REQEND so that we cannot
- * get stuck encrypting. We should only get this
- * if we have been able to get in the correct mode
- * anyhow.
- */
- encrypt_request_end();
- break;
- case ENCRYPT_IS:
- if (my_want_state_is_dont(TELOPT_ENCRYPT))
- return;
- encrypt_is(subpointer, SB_LEN());
- break;
- case ENCRYPT_REPLY:
- if (my_want_state_is_wont(TELOPT_ENCRYPT))
- return;
- encrypt_reply(subpointer, SB_LEN());
- break;
- case ENCRYPT_ENC_KEYID:
- if (my_want_state_is_dont(TELOPT_ENCRYPT))
- return;
- encrypt_enc_keyid(subpointer, SB_LEN());
- break;
- case ENCRYPT_DEC_KEYID:
- if (my_want_state_is_wont(TELOPT_ENCRYPT))
- return;
- encrypt_dec_keyid(subpointer, SB_LEN());
- break;
- default:
- break;
- }
- break;
-#endif /* ENCRYPTION */
- default:
- break;
- }
-}
-
-static unsigned char str_lm[] = { IAC, SB, TELOPT_LINEMODE, 0, 0, IAC, SE };
-
- void
-lm_will(cmd, len)
- unsigned char *cmd;
- int len;
-{
- if (len < 1) {
-/*@*/ printf("lm_will: no command!!!\n"); /* Should not happen... */
- return;
- }
- switch(cmd[0]) {
- case LM_FORWARDMASK: /* We shouldn't ever get this... */
- default:
- str_lm[3] = DONT;
- str_lm[4] = cmd[0];
- if (NETROOM() > sizeof(str_lm)) {
- ring_supply_data(&netoring, str_lm, sizeof(str_lm));
- printsub('>', &str_lm[2], sizeof(str_lm)-2);
- }
-/*@*/ else printf("lm_will: not enough room in buffer\n");
- break;
- }
-}
-
- void
-lm_wont(cmd, len)
- unsigned char *cmd;
- int len;
-{
- if (len < 1) {
-/*@*/ printf("lm_wont: no command!!!\n"); /* Should not happen... */
- return;
- }
- switch(cmd[0]) {
- case LM_FORWARDMASK: /* We shouldn't ever get this... */
- default:
- /* We are always DONT, so don't respond */
- return;
- }
-}
-
- void
-lm_do(cmd, len)
- unsigned char *cmd;
- int len;
-{
- if (len < 1) {
-/*@*/ printf("lm_do: no command!!!\n"); /* Should not happen... */
- return;
- }
- switch(cmd[0]) {
- case LM_FORWARDMASK:
- default:
- str_lm[3] = WONT;
- str_lm[4] = cmd[0];
- if (NETROOM() > sizeof(str_lm)) {
- ring_supply_data(&netoring, str_lm, sizeof(str_lm));
- printsub('>', &str_lm[2], sizeof(str_lm)-2);
- }
-/*@*/ else printf("lm_do: not enough room in buffer\n");
- break;
- }
-}
-
- void
-lm_dont(cmd, len)
- unsigned char *cmd;
- int len;
-{
- if (len < 1) {
-/*@*/ printf("lm_dont: no command!!!\n"); /* Should not happen... */
- return;
- }
- switch(cmd[0]) {
- case LM_FORWARDMASK:
- default:
- /* we are always WONT, so don't respond */
- break;
- }
-}
-
-static unsigned char str_lm_mode[] = {
- IAC, SB, TELOPT_LINEMODE, LM_MODE, 0, IAC, SE
-};
-
- void
-lm_mode(cmd, len, init)
- unsigned char *cmd;
- int len, init;
-{
- if (len != 1)
- return;
- if ((linemode&MODE_MASK&~MODE_ACK) == *cmd)
- return;
- if (*cmd&MODE_ACK)
- return;
- linemode = *cmd&(MODE_MASK&~MODE_ACK);
- str_lm_mode[4] = linemode;
- if (!init)
- str_lm_mode[4] |= MODE_ACK;
- if (NETROOM() > sizeof(str_lm_mode)) {
- ring_supply_data(&netoring, str_lm_mode, sizeof(str_lm_mode));
- printsub('>', &str_lm_mode[2], sizeof(str_lm_mode)-2);
- }
-/*@*/ else printf("lm_mode: not enough room in buffer\n");
- setconnmode(0); /* set changed mode */
-}
-
-\f
-
-/*
- * slc()
- * Handle special character suboption of LINEMODE.
- */
-
-struct spc {
- cc_t val;
- cc_t *valp;
- char flags; /* Current flags & level */
- char mylevel; /* Maximum level & flags */
-} spc_data[NSLC+1];
-
-#define SLC_IMPORT 0
-#define SLC_EXPORT 1
-#define SLC_RVALUE 2
-static int slc_mode = SLC_EXPORT;
-
- void
-slc_init()
-{
- register struct spc *spcp;
-
- localchars = 1;
- for (spcp = spc_data; spcp < &spc_data[NSLC+1]; spcp++) {
- spcp->val = 0;
- spcp->valp = 0;
- spcp->flags = spcp->mylevel = SLC_NOSUPPORT;
- }
-
-#define initfunc(func, flags) { \
- spcp = &spc_data[func]; \
- if ((spcp->valp = tcval(func)) != NULL) { \
- spcp->val = *spcp->valp; \
- spcp->mylevel = SLC_VARIABLE|flags; \
- } else { \
- spcp->val = 0; \
- spcp->mylevel = SLC_DEFAULT; \
- } \
- }
-
- initfunc(SLC_SYNCH, 0);
- /* No BRK */
- initfunc(SLC_AO, 0);
- initfunc(SLC_AYT, 0);
- /* No EOR */
- initfunc(SLC_ABORT, SLC_FLUSHIN|SLC_FLUSHOUT);
- initfunc(SLC_EOF, 0);
-#ifndef SYSV_TERMIO
- initfunc(SLC_SUSP, SLC_FLUSHIN);
-#endif
- initfunc(SLC_EC, 0);
- initfunc(SLC_EL, 0);
-#ifndef SYSV_TERMIO
- initfunc(SLC_EW, 0);
- initfunc(SLC_RP, 0);
- initfunc(SLC_LNEXT, 0);
-#endif
- initfunc(SLC_XON, 0);
- initfunc(SLC_XOFF, 0);
-#ifdef SYSV_TERMIO
- spc_data[SLC_XON].mylevel = SLC_CANTCHANGE;
- spc_data[SLC_XOFF].mylevel = SLC_CANTCHANGE;
-#endif
- initfunc(SLC_FORW1, 0);
-#ifdef USE_TERMIO
- initfunc(SLC_FORW2, 0);
- /* No FORW2 */
-#endif
-
- initfunc(SLC_IP, SLC_FLUSHIN|SLC_FLUSHOUT);
-#undef initfunc
-
- if (slc_mode == SLC_EXPORT)
- slc_export();
- else
- slc_import(1);
-
-}
-
- void
-slcstate()
-{
- printf("Special characters are %s values\n",
- slc_mode == SLC_IMPORT ? "remote default" :
- slc_mode == SLC_EXPORT ? "local" :
- "remote");
-}
-
- void
-slc_mode_export()
-{
- slc_mode = SLC_EXPORT;
- if (my_state_is_will(TELOPT_LINEMODE))
- slc_export();
-}
-
- void
-slc_mode_import(def)
- int def;
-{
- slc_mode = def ? SLC_IMPORT : SLC_RVALUE;
- if (my_state_is_will(TELOPT_LINEMODE))
- slc_import(def);
-}
-
-unsigned char slc_import_val[] = {
- IAC, SB, TELOPT_LINEMODE, LM_SLC, 0, SLC_VARIABLE, 0, IAC, SE
-};
-unsigned char slc_import_def[] = {
- IAC, SB, TELOPT_LINEMODE, LM_SLC, 0, SLC_DEFAULT, 0, IAC, SE
-};
-
- void
-slc_import(def)
- int def;
-{
- if (NETROOM() > sizeof(slc_import_val)) {
- if (def) {
- ring_supply_data(&netoring, slc_import_def, sizeof(slc_import_def));
- printsub('>', &slc_import_def[2], sizeof(slc_import_def)-2);
- } else {
- ring_supply_data(&netoring, slc_import_val, sizeof(slc_import_val));
- printsub('>', &slc_import_val[2], sizeof(slc_import_val)-2);
- }
- }
-/*@*/ else printf("slc_import: not enough room\n");
-}
-
- void
-slc_export()
-{
- register struct spc *spcp;
-
- TerminalDefaultChars();
-
- slc_start_reply();
- for (spcp = &spc_data[1]; spcp < &spc_data[NSLC+1]; spcp++) {
- if (spcp->mylevel != SLC_NOSUPPORT) {
- if (spcp->val == (cc_t)(_POSIX_VDISABLE))
- spcp->flags = SLC_NOSUPPORT;
- else
- spcp->flags = spcp->mylevel;
- if (spcp->valp)
- spcp->val = *spcp->valp;
- slc_add_reply(spcp - spc_data, spcp->flags, spcp->val);
- }
- }
- slc_end_reply();
- (void)slc_update();
- setconnmode(1); /* Make sure the character values are set */
-}
-
- void
-slc(cp, len)
- register unsigned char *cp;
- int len;
-{
- register struct spc *spcp;
- register int func,level;
-
- slc_start_reply();
-
- for (; len >= 3; len -=3, cp +=3) {
-
- func = cp[SLC_FUNC];
-
- if (func == 0) {
- /*
- * Client side: always ignore 0 function.
- */
- continue;
- }
- if (func > NSLC) {
- if ((cp[SLC_FLAGS] & SLC_LEVELBITS) != SLC_NOSUPPORT)
- slc_add_reply(func, SLC_NOSUPPORT, 0);
- continue;
- }
-
- spcp = &spc_data[func];
-
- level = cp[SLC_FLAGS]&(SLC_LEVELBITS|SLC_ACK);
-
- if ((cp[SLC_VALUE] == (unsigned char)spcp->val) &&
- ((level&SLC_LEVELBITS) == (spcp->flags&SLC_LEVELBITS))) {
- continue;
- }
-
- if (level == (SLC_DEFAULT|SLC_ACK)) {
- /*
- * This is an error condition, the SLC_ACK
- * bit should never be set for the SLC_DEFAULT
- * level. Our best guess to recover is to
- * ignore the SLC_ACK bit.
- */
- cp[SLC_FLAGS] &= ~SLC_ACK;
- }
-
- if (level == ((spcp->flags&SLC_LEVELBITS)|SLC_ACK)) {
- spcp->val = (cc_t)cp[SLC_VALUE];
- spcp->flags = cp[SLC_FLAGS]; /* include SLC_ACK */
- continue;
- }
-
- level &= ~SLC_ACK;
-
- if (level <= (spcp->mylevel&SLC_LEVELBITS)) {
- spcp->flags = cp[SLC_FLAGS]|SLC_ACK;
- spcp->val = (cc_t)cp[SLC_VALUE];
- }
- if (level == SLC_DEFAULT) {
- if ((spcp->mylevel&SLC_LEVELBITS) != SLC_DEFAULT)
- spcp->flags = spcp->mylevel;
- else
- spcp->flags = SLC_NOSUPPORT;
- }
- slc_add_reply(func, spcp->flags, spcp->val);
- }
- slc_end_reply();
- if (slc_update())
- setconnmode(1); /* set the new character values */
-}
-
- void
-slc_check()
-{
- register struct spc *spcp;
-
- slc_start_reply();
- for (spcp = &spc_data[1]; spcp < &spc_data[NSLC+1]; spcp++) {
- if (spcp->valp && spcp->val != *spcp->valp) {
- spcp->val = *spcp->valp;
- if (spcp->val == (cc_t)(_POSIX_VDISABLE))
- spcp->flags = SLC_NOSUPPORT;
- else
- spcp->flags = spcp->mylevel;
- slc_add_reply(spcp - spc_data, spcp->flags, spcp->val);
- }
- }
- slc_end_reply();
- setconnmode(1);
-}
-
-
-unsigned char slc_reply[128];
-unsigned char *slc_replyp;
-
- void
-slc_start_reply()
-{
- slc_replyp = slc_reply;
- *slc_replyp++ = IAC;
- *slc_replyp++ = SB;
- *slc_replyp++ = TELOPT_LINEMODE;
- *slc_replyp++ = LM_SLC;
-}
-
- void
-slc_add_reply(func, flags, value)
- unsigned char func;
- unsigned char flags;
- cc_t value;
-{
- if ((slc_replyp - slc_reply) + 6 > sizeof(slc_reply))
- return;
- if ((*slc_replyp++ = func) == IAC)
- *slc_replyp++ = IAC;
- if ((*slc_replyp++ = flags) == IAC)
- *slc_replyp++ = IAC;
- if ((*slc_replyp++ = (unsigned char)value) == IAC)
- *slc_replyp++ = IAC;
-}
-
- void
-slc_end_reply()
-{
- register int len;
-
- len = slc_replyp - slc_reply;
- if (len <= 4 || (len + 2 > sizeof(slc_reply)))
- return;
- *slc_replyp++ = IAC;
- *slc_replyp++ = SE;
- len += 2;
- if (NETROOM() > len) {
- ring_supply_data(&netoring, slc_reply, slc_replyp - slc_reply);
- printsub('>', &slc_reply[2], slc_replyp - slc_reply - 2);
- }
-/*@*/else printf("slc_end_reply: not enough room\n");
-}
-
- int
-slc_update()
-{
- register struct spc *spcp;
- int need_update = 0;
-
- for (spcp = &spc_data[1]; spcp < &spc_data[NSLC+1]; spcp++) {
- if (!(spcp->flags&SLC_ACK))
- continue;
- spcp->flags &= ~SLC_ACK;
- if (spcp->valp && (*spcp->valp != spcp->val)) {
- *spcp->valp = spcp->val;
- need_update = 1;
- }
- }
- return(need_update);
-}
-
-#ifdef OLD_ENVIRON
-# ifdef ENV_HACK
-/*
- * Earlier version of telnet/telnetd from the BSD code had
- * the definitions of VALUE and VAR reversed. To ensure
- * maximum interoperability, we assume that the server is
- * an older BSD server, until proven otherwise. The newer
- * BSD servers should be able to handle either definition,
- * so it is better to use the wrong values if we don't
- * know what type of server it is.
- */
-int env_auto = 1;
-int old_env_var = OLD_ENV_VAR;
-int old_env_value = OLD_ENV_VALUE;
-# else
-# define old_env_var OLD_ENV_VAR
-# define old_env_value OLD_ENV_VALUE
-# endif
-#endif
-
- void
-env_opt(buf, len)
- register unsigned char *buf;
- register int len;
-{
- register unsigned char *ep = 0, *epc = 0;
- register int i;
-
- switch(buf[0]&0xff) {
- case TELQUAL_SEND:
- env_opt_start();
- if (len == 1) {
- env_opt_add(NULL);
- } else for (i = 1; i < len; i++) {
- switch (buf[i]&0xff) {
-#ifdef OLD_ENVIRON
- case OLD_ENV_VAR:
-# ifdef ENV_HACK
- if (telopt_environ == TELOPT_OLD_ENVIRON
- && env_auto) {
- /* Server has the same definitions */
- old_env_var = OLD_ENV_VAR;
- old_env_value = OLD_ENV_VALUE;
- }
- /* FALL THROUGH */
-# endif
- case OLD_ENV_VALUE:
- /*
- * Although OLD_ENV_VALUE is not legal, we will
- * still recognize it, just in case it is an
- * old server that has VAR & VALUE mixed up...
- */
- /* FALL THROUGH */
-#else
- case NEW_ENV_VAR:
-#endif
- case ENV_USERVAR:
- if (ep) {
- *epc = 0;
- env_opt_add(ep);
- }
- ep = epc = &buf[i+1];
- break;
- case ENV_ESC:
- i++;
- /*FALL THROUGH*/
- default:
- if (epc)
- *epc++ = buf[i];
- break;
- }
- }
- if (ep) {
- *epc = 0;
- env_opt_add(ep);
- }
- env_opt_end(1);
- break;
-
- case TELQUAL_IS:
- case TELQUAL_INFO:
- /* Ignore for now. We shouldn't get it anyway. */
- break;
-
- default:
- break;
- }
-}
-
-#define OPT_REPLY_SIZE 256
-unsigned char *opt_reply;
-unsigned char *opt_replyp;
-unsigned char *opt_replyend;
-
- void
-env_opt_start()
-{
- if (opt_reply)
- opt_reply = (unsigned char *)realloc(opt_reply, OPT_REPLY_SIZE);
- else
- opt_reply = (unsigned char *)malloc(OPT_REPLY_SIZE);
- if (opt_reply == NULL) {
-/*@*/ printf("env_opt_start: malloc()/realloc() failed!!!\n");
- opt_reply = opt_replyp = opt_replyend = NULL;
- return;
- }
- opt_replyp = opt_reply;
- opt_replyend = opt_reply + OPT_REPLY_SIZE;
- *opt_replyp++ = IAC;
- *opt_replyp++ = SB;
- *opt_replyp++ = telopt_environ;
- *opt_replyp++ = TELQUAL_IS;
-}
-
- void
-env_opt_start_info()
-{
- env_opt_start();
- if (opt_replyp)
- opt_replyp[-1] = TELQUAL_INFO;
-}
-
- void
-env_opt_add(ep)
- register unsigned char *ep;
-{
- register unsigned char *vp, c;
- unsigned int len, olen, elen;
-
- if (opt_reply == NULL) /*XXX*/
- return; /*XXX*/
-
- if (ep == NULL || *ep == '\0') {
- /* Send user defined variables first. */
- env_default(1, 0);
- while ((ep = env_default(0, 0)) != NULL)
- env_opt_add(ep);
-
- /* Now add the list of well know variables. */
- env_default(1, 1);
- while ((ep = env_default(0, 1)) != NULL)
- env_opt_add(ep);
- return;
- }
- vp = env_getvalue(ep);
- elen = 2 * (vp ? strlen((char *)vp) : 0) +
- 2 * strlen((char *)ep) + 6;
- if ((opt_replyend - opt_replyp) < elen)
- {
- len = opt_replyend - opt_reply + elen;
- olen = opt_replyp - opt_reply;
- opt_reply = (unsigned char *)realloc(opt_reply, len);
- if (opt_reply == NULL) {
-/*@*/ printf("env_opt_add: realloc() failed!!!\n");
- opt_reply = opt_replyp = opt_replyend = NULL;
- return;
- }
- opt_replyp = opt_reply + olen;
- opt_replyend = opt_reply + len;
- }
- if (opt_welldefined((char *) ep))
-#ifdef OLD_ENVIRON
- if (telopt_environ == TELOPT_OLD_ENVIRON)
- *opt_replyp++ = old_env_var;
- else
-#endif
- *opt_replyp++ = NEW_ENV_VAR;
- else
- *opt_replyp++ = ENV_USERVAR;
- for (;;) {
- while ((c = *ep++)) {
- switch(c&0xff) {
- case IAC:
- *opt_replyp++ = IAC;
- break;
- case NEW_ENV_VAR:
- case NEW_ENV_VALUE:
- case ENV_ESC:
- case ENV_USERVAR:
- *opt_replyp++ = ENV_ESC;
- break;
- }
- *opt_replyp++ = c;
- }
- if ((ep = vp) != NULL) {
-#ifdef OLD_ENVIRON
- if (telopt_environ == TELOPT_OLD_ENVIRON)
- *opt_replyp++ = old_env_value;
- else
-#endif
- *opt_replyp++ = NEW_ENV_VALUE;
- vp = NULL;
- } else
- break;
- }
-}
-
- int
-opt_welldefined(ep)
- char *ep;
-{
- if ((strcmp(ep, "USER") == 0) ||
- (strcmp(ep, "DISPLAY") == 0) ||
- (strcmp(ep, "PRINTER") == 0) ||
- (strcmp(ep, "SYSTEMTYPE") == 0) ||
- (strcmp(ep, "JOB") == 0) ||
- (strcmp(ep, "ACCT") == 0))
- return(1);
- return(0);
-}
- void
-env_opt_end(emptyok)
- register int emptyok;
-{
- register int len;
-
- len = opt_replyp - opt_reply + 2;
- if (emptyok || len > 6) {
- *opt_replyp++ = IAC;
- *opt_replyp++ = SE;
- if (NETROOM() > len) {
- ring_supply_data(&netoring, opt_reply, len);
- printsub('>', &opt_reply[2], len - 2);
- }
-/*@*/ else printf("slc_end_reply: not enough room\n");
- }
- if (opt_reply) {
- free(opt_reply);
- opt_reply = opt_replyp = opt_replyend = NULL;
- }
-}
-
-\f
-
- int
-telrcv()
-{
- register int c;
- register int scc;
- register unsigned char *sbp = NULL;
- int count;
- int returnValue = 0;
-
- scc = 0;
- count = 0;
- while (TTYROOM() > 2) {
- if (scc == 0) {
- if (count) {
- ring_consumed(&netiring, count);
- returnValue = 1;
- count = 0;
- }
- sbp = netiring.consume;
- scc = ring_full_consecutive(&netiring);
- if (scc == 0) {
- /* No more data coming in */
- break;
- }
- }
-
- c = *sbp++ & 0xff, scc--; count++;
-#ifdef ENCRYPTION
- if (decrypt_input)
- c = (*decrypt_input)(c);
-#endif /* ENCRYPTION */
-
- switch (telrcv_state) {
-
- case TS_CR:
- telrcv_state = TS_DATA;
- if (c == '\0') {
- break; /* Ignore \0 after CR */
- }
- else if ((c == '\n') && my_want_state_is_dont(TELOPT_ECHO) && !crmod) {
- TTYADD(c);
- break;
- }
- /* Else, fall through */
-
- case TS_DATA:
- if (c == IAC) {
- telrcv_state = TS_IAC;
- break;
- }
-# if defined(TN3270)
- if (In3270) {
- *Ifrontp++ = c;
- while (scc > 0) {
- c = *sbp++ & 0377, scc--; count++;
-#ifdef ENCRYPTION
- if (decrypt_input)
- c = (*decrypt_input)(c);
-#endif /* ENCRYPTION */
- if (c == IAC) {
- telrcv_state = TS_IAC;
- break;
- }
- *Ifrontp++ = c;
- }
- } else
-# endif /* defined(TN3270) */
- /*
- * The 'crmod' hack (see following) is needed
- * since we can't * set CRMOD on output only.
- * Machines like MULTICS like to send \r without
- * \n; since we must turn off CRMOD to get proper
- * input, the mapping is done here (sigh).
- */
- if ((c == '\r') && my_want_state_is_dont(TELOPT_BINARY)) {
- if (scc > 0) {
- c = *sbp&0xff;
-#ifdef ENCRYPTION
- if (decrypt_input)
- c = (*decrypt_input)(c);
-#endif /* ENCRYPTION */
- if (c == 0) {
- sbp++, scc--; count++;
- /* a "true" CR */
- TTYADD('\r');
- } else if (my_want_state_is_dont(TELOPT_ECHO) &&
- (c == '\n')) {
- sbp++, scc--; count++;
- TTYADD('\n');
- } else {
-#ifdef ENCRYPTION
- if (decrypt_input)
- (*decrypt_input)(-1);
-#endif /* ENCRYPTION */
-
- TTYADD('\r');
- if (crmod) {
- TTYADD('\n');
- }
- }
- } else {
- telrcv_state = TS_CR;
- TTYADD('\r');
- if (crmod) {
- TTYADD('\n');
- }
- }
- } else {
- TTYADD(c);
- }
- continue;
-
- case TS_IAC:
-process_iac:
- switch (c) {
-
- case WILL:
- telrcv_state = TS_WILL;
- continue;
-
- case WONT:
- telrcv_state = TS_WONT;
- continue;
-
- case DO:
- telrcv_state = TS_DO;
- continue;
-
- case DONT:
- telrcv_state = TS_DONT;
- continue;
-
- case DM:
- /*
- * We may have missed an urgent notification,
- * so make sure we flush whatever is in the
- * buffer currently.
- */
- printoption("RCVD", IAC, DM);
- SYNCHing = 1;
- (void) ttyflush(1);
- SYNCHing = stilloob();
- settimer(gotDM);
- break;
-
- case SB:
- SB_CLEAR();
- telrcv_state = TS_SB;
- continue;
-
-# if defined(TN3270)
- case EOR:
- if (In3270) {
- if (Ibackp == Ifrontp) {
- Ibackp = Ifrontp = Ibuf;
- ISend = 0; /* should have been! */
- } else {
- Ibackp += DataFromNetwork(Ibackp, Ifrontp-Ibackp, 1);
- ISend = 1;
- }
- }
- printoption("RCVD", IAC, EOR);
- break;
-# endif /* defined(TN3270) */
-
- case IAC:
-# if !defined(TN3270)
- TTYADD(IAC);
-# else /* !defined(TN3270) */
- if (In3270) {
- *Ifrontp++ = IAC;
- } else {
- TTYADD(IAC);
- }
-# endif /* !defined(TN3270) */
- break;
-
- case NOP:
- case GA:
- default:
- printoption("RCVD", IAC, c);
- break;
- }
- telrcv_state = TS_DATA;
- continue;
-
- case TS_WILL:
- printoption("RCVD", WILL, c);
- willoption(c);
- SetIn3270();
- telrcv_state = TS_DATA;
- continue;
-
- case TS_WONT:
- printoption("RCVD", WONT, c);
- wontoption(c);
- SetIn3270();
- telrcv_state = TS_DATA;
- continue;
-
- case TS_DO:
- printoption("RCVD", DO, c);
- dooption(c);
- SetIn3270();
- if (c == TELOPT_NAWS) {
- sendnaws();
- } else if (c == TELOPT_LFLOW) {
- localflow = 1;
- setcommandmode();
- setconnmode(0);
- }
- telrcv_state = TS_DATA;
- continue;
-
- case TS_DONT:
- printoption("RCVD", DONT, c);
- dontoption(c);
- flushline = 1;
- setconnmode(0); /* set new tty mode (maybe) */
- SetIn3270();
- telrcv_state = TS_DATA;
- continue;
-
- case TS_SB:
- if (c == IAC) {
- telrcv_state = TS_SE;
- } else {
- SB_ACCUM(c);
- }
- continue;
-
- case TS_SE:
- if (c != SE) {
- if (c != IAC) {
- /*
- * This is an error. We only expect to get
- * "IAC IAC" or "IAC SE". Several things may
- * have happend. An IAC was not doubled, the
- * IAC SE was left off, or another option got
- * inserted into the suboption are all possibilities.
- * If we assume that the IAC was not doubled,
- * and really the IAC SE was left off, we could
- * get into an infinate loop here. So, instead,
- * we terminate the suboption, and process the
- * partial suboption if we can.
- */
- SB_ACCUM(IAC);
- SB_ACCUM(c);
- subpointer -= 2;
- SB_TERM();
-
- printoption("In SUBOPTION processing, RCVD", IAC, c);
- suboption(); /* handle sub-option */
- SetIn3270();
- telrcv_state = TS_IAC;
- goto process_iac;
- }
- SB_ACCUM(c);
- telrcv_state = TS_SB;
- } else {
- SB_ACCUM(IAC);
- SB_ACCUM(SE);
- subpointer -= 2;
- SB_TERM();
- suboption(); /* handle sub-option */
- SetIn3270();
- telrcv_state = TS_DATA;
- }
- }
- }
- if (count)
- ring_consumed(&netiring, count);
- return returnValue||count;
-}
-
-static int bol = 1, local = 0;
-
- int
-rlogin_susp()
-{
- if (local) {
- local = 0;
- bol = 1;
- command(0, "z\n", 2);
- return(1);
- }
- return(0);
-}
-
- static int
-telsnd()
-{
- int tcc;
- int count;
- int returnValue = 0;
- unsigned char *tbp = NULL;
-
- tcc = 0;
- count = 0;
- while (NETROOM() > 2) {
- register int sc;
- register int c;
-
- if (tcc == 0) {
- if (count) {
- ring_consumed(&ttyiring, count);
- returnValue = 1;
- count = 0;
- }
- tbp = ttyiring.consume;
- tcc = ring_full_consecutive(&ttyiring);
- if (tcc == 0) {
- break;
- }
- }
- c = *tbp++ & 0xff, sc = strip(c), tcc--; count++;
- if (rlogin != _POSIX_VDISABLE) {
- if (bol) {
- bol = 0;
- if (sc == rlogin) {
- local = 1;
- continue;
- }
- } else if (local) {
- local = 0;
- if (sc == '.' || c == termEofChar) {
- bol = 1;
- command(0, "close\n", 6);
- continue;
- }
- if (sc == termSuspChar) {
- bol = 1;
- command(0, "z\n", 2);
- continue;
- }
- if (sc == escape) {
- command(0, (char *)tbp, tcc);
- bol = 1;
- count += tcc;
- tcc = 0;
- flushline = 1;
- break;
- }
- if (sc != rlogin) {
- ++tcc;
- --tbp;
- --count;
- c = sc = rlogin;
- }
- }
- if ((sc == '\n') || (sc == '\r'))
- bol = 1;
- } else if (sc == escape) {
- /*
- * Double escape is a pass through of a single escape character.
- */
- if (tcc && strip(*tbp) == escape) {
- tbp++;
- tcc--;
- count++;
- bol = 0;
- } else {
- command(0, (char *)tbp, tcc);
- bol = 1;
- count += tcc;
- tcc = 0;
- flushline = 1;
- break;
- }
- } else
- bol = 0;
-#ifdef KLUDGELINEMODE
- if (kludgelinemode && (globalmode&MODE_EDIT) && (sc == echoc)) {
- if (tcc > 0 && strip(*tbp) == echoc) {
- tcc--; tbp++; count++;
- } else {
- dontlecho = !dontlecho;
- settimer(echotoggle);
- setconnmode(0);
- flushline = 1;
- break;
- }
- }
-#endif
- if (MODE_LOCAL_CHARS(globalmode)) {
- if (TerminalSpecialChars(sc) == 0) {
- bol = 1;
- break;
- }
- }
- if (my_want_state_is_wont(TELOPT_BINARY)) {
- switch (c) {
- case '\n':
- /*
- * If we are in CRMOD mode (\r ==> \n)
- * on our local machine, then probably
- * a newline (unix) is CRLF (TELNET).
- */
- if (MODE_LOCAL_CHARS(globalmode)) {
- NETADD('\r');
- }
- NETADD('\n');
- bol = flushline = 1;
- break;
- case '\r':
- if (!crlf) {
- NET2ADD('\r', '\0');
- } else {
- NET2ADD('\r', '\n');
- }
- bol = flushline = 1;
- break;
- case IAC:
- NET2ADD(IAC, IAC);
- break;
- default:
- NETADD(c);
- break;
- }
- } else if (c == IAC) {
- NET2ADD(IAC, IAC);
- } else {
- NETADD(c);
- }
- }
- if (count)
- ring_consumed(&ttyiring, count);
- return returnValue||count; /* Non-zero if we did anything */
-}
-\f
-/*
- * Scheduler()
- *
- * Try to do something.
- *
- * If we do something useful, return 1; else return 0.
- *
- */
-
-
- int
-Scheduler(block)
- int block; /* should we block in the select ? */
-{
- /* One wants to be a bit careful about setting returnValue
- * to one, since a one implies we did some useful work,
- * and therefore probably won't be called to block next
- * time (TN3270 mode only).
- */
- int returnValue;
- int netin, netout, netex, ttyin, ttyout;
-
- /* Decide which rings should be processed */
-
- netout = ring_full_count(&netoring) &&
- (flushline ||
- (my_want_state_is_wont(TELOPT_LINEMODE)
-#ifdef KLUDGELINEMODE
- && (!kludgelinemode || my_want_state_is_do(TELOPT_SGA))
-#endif
- ) ||
- my_want_state_is_will(TELOPT_BINARY));
- ttyout = ring_full_count(&ttyoring);
-
-#if defined(TN3270)
- ttyin = ring_empty_count(&ttyiring) && (shell_active == 0);
-#else /* defined(TN3270) */
- ttyin = ring_empty_count(&ttyiring);
-#endif /* defined(TN3270) */
-
-#if defined(TN3270)
- netin = ring_empty_count(&netiring);
-# else /* !defined(TN3270) */
- netin = !ISend && ring_empty_count(&netiring);
-# endif /* !defined(TN3270) */
-
- netex = !SYNCHing;
-
- /* If we have seen a signal recently, reset things */
-# if defined(TN3270) && defined(unix)
- if (HaveInput) {
- HaveInput = 0;
- (void) signal(SIGIO, inputAvailable);
- }
-#endif /* defined(TN3270) && defined(unix) */
-
- if (scheduler_lockout_tty) {
- ttyin = ttyout = 0;
- }
-
- /* Call to system code to process rings */
-
- returnValue = process_rings(netin, netout, netex, ttyin, ttyout, !block);
-
- /* Now, look at the input rings, looking for work to do. */
-
- if (ring_full_count(&ttyiring)) {
-# if defined(TN3270)
- if (In3270) {
- int c;
-
- c = DataFromTerminal(ttyiring.consume,
- ring_full_consecutive(&ttyiring));
- if (c) {
- returnValue = 1;
- ring_consumed(&ttyiring, c);
- }
- } else {
-# endif /* defined(TN3270) */
- returnValue |= telsnd();
-# if defined(TN3270)
- }
-# endif /* defined(TN3270) */
- }
-
- if (ring_full_count(&netiring)) {
-# if !defined(TN3270)
- returnValue |= telrcv();
-# else /* !defined(TN3270) */
- returnValue = Push3270();
-# endif /* !defined(TN3270) */
- }
- return returnValue;
-}
-\f
-/*
- * Select from tty and network...
- */
- void
-telnet(user)
- char *user;
-{
- int printed_encrypt = 0;
-
- sys_telnet_init();
-
-#if defined(AUTHENTICATION) || defined(ENCRYPTION)
- {
- static char local_host[256] = { 0 };
-
- if (!local_host[0]) {
- gethostname(local_host, sizeof(local_host));
- local_host[sizeof(local_host)-1] = 0;
- }
- auth_encrypt_init(local_host, hostname, "TELNET", 0);
- auth_encrypt_user(user);
- }
-#endif /* defined(AUTHENTICATION) || defined(ENCRYPTION) */
-# if !defined(TN3270)
-#if defined(AUTHENTICATION)
- if (autologin)
- send_will(TELOPT_AUTHENTICATION, 1);
-#endif
-#ifdef ENCRYPTION
- if (telnetport || wantencryption) {
- send_do(TELOPT_ENCRYPT, 1);
- send_will(TELOPT_ENCRYPT, 1);
- }
-#endif /* ENCRYPTION */
- if (telnetport) {
- send_do(TELOPT_SGA, 1);
- send_will(TELOPT_TTYPE, 1);
- send_will(TELOPT_NAWS, 1);
- send_will(TELOPT_TSPEED, 1);
- send_will(TELOPT_LFLOW, 1);
- send_will(TELOPT_LINEMODE, 1);
- send_will(TELOPT_NEW_ENVIRON, 1);
- send_do(TELOPT_STATUS, 1);
- if (env_getvalue((unsigned char *)"DISPLAY") &&
- env_is_exported((unsigned char *)"DISPLAY"))
- send_will(TELOPT_XDISPLOC, 1);
- if (eight)
- tel_enter_binary(eight);
- }
-# endif /* !defined(TN3270) */
-
-#ifdef ENCRYPTION
- /*
- * Note: we assume a tie to the authentication option here. This
- * is necessary so that authentication fails, we don't spin
- * forever.
- */
- if (wantencryption) {
- extern int auth_has_failed;
- time_t time_out = time(0) + 60;
-
- send_do(TELOPT_ENCRYPT, 1);
- send_will(TELOPT_ENCRYPT, 1);
- while (1) {
- if (my_want_state_is_wont(TELOPT_AUTHENTICATION)) {
- printf("\nServer refused to negotiate authentication, which is required\n");
- printf("for encryption. Good-bye.\n\r");
- Exit(1);
- }
- if (auth_has_failed) {
- printf("\nNegotiation of authentication, which is required for encryption,\n");
- printf("has failed. Good-bye.\n\r");
- Exit(1);
- }
- if (my_want_state_is_dont(TELOPT_ENCRYPT) ||
- my_want_state_is_wont(TELOPT_ENCRYPT)) {
- printf("\nServer refused to negotiate encryption. Good-bye.\n\r");
- Exit(1);
- }
- if (encrypt_is_encrypting())
- break;
- if (time(0) > time_out) {
- printf("\nEncryption could not be enabled. Good-bye.\n\r");
- Exit(1);
- }
- if (printed_encrypt == 0) {
- printed_encrypt = 1;
- printf("Waiting for encryption to be negotiated...\n");
- /*
- * Turn on MODE_TRAPSIG and then turn off localchars
- * so that ^C will cause telnet to exit.
- */
- TerminalNewMode(getconnmode()|MODE_TRAPSIG);
- intr_waiting = 1;
- }
- if (intr_happened) {
- printf("\nUser requested an interrupt. Good-bye.\n\r");
- Exit(1);
- }
- telnet_spin();
- }
- if (printed_encrypt) {
- printf("done.\n");
- intr_waiting = 0;
- setconnmode(0);
- }
- }
-#endif
-
-
-# if !defined(TN3270)
- for (;;) {
- int schedValue;
-
- while ((schedValue = Scheduler(0)) != 0) {
- if (schedValue == -1) {
- setcommandmode();
- return;
- }
- }
-
- if (Scheduler(1) == -1) {
- setcommandmode();
- return;
- }
- }
-# else /* !defined(TN3270) */
- for (;;) {
- int schedValue;
-
- while (!In3270 && !shell_active) {
- if (Scheduler(1) == -1) {
- setcommandmode();
- return;
- }
- }
-
- while ((schedValue = Scheduler(0)) != 0) {
- if (schedValue == -1) {
- setcommandmode();
- return;
- }
- }
- /* If there is data waiting to go out to terminal, don't
- * schedule any more data for the terminal.
- */
- if (ring_full_count(&ttyoring)) {
- schedValue = 1;
- } else {
- if (shell_active) {
- if (shell_continue() == 0) {
- ConnectScreen();
- }
- } else if (In3270) {
- schedValue = DoTerminalOutput();
- }
- }
- if (schedValue && (shell_active == 0)) {
- if (Scheduler(1) == -1) {
- setcommandmode();
- return;
- }
- }
- }
-# endif /* !defined(TN3270) */
-}
-\f
-#if 0 /* XXX - this not being in is a bug */
-/*
- * nextitem()
- *
- * Return the address of the next "item" in the TELNET data
- * stream. This will be the address of the next character if
- * the current address is a user data character, or it will
- * be the address of the character following the TELNET command
- * if the current address is a TELNET IAC ("I Am a Command")
- * character.
- */
-
- static char *
-nextitem(current)
- char *current;
-{
- if ((*current&0xff) != IAC) {
- return current+1;
- }
- switch (*(current+1)&0xff) {
- case DO:
- case DONT:
- case WILL:
- case WONT:
- return current+3;
- case SB: /* loop forever looking for the SE */
- {
- register char *look = current+2;
-
- for (;;) {
- if ((*look++&0xff) == IAC) {
- if ((*look++&0xff) == SE) {
- return look;
- }
- }
- }
- }
- default:
- return current+2;
- }
-}
-#endif /* 0 */
-
-/*
- * netclear()
- *
- * We are about to do a TELNET SYNCH operation. Clear
- * the path to the network.
- *
- * Things are a bit tricky since we may have sent the first
- * byte or so of a previous TELNET command into the network.
- * So, we have to scan the network buffer from the beginning
- * until we are up to where we want to be.
- *
- * A side effect of what we do, just to keep things
- * simple, is to clear the urgent data pointer. The principal
- * caller should be setting the urgent data pointer AFTER calling
- * us in any case.
- */
-
- static void
-netclear()
-{
-#if 0 /* XXX */
- register char *thisitem, *next;
- char *good;
-#define wewant(p) ((nfrontp > p) && ((*p&0xff) == IAC) && \
- ((*(p+1)&0xff) != EC) && ((*(p+1)&0xff) != EL))
-
- thisitem = netobuf;
-
- while ((next = nextitem(thisitem)) <= netobuf.send) {
- thisitem = next;
- }
-
- /* Now, thisitem is first before/at boundary. */
-
- good = netobuf; /* where the good bytes go */
-
- while (netoring.add > thisitem) {
- if (wewant(thisitem)) {
- int length;
-
- next = thisitem;
- do {
- next = nextitem(next);
- } while (wewant(next) && (nfrontp > next));
- length = next-thisitem;
- memcpy(good, thisitem, length);
- good += length;
- thisitem = next;
- } else {
- thisitem = nextitem(thisitem);
- }
- }
-
-#endif /* 0 */
-}
-\f
-/*
- * These routines add various telnet commands to the data stream.
- */
-
- static void
-doflush()
-{
- NET2ADD(IAC, DO);
- NETADD(TELOPT_TM);
- flushline = 1;
- flushout = 1;
- (void) ttyflush(1); /* Flush/drop output */
- /* do printoption AFTER flush, otherwise the output gets tossed... */
- printoption("SENT", DO, TELOPT_TM);
-}
-
- void
-xmitAO()
-{
- NET2ADD(IAC, AO);
- printoption("SENT", IAC, AO);
- if (autoflush) {
- doflush();
- }
-}
-
-
- void
-xmitEL()
-{
- NET2ADD(IAC, EL);
- printoption("SENT", IAC, EL);
-}
-
- void
-xmitEC()
-{
- NET2ADD(IAC, EC);
- printoption("SENT", IAC, EC);
-}
-
-
- int
-dosynch(s)
- char *s;
-{
- netclear(); /* clear the path to the network */
- NETADD(IAC);
- setneturg();
- NETADD(DM);
- printoption("SENT", IAC, DM);
- return 1;
-}
-
-int want_status_response = 0;
-
- int
-get_status(s)
- char *s;
-{
- unsigned char tmp[16];
- register unsigned char *cp;
-
- if (my_want_state_is_dont(TELOPT_STATUS)) {
- printf("Remote side does not support STATUS option\n");
- return 0;
- }
- cp = tmp;
-
- *cp++ = IAC;
- *cp++ = SB;
- *cp++ = TELOPT_STATUS;
- *cp++ = TELQUAL_SEND;
- *cp++ = IAC;
- *cp++ = SE;
- if (NETROOM() >= cp - tmp) {
- ring_supply_data(&netoring, tmp, cp-tmp);
- printsub('>', tmp+2, cp - tmp - 2);
- }
- ++want_status_response;
- return 1;
-}
-
- void
-intp()
-{
- NET2ADD(IAC, IP);
- printoption("SENT", IAC, IP);
- flushline = 1;
- if (autoflush) {
- doflush();
- }
- if (autosynch) {
- dosynch(NULL);
- }
-}
-
- void
-sendbrk()
-{
- NET2ADD(IAC, BREAK);
- printoption("SENT", IAC, BREAK);
- flushline = 1;
- if (autoflush) {
- doflush();
- }
- if (autosynch) {
- dosynch(NULL);
- }
-}
-
- void
-sendabort()
-{
- NET2ADD(IAC, ABORT);
- printoption("SENT", IAC, ABORT);
- flushline = 1;
- if (autoflush) {
- doflush();
- }
- if (autosynch) {
- dosynch(NULL);
- }
-}
-
- void
-sendsusp()
-{
- NET2ADD(IAC, SUSP);
- printoption("SENT", IAC, SUSP);
- flushline = 1;
- if (autoflush) {
- doflush();
- }
- if (autosynch) {
- dosynch(NULL);
- }
-}
-
- void
-sendeof()
-{
- NET2ADD(IAC, xEOF);
- printoption("SENT", IAC, xEOF);
-}
-
- void
-sendayt()
-{
- NET2ADD(IAC, AYT);
- printoption("SENT", IAC, AYT);
-}
-
-/*
- * Send a window size update to the remote system.
- */
-
- void
-sendnaws()
-{
- long rows, cols;
- unsigned char tmp[16];
- register unsigned char *cp;
-
- if (my_state_is_wont(TELOPT_NAWS))
- return;
-
-#define PUTSHORT(cp, x) { if ((*cp++ = ((x)>>8)&0xff) == IAC) *cp++ = IAC; \
- if ((*cp++ = ((x))&0xff) == IAC) *cp++ = IAC; }
-
- if (TerminalWindowSize(&rows, &cols) == 0) { /* Failed */
- return;
- }
-
- cp = tmp;
-
- *cp++ = IAC;
- *cp++ = SB;
- *cp++ = TELOPT_NAWS;
- PUTSHORT(cp, cols);
- PUTSHORT(cp, rows);
- *cp++ = IAC;
- *cp++ = SE;
- if (NETROOM() >= cp - tmp) {
- ring_supply_data(&netoring, tmp, cp-tmp);
- printsub('>', tmp+2, cp - tmp - 2);
- }
-}
-
- void
-tel_enter_binary(rw)
- int rw;
-{
- if (rw&1)
- send_do(TELOPT_BINARY, 1);
- if (rw&2)
- send_will(TELOPT_BINARY, 1);
-}
-
- void
-tel_leave_binary(rw)
- int rw;
-{
- if (rw&1)
- send_dont(TELOPT_BINARY, 1);
- if (rw&2)
- send_wont(TELOPT_BINARY, 1);
-}
+++ /dev/null
-/*
- * Copyright (c) 1988, 1990, 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.
- */
-
-/* based on @(#)terminal.c 8.1 (Berkeley) 6/6/93 */
-
-#include <arpa/telnet.h>
-#include <sys/types.h>
-
-#include "ring.h"
-
-#include "externs.h"
-#include "types.h"
-
-#ifdef ENCRYPTION
-#include <libtelnet/encrypt.h>
-#endif
-
-Ring ttyoring, ttyiring;
-unsigned char ttyobuf[2*BUFSIZ], ttyibuf[BUFSIZ];
-
-int termdata; /* Debugging flag */
-
-#ifdef USE_TERMIO
-# ifndef VDISCARD
-cc_t termFlushChar;
-# endif
-# ifndef VLNEXT
-cc_t termLiteralNextChar;
-# endif
-# ifndef VSUSP
-cc_t termSuspChar;
-# endif
-# ifndef VWERASE
-cc_t termWerasChar;
-# endif
-# ifndef VREPRINT
-cc_t termRprntChar;
-# endif
-# ifndef VSTART
-cc_t termStartChar;
-# endif
-# ifndef VSTOP
-cc_t termStopChar;
-# endif
-# ifndef VEOL
-cc_t termForw1Char;
-# endif
-# ifndef VEOL2
-cc_t termForw2Char;
-# endif
-# ifndef VSTATUS
-cc_t termAytChar;
-# endif
-#else
-cc_t termForw2Char;
-cc_t termAytChar;
-#endif
-
-/*
- * initialize the terminal data structures.
- */
-
- void
-init_terminal()
-{
- if (ring_init(&ttyoring, ttyobuf, sizeof ttyobuf) != 1) {
- exit(1);
- }
- if (ring_init(&ttyiring, ttyibuf, sizeof ttyibuf) != 1) {
- exit(1);
- }
- autoflush = TerminalAutoFlush();
-}
-
-
-/*
- * Send as much data as possible to the terminal.
- *
- * Return value:
- * -1: No useful work done, data waiting to go out.
- * 0: No data was waiting, so nothing was done.
- * 1: All waiting data was written out.
- * n: All data - n was written out.
- */
-
-
- int
-ttyflush(drop)
- int drop;
-{
- register int n, n0, n1;
-
- n0 = ring_full_count(&ttyoring);
- if ((n1 = n = ring_full_consecutive(&ttyoring)) > 0) {
- if (drop) {
- TerminalFlushOutput();
- /* we leave 'n' alone! */
- } else {
- n = TerminalWrite(ttyoring.consume, n);
- }
- }
- if (n > 0) {
- if (termdata && n) {
- Dump('>', ttyoring.consume, n);
- }
- /*
- * If we wrote everything, and the full count is
- * larger than what we wrote, then write the
- * rest of the buffer.
- */
- if (n1 == n && n0 > n) {
- n1 = n0 - n;
- if (!drop)
- n1 = TerminalWrite(ttyoring.bottom, n1);
- n += n1;
- }
- ring_consumed(&ttyoring, n);
- }
- if (n < 0)
- return -1;
- if (n == n0) {
- if (n0)
- return -1;
- return 0;
- }
- return n0 - n + 1;
-}
-
-\f
-/*
- * These routines decides on what the mode should be (based on the values
- * of various global variables).
- */
-
-
- int
-getconnmode()
-{
- extern int linemode;
- int mode = 0;
-#ifdef KLUDGELINEMODE
- extern int kludgelinemode;
-#endif
-
- if (In3270)
- return(MODE_FLOW);
-
- if (my_want_state_is_dont(TELOPT_ECHO))
- mode |= MODE_ECHO;
-
- if (localflow)
- mode |= MODE_FLOW;
-
- if (my_want_state_is_will(TELOPT_BINARY))
- mode |= MODE_INBIN;
-
- if (his_want_state_is_will(TELOPT_BINARY))
- mode |= MODE_OUTBIN;
-
-#ifdef KLUDGELINEMODE
- if (kludgelinemode) {
- if (my_want_state_is_dont(TELOPT_SGA)) {
- mode |= (MODE_TRAPSIG|MODE_EDIT);
- if (dontlecho && (clocks.echotoggle > clocks.modenegotiated)) {
- mode &= ~MODE_ECHO;
- }
- }
- return(mode);
- }
-#endif
- if (my_want_state_is_will(TELOPT_LINEMODE))
- mode |= linemode;
- return(mode);
-}
-
- void
-setconnmode(force)
- int force;
-{
-#ifdef ENCRYPTION
- static int enc_passwd = 0;
-#endif /* ENCRYPTION */
- register int newmode;
-
- newmode = getconnmode()|(force?MODE_FORCE:0);
-
- TerminalNewMode(newmode);
-
-#ifdef ENCRYPTION
- if ((newmode & (MODE_ECHO|MODE_EDIT)) == MODE_EDIT) {
- if (my_want_state_is_will(TELOPT_ENCRYPT)
- && (enc_passwd == 0) && !encrypt_output) {
- encrypt_request_start(0, 0);
- enc_passwd = 1;
- }
- } else {
- if (enc_passwd) {
- encrypt_request_end();
- enc_passwd = 0;
- }
- }
-#endif /* ENCRYPTION */
-
-}
-
-
- void
-setcommandmode()
-{
- TerminalNewMode(-1);
-}
+++ /dev/null
-.\" Copyright (c) 1991 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.
-.\"
-.\" @(#)doc 5.8 (Berkeley) 8/5/91
-.\"
-.\" .mdoc-parse - attempt to parse troff request arguments
-.\" This version has had comments stripped; an unstripped version is available.
-.if \n(.g \{\
-.cp 0
-.ftr C CR
-.\}
-.if t \{\
-.\" tmac.mdoc-ditroff
-.ds aD \fI\s10
-.ds aR \f(CO\s10
-.ds cM \f(CB\s10
-.ds dF \fR\s10
-.ds eM \fI\s10
-.ds eR \fC\s10
-.ds eV \fC\s10
-.ds fA \f(CO\s10
-.ds fD \f(CB\s10
-.ds fL \f(CB\s10
-.ds fN \f(CB\s10
-.ds fP \fP\s0
-.ds fS \s0
-.ds fT \f(CO\s10
-.ds Hs \fR\s10
-.ds iC \f(CB\s10
-.ds lI \fC
-.ds lP \fR\|(\|\fP\s10
-.ds lp \fR(\fP\s10
-.ds rP \fR\|)\|\fP\s10
-.ds rp \fR)\fP\s10
-.ds lB \fR\^[\^\fP\s10
-.ds rB \fR\^]\fP\s10
-.ds mL \fB\s10
-.ds nM \f(CB\s10
-.ds nO \fR\s10
-.ds nT \s0
-.ds pA \fC\s10
-.ds Pu \fR{\ .\ ,\ :\ ;\ (\ )\ [\ ]\ \fR}
-.ds rA \fR\s10
-.ds rT \f(CO\s10
-.ds sH \fB\s10
-.ds sP \s0
-.ds sY \fB\s10
-.ds sX \fR\s10
-.ds tF \fR
-.ds tN \s9
-.ds vA \fI\s10
-.ds Vs \fR\s10
-.ds vT \f(CB\s10
-.ds xR \fC\s10
-.tr *\(**
-.nr sI \w\a\fC,\au*5
-.nr Ti \n(sIu
-.nr Pp .5v
-.ds lS \0
-.nr lS \w'\0'u
-.nr dI 6n
-.de pL
-.nr Hm .5i
-.nr Fm .5i
-.nr ll 6.5i
-.ll 6.5i
-.nr lt 6.5i
-.lt 6.5i
-.nr po 1i
-.po 1.i
-.nr dV .5v
-..
-.ds <= \(<=
-.ds >= \(>=
-.ds Lq \&``
-.ds Rq \&''
-.ds ua \(ua
-.ds aa \(aa
-.ds ga \(ga
-.ds sR \&'
-.ds sL \&`
-.ds q \&"
-.ds Pi \(*p
-.ds Ne \(!=
-.ds Le \(<=
-.ds Ge \(>=
-.ds Lt <
-.ds Gt >
-.ds Pm \(+-
-.ds If \(if
-.ds Na \fINaN\fP
-.ds Ba \fR\&|\fP
-.nr gX 0
-.de hK
-.ds hT \\*(dT
-.if !"\\*(cH"Null" \{\
-. ie !"\\*(gP"Null" .as hT \|(\|\\*(cH\\*(gP\|)
-. el .as hT \\|(\\|\\*(cH\\|)
-.\}
-.if "\\*(cH"Null" \{\
-. if !"\\*(gP"Null" .as hT \&\|(\|\\*(gP\|)
-.\}
-.wh 0 hM
-.wh -1.25i fM
-.ie \\n(gX==1 \{\
-. rm n1
-. if \\n(.g .br
-. if !\\n(.g .bp
-.\}
-.el \{\
-. if \\n(.g .br
-. if !\\n(.g 'bp
-.\}
-.nr % 1
-.nr gX 0
-.em lM
-..
-.nr fW \w\a\fC0\a
-.de sW
-.nr sW \w\a\fC\\$1\a
-.ie \\n(sW>=\\n(fW \{\
-. ie \\n(sW%\\n(fW .nr sW (\\n(sW/\\n(fW)+1
-. el .nr sW \\n(sW/\\n(fW
-.\}
-.el \{\
-. ie \\n(sW>0 .nr sW 1
-. el .nr sW 0
-.\}
-..
-.de aW
-.nr sW \w\a\fC\\*(A\\$1\a
-.ie \\n(sW>=\\n(fW \{\
-. ie \\n(sW%\\n(fW .nr sW (\\n(sW/\\n(fW)+1
-. el .nr sW \\n(sW/\\n(fW
-.\}
-.el \{\
-. ie \\n(sW>0 .nr sW 1
-. el .nr sW 0
-.\}
-..
-.de Ql
-.if \\n(aC==0 \{\
-. ds mN Ql
-. ds A1 \\$1
-. ds A2 \\$2
-. ds A3 \\$3
-. ds A4 \\$4
-. ds A5 \\$5
-. ds A6 \\$6
-. ds A7 \\$7
-. ds A8 \\$8
-. nr fV \\n(.$
-. fV
-.\}
-.nr aP \\n(aP+1
-.aW \\n(aP
-.nr aP \\n(aP-1
-.if \\n(sW>2 .Li
-.if \\n(sW<=2 \{\
-. if (\\n(aP>0) \{\
-. ds A\\n(aP Li
-. nr aP \\n(aP -1
-. \}
-. if (\\n(aP==0) \{\
-. rm C0 C1 C2 C3 C4 C5 C6 C7 C8 C9
-. rm S1 S2 S3 S4 S5 S6 S7 S8 S9
-. rn A8 A9
-. rn A7 A8
-. rn A6 A7
-. rn A5 A6
-. rn A4 A5
-. rn A3 A4
-. rn A2 A3
-. rn A1 A2
-. ds A1 Li
-. nr fV \\n(aC+1
-. nr aC 0
-. fV
-. \}
-. ds qL \&\\*(sL
-. ds qR \&\\*(sR
-. En
-.\}
-..
-.de Sh
-.nr nS 0
-.nr sE 0
-.nr iS 0
-'ad
-.ie "\\$1"NAME" \{\
-. hK
-' in 0
-.\}
-.el \{\
-. nr nS 0
-. nr nA 0
-. nr nF 0
-. nr nT 0
-. nr nY 0
-. nr oT 0
-. if "\\$1"SYNOPSIS" \{\
-. na
-. nr nS 1
-. \}
-. if "\\$1"DESCRIPTION" \{\
-. nr fY 0
-. nr fZ 0
-. nr fB 0
-. nr Fb 0
-. ds Fb
-. \}
-. if "\\$1"SEE" \{\
-. nr nA 1
-. na
-. \}
-. if "\\$1"FILES" .nr nF 1
-. if "\\$1"STANDARDS" .nr nT 1
-. if "\\$1"AUTHORS" .nr nY 1
-. if "\\$1"SEE" .nr sE 1
-. in 0
-. nr aN 0
-.\}
-.pL
-'sp
-.ns
-.ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i
-.if !\\n(cR .ne 3
-'fi
-\&\\*(sH\\$1 \|\\$2 \|\\$3 \|\\$4 \|\\$5 \|\\$6 \|\\$7 \|\\$8 \|\\$9
-\&\fP\s0\&
-.in \\n(.iu+\\n(Tiu
-.ns
-..
-.\}
-.if n \{\
-.\" tmac.mdoc-nroff
-.ds aD \fI
-.ds aR \fI
-.ds cM \fB
-.ds dF \fR
-.ds eM \fI
-.ds eR \fR
-.ds eV \fR
-.ds fA \fI
-.ds fD \fB
-.ds fL \fB
-.ds fN \fB
-.ds fP \fP
-.ds fS
-.ds fT \fI
-.ds Hs \fR
-.ds iC \fB
-.ds lI \fR
-.ds lP \fR\|(\fP
-.ds rP \fR\|)\fP
-.ds lp \fR\|(\fP
-.ds rp \fR\|)\fP
-.ds lB \fR\|[\|\fP
-.ds rB \fR\|]\fP
-.ds mL \fB
-.ds nM \fB
-.ds nO \fR
-.ds pA \fI
-.ds Pu {\ .\ ,\ ;\ :\ (\ )\ [\ ]}
-.ds rA \fR
-.ds rT \fI
-.ds sH \fB
-.ds sP
-.ds sY \fB
-.ds sX \fI
-.ds tF \fR
-.ds tN
-.ds vA \fI
-.ds Vs \fR
-.ds vT \fB
-.ds xR \fR
-.nr sI .5i
-.nr Ti .5i
-.nr cR 1
-.nr Pp 1v
-.ds lS \0\0
-.nr lS \w'\0\0'u
-.nr dI 6n
-.de pL
-.ie \\n(cR .nr Hm 0
-.el .nr Hm .5i
-.nr Fm .5i
-.nr ll 78n
-.ll 78n
-.nr lt 78n
-.lt 78n
-.nr po 0i
-.po 0i
-.nr dV 1v
-.ad l
-.na
-..
-.ds <= \&<\&=
-.ds >= \&>\&=
-.ds Rq ''
-.ds Lq ``
-.ds ua ^
-.ds aa \'
-.ds ga \`
-.ds sL `
-.ds sR '
-.ds q \&"
-.ds Pi pi
-.ds Ne !=
-.ds Le <=
-.ds Ge >=
-.ds Lt <
-.ds Gt >
-.ds Pm +-
-.ds If infinity
-.ds Na \fINaN\fP
-.ds Ba \fR\&|\fP
-.de hK
-.nr % 1
-.ds hT \\*(dT
-.if !"\\*(cH"Null" \{\
-. ie !"\\*(gP"Null" .as hT \|(\|\\*(cH\\*(gP\|)
-. el .as hT \\|(\\|\\*(cH\\|)
-.\}
-.if "\\*(cH"Null" .if !"\\*(gP"Null" .as hT \&\|(\|\\*(gP\|)
-.ie \\n(cR \{\
-. hM
-. wh -1v fM
-.\}
-.el \{\
-. wh 0 hM
-. wh -1.167i fM
-.\}
-.if \\n(nl==0:\\n(nl==-1 'bp
-.em lM
-..
-.nr fW \w'0'
-.de sW
-.nr sW \w\a\\$1\a
-.ie \\n(sW>=\\n(fW \{\
-. ie \\n(sW%\\n(fW .nr sW (\\n(sW/\\n(fW)+1
-. el .nr sW \\n(sW/\\n(fW
-.\}
-.el .nr sW 0
-..
-.de aW
-.nr sW \w\a\\*(A\\$1\a
-.ie \\n(sW>=\\n(fW \{\
-. ie \\n(sW%\\n(fW .nr sW (\\n(sW/\\n(fW)+1
-. el .nr sW \\n(sW/\\n(fW
-.\}
-.el .nr sW 0
-..
-.de Ql
-.if \\n(aC==0 \{\
-. ds mN Ql
-. ds A1 \\$1
-. ds A2 \\$2
-. ds A3 \\$3
-. ds A4 \\$4
-. ds A5 \\$5
-. ds A6 \\$6
-. ds A7 \\$7
-. ds A8 \\$8
-. ds A9 \\$9
-. nr fV \\n(.$
-. fV
-.\}
-.ds qL \&\\*(sL
-.ds qR \&\\*(sR
-.En \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Sh
-.nr nS 0
-.nr sE 0
-.nr iS 0
-.ie "\\$1"NAME" \{\
-. hK
-' in 0
-.\}
-.el \{\
-. nr nS 0
-. nr nA 0
-. nr nF 0
-. nr nT 0
-. nr nY 0
-. nr aN 0
-. nr oT 0
-. if "\\$1"SEE" .nr nA 1
-. if "\\$1"FILES" .nr nF 1
-. if "\\$1"STANDARDS" .nr nT 1
-. if "\\$1"SYNOPSIS" .nr nS 1
-. if "\\$1"DESCRIPTION" \{\
-. rr fB
-. rr Fb
-. ds Fb
-. nr fY 0
-. nr fZ 0
-. \}
-. if "\\$1"AUTHORS" .nr nY 1
-. in 0
-.\}
-.pL
-'sp
-.ns
-.ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i
-.if !\\n(cR .ne 3
-'fi
-\&\\*(sH\\$1 \|\\$2 \|\\$3 \|\\$4 \|\\$5 \|\\$6 \|\\$7 \|\\$8 \|\\$9
-\&\fP\s0\&
-.in \\n(.iu+\\n(Tiu
-.if "\\$1"SEE" .nr sE 1
-.ns
-..
-.\}
-.\" @(#)doc-common 5.7 (Berkeley) 8/5/91
-.nr %A 1
-.nr %J 1
-.nr %N 1
-.nr %O 1
-.nr %R 1
-.nr %T 1
-.nr %V 1
-.nr Ad 12n
-.nr Ac 3
-.nr Ao 12n
-.nr Ap 2
-.nr An 12n
-.nr Aq 12n
-.nr Ar 12n
-.nr Bc 3
-.nr Bl 1
-.nr Bo 12n
-.nr Bq 12n
-.nr Bx 12n
-.nr Cd 12n
-.nr Cm 10n
-.nr Co 15n
-.nr Cx 20n
-.nr Dc 3
-.nr Do 10n
-.nr Dq 12n
-.nr Ds 6n
-.nr Dq 12n
-.nr Dv 12n
-.nr tI \n(Dsu
-.nr Ec 3
-.nr El 1
-.nr Eo 12n
-.nr Eq 12n
-.nr Em 10n
-.nr Er 12n
-.nr Ev 15n
-.nr Ex 10n
-.nr Fa 12n
-.nr Fl 10n
-.nr Fc 3
-.nr Fo 16n
-.nr Fn 16n
-.nr Hl 1
-.nr I1 6n
-.nr I2 12n
-.nr I3 18n
-.nr Ic 10n
-.nr Li 16n
-.nr Ms 6n
-.nr Nm 10n
-.nr No 12n
-.nr Ns 2
-.nr Oo 10n
-.nr Oc 3
-.nr Op 14n
-.nr Pa 32n
-.nr Pf 12n
-.nr Pc 3
-.nr Po 12n
-.nr Pq 12n
-.nr Ql 16n
-.nr Qc 3
-.nr Qo 12n
-.nr Qq 12n
-.nr Sc 3
-.nr So 12n
-.nr Sq 12n
-.nr Sy 6n
-.nr Sx 16n
-.nr Ra 1
-.nr Rj 1
-.nr Rn 1
-.nr Ro 1
-.nr Rr 1
-.nr Rt 1
-.nr Rv 1
-.nr Tn 10n
-.nr Ta 1
-.nr Tv 1
-.nr Tx 22n
-.nr Ux 10n
-.nr Va 12n
-.nr Xc 3
-.nr Xo 1
-.nr Xr 10n
-.ds sV \& \&
-.ds hV \&\ \&
-.ds iV \& \&
-.ds tV \&\\t\&
-.nr z. 3
-.nr z, 3
-.nr z: 3
-.nr z; 3
-.nr z( 4
-.nr z) 3
-.nr z[ 4
-.nr z] 3
-.ds z( z)
-.ds z[ z]
-.ds z< z>
-.nr z0 0
-.nr z1 0
-.nr z2 0
-.nr z3 0
-.nr z4 0
-.nr z5 0
-.nr z6 0
-.nr z7 0
-.nr z8 0
-.nr z9 0
-.nr z# 0
-.de Dt
-.ds dT UNTITLED
-.ds vT LOCAL
-.ds cH Null
-.if !"\\$1"" .ds dT \\$1
-.if !"\\$2"" \{\
-. ds cH \\$2
-. if \\$2>=1 .if \\$2<=8 \{\
-. ds vT NetBSD Reference Manual
-. if \\$2>1 .if \\$2<6 .ds vT NetBSD Programmer's Manual
-. if "\\$2"8" .ds vT NetBSD System Manager's Manual
-. nr sN \\$2
-. \}
-. if "\\$2"unass" .ds vT DRAFT
-. if "\\$2"draft" .ds vT DRAFT
-. if "\\$2"paper" .ds vT UNTITLED
-.\}
-.if !"\\$3"" \{\
-. if "\\$3"USD" .ds vT NetBSD User's Supplementary Documents
-. if "\\$3"PS1" .ds vT NetBSD Programmers's Supplementary Documents
-. if "\\$3"AMD" .ds vT NetBSD Ancestral Manual Documents
-. if "\\$3"SMM" .ds vT NetBSD System Manager's Manual
-. if "\\$3"URM" .ds vT NetBSD Reference Manual
-. if "\\$3"PRM" .ds vT NetBSD Programmers's Manual
-. if "\\$3"IND" .ds vT NetBSD Manual Master Index
-. if "\\$3"LOCAL" .ds vT NetBSD Local Manual
-. if "\\$3"tahoe" .as vT \ (Tahoe Architecture)
-. if "\\$3"vax" .as vT \ (VAX Architecture)
-. if "\\$3"hp300" .as vT \ (HP300 Architecture)
-. if "\\*(vT"LOCAL" .ds vT \\$3
-.\}
-..
-.de Os
-.ds oS Null
-.if "\\$1"" \{\
-. ds oS BSD Experimental
-.\}
-.if "\\$2"" \{\
-. ds aa Non-Null
-.\}
-.if "\\$1"ATT" \{\
-. ds oS AT&T
-. if "\\$2"" .as oS \0UNIX
-. if "\\$2"7th" .as oS \07th Edition
-. if "\\$2"7" .as oS \07th Edition
-. if "\\$2"III" .as oS \0System III
-. if "\\$2"3" .as oS \0System III
-. if "\\$2"V" .as oS \0System V
-. if "\\$2"V.2" .as oS \0System V Release 2
-. if "\\$2"V.3" .as oS \0System V Release 3
-. if "\\$2"V.4" .as oS \0System V Release 4
-.\}
-.if "\\$1"BSD" \{\
-. if "\\$2"3" .ds oS 3rd Berkeley Distribution
-. if "\\$2"4" .ds oS 4th Berkeley Distribution
-. if "\\$2"4.1" .ds oS 4.1 Berkeley Distribution
-. if "\\$2"4.2" .ds oS 4.2 Berkeley Distribution
-. if "\\$2"4.3" .ds oS 4.3 Berkeley Distribution
-. if "\\$2"4.3T" .ds oS 4.3-Tahoe Berkeley Distribution
-. if "\\$2"4.3R" .ds oS 4.3-Reno Berkeley Distribution
-. if "\\$2"4.3t" .ds oS 4.3-Tahoe Berkeley Distribution
-. if "\\$2"4.3r" .ds oS 4.3-Reno Berkeley Distribution
-. if "\\$2"4.4" .ds oS BSD Experimental
-.\}
-.if "\\$1"NetBSD" \{\
-. ds oS NetBSD
-. if "\\$2"0.8" .as oS \00.8
-. if "\\$2"0.8a" .as oS \00.8a
-. if "\\$2"0.9" .as oS \00.9
-. if "\\$2"0.9a" .as oS \00.9a Experimental
-. if "\\$2"1.0" .as oS \01.0 Experimental
-.\}
-.if "\\*(oS"Null" .ds oS \0\\$1
-.if "\\*(aa"Non-Null" .as oS \0\\$2
-.rm aa
-..
-.de Dd
-.if !"\\*(dD"" .nr gX 1
-.ie \\n(.$>0 \{\
-. ie \\n(.$==3 \{\
-. ds dD \\$1 \\$2 \\$3
-. \}
-. el \{\
-. if "\\n(mo"1" .ds dD January
-. if "\\n(mo"2" .ds dD February
-. if "\\n(mo"3" .ds dD March
-. if "\\n(mo"4" .ds dD April
-. if "\\n(mo"5" .ds dD May
-. if "\\n(mo"6" .ds dD June
-. if "\\n(mo"7" .ds dD July
-. if "\\n(mo"8" .ds dD August
-. if "\\n(mo"9" .ds dD September
-. if "\\n(mo"10" .ds dD October
-. if "\\n(mo"11" .ds dD November
-. if "\\n(mo"12" .ds dD December
-. as dD \&\ \\n(dy, 19\\n(yr
-. \}
-.\}
-.el \{\
-. ds dD Epoch
-.\}
-..
-.de hM
-.ev 1
-.pL
-.if !\\n(cR 'sp \\n(Hmu
-.tl @\\*(Hs\\*(hT\fP@\\*(Vs\\*(vT\fP@\\*(Hs\\*(hT\fP@
-'sp \\n(Hmu
-.ev
-..
-.de fM
-.ie \\n(cR 'br
-.el \{\
-. ev 1
-. pL
-. if !\\n(cR \{\
-' sp \\n(Fmu
-. tl @\\*(Hs\\*(oS\fP@\\*(Vs\\*(dD\fP@%@
-' bp
-. \}
-. ev
-.\}
-..
-.de lM
-.fl
-.if \\n(cR \{\
-' sp
-. tl @\\*(Hs\\*(oS\fP@\\*(Vs\\*(dD\fP@%@
-. pl \\n(nlu
-.\}
-..
-.de Pp
-.sp \\n(Ppu
-.ne 2
-.ns
-..
-.de Lp
-.Pp
-..
-.de LP
-.tm Not a \-mdoc command: .LP
-..
-.de PP
-.tm Not a \-mdoc command: .PP
-..
-.de pp
-.tm Not a \-mdoc command: .pp
-..
-.de Nd
-\&\-\& \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Ss
-.sp
-.ne 2
-.ti -.25i
-\&\\*(sH\\$1 \|\\$2 \|\\$3 \|\\$4 \|\\$5 \|\\$6 \|\\$7 \|\\$8 \|\\$9
-\&\fP\s0
-.ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i
-.if !\\n(cR .ne 2
-.br
-..
-.de Rd
-.tm MDOC REGISTER DUMP
-.tm Db==\\n(Db register DEBUG MODE
-.tm L[0-9] registers - stack of list types
-.tm L0==\\n(L0
-.tm L1==\\n(L1
-.tm L2==\\n(L2
-.tm L3==\\n(L3
-.tm L4==\\n(L4
-.tm L5==\\n(L5
-.tm L6==\\n(L6
-.tm L7==\\n(L7
-.tm L8==\\n(L8
-.tm L9==\\n(L9
-.tm O[0-9] registers - stack of indent
-.tm O0==\\n(O0
-.tm O1==\\n(O1
-.tm O2==\\n(O2
-.tm O3==\\n(O3
-.tm O4==\\n(O4
-.tm O5==\\n(O5
-.tm O6==\\n(O6
-.tm O7==\\n(O7
-.tm O8==\\n(O8
-.tm O9==\\n(O9
-.tm aC==\\n(aC register argument counter (aV/fV)
-.tm aJ==\\n(aJ register (for vR)
-.tm aN==\\n(aN register
-.tm aP==\\n(aP register argument pointer (aV)
-.tm aT==\\n(aT register argument type
-.tm aa==\\n(aa local register
-.tm bK==\\n(bK register - Book Name flag
-.tm cF==\\n(cF register save current font
-.tm cI==\\n(cI register - column indent width
-.tm cZ==\\n(cZ register save current font size
-.tm dK==\\n(dK register - Date flag
-.tm d[0-9] registers - display-type stack
-.tm d0==\\n(d0
-.tm d1==\\n(d1
-.tm d2==\\n(d2
-.tm d3==\\n(d3
-.tm d4==\\n(d4
-.tm d5==\\n(d5
-.tm d6==\\n(d6
-.tm d7==\\n(d7
-.tm d8==\\n(d8
-.tm d9==\\n(d9
-.tm dZ==\\n(dZ register diversion count
-.tm fD==\\n(fD register subroutine test (in synopsis only)
-.tm fV==\\n(fV register argument counter (must set to \\n(.$ prior to
-.tm fY==\\n(fY register - dick with old style function declarations (fortran)
-.tm fZ==\\n(fZ register also subroutine count (in synopsis only)
-.tm h[0-9] register horizontal tag stack (continuous if 1, break if
-.tm h0==\\n(h0
-.tm h1==\\n(h1
-.tm h2==\\n(h2
-.tm h3==\\n(h3
-.tm h4==\\n(h4
-.tm h5==\\n(h5
-.tm h6==\\n(h6
-.tm h7==\\n(h7
-.tm h8==\\n(h8
-.tm h9==\\n(h9
-.tm iD==\\n(iD local register
-.tm iI==\\n(iI local register (indent for inline debug mode)
-.tm iN==\\n(iN register DEBUG MODE (inline if 1, to stderr if
-.tm iS==\\n(iS register - indent second command line in a synopsis
-.tm jK==\\n(jK register - [reference] Journal Name flag
-.tm jM==\\n(jM local register
-.tm jN==\\n(jN local register
-.tm lC==\\n(lC register - list type stack counter
-.tm lK==\\n(lK register count of lines read from input file
-.tm nK==\\n(nK register - [reference] issue number flag
-.tm nU==\\n(nU register count
-.tm oK==\\n(oK register - [reference] optional information flag
-.tm oM==\\n(oM register (extension possible)
-.tm o[0-9] register offset stack (nested tags)
-.tm o0==\\n(o0
-.tm o1==\\n(o1
-.tm o2==\\n(o2
-.tm o3==\\n(o3
-.tm o4==\\n(o4
-.tm o5==\\n(o5
-.tm o6==\\n(o6
-.tm o7==\\n(o7
-.tm o8==\\n(o8
-.tm o9==\\n(o9
-.tm oM==\\n(oM register open ended line flag
-.tm pK==\\n(pK register - [reference] page number flag
-.tm qK==\\n(qK register - Corporate or Foreign Author flag
-.tm rK==\\n(rK register - [reference] report flag
-.tm rS==\\n(rS register - Reference Start flag
-.tm sM==\\n(sM register - default is one (space mode on)
-.tm tK==\\n(tK register - reference title flag
-.tm tP==\\n(tP register tag flag (for diversions)
-.tm tX==\\n(tX register (initial class)
-.tm tY==\\n(tY register (next possible lC value)
-.tm t[0-9] register tag string stack (nested tags)
-.tm t0==\\n(t0
-.tm t1==\\n(t1
-.tm t2==\\n(t2
-.tm t3==\\n(t3
-.tm t4==\\n(t4
-.tm t5==\\n(t5
-.tm t6==\\n(t6
-.tm t7==\\n(t7
-.tm t8==\\n(t8
-.tm t9==\\n(t9
-.tm uK==\\n(uK register - reference author(s) counter
-.tm vK==\\n(vK register - reference volume flag
-.tm v[0-9] register vertical tag break stack
-.tm v0==\\n(v0
-.tm v1==\\n(v1
-.tm v2==\\n(v2
-.tm v3==\\n(v3
-.tm v4==\\n(v4
-.tm v5==\\n(v5
-.tm v6==\\n(v6
-.tm v7==\\n(v7
-.tm v8==\\n(v8
-.tm v9==\\n(v9
-.tm w[0-9] register tag stack (nested tags)
-.tm w0==\\n(w0
-.tm w1==\\n(w1
-.tm w2==\\n(w2
-.tm w3==\\n(w3
-.tm w4==\\n(w4
-.tm w5==\\n(w5
-.tm w6==\\n(w6
-.tm w7==\\n(w7
-.tm w8==\\n(w8
-.tm w9==\\n(w9
-.tm xX==\\n(xX local register
-.tm END OF REGISTER DUMP
-..
-.\" @(#)doc-syms 5.6 (Berkeley) 8/5/91
-.de Ux
-.nr cF \\n(.f
-.nr cZ \\n(.s
-.ds aa \&\f\\n(cF\s\\n(cZ
-.as b1 \&\\*(tNUNIX\\*(aa
-.rm aa
-.if \\n(aC==0 \{\
-. if \\n(.$>0 .aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-.\}
-.ie \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. ie \\n(C\\n(aP==1 \{\
-. \\*(A\\n(aP
-. \}
-. el .nR
-.\}
-.el .aZ
-..
-.de Bx
-.nr cF \\n(.f
-.nr cZ \\n(.s
-.ds aa \&\f\\n(cF\s\\n(cZ
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 \&\\*(tNBSD\\*(aa \\*(tNUNIX\\*(aa
-. el .aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-.\}
-.if "\\$1"-alpha" \{\
-\¤tly in alpha test.
-. aY
-.\}
-.if "\\$1"-beta" \{\
-\¤tly in beta test.
-. aY
-.\}
-.if "\\$1"-devel" \{\
-\¤tly under development.
-. aY
-.\}
-.if \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. ie \\n(C\\n(aP==2 \{\
-. as b1 \&\\*(A\\n(aP\&\\*(tNBSD\\*(aa
-. ie \\n(aC>\\n(aP \{\
-. nr jj \\n(aP+1
-. ie \\n(C\\n(jj==2 \{\
-. if "\\*(A\\n(jj"Reno" \{\
-. nr aP \\n(aP+1
-. as b1 \&\-\\*(A\\n(jj
-. \}
-. if "\\*(A\\n(jj"reno" \{\
-. nr aP \\n(aP+1
-. as b1 \&\-Reno
-. \}
-. if "\\*(A\\n(jj"Tahoe" \{\
-. nr aP \\n(aP+1
-. as b1 \&\-\\*(A\\n(jj
-. \}
-. if "\\*(A\\n(jj"tahoe" \{\
-. nr aP \\n(aP+1
-. as b1 \&\-Tahoe
-. \}
-. ie \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. nR
-. \}
-. el .aZ
-. \}
-. el \{\
-. nr aP \\n(aP+1
-. nR
-. \}
-. rr jj
-. \}
-. el .aZ
-. \}
-. el \{\
-. as b1 \&\\*(tNBSD\\*(aa U\\*(tNNIX\\*(aa
-. nR
-. \}
-.\}
-..
-.de Ud
-\¤tly under development.
-..
-.de Nx
-.nr cF \\n(.f
-.nr cZ \\n(.s
-.ds aa \&\f\\n(cF\s\\n(cZ
-.if \\n(.$==2 \{\
-. if "\\$1"0.8" \&\\*(tNNetBSD\\*(aa 0.8\\*(aa\\$2
-. if "\\$1"0.8a" \&\\*(tNNetBSD\\*(aa 0.8a\\*(aa\\$2
-. if "\\$1"0.9" \&\\*(tNNetBSD\\*(aa 0.9\\*(aa\\$2
-. if "\\$1"0.9a" \&\\*(tNNetBSD\\*(aa 0.9a\\*(aa\\$2
-. if "\\$1"1.0" \&\\*(tNNetBSD\\*(aa 1.0\\*(aa\\$2
-. if "\\$1"1.0a" \&\\*(tNNetBSD\\*(aa 1.0a\\*(aa\\$2
-.\}
-.if \\n(.$==1 \{\
-. if "\\$1"0.8" \&\\*(tNNetBSD\\*(aa 0.8\\*(aa
-. if "\\$1"0.8a" \&\\*(tNNetBSD\\*(aa 0.8a\\*(aa
-. if "\\$1"0.9" \&\\*(tNNetBSD\\*(aa 0.9\\*(aa
-. if "\\$1"0.9a" \&\\*(tNNetBSD\\*(aa 0.9a\\*(aa
-. if "\\$1"1.0" \&\\*(tNNetBSD\\*(aa 1.0\\*(aa
-. if "\\$1"1.0a" \&\\*(tNNetBSD\\*(aa 1.0a\\*(aa
-.\}
-..
-.de At
-.nr cF \\n(.f
-.nr cZ \\n(.s
-.ds aa \&\f\\n(cF\s\\n(cZ
-.if \\n(.$==2 \{\
-. if "\\$1"32v" \&Version 32V \\*(tNAT&T UNIX\\*(aa\\$2
-. if "\\$1"v6" \&Version 6 \\*(tNAT&T UNIX\\*(aa\\$2
-. if "\\$1"v7" \&Version 7 \\*(tNAT&T UNIX\\*(aa\\$2
-. if "\\$1"V" \&\\*(tNAT&T\\*(aa System V \\*(tNUNIX\\*(aa\\$2
-. if "\\$1"V.1" \&\\*(tNAT&T\\*(aa System V.1 \\*(tNUNIX\\*(aa\\$2
-. if "\\$1"V.2" \&\\*(tNAT&T\\*(aa System V.2 \\*(tNUNIX\\*(aa\\$2
-. if "\\$1"V.4" \&\\*(tNAT&T\\*(aa System V.4 \\*(tNUNIX\\*(aa\\$2
-.\}
-.if \\n(.$==1 \{\
-. if "\\$1"32v" \&Version 32V \\*(tNAT&T UNIX\\*(aa
-. if "\\$1"v6" \&Version 6 \\*(tNAT&T UNIX\\*(aa
-. if "\\$1"v7" \&Version 7 \\*(tNAT&T UNIX\\*(aa
-. if "\\$1"V" \&\\*(tNAT&T\\*(aa System V \\*(tNUNIX\\*(aa
-. if "\\$1"V.1" \&\\*(tNAT&T\\*(aa System V.1 \\*(tNUNIX\\*(aa
-. if "\\$1"V.2" \&\\*(tNAT&T\\*(aa System V.2 \\*(tNUNIX\\*(aa
-. if "\\$1"V.4" \&\\*(tNAT&T\\*(aa System V.4 \\*(tNUNIX\\*(aa
-.\}
-..
-.de Bt
-\&is currently in beta test.
-..
-.ds Px \\*(tNPOSIX
-.ds Ai \\*(tNANSI
-.de St
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 \{\
-.tm Usage: .St [-p1003.1-90 | -p1003.2 | -ansiC-89 | -iso ] \\*(Pu ... (#\\n(.c)
-. \}
-. el \{\
-. ds mN St
-. nr aP 0
-. ds A1 \\$1
-. ds A2 \\$2
-. ds A3 \\$3
-. ds A4 \\$4
-. ds A5 \\$5
-. ds A6 \\$6
-. ds A7 \\$7
-. ds A8 \\$8
-. ds A9 \\$9
-. nr fV \\n(.$
-. fV
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. ds aa \&\f\\n(cF\s\\n(cZ
-. nr aP \\n(aP+1
-. if "\\*(A\\n(aP"-p1003.1-90" \{\
-. ie \\n(sT==1 \{\
-. ds b1 \&\\*(tNIEEE Std\\*(aa1003.1-1990\\*(sV
-. as b1 (``\\*(tN\\*(Px\\*(aa'')
-. \}
-. el \{\
-. ds b1 \&\\*(tNIEEE Std\\*(aa1003.1-1990\\*(sV
-. as b1 (``\\*(tN\\*(Px\\*(aa'')
-. \}
-. \}
-. if "\\*(A\\n(aP"-p1003.1-88" \{\
-. ie \\n(sT==1 \{\
-. ds b1 \&\\*(tNIEEE Std\\*(aa1003.1-1988\\*(sV
-. as b1 (``\\*(tN\\*(Px\\*(aa'')
-. \}
-. el \{\
-. ds b1 \&\\*(tNIEEE Std\\*(aa1003.1-1988\\*(sV
-. as b1 (``\\*(tN\\*(Px\\*(aa'')
-. \}
-. \}
-. if "\\*(A\\n(aP"-p1003.1" \{\
-. ie \\n(sT==1 \{\
-. ds b1 \&\\*(tNIEEE Std\\*(aa1003.1\\*(sV
-. as b1 (``\\*(tN\\*(Px\\*(aa'')
-. \}
-. el \{\
-. ds b1 \&\\*(tNIEEE Std\\*(aa1003.1\\*(sV
-. as b1 (``\\*(tN\\*(Px\\*(aa'')
-. \}
-. \}
-. if "\\*(A\\n(aP"-p1003.2-92" \{\
-. ie \\n(sT==1 \{\
-. ds b1 \&\\*(tNIEEE Std\\*(aa1003.2-1992\\*(sV
-. as b1 (``\\*(tN\\*(Px.2\\*(aa'')
-. \}
-. el \{\
-. ds b1 \&\\*(tNIEEE Std\\*(aa1003.2-1992\\*(sV
-. as b1 (``\\*(tN\\*(Px.2\\*(aa'')
-. \}
-. \}
-. if "\\*(A\\n(aP"-p1003.2" \{\
-. ie \\n(sT==1 \{\
-. ds b1 \&\\*(tNIEEE Std\\*(aa1003.2\\*(sV
-. as b1 (``\\*(tN\\*(Px.2\\*(aa'')
-. \}
-. el \{\
-. ds b1 \&\\*(tNIEEE Std\\*(aa1003.2\\*(sV
-. as b1 (``\\*(tN\\*(Px.2\\*(aa'')
-. \}
-. \}
-. if "\\*(A\\n(aP"-ansiC" \{\
-. ie \\n(sT==1 \{\
-. ds b1 \&\\*(tNANSI \\*(aaX3.159-1989\\*(sV
-. as b1 (``\\*(tNANSI C\\*(aa'')
-. \}
-. el \{\
-. ds b1 \&\\*(tNANSI \\*(aaX3.159-1989\\*(sV
-. as b1 (``\\*(tNANSI C\\*(aa'')
-. \}
-. \}
-. if "\\*(A\\n(aP"-ansiC-89" \{\
-. ie \\n(sT==1 \{\
-. ds b1 \&\\*(tNANSI \\*(aaX3.159-1989\\*(sV
-. as b1 (``\\*(tNANSI C\\*(aa'')
-. \}
-. el \{\
-. ds b1 \&\\*(tNANSI \\*(aaX3.159-1989\\*(sV
-. as b1 (``\\*(tNANSI C\\*(aa'')
-. \}
-. \}
-. if "\\*(A\\n(aP"-ieee754" \{\
-. ie \\n(sT==1 \{\
-. ds b1 \&\\*(tNIEEE Std\\*(aa754-1985
-. \}
-. el \{\
-. ds b1 \&\\*(tNIEEE Std\\*(aa754-1985
-. \}
-. \}
-. if "\\*(A\\n(aP"-iso8802-3" \{\
-. ie \\n(sT==1 \{\
-. ds b1 \&\\*(tNISO \\*(aa8802-3: 1989\\*(sV
-. \}
-. el \{\
-. ds b1 \&\\*(tNISO \\*(aa8802-3: 1989\\*(sV
-. \}
-. \}
-. ie \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. nR
-. \}
-. el .aZ
-.\}
-..
-.nr Db 0
-.de Db
-.ie \\n(.$==0 \{\
-. ie \\n(Db==0 \{\
-.tm DEBUGGING ON
-. nr Db 1
-. \}
-. el \{\
-.tm DEBUGGING OFF
-. nr Db 0
-. \}
-.\}
-.el \{\
-. if "\\$1"on" \{\
-.tm DEBUGGING ON
-. nr Db 1
-. \}
-. if "\\$1"off" \{\
-.tm DEBUGGING OFF
-. nr Db 0
-. \}
-.\}
-..
-.de aV
-.nr aC \\n(aC+1
-.ie "\\$1"|" \{\
-. if "\\*(mN"Op" .ds A\\n(aC \fR\\$1\fP
-. if "\\*(mN"Ar" .ds A\\n(aC \fR\\$1\fP
-. if "\\*(mN"Fl" .ds A\\n(aC \fR\\$1\fP
-. if "\\*(mN"Cm" .ds A\\n(aC \fR\\$1\fP
-. if "\\*(mN"It" .ds A\\n(aC \fR\\$1\fP
-.\}
-.el .ds A\\n(aC \\$1
-.aU \\n(aC
-.nr C\\n(aC \\n(aT
-.s\\n(aT
-.if \\n(Db \{\
-. if \\n(aT==1 .ds yU Executable
-. if \\n(aT==2 .ds yU String
-. if \\n(aT==3 .ds yU Closing Punctuation or suffix
-. if \\n(aT==4 .ds yU Opening Punctuation or prefix
-. if \\n(iN==1 \{\
-. br
-. nr iI \\n(.iu
-. in -\\n(iIu
-. if \\n(aC==1 \{\
-\&\fBDEBUG(argv) MACRO:\fP `.\\*(mN' \fBLine #:\fP \\n(.c
-. \}
-\&\t\fBArgc:\fP \\n(aC \fBArgv:\fP `\\*(A\\n(aC' \fBLength:\fP \\n(sW
-\&\t\fBSpace:\fP `\\*(S\\n(aC' \fBClass:\fP \\*(yU
-. \}
-. if \\n(iN==0 \{\
-. if \\n(aC==1 \{\
-. tm DEBUG(argv) MACRO: `.\\*(mN' Line #: \\n(.c
-. \}
-. tm \tArgc: \\n(aC Argv: `\\*(A\\n(aC' Length: \\n(sW
-. tm \tSpace: `\\*(S\\n(aC' Class: \\*(yU
-. \}
-.\}
-.ie \\n(.$==1 \{\
-. nr aP 0
-. ie \\n(dZ==1 \{\
-. if \\n(oM>1 .as b1 \\*(S0
-. \}
-. el \{\
-. if \\n(oM>0 \{\
-. if \\n(fC==0 .as b1 \\*(S0
-. \}
-. \}
-. ds S0 \\*(S\\n(aC
-. if \\n(Db \{\
-. if \\n(iN==1 \{\
-\&MACRO REQUEST: \t.\\*(mN \\*(A1 \\*(A2 \\*(A3 \\*(A4 \\*(A5 \\*(A6 \\*(A7 \\*(A8 \\*(A9
-. br
-. in \\n(iIu
-. \}
-. if \\n(iN==0 \{\
-.tm \tMACRO REQUEST: .\\*(mN \\*(A1 \\*(A2 \\*(A3 \\*(A4 \\*(A5 \\*(A6 \\*(A7 \\*(A8 \\*(A9
-. \}
-. \}
-.\}
-.el .aV \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de fV
-.nr aC \\n(aC+1
-.if "\\*(A\\n(aC"|" \{\
-. if "\\*(mN"Op" .ds A\\n(aC \fR\\*(A\\n(aC\fP
-. if "\\*(mN"Ar" .ds A\\n(aC \fR\\*(A\\n(aC\fP
-. if "\\*(mN"Fl" .ds A\\n(aC \fR\&\\*(A\\n(aC\fP
-. if "\\*(mN"Cm" .ds A\\n(aC \fR\\*(A\\n(aC\fP
-. if "\\*(mN"It" .ds A\\n(aC \fR\\*(A\\n(aC\fP
-.\}
-.aU \\n(aC
-.nr C\\n(aC \\n(aT
-.s\\n(aT
-.if \\n(Db \{\
-. if \\n(aT==1 .ds yU Executable
-. if \\n(aT==2 .ds yU String
-. if \\n(aT==3 .ds yU Closing Punctuation or suffix
-. if \\n(aT==4 .ds yU Opening Punctuation or prefix
-. if \\n(iN==1 \{\
-. br
-. nr iI \\n(.iu
-. in -\\n(iIu
-. if \\n(aC==1 \{\
-\&\fBDEBUG(fargv) MACRO:\fP `.\\*(mN' \fBLine #:\fP \\n(.c
-. \}
-\&\t\fBArgc:\fP \\n(aC \fBArgv:\fP `\\*(A\\n(aC' \fBLength:\fP \\n(sW
-\&\t\fBSpace:\fP `\\*(S\\n(aC' \fBClass:\fP \\*(yU
-. \}
-. if \\n(iN==0 \{\
-. if \\n(aC==1 \{\
-. tm DEBUG(fargv) MACRO: `.\\*(mN' Line #: \\n(.c
-. \}
-. tm \tArgc: \\n(aC Argv: `\\*(A\\n(aC' Length: \\n(sW
-. tm \tSpace: `\\*(S\\n(aC' Class: \\*(yU
-. \}
-.\}
-.ie \\n(fV==1 \{\
-. nr aP 0
-. ie \\n(dZ==1 \{\
-. if \\n(oM>1 .as b1 \\*(S0
-. \}
-. el \{\
-. if \\n(oM>0 \{\
-. if \\n(fC==0 .as b1 \\*(S0
-. \}
-. \}
-. ds S0 \\*(S\\n(aC
-. nr fV 0
-. if \\n(Db \{\
-. ie \\n(iN \{\
-\&\tMACRO REQUEST: .\\*(mN \\*(A1 \\*(A2 \\*(A3 \\*(A4 \\*(A5 \\*(A6 \\*(A7 \\*(A8 \\*(A9
-. br
-. in \\n(iIu
-. \}
-. el \{\
-.tm \tMACRO REQUEST: .\\*(mN \\*(A1 \\*(A2 \\*(A3 \\*(A4 \\*(A5 \\*(A6 \\*(A7 \\*(A8 \\*(A9
-. \}
-. \}
-.\}
-.el \{\
-. nr fV \\n(fV-1
-. fV
-.\}
-..
-.de aX
-.nr aP \\n(aP+1
-.as b1 \&\\*(A\\n(aP
-.ie \\n(fV==1 \{\
-. nr aP 0
-. nr fV 0
-.\}
-.el \{\
-. as b1 \&\\*(sV
-. nr fV \\n(fV-1
-. aX
-.\}
-..
-.de aI
-.ie \\n(aC<9 \{\
-. nr aC \\n(aC+1
-. ds A\\n(aC \\$1
-. nr C\\n(aC \\$2
-. s\\$2
-. ds xV S\\n(aC
-.\}
-.el \{\
-. tm Usage: Too many arguments (maximum of 8 accepted) (#\\n(.c)
-. tm \\*(A1 \\*(A2 \\*(A3 \\*(A4 \\*(A5 \\*(A6 \\*(A7 \\*(A8 \\*(A9
-.\}
-..
-.de aZ
-.pB
-.aY
-..
-.de aY
-.rm C0 C1 C2 C3 C4 C5 C6 C7 C8 C9
-.rm A0 A1 A2 A3 A4 A5 A6 A7 A8 A9
-.rm S1 S2 S3 S4 S5 S6 S7 S8 S9
-.nr aC 0
-.nr aP 0
-..
-.de pB
-.ie \\n(dZ==1 \{\
-. if \\n(oM==1 \{\&\\*(b1
-. rm S0
-. ds b1
-. \}
-. if \\n(oM==0 \{\
-. x2
-. \}
-.\}
-.el \{\
-. ie \\n(oM==0 \{\&\\*(b1
-. rm S0
-. ds b1
-. \}
-. el \{\
-. if ((\\n(sM==1)&(\\n(tP==0)) \{\
-. x1
-. \}
-. \}
-.\}
-.hy
-..
-.de x1
-.nr dZ \\n(dZ+1
-.ds b2 \\*(b1
-.ds b1
-.nr lK \\n(.c
-.ev 2
-.fi
-.di eB
-..
-.de x2
-.br
-.di
-.ev
-.ie (\\n(.c-\\n(lK>1) \{\
-. ds b0 \&\\*(eB\\
-. ds b1 \\*(b2\\*(b0\\*(b1
-.\}
-.el .ds b1 \\*(b2\\*(b1
-\&\\*(b1
-.rm eB b2 b0 b1
-.nr dZ \\n(dZ-1
-..
-.de Fl
-.as b1 \&\\*(fL
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 \{\
-. as b1 \&\|\-\|\fP\s0
-. pB
-. \}
-. el \{\
-. ds mN Fl
-. aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. \}
-.\}
-.if \\n(aC>0 \{\
-. ie (\\n(aC-\\n(aP)==0 \{\
-. as b1 \&\|\-\fP\s0
-. aZ
-. \}
-. el \{\
-. nr aP \\n(aP+1
-. ie \\n(C\\n(aP==1 \{\
-. as b1 \&\|\-\fP\s0
-. \\*(A\\n(aP
-. \}
-. el \{\
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. if \\n(C\\n(aP==3 \{\
-. as b1 \&\|\-\|
-. \}
-. fR
-. \}
-. \}
-.\}
-..
-.de fR
-.hy 0
-.nr jM \\n(C\\n(aP
-.ie \\n(jM==1 \{\
-. as b1 \&\fP\s0
-. \\*(A\\n(aP
-.\}
-.el \{\
-. nr jN \\n(aP
-. ie \\n(jM==2 \{\
-. ie !"\\*(A\\n(aP"\\*(Ba" \{\
-. ie !"\\*(A\\n(aP"\fR|\fP" \{\
-. ie "\\*(A\\n(aP"-" .as b1 \&\|\-\^\-\|
-. el .as b1 \&\|\-\\*(A\\n(aP
-. \}
-. el .as b1 \&\\*(A\\n(aP
-. \}
-. el .as b1 \&\\*(A\\n(aP
-. \}
-. el .as b1 \&\f\\n(cF\s\\n(cZ\\*(A\\n(aP\fP\s0
-. ie \\n(aC==\\n(aP \{\
-. if \\n(jM==4 .as b1 \&\|\-
-. as b1 \&\fP\s0
-. aZ
-. \}
-. el \{\
-. nr aP \\n(aP+1
-. ie ((\\n(C\\n(aP==3)&(\\n(C\\n(jN==4)) .as b1 \&\|\-
-. el .as b1 \&\\*(S\\n(jN
-. fR \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. \}
-.\}
-.rr jM jN
-..
-.de nR
-.hy 0
-.nr jM \\n(C\\n(aP
-.ie \\n(jM==1 \{\
-. as b1 \&\f\\n(cF\s\\n(cZ
-. \\*(A\\n(aP
-.\}
-.el \{\
-. nr jN \\n(aP
-. ie \\n(jM==2 .as b1 \&\\*(A\\n(aP
-. el .as b1 \&\f\\n(cF\s\\n(cZ\\*(A\\n(aP\fP\s0
-. ie \\n(aC==\\n(aP \{\
-. as b1 \&\f\\n(cF\s\\n(cZ
-. aZ
-. \}
-. el \{\
-. nr aP \\n(aP+1
-. as b1 \&\\*(S\\n(jN
-. nR
-. \}
-.\}
-.rr jM jN
-..
-.de Ar
-.as b1 \\*(aR
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 \{\
-. as b1 file\ ...\fP\s0
-. pB
-. \}
-. el \{\
-. ds mN Ar
-. aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. \}
-.\}
-.if \\n(aC>0 \{\
-. ie (\\n(aC-\\n(aP)==0 \{\
-. as b1 \&file\ ...\fP\s0
-. aZ
-. \}
-. el \{\
-. nr aP \\n(aP+1
-. ie \\n(C\\n(aP==1 \{\
-. as b1 \&file\ ...\fP\s0
-. \\*(A\\n(aP
-. \}
-. el \{\
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. if \\n(C\\n(aP==3 \{\
-. as b1 \&file\ ...
-. \}
-. nR
-. \}
-. \}
-.\}
-..
-.de Ad
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .Ad address ... \\*(Pu (#\\n(.c)
-. el \{\
-. ds mN Ad
-. aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. as b1 \\*(aD
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. nR
-.\}
-..
-.de Cd
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .Cd Configuration file declaration (#\\n(.c)
-. el \{\
-. ds mN Cd
-. ds A1 \\$1
-. ds A2 \\$2
-. ds A3 \\$3
-. ds A4 \\$4
-. ds A5 \\$5
-. ds A6 \\$6
-. ds A7 \\$7
-. ds A8 \\$8
-. ds A9 \\$9
-. nr fV \\n(.$
-. fV
-. \}
-.\}
-.br
-.if \\n(aC>\\n(aP \{\
-. as b1 \\*(nM
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. ie \\n(nS \{\
-. if "\\*(mN"Cd" \{\
-. rs
-. ie \\n(nS>1 .br
-. el \{\
-. if \\n(iS==0 .nr iS \\n(Dsu
-. \}
-. in +\\n(iSu
-. ti -\\n(iSu
-. nr nS \\n(nS+1
-. \}
-. nR
-. in -\\n(iSu
-. \}
-. el .nR
-.\}
-..
-.de Cm
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .Cm Interactive command modifier ... \\*(Pu (#\\n(.c)
-. el \{\
-. ds mN Cm
-. ds A1 \\$1
-. ds A2 \\$2
-. ds A3 \\$3
-. ds A4 \\$4
-. ds A5 \\$5
-. ds A6 \\$6
-. ds A7 \\$7
-. ds A8 \\$8
-. ds A9 \\$9
-. nr fV \\n(.$
-. fV
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. as b1 \\*(cM
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. nR
-.\}
-..
-.de Dv
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .Dv define_variable ... \\*(Pu (#\\n(.c)
-. el \{\
-. ds mN Dv
-. aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. as b1 \\*(eR
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. nR
-.\}
-..
-.de Em
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 \{\
-. tm Usage: .Em text ... \\*(Pu (#\\n(.c)
-. \}
-. el \{\
-. ds mN Em
-. ds A1 \\$1
-. ds A2 \\$2
-. ds A3 \\$3
-. ds A4 \\$4
-. ds A5 \\$5
-. ds A6 \\$6
-. ds A7 \\$7
-. ds A8 \\$8
-. ds A9 \\$9
-. nr fV \\n(.$
-. fV
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. as b1 \\*(eM
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. nR
-.\}
-..
-.de Er
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .Er ERRNOTYPE ... \\*(Pu (#\\n(.c)
-. el \{\
-. ds mN Er
-. aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. as b1 \\*(eR
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. nR
-.\}
-..
-.de Ev
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .Ev ENVIRONMENT_VARIABLE ... \\*(Pu (#\\n(.c)
-. el \{\
-. ds mN Ev
-. aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. as b1 \\*(eV
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. nR
-.\}
-..
-.de Fd
-.ds mN Fd
-.if \\n(nS>0 \{\
-. if \\n(fX>0 \{\
-. Pp
-. nr fX 0
-. \}
-. if \\n(fZ>0 \{\
-. ie \\n(fD==0 \{\
-. Pp
-. rs
-. \}
-. el .br
-. \}
-. nr fD \\n(fD+1
-.\}
-.nr cF \\n(.f
-.nr cZ \\n(.s
-\&\\*(fD\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-.br
-.ft \\n(cF
-.fs \\n(cZ
-..
-.de Fr
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .Fr Function_return_value... \\*(Pu (#\\n(.c)
-. el \{\
-. ds mN Fr
-. aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. as b1 \\*(aR
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. nR
-.\}
-..
-.de Ic
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .Ic Interactive command ... \\*(Pu (#\\n(.c)
-. el \{\
-. ds mN Ic
-. aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. as b1 \\*(iC
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. nR
-.\}
-..
-.de Li
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage .Li argument ... \\*(Pu (#\\n(.c)
-. el \{\
-. ds mN Li
-. ds A1 \\$1
-. ds A2 \\$2
-. ds A3 \\$3
-. ds A4 \\$4
-. ds A5 \\$5
-. ds A6 \\$6
-. ds A7 \\$7
-. ds A8 \\$8
-. ds A9 \\$9
-. nr fV \\n(.$
-. fV
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. as b1 \\*(lI
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. nR
-.\}
-..
-.de Or
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .Or ... \\*(Pu (#\\n(.c)
-. el \{\
-. ds mN Or
-. aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. as b1 \\*(iC
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. nR
-.\}
-..
-.de Ms
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .Ms Math symbol ... \\*(Pu (#\\n(.c)
-. el \{\
-. ds mN Ms
-. aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. as b1 \\*(sY
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. nR
-.\}
-..
-.de Nm
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 \{\
-. ie "\\*(n1"" .tm Usage: .Nm Name(s) ... \\*(Pu (#\\n(.c)
-. el \&\\*(nM\\*(n1\fP\s0
-. \}
-. el \{\
-. ds mN Nm
-. ds A1 \\$1
-. ds A2 \\$2
-. ds A3 \\$3
-. ds A4 \\$4
-. ds A5 \\$5
-. ds A6 \\$6
-. ds A7 \\$7
-. ds A8 \\$8
-. ds A9 \\$9
-. nr fV \\n(.$
-. fV
-. \}
-.\}
-.if \\n(aC>0 \{\
-. ie \\n(aC==\\n(aP \{\
-. as b1 \&\\*(nM\\*(n1\fP\s0
-. aZ
-. \}
-. el \{\
-. as b1 \\*(nM
-. nr aP \\n(aP+1
-. ie \\n(C\\n(aP==1 \{\
-. as b1 \&\\*(n1\fP\s0
-. \\*(A\\n(aP
-. \}
-. el \{\
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. if \\n(nS \{\
-. if "\\*(mN"Nm" \{\
-. rs
-. in -\\n(iSu
-. ie \\n(nS>1 .br
-. el \{\
-. if \\n(iS==0 \{\
-. sw \\$1
-. nr iS ((\\n(sWu+1)*\\n(fW)u
-. \}
-. \}
-. in +\\n(iSu
-. ti -\\n(iSu
-. nr nS \\n(nS+1
-. \}
-. \}
-. if "\\*(n1"" .ds n1 \\*(A\\n(aP
-. nR
-. \}
-. \}
-.\}
-..
-.de Pa
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 \&\\*(pA~\fP\s0
-. el \{\
-. ds mN Pa
-. aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. as b1 \\*(pA
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. nR
-.\}
-..
-.de Sy
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .Sy symbolic_text ... \\*(Pu (#\\n(.c)
-. el \{\
-. ds mN Sy
-. ds A1 \\$1
-. ds A2 \\$2
-. ds A3 \\$3
-. ds A4 \\$4
-. ds A5 \\$5
-. ds A6 \\$6
-. ds A7 \\$7
-. ds A8 \\$8
-. ds A9 \\$9
-. nr fV \\n(.$
-. fV
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. as b1 \\*(sY
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. nR
-.\}
-..
-.de Tn
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .Tn Trade_name(s) ... \\*(Pu (#\\n(.c)
-. el \{\
-. ds mN Tn
-. aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. as b1 \\*(tN\\*(tF
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. nR
-.\}
-..
-.de nN
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .Tn Trade_name(s) ... \\*(Pu (#\\n(.c)
-. el \{\
-. ds mN Tn
-. aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. as b1 \\*(tN
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. rR
-.\}
-..
-.de Va
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .Va variable_name(s) ... \\*(Pu (#\\n(.c)
-. el \{\
-. ds mN Va
-. aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. as b1 \\*(vA
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. nR
-.\}
-..
-.de No
-.as b1 \\*(nO
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .No must be called with arguments (#\\n(.c)
-. el \{\
-. ds mN No
-. aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. ie \\n(C\\n(aP==1 \{\
-. \\*(A\\n(aP
-. \}
-. el \{\
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. nR
-. \}
-.\}
-..
-.de Op
-.if \\n(aC==0 \{\
-. ds mN Op
-.\}
-.ds qL \&\\*(lB
-.ds qR \&\\*(rB
-.En \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
-..
-.de Aq
-.if \\n(aC==0 .ds mN Aq
-.ds qL \&<
-.ds qR \&>
-.En \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Bq
-.if \\n(aC==0 .ds mN Bq
-.ds qL \&\\*(lB
-.ds qR \&\\*(rB
-.En \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Dq
-.if \\n(aC==0 .ds mN Dq
-.ds qL \&\\*(Lq
-.ds qR \&\\*(Rq
-.En \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Eq
-.if \\n(aC==0 .ds mN Eq
-.ds qL \\$1
-.ds qR \\$2
-.En \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Pq
-.if \\n(aC==0 .ds mN Pq
-.ds qL \&\\*(lP
-.ds qR \&\\*(rP
-.En \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Qq
-.if \\n(aC==0 .ds mN Qq
-.ds qL \&\\*q
-.ds qR \&\\*q
-.En \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Sq
-.if \\n(aC==0 .ds mN Sq
-.ds qL \&\\*(sL
-.ds qR \&\\*(sR
-.En \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Es
-.if \\n(aC==0 \{\
-. ie \\n(.$>2 .aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. el \{\
-. ds qL \\$1
-. ds qR \\$2
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. ds qL \\*(A\\n(aP
-. nr aP \\n(aP+1
-. ds qR \\*(A\\n(aP
-. ie \\n(aC>\\n(aP .c\\n(C\\n(aP
-. el .aZ
-.\}
-..
-.de En
-.ie \\n(aC==0 \{\
-. ie \\n(.$==0 \{\
-. as b1 \&\\*(qL\\*(qR
-. pB
-. \}
-. el \{\
-. aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. as b1 \&\\*(qL
-. \}
-.\}
-.el \{\
-. as b1 \&\\*(qL
-.\}
-.if \\n(aC>0 \{\
-. ie (\\n(aC-\\n(aP)==0 \{\
-. as b1 \&\\*(qR
-. aZ
-. \}
-. el \{\
-. ie \\n(C\\n(aC==3 \{\
-. nr aJ \\n(aC-1
-. vR
-. nr aJ \\n(aJ+1
-. ds A\\n(aJ \&\\*(qR\\*(A\\n(aJ
-. nr aJ 0
-. \}
-. el .aI \&\\*(qR 3
-. nr aP \\n(aP+1
-. if \\n(C\\n(aP==1 .\\*(A\\n(aP
-. if \\n(C\\n(aP>1 \{\
-. nr aP \\n(aP-1
-. No
-. \}
-. \}
-.\}
-..
-.de vR
-.if \\n(C\\n(aJ==3 \{\
-. nr aJ \\n(aJ-1
-. vR
-.\}
-..
-.de Ao
-.if \\n(aC==0 .ds mN Ao
-.ds qL \&<
-.eO \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Ac
-.if \\n(aC==0 .ds mN Ac
-.ds qR \&>
-.eC \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Bo
-.if \\n(aC==0 .ds mN Bo
-.ds qL \&[
-.eO \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Bc
-.if \\n(aC==0 .ds mN Bc
-.ds qR \&]
-.eC \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Do
-.if \\n(aC==0 .ds mN Do
-.ds qL \&\\*(Lq
-.eO \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Dc
-.if \\n(aC==0 .ds mN Dc
-.ds qR \&\\*(Rq
-.eC \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Eo
-.if \\n(aC==0 .ds mN Eo
-.ds qL \\$1
-.eO \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Ec
-.if \\n(aC==0 .ds mN Ec
-.ds qR \\$1
-.eC \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Oo
-.if \\n(aC==0 .ds mN Oo
-.ds qL \&[
-.eO \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Oc
-.if \\n(aC==0 .ds mN Oc
-.ds qR \&]
-.eC \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Po
-.if \\n(aC==0 .ds mN Po
-.ds qL \&(
-.eO \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Pc
-.if \\n(aC==0 .ds mN Pc
-.ds qR \&)
-.eC \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Qo
-.if \\n(aC==0 .ds mN Qo
-.ds qL \&\\*q
-.eO \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Qc
-.if \\n(aC==0 .ds mN Qc
-.ds qR \&\\*q
-.eC \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de So
-.if \\n(aC==0 .ds mN So
-.ds qL \&\\*(sL
-.eO \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Sc
-.if \\n(aC==0 .ds mN Sc
-.ds qR \&\\*(sR
-.eC \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Xo
-.if \\n(aC==0 .ds mN Xo
-.ds qL
-.eO \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Xc
-.if \\n(aC==0 .ds mN Xc
-.ds qR
-.eC \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de eO
-.nr oM \\n(oM+1
-.ie \\n(aC==0 \{\
-. ie \\n(.$>0 \{\
-. aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. as b1 \\*(qL
-. \}
-. el \{\
-. as b1 \\*(qL
-. if (\\n(dZ==0)&(\\n(sM==1) \{\
-. nr dZ \\n(dZ+1
-. ds b2 \\*(b1
-. ds b1
-. nr lK \\n(.c
-. ev 2
-. fi
-. di eB
-. \}
-. \}
-.\}
-.el \{\
-. as b1 \\*(qL
-.\}
-.ie \\n(aC>0 \{\
-. if \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. ie \\n(C\\n(aP==1 .\\*(A\\n(aP
-. el \{\
-. nr aP \\n(aP-1
-. No
-. \}
-. \}
-. if \\n(aC==\\n(aP \{\
-. if \\n(tP==1 \{\
-. nr Xt 1
-. \}
-. aY
-. \}
-.\}
-.el \{\
-. if \\n(oM>1 .as b1 \\*(sV
-.\}
-..
-.de eC
-.nr oM \\n(oM-1
-.as b1 \\*(qR
-.if \\n(aC==0 \{\
-. ie \\n(.$>0 \{\
-. aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. \}
-. el \{\
-. ie "\\*(xB"" \{\
-. pB
-. \}
-. el \{\
-. pB
-.\\*(L\\n(lC
-. nr Xt 0
-. ds xB
-. \}
-. \}
-.\}
-.if \\n(aC>0 \{\
-. ie \\n(aC==\\n(aP \{\
-. ie \\n(oM==0 \{\
-. aZ
-. \}
-. el .aY
-. \}
-. el \{\
-. nr aa \\n(aP+1
-. if \\n(C\\n(aa==2 .as b1 \\*(S\\n(aC
-. rr aa
-. if \\n(tP>0 \{\
-. if \\n(Xt>0 .nr Xt \\n(Xt-1
-. \}
-. No
-. \}
-.\}
-..
-.de Pf
-.if \\n(aC==0 .ds mN Pf
-.ds qL \&\\$1
-.pF \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de pF
-.ie \\n(aC==0 \{\
-. as b1 \&\\*(qL
-. ie \\n(.$<2 \{\
-. tm Warning: Missing arguments - prefix .Pf)
-. pB
-. \}
-. el .aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-.\}
-.el \{\
-. ie (\\n(aC-\\n(aP)>1 \{\
-. nr aP \\n(aP+1
-. as b1 \&\\*(A\\n(aP
-. \}
-. el .tm Warning: .Pf: trailing prefix (#\\n(.c)
-.\}
-.if \\n(aC>0 \{\
-. ie (\\n(aC-\\n(aP)==0 .aZ
-. el \{\
-. nr aP \\n(aP+1
-. c\\n(C\\n(aP
-. \}
-.\}
-..
-.de Ns
-.if \\n(aC==0 \{\
-. ds mN Ns
-. ie \\n(.$>0 .aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. el .tm Usage: .Ns must be called with arguments (#\\n(.c)
-.\}
-.No
-..
-.de Ap
-.if \\n(aC==0 \{\
-. ds mN Ap
-. tm Usage: Ap "cannot be first request on a line (no .Ap)" (#\\n(.c)
-.\}
-.as b1 \&'
-.No
-..
-.de Hv
-.ds iV \\*(sV
-.ds sV \\*(hV
-..
-.de Sv
-.ds sV \\*(iV
-..
-.de Tv
-.ds sV \\*(tV
-..
-.nr sM 1
-.de Sm
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm "Usage: .Sm [off | on]" (#\\n(.c)
-. el \{\
-. ds mN Sm
-. aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. \}
-.\}
-.if \\n(aC>0 \{\
-. nr aP \\n(aP+1
-. if "\\*(A\\n(aP"on" \{\
-. ds sV \\*(iV
-. nr sM 1
-. \}
-. if "\\*(A\\n(aP"off" \{\
-. ds sV
-. rm S0 S1 S2 S3 S4 S5 S6 S7 S8 S9
-. nr sM 0
-. \}
-. ie \\n(aC>\\n(aP \{\
-. No
-. \}
-. el .aY
-.\}
-..
-.if \n(.g \{\
-.de aT
-.nr aT 0
-.ie \\n(sW>2:(\A'\\$1'==0) \{\
-. nr aT 2
-.\}
-.el \{\
-. if \\n(sW==1 \{\
-. ie \\n(z\\$1>2 \{\
-. nr aT \\n(z\\$1
-. \}
-. el .nr aT 2
-. \}
-. if \\n(sW==2 \{\
-. ie \\n(\\$1 \{\
-. nr aT 1
-. \}
-. el .nr aT 2
-. \}
-.\}
-..
-.de aU
-.nr aT 0
-.aW \\$1
-.ie \\n(sW>2:(\A'\\*(A\\$1'==0) .nr aT 2
-.el \{\
-. if \\n(sW==1 \{\
-. ie \\n(z\\*(A\\$1>2 \{\
-. nr aT \\n(z\\*(A\\$1
-. \}
-. el .nr aT 2
-. \}
-. if \\n(sW==2 \{\
-. ie (\\n(\\*(A\\$1) \{\
-. nr aT 1
-. \}
-. el .nr aT 2
-. \}
-.\}
-..
-.\}
-.if !\n(.g \{\
-.de aT
-.nr aT 0
-.ie \\n(sW>2 \{\
-. nr aT 2
-.\}
-.el \{\
-. if \\n(sW==1 \{\
-. ie \\n(z\\$1>2 \{\
-. nr aT \\n(z\\$1
-. \}
-. el .nr aT 2
-. \}
-. if \\n(sW==2 \{\
-. ie \\n(\\$1 \{\
-. nr aT 1
-. \}
-. el .nr aT 2
-. \}
-.\}
-..
-.de aU
-.nr aT 0
-.aW \\$1
-.ie \\n(sW>2 .nr aT 2
-.el \{\
-. if \\n(sW==1 \{\
-. ie \\n(z\\*(A\\$1>2 \{\
-. nr aT \\n(z\\*(A\\$1
-. \}
-. el .nr aT 2
-. \}
-. if \\n(sW==2 \{\
-. ie (\\n(\\*(A\\$1) \{\
-. nr aT 1
-. \}
-. el .nr aT 2
-. \}
-.\}
-..
-.\}
-.de s0
-.tm MDOC-ERROR: bogus type 0 (can't set space '\\*(A\\n(aC') (#\\n(.c)
-..
-.de s1
-.if \\n(\\*(A\\n(aC==3 \{\
-. nr xX \\n(aC-1
-. rm S\\n(xX
-. ds S\\n(aC \\*(sV
-.\}
-.if \\n(\\*(A\\n(aC==2 \{\
-. nr xX \\n(aC-1
-. ie "\\*(A\\n(aC"Nb" .ds S\\n(xX \\*(hV
-. el .rm S\\n(xX
-.\}
-..
-.de s2
-.ds S\\n(aC \\*(sV
-..
-.de s3
-.if \\n(aC>1 \{\
-. nr xX \\n(aC-1
-. rm S\\n(xX
-.\}
-.ds S\\n(aC \\*(sV
-..
-.de s4
-.nr aa 0
-..
-.de c0
-.tm MDOC-ERROR: bogus class 0 (can't determine '\\*(A\\n(aC') (#\\n(.c)
-..
-.de c1
-.\\*(A\\n(aP
-..
-.de c2
-.nr aP \\n(aP-1
-.No
-..
-.de c3
-.nr aP \\n(aP-1
-.No
-..
-.de c4
-.nr aP \\n(aP-1
-.No
-..
-.de y1
-.nr aa 1
-..
-.de y2
-.nr aa 1
-..
-.de y3
-.as b1 \\*(A\\n(aP
-.nr aP \\n(aP+1
-.n\\C\\n(aP
-..
-.de y4
-.as b1 \\*(A\\n(aP
-.nr aP \\n(aP+1
-.n\\C\\n(aP
-..
-.de Bf
-.ds mN Bf
-.ie \\n(.$>0 \{\
-. nr bF \\n(.f
-. nr bZ \\n(.s
-. if "\\$1"Em" \&\\*(eM\c
-. if "\\$1"Li" \&\\*(lI\c
-. if "\\$1"Sy" \&\\*(sY\c
-. if "\\$1"-emphasis" \&\\*(eM\c
-. if "\\$1"-literal" \&\\*(lI\c
-. if "\\$1"-symbolic" \&\\*(sY\c
-.\}
-.el .tm Usage .Bf [Em | emphasis | Li | literal | Sy | symbolic] (#\\n(.c)
-..
-.de Ef
-.ds mN Ef
-.ie \\n(.$>0 .tm Usage .Ef (does not take arguments) (#\\n(.c)
-.el \&\f\\n(bF\s\\n(bZ
-..
-.de Bk
-.ds mN Bk
-.ie \\n(.$==0 \{\
-.tm Usage: .Bk [-lines | -words] (#\\n(.c)
-.\}
-.el \{\
-. if !"\\*(kS"" .tm .Bk: nesting keeps not implemented yet. (#\\n(.c)
-. if "\\$1"-lines" .tm .Bd -lines: Not implemented yet. (#\\n(.c)
-. if "\\$1"-words" .Hv
-. ds kS \\$1
-.\}
-..
-.de Ek
-.ds mN Ek
-.ie \\n(.$>0 .tm Usage .Ek (does not take arguments) (#\\n(.c)
-.el \{\
-. if "\\*(kS"-lines" .tm .Bd -lines: Not implemented yet. (#\\n(.c)
-. if "\\*(kS"-words" .Sv
-. rm kS
-.\}
-..
-.de Bd
-.ds mN Bd
-.ie \\n(.$==0 \{\
-.tm Usage: .Bd [-literal | -filled | -ragged | -unfilled] [-offset [string]] [-compact] (#\\n(.c)
-.\}
-.el \{\
-. ds aa
-. nr bV 0
-. nr iD 0
-. nr dP \\n(dP+1
-. if "\\$1"-literal" \{\
-. nr iD \\n(iD+1
-. ds d\\n(dP dL
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. ie t \{\&\\*(lI
-' ta 9n 18n 27n 36n 45n 54n 63n 72n
-. \}
-. el \{\
-' ta 8n 16n 24n 32n 40n 48n 56n 64n 72n
-. \}
-. nf
-. \}
-. if "\\$1"-filled" \{\
-. nr iD \\n(iD+1
-. ds d\\n(dP dF
-. br
-. \}
-. if "\\$1"-ragged" \{\
-. nr iD \\n(iD+1
-. ds d\\n(dP dR
-. na
-. \}
-. if "\\$1"-unfilled" \{\
-. nr iD \\n(iD+1
-. ds d\\n(dP dU
-. nf
-. \}
-. if ((\\n(iD>=1)&(\\n(.$>\\n(iD)) \{\
-. bV \\$2 \\$3 \\$4
-. \}
-. if \\n(O\\n(dP>0 'in \\n(.iu+\\n(O\\n(dPu
-. if (\\n(bV==0) \{\
-. if (\\n(nS==0) \{\
-. ie "\\*(d\\n(dP"dR" .sp \\n(dVu
-. el 'sp \\n(dVu
-. \}
-. \}
-. if \\n(cR==0 .ne 2v
-. nr bV 0
-. nr iD 0
-.\}
-..
-.de bV
-.nr iD 1
-.ds bY
-.if "\\$1"-offset" \{\
-. ds bY \\$2
-. if "\\*(bY"left" \{\
-. nr iD \\n(iD+1
-. nr O\\n(dP 0
-. \}
-. if "\\*(bY"right" \{\
-. nr iD \\n(iD+1
-. nr O\\n(dP (\\n(.l/3)u
-. \}
-. if "\\*(bY"center" \{\
-. nr iD \\n(iD+1
-. nr O\\n(dP (\\n(.l-\\n(.i)/4u
-. \}
-. if "\\*(bY"indent" \{\
-. nr iD \\n(iD+1
-. nr O\\n(dP \\n(dIu
-. \}
-. if "\\*(bY"indent-two" \{\
-. nr iD \\n(iD+1
-. nr O\\n(dP \\n(dIu+\\n(dIu
-. \}
-. if \\n(iD==1 \{\
-. nr iD \\n(iD+1
-. sW "\\*(bY"
-. ie \\n(sW>2 \{\
-. ie ((\\*(bY>9n)&(\\*(bY<100n)) \{\
-. nr O\\n(dP \\*(bY
-. \}
-. el .nr O\\n(dP (\\n(sW)*\\n(fWu
-. \}
-. el \{\
-. if \\n(sW==2 .aT \\*(bY
-. ie \\n(aT==1 \{\
-. nr O\\n(dP \\n(\\*(bY
-. \}
-. el .nr O\\n(dP \\*(bY
-. \}
-. \}
-.\}
-.if "\\$1"-compact" \{\
-. nr bV 1
-.\}
-.if \\n(iD<\\n(.$ \{\
-. ie "\\*(bY"" \{\
-. bV \\$2 \\$3
-. \}
-. el \{\
-. bV \\$3
-. \}
-.\}
-..
-.de Ed
-.ds mN Ed
-.br
-.if \\n(dP==0 .tm mdoc: Extraneous .Ed
-.if "\\*(d\\n(dP"dL" \{\
-. ft \\n(cF
-. fz \\n(cZ
-.\}
-.in \\n(.iu-\\n(O\\n(dPu
-.rr O\\n(dP
-.rm d\\n(dP
-.nr dP \\n(dP-1
-.fi
-.if t .ad
-..
-.de Bl
-.ie \\n(.$==0 \{\
-.tm Usage: .Bl [[-hang | -tag] [-width]] [ -item | -enum | -bullet | -diag] (#\\n(.c)
-.\}
-.el \{\
-. ds mN Bl
-. nr aP 0
-. nr lC \\n(lC+1
-. ds A1 \\$2
-. ds A2 \\$3
-. ds A3 \\$4
-. ds A4 \\$5
-. ds A5 \\$6
-. ds A6 \\$7
-. ds A7 \\$8
-. ds A8 \\$9
-. nr fV \\n(.$-1
-. if "\\$1"-hang" \{\
-. nr aP \\n(aP+1
-. ds L\\n(lC hL
-. nr w\\n(lC 6n
-. nr tC 1
-. \}
-. if "\\$1"-tag" \{\
-. nr aP \\n(aP+1
-. ds L\\n(lC tL
-. nr tC 1
-. \}
-. if "\\$1"-item" \{\
-. nr aP \\n(aP+1
-. ds L\\n(lC iT
-. nr tC 1
-. \}
-. if "\\$1"-enum" \{\
-. nr aP \\n(aP+1
-. ds L\\n(lC nU
-. nr w\\n(lC 3n
-. nr tC 1
-. \}
-. if "\\$1"-bullet" \{\
-. nr aP \\n(aP+1
-. ds L\\n(lC bU
-. nr w\\n(lC 2n
-. nr tC 1
-. \}
-. if "\\$1"-dash" \{\
-. nr aP \\n(aP+1
-. ds L\\n(lC hU
-. nr w\\n(lC 2n
-. nr tC 1
-. \}
-. if "\\$1"-hyphen" \{\
-. nr aP \\n(aP+1
-. ds L\\n(lC hU
-. nr w\\n(lC 2n
-. nr tC 1
-. \}
-. if "\\$1"-inset" \{\
-. nr aP \\n(aP+1
-. ds L\\n(lC lL
-. nr tC 1
-. \}
-. if "\\$1"-diag" \{\
-. nr aP \\n(aP+1
-. ds L\\n(lC mL
-. nr mL 1
-. \}
-. if "\\$1"-ohang" \{\
-. nr aP \\n(aP+1
-. ds L\\n(lC oL
-. nr tC 1
-. \}
-. if "\\$1"-column" \{\
-. nr aP \\n(aP+1
-. ds L\\n(lC cL
-. \}
-. ie \\n(aP==0 \{\
-. tm \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. tm Usage: .Bl [[-inset|-tag] -width] [-item|-enum|-bullet|-diag] (#\\n(.c)
-. \}
-. el \{\
-. tY
-. if (\\n(aP==1)&(\\n(aP<\\n(.$) \{\
-. nr aP 0
-. lV
-. if "\\*(L\\n(lC"cL" \{\
-. W\\n(wV
-. nr w\\n(lC 0
-' in -\\n(eWu
-. ie \\n(v\\n(lC==1 \{\
-. nr aa 0
-. \}
-. el \{\
-. sp \\n(dVu
-. \}
-. nf
-. nr wV 0
-. \}
-. \}
-. \}
-. nr aP 0
-. aY
-.\}
-..
-.if \n(.g \{\
-. nr i 10
-. while \ni<100 \{\
-. nr num!\nin 1
-. nr i +1
-. \}
-.\}
-.de lV
-.nr aP \\n(aP+1
-.if \\n(fV>=\\n(aP \{\
-. nr iD 0
-. if "\\*(A\\n(aP"-compact" \{\
-. nr iD 1
-. nr v\\n(lC 1
-. \}
-. if "\\*(A\\n(aP"-width" \{\
-. nr iD 1
-. nr aP \\n(aP+1
-. nr tW 1
-. ds t\\n(lC TagwidtH
-. ds tS \\*(A\\n(aP
-. aW \\n(aP
-. ie \\n(sW>2 \{\
-. nr w\\n(lC (\\n(sW)*\\n(fWu
-. if \\n(sW==3 \{\
-. ie \\n(.g \{\
-. if \A'\\*(tS' .if r num!\\*(tS \{\
-. nr w\\n(lC \\*(tS
-. \}
-. \}
-. el \{\
-. if (\\*(tS>9n)&(\\*(tS<99n) \{\
-. nr w\\n(lC \\*(tSu
-. \}
-. \}
-. \}
-. \}
-. el \{\
-. aT \\*(tS
-. ie \\n(aT==1 \{\
-. nr w\\n(lC \\n(\\*(tS
-. \}
-. el \{\
-. nr w\\n(lC \\*(tSu
-. \}
-. \}
-. \}
-. if "\\*(A\\n(aP"-offset" \{\
-. nr iD 1
-. nr aP \\n(aP+1
-. ie "\\*(A\\n(aP"indent" \{\
-. nr o\\n(lC \\n(Dsu
-. \}
-. el \{\
-. ds tS \\*(A\\n(aP
-. aW \\n(aP
-. ie \\n(sW>2 \{\
-. nr o\\n(lC (\\n(sW)*\\n(fWu
-. ie \\n(.g \{\
-. if \A'\\*(tS' .if r num!\\*(tS \{\
-. nr o\\n(lC \\*(tS
-. \}
-. \}
-. el \{\
-. if (\\*(tS>9n)&(\\*(tS<100n) \{\
-. nr o\\n(lC \\*(tS
-. \}
-. \}
-. \}
-. el \{\
-. ie \\n(C\\n(aP==1 .nr o\\n(lC \\n(\\*(tS
-. el .nr o\\n(lC \\*(tS
-. \}
-. \}
-. \}
-. if \\n(iD==0 \{\
-. if "\\*(L\\n(lC"cL" \{\
-. nr wV \\n(wV+1
-. ds A\\n(wV \\*(A\\n(aP
-. \}
-. \}
-. if \\n(fV>\\n(aP .lV
-.\}
-..
-.de El
-.ie \\n(.$>0 \{\
-. tm Usage: .El (#\\n(.c)
-.\}
-.el \{\
-. ds mN El
-. nr iD 0
-. if "\\*(L\\n(lC"cL" \{\
-. nr iD 1
-. cC
-. \}
-. if "\\*(L\\n(lC"nU" \{\
-. nr nU 0
-. \}
-. if \\n(mL>0 \{\
-. nr iD 1
-. nr mL 0
-. tZ
-. nr lC \\n(lC-1
-. tY
-. \}
-. if "\\*(L\\n(lC"iT" \{\
-' in \\n(.iu-\\n(o\\n(lCu
-. tZ
-. nr lC \\n(lC-1
-. tY
-. nr iD 1
-. \}
-. if "\\*(L\\n(lC"oL" \{\
-' in \\n(.iu-\\n(o\\n(lCu
-. tZ
-. nr lC \\n(lC-1
-. tY
-. nr iD 1
-. \}
-. if "\\*(L\\n(lC"lL" \{\
-' in \\n(.iu-\\n(o\\n(lCu
-. tZ
-. nr lC \\n(lC-1
-. tY
-. nr iD 1
-. \}
-. if \\n(iD==0 \{\
-. lE
-. \}
-. br
-. nr iD 0
-.\}
-..
-.de It
-.if "\\*(L\\n(lC"" \{\
-. tm Usage .Bl -list-type [-width [string] | -compact | -offset [string]] (#\\n(.c)
-. tm .It \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
-.\}
-.ne 3v
-.ie \\n(.$>0 \{\
-. ds mN It
-. ds b1
-. nr iD 0
-. ds A1 \\$1
-. ds A2 \\$2
-. ds A3 \\$3
-. ds A4 \\$4
-. ds A5 \\$5
-. ds A6 \\$6
-. ds A7 \\$7
-. ds A8 \\$8
-. ds A9 \\$9
-. nr fV \\n(.$
-. if "\\*(L\\n(lC"mL" \{\
-. nr iD 1
-. nr aP 0
-. aX
-. \\*(L\\n(lC
-. \}
-. if "\\*(L\\n(lC"cL" \{\
-. ds b1
-. nr aP 0
-. nr iD 1
-. \\*(L\\n(lC
-. \}
-. if "\\*(L\\n(lC"iT" \{\
-. nr aP 0
-. nr iD 1
-. \\*(L\\n(lC
-. \}
-. if \\n(iD==0 \{\
-. fV
-. nr oM \\n(oM+1
-. nr tP 1
-. nr aP \\n(aP+1
-. nr tX \\n(C\\n(aP
-. ds tX \\*(A\\n(aP
-. if \\n(nF==1 \{\
-. ds aA \\*(pA
-. if n .ds pA \\*(nO
-. \}
-. ie \\n(C\\n(aP==1 \{\
-. \\*(A\\n(aP
-. \}
-. el \{\
-. nr aP \\n(aP-1
-. No
-. \}
-. ie \\n(Xt==1 .ds xB \&\\*(L\\n(lC
-. el .\\*(L\\n(lC
-. \}
-. nr iD 0
-.\}
-.el .\\*(L\\n(lC
-..
-.de lL
-.lY
-.br
-\&\\*(b1
-.nr oM \\n(oM-1
-.nr tP 0
-.ds b1
-.aY
-'fi
-..
-.de hL
-.lX
-.nr bb \\n(w\\n(lCu+\\n(lSu
-.ti -\\n(bbu
-.ie \w\a\\*(b1\au>=(\\n(w\\n(lCu) \&\\*(b1
-.el \&\\*(b1\h'|\\n(bbu'\c
-.nr oM \\n(oM-1
-.ds b1
-.nr tP 0
-.aY
-'fi
-..
-.de oL
-.lY
-\&\\*(b1
-.br
-.nr oM \\n(oM-1
-.ds b1
-.nr tP 0
-.aY
-'fi
-..
-.de iT
-.lY
-.br
-.aY
-'fi
-..
-.de nU
-.nr oM \\n(oM+1
-.nr nU \\n(nU+1
-.ds b1 \&\\n(nU.
-.uL
-..
-.de bU
-.nr oM \\n(oM+1
-.nr bU \\n(bU+1
-.ds b1 \&\\*(sY\&\(bu\fP
-.uL
-..
-.de hU
-.nr oM \\n(oM+1
-.nr bU \\n(bU+1
-.ds b1 \&\\*(sY\&\-\fP
-.uL
-..
-.de uL
-.lX
-.nr bb \\n(w\\n(lCu+\\n(lSu
-.ti -\\n(bbu
-.ie \w\a\\*(b1\au>=(\\n(w\\n(lCu) \&\\*(b1
-.el \&\\*(b1\h'|\\n(bbu'\c
-.nr oM \\n(oM-1
-.ds b1
-.nr tP 0
-.aY
-'fi
-..
-.de mL
-.nr cF \\n(.f
-.nr cZ \\n(.s
-.ie \\n(mL==1 \{\
-. nr zB \\n(.c
-. ie (\\n(zB-\\n(zA)>1 .Pp
-. el .br
-. nr zA \\n(zB
-. nr zB 0
-.\}
-.el \{\
-. nr zA \\n(.c
-. br
-.\}
-\&\\*(sY\\*(b1\f\\n(cF\s\\n(cZ\\*(lS\c
-.aY
-.ds b1
-'fi
-..
-.de tL
-.if \\n(tW==0 .lW
-.lX
-.nr bb \\n(w\\n(lCu+\\n(lSu
-.ti -\\n(bbu
-.ie (\w\a\\*(b1\au)>(\\n(w\\n(lCu) \{\&\\*(b1
-. br
-.\}
-.el \&\\*(b1\h'|\\n(bbu'\c
-.if \\n(nF==1 \{\
-. if n .ds pA \\*(aA
-.\}
-.nr oM \\n(oM-1
-.nr tP 0
-.ds b1
-.aY
-'fi
-..
-.de lW
-.if !"TagwidtH"\\*(t\\n(lC" \{\
-. ie \\n(tX==1 \{\
-. ds t\\n(lN \\*(tX
-. nr w\\n(lN \\n(\\*(tX
-. \}
-. el \{\
-. ds t\\n(lN No
-. nr w\\n(lN \\n(No
-. \}
-. if !"\\*(t\\n(lC"\\*(t\\n(lN" .nr tC 1
-.\}
-..
-.de lX
-.ie \\n(tC \{\
-. nr tC 0
-. nr tW 0
-. if \\n(v\\n(lC==0 .sp \\n(dVu
-. in \\n(.iu+\\n(w\\n(lCu+\\n(o\\n(lCu+\\n(lSu
-.\}
-.el \{\
-. ie \\n(v\\n(lC==1 \{\
-. nr aa 0
-. \}
-. el \{\
-. sp \\n(dVu
-. \}
-.\}
-.if !\\n(cR .ne 2v
-..
-.de lY
-.ie \\n(tC \{\
-. nr tC 0
-. nr tW 0
-. if \\n(v\\n(lC==0 .sp \\n(dVu
-. in \\n(.iu+\\n(o\\n(lCu
-.\}
-.el \{\
-. ie \\n(v\\n(lC==1 \{\
-. nr aa 0
-. \}
-. el \{\
-. sp \\n(dVu
-. \}
-.\}
-.if !\\n(cR .ne 2v
-..
-.nr lC 0
-.nr wV 0
-.nr w1 0
-.nr o1 0
-.nr v1 0
-.nr h1 0
-.ds t\n(lC
-.de lE
-.ie \\n(o\\n(lC>0 \{\
-' in \\n(.iu-(\\n(w\\n(lCu)-(\\n(o\\n(lCu)-\\n(lSu
-. rr o\\n(lC
-.\}
-.el 'in \\n(.iu-\\n(w\\n(lCu-\\n(lSu
-.if \\n(lC<=0 .tm Extraneous .El call (#\\n(.c)
-.tZ
-.nr lC \\n(lC-1
-.tY
-..
-.de tY
-.nr tY (\\n(lC+1)
-.nr w\\n(tY 0
-.nr h\\n(tY 0
-.nr o\\n(tY 0
-.ds t\\n(tY \\*(t\\n(lC
-.ds L\\n(tY
-.nr v\\n(tY 0
-..
-.de tZ
-.rm L\\n(tY
-.rr w\\n(tY
-.rr h\\n(tY
-.rr o\\n(tY
-.rm t\\n(tY
-.rr v\\n(tY
-.nr tY \\n(tY-1
-..
-.nr w1 0
-.nr o1 0
-.nr h1 0
-.ds t1
-.nr v1 0
-.nr tY 1
-.de Xr
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .Xr manpage_name [section#] \\*(Pu (#\\n(.c)
-. el \{\
-. ds mN Xr
-. aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. ie \\n(C\\n(aP==1 .tm Usage: .Xr manpage_name [section#] \\*(Pu (#\\n(.c)
-. el \{\
-. ie \\n(C\\n(aP>2 .y\\n(C\\n(aP
-. el \{\
-. as b1 \&\\*(xR\\*(A\\n(aP\fP\s0
-. if \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. if \\n(C\\n(aP==2 \{\
-. as b1 \&(\\*(A\\n(aP)
-. nr aP \\n(aP+1
-. \}
-. if \\n(aC>=\\n(aP \{\
-. c\\n(C\\n(aP
-. \}
-. \}
-. \}
-. aZ
-. \}
-.\}
-..
-.de Sx
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Sx Usage: .Sx Section Header \\*(Pu (#\\n(.c)
-. el \{\
-. ds mN Sx
-. aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. \}
-.\}
-.\}
-.if \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. as b1 \\*(sX
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. nR
-.\}
-..
-.de cC
-'in \\n(.iu-\\n(o\\n(lCu-\\n(w\\n(lCu
-.ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i
-.fi
-.tZ
-.nr lC \\n(lC-1
-.tY
-..
-.de W1
-.ta \w\a\\*(A1 \au
-.nr eW \w\a\\*(A1 \au
-'in \\n(.iu+\\n(eWu+\\n(o\\n(lCu
-..
-.de W2
-.ta \w\a\\*(A1 \au +\w\a\\*(A2 \au
-.nr eW \w\a\\*(A1 \au+\w\a\\*(A2 \au
-'in \\n(.iu+\\n(eWu+\\n(o\\n(lCu
-..
-.de W3
-.ta \w\a\\*(A1 \au +\w\a\\*(A2 \au +\w\a\\*(A3 \au
-.nr eW \w\a\\*(A1 \au+\w\a\\*(A2 \au+\w\a\\*(A3 \au
-'in \\n(.iu+\\n(eWu+\\n(o\\n(lCu
-..
-.de W4
-.ta \w\a\\*(A1 \au +\w\a\\*(A2 \au +\w\a\\*(A3 \au +\w\a\\*(A4 \au
-.nr eW \w\a\\*(A1 \au+\w\a\\*(A2 \au +\w\a\\*(A3 \au +\w\a\\*(A4 \au
-'in \\n(.iu+\\n(eWu+\\n(o\\n(lCu
-..
-.de W5
-.ta \w\a\\*(A1 \au +\w\a\\*(A2 \au +\w\a\\*(A3 \au +\w\a\\*(A4 \au +\w\a\\*(A5 \au
-.nr eW \w\a\\*(A1 \au +\w\a\\*(A2 \au +\w\a\\*(A3 \au +\w\a\\*(A4 \au +\w\a\\*(A5 \au
-' in \\n(.iu+\\n(eWu+\\n(o\\n(lCu
-..
-.de W6
-.ta \w\a\\*(A1 \au +\w\a\\*(A2 \au +\w\a\\*(A3 \au +\w\a\\*(A4 \au +\w\a\\*(A5 \au +\w\a\\*(A6
-.nr eW \w\a\\*(A1 \au +\w\a\\*(A2 \au +\w\a\\*(A3 \au +\w\a\\*(A4 \au +\w\a\\*(A5 \au +\w\a\\*(A6
-' in \\n(.iu+\\n(eWu+\\n(o\\n(lCu
-..
-.de cL
-.if \\n(w\\n(lC==0 .nr w\\n(lC \\n(eWu
-.if \\n(.u==0 \{\
-. fi
-' in \\n(.iu+\\n(eWu
-.\}
-.ti -\\n(eWu
-.fV
-.nr aP \\n(aP+1
-.ie \\n(aC>=\\n(aP \{\
-. if "\\*(A\\n(aP"Ta" \{\
-. nr jJ \\n(aP-1
-. rm S\\n(jJ
-. rr jJ
-. \}
-. c\\n(C\\n(aP
-.\}
-.el .tm Usage: .It column_string [Ta [column_string ...] ] (#\\n(.c)
-..
-.de Ta
-.ie \\n(aC>0 \{\
-. nr aP \\n(aP+1
-. ie \\n(aC>=\\n(aP \{\
-. if "\\*(A\\n(aP"Ta" \{\
-. nr jJ \\n(aP-1
-. rm S\\n(jJ
-. rr jJ
-. \}
-. as b1 \\t
-. c\\n(C\\n(aP
-. \}
-. el \{\
-. as b1 \\t\\c
-. rm S\\n(aP
-. pB
-. aY
-. \}
-.\}
-.el \{\
-. tm Usage: Ta must follow column entry: e.g. (#\\n(.c)
-. tm .It column_string [Ta [column_string ...] ]
-.\}
-..
-.de Dl
-'ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i
-.in \\n(.iu+\\n(Dsu
-.ie \\n(aC==0 \{\
-. ie \\n(.$==0 \{\
-. tm Usage: .Dl argument ... (#\\n(.c)
-. \}
-. el \{\
-. ds mN Dl
-. ds A1 \\$1
-. ds A2 \\$2
-. ds A3 \\$3
-. ds A4 \\$4
-. ds A5 \\$5
-. ds A6 \\$6
-. ds A7 \\$7
-. ds A8 \\$8
-. ds A9 \\$9
-. nr fV \\n(.$
-. fV
-. Li
-. \}
-.\}
-.el \{\
-. tm Usage: .Dl not callable by other macros (#\\n(.c)
-.\}
-.in \\n(.iu-\\n(Dsu
-..
-.de D1
-'ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i
-.in \\n(.iu+\\n(Dsu
-.ie \\n(aC==0 \{\
-. ie \\n(.$==0 \{\
-. tm Usage: .D1 argument ... (#\\n(.c)
-. \}
-. el \{\
-. ds mN D1
-. ds A1 \\$1
-. ds A2 \\$2
-. ds A3 \\$3
-. ds A4 \\$4
-. ds A5 \\$5
-. ds A6 \\$6
-. ds A7 \\$7
-. ds A8 \\$8
-. ds A9 \\$9
-. nr fV \\n(.$
-. fV
-. nr aP \\n(aP+1
-. ie \\n(C\\n(aP==1 .\\*(A\\n(aP
-. el .No
-. \}
-.\}
-.el \{\
-. tm Usage: .D1 not callable by other macros (#\\n(.c)
-.\}
-.in \\n(.iu-\\n(Dsu
-..
-.de Ex
-.tm Ex defunct, Use .D1: \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Ex
-.tm Ex defunct, Use .D1: \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-..
-.de Vt
-.if \\n(fD>0 \{\
-. Pp
-. nr fD 0
-.\}
-.if \\n(fZ>0 \{\
-. ie \\n(fX==0 \{\
-. Pp
-. rs
-. \}
-. el .br
-.\}
-.nr fX \\n(fX+1
-.nr cF \\n(.f
-.nr cZ \\n(.s
-\\*(fT\&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-.ie \\n(oT==0 .br
-.el \&\ \&
-.ft \\n(cF
-.fs \\n(cZ
-..
-.nr fZ 0
-.de Ft
-.if \\n(nS>0 \{\
-. if \\n(fZ>0 \{\
-. Pp
-. nr fD 0
-. nr fX 0
-. \}
-. if \\n(fD>0 \{\
-. Pp
-. nr fD 0
-. nr fX 0
-. \}
-. if \\n(fX>0 \{\
-. Pp
-. nr fX 0
-. \}
-. nr fY 1
-.\}
-.nr cF \\n(.f
-.nr cZ \\n(.s
-\&\\*(fT\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-.ft \\n(cF
-.fs \\n(cZ
-..
-.nr oT 0
-.de Ot
-.nr oT 1
-.if \\n(nS>0 \{\
-. if \\n(fZ>0 \{\
-. Pp
-. nr fD 0
-. nr fX 0
-. \}
-. if \\n(fD>0 \{\
-. Pp
-. nr fD 0
-. nr fX 0
-. \}
-. if \\n(fX>0 \{\
-. Pp
-. nr fX 0
-. \}
-. nr fY 1
-.\}
-.if \\n(.$==4 .as b1 \&\\*(fT\&\\$1 \\$2 \\$3 \\$4
-.if \\n(.$==3 .as b1 \&\\*(fT\&\\$1 \\$2 \\$3
-.if \\n(.$==2 .as b1 \&\\*(fT\&\\$1 \\$2
-.if \\n(.$==1 .as b1 \&\\*(fT\&\\$1
-.as b1 \&\ \fP
-..
-.de Fa
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .Fa Function Arguments ... \\*(Pu (#\\n(.c)
-. el \{\
-. ds mN Fa
-. ds A1 \\$1
-. ds A2 \\$2
-. ds A3 \\$3
-. ds A4 \\$4
-. ds A5 \\$5
-. ds A6 \\$6
-. ds A7 \\$7
-. ds A8 \\$8
-. ds A9 \\$9
-. nr fV \\n(.$
-. fV
-. \}
-.\}
-.ie \\n(fC>0 \{\
-. fC
-.\}
-.el \{\
-. if \\n(aC>\\n(aP \{\
-. as b1 \\*(fA
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. nR
-. if \\n(nS>0 \{\
-. if \\n(fZ>0 .br
-. \}
-. \}
-.\}
-..
-.de fC
-.ie \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. ds Fb
-. nr fB 0
-. nr Fb 0
-. fB \\*(A\\n(aP
-. if \\n(fB>1 \{\
-. rm A\\n(aP
-. rn Fb A\\n(aP
-. \}
-. if \\n(fC>1 \{\
-. as b1 \&\f\\n(cF\s\\n(cZ,\\*(S\\n(aP\\*(fA\\*(A\\n(aP\fP\s0
-. \}
-. if \\n(fC==1 \{\
-. as b1 \&\|\\*(fA\\*(A\\n(aP\fP\s0
-. \}
-. nr fC \\n(fC+1
-. fC
-.\}
-.el \{\
-. aY
-.\}
-..
-.de Fn
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .Fn function_name function_arg(s) ... \\*(Pu (#\\n(.c)
-. el \{\
-. ds mN Fn
-. ds A1 \\$1
-. ds A2 \\$2
-. ds A3 \\$3
-. ds A4 \\$4
-. ds A5 \\$5
-. ds A6 \\$6
-. ds A7 \\$7
-. ds A8 \\$8
-. ds A9 \\$9
-. nr fV \\n(.$
-. fV
-. \}
-.\}
-.if \\n(nS>0 \{\
-. if \\n(fY==0 \{\
-. if \\n(fZ>0 \{\
-. Pp
-. nr fX 0
-. nr fD 0
-. \}
-. \}
-. if \\n(fY==1 \{\
-. br
-. nr fX 0
-. nr fD 0
-. nr fY 0
-. \}
-. if \\n(fD>0 \{\
-. Pp
-. nr fX 0
-. \}
-. if \\n(fX>0 \{\
-. Pp
-. nr fD 0
-. \}
-. nr fZ \\n(fZ+1
-. nr fY 0
-. rs
-. ie \\n(nS>1 .br
-. el \{\
-. if \\n(iS==0 \{\
-. nr iS ((8)*\\n(fW)u
-. \}
-. \}
-. in +\\n(iSu
-. ti -\\n(iSu
-. nr nS \\n(nS+1
-.\}
-.if \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. as b1 \\*(fN\\*(A\\n(aP\fP\s0\\*(lp
-. ie \\n(aC>\\n(aP \{\
-. as b1 \\*(fA
-. nr aP \\n(aP+1
-. f\\n(C\\n(aP
-. \}
-. el \{\
-. as b1 \|\\*(rp
-. aZ
-. \}
-. if \\n(nS>0 \{\
-. in -\\n(iSu
-. \}
-.\}
-..
-.de f1
-.as b1 \\*(rp\f\\n(cF\s\\n(cZ
-.\\*(A\\n(aP
-..
-.de f2
-.if \\n(nS>0 \{\
-. ds Fb
-. nr fB 0
-. nr Fb 0
-. fB \\*(A\\n(aP
-. if \\n(fB>1 \{\
-. rm A\\n(aP
-. rn Fb A\\n(aP
-. \}
-.\}
-.as b1 \\*(A\\n(aP
-.ie \\n(aC>\\n(aP \{\
-. nr aa \\n(aP
-. nr aP \\n(aP+1
-. if \\n(C\\n(aP==2 \{\
-. as b1 \&\|\f\\n(cF\s\\n(cZ,\\*(S\\n(aa\fP\s0\|
-. \}
-. f\\n(C\\n(aP
-.\}
-.el \{\
-. as b1 \\*(rp\f\\n(cF\s\\n(cZ
-. aZ
-.\}
-..
-.de f3
-.as b1 \\*(rp\f\\n(cF\s\\n(cZ\\*(A\\n(aP
-.ie \\n(aC>\\n(aP \{\
-. No
-.\}
-.el .aZ
-..
-.de f4
-.as b1 \\*(rp\f\\n(cF\s\\n(cZ\\*(S\\n(aP\\*(A\\n(aP
-.ie \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. No
-.\}
-.el .aZ
-..
-.de Fo
-.hy 0
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .Fo function_name
-. el \{\
-. ds mN Fo
-. ds A1 \\$1
-. ds A2 \\$2
-. ds A3 \\$3
-. ds A4 \\$4
-. ds A5 \\$5
-. ds A6 \\$6
-. ds A7 \\$7
-. ds A8 \\$8
-. ds A9 \\$9
-. nr fV \\n(.$
-. fV
-. \}
-.\}
-.if \\n(nS>0 \{\
-. if \\n(fY==0 \{\
-. if \\n(fZ>0 \{\
-. Pp
-. nr fX 0
-. nr fD 0
-. \}
-. \}
-. if \\n(fY==1 \{\
-. br
-. nr fX 0
-. nr fD 0
-. nr fY 0
-. \}
-. if \\n(fD>0 \{\
-. Pp
-. nr fX 0
-. \}
-. if \\n(fX>0 \{\
-. Pp
-. nr fD 0
-. \}
-. nr fZ \\n(fZ+1
-. nr fY 0
-. rs
-. ie \\n(nS>1 .br
-. el \{\
-. if \\n(iS==0 \{\
-. nr iS ((8)*\\n(fW)u
-. \}
-. \}
-. in +\\n(iSu
-. ti -\\n(iSu
-. nr nS \\n(nS+1
-.\}
-.if \\n(aC>\\n(aP \{\
-. nr oM \\n(oM+1
-. nr fC 1
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. as b1 \\*(fN\\*(A\\n(aP\fP\s0\\*(lp
-. aY
-.\}
-..
-.de Fc
-.if \\n(aC==0 \{\
-. if \\n(.$>0 \{\
-. ds mN Fo
-. ds A1 \\$1
-. ds A2 \\$2
-. ds A3 \\$3
-. ds A4 \\$4
-. ds A5 \\$5
-. ds A6 \\$6
-. ds A7 \\$7
-. ds A8 \\$8
-. ds A9 \\$9
-. nr fV \\n(.$
-. fV
-. \}
-.\}
-.nr fC 0
-.nr oM \\n(oM-1
-.as b1 \|\\*(rp
-.ie \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. \\*(A\\n(aP
-.\}
-.el \{\
-. aZ
-.\}
-.if \\n(nS>0 \{\
-. in -\\n(iSu
-.\}
-.hy
-..
-.de fB
-.if \\n(fB==0 \{\
-. nr fB \\n(.$
-. nr Fb 0
-. ds Fb
-.\}
-.nr Fb \\n(Fb+1
-.as Fb \&\\$1
-.if \\n(Fb<\\n(fB \{\
-. as Fb \&\\*(hV
-. fB \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-.\}
-..
-.de Rs
-.nr rS 1
-.rC
-.if \\n(nA==1 .Pp
-.nr Kl 0
-..
-.de Re
-.rZ
-.rC
-.nr rS 0
-..
-.de rC
-.nr uK 0
-.nr jK 0
-.nr nK 0
-.nr oK 0
-.nr qK 0
-.nr rK 0
-.nr tK 0
-.nr vK 0
-.nr dK 0
-.nr pK 0
-.nr bK 0
-.ds rS
-.rm U1 U2 U3 U4 U5 U6 U7 U8
-.rm uK jK nK oK rK qK tK vK dK pK bK
-..
-.de rZ
-.if \\n(uK \{\&\\*(U1,
-. nr aK 1
-. if (\\n(uK>1 \{\
-. aK
-. \}
-. nr Kl -\\n(uK
-.\}
-.if \\n(tK \{\
-. nr Kl \\n(Kl-1
-. if \\n(Kl==0 \{\
-. ie (\\n(jK==1):(\\n(bK==1) \{\&\\*q\\*(tK\\*q.
-. \}
-. el \{\&\\*(eM\\*(tK\\*(nO.
-. \}
-. \}
-. if \\n(Kl>0 \{\
-. ie (\\n(jK==1):(\\n(bK==1) \{\&\\*q\\*(tK\\*q,
-. \}
-. el \{\&\\*(eM\\*(tK\\*(nO,
-. \}
-. \}
-.\}
-.if \\n(bK \{\
-. nr Kl \\n(Kl-1
-. if \\n(Kl==0 \&\\*(eM\\*(bK\\*(nO.
-. if \\n(Kl>0 \&\\*(eM\\*(bK\\*(nO,
-.\}
-.if \\n(jK \{\
-. nr Kl \\n(Kl-1
-. if \\n(Kl==0 \&\\*(eM\\*(jK\\*(nO.
-. if \\n(Kl>0 \&\\*(eM\\*(jK\\*(nO,
-.\}
-.if \\n(rK \{\
-. nr Kl \\n(Kl-1
-. if \\n(Kl==0 \&\\*(rK.
-. if \\n(Kl>0 \&\\*(rK,
-.\}
-.if \\n(nK \{\
-. nr Kl \\n(Kl-1
-. if \\n(Kl==0 \&\\*(nK.
-. if \\n(Kl>0 \&\\*(nK,
-.\}
-.if \\n(vK \{\
-. nr Kl \\n(Kl-1
-. if \\n(Kl==0 \&\\*(vK.
-. if \\n(Kl>0 \&\\*(vK,
-.\}
-.if \\n(pK \{\
-. nr Kl \\n(Kl-1
-. if \\n(Kl==0 \&\\*(pK.
-. if \\n(Kl>0 \&\\*(pK,
-.\}
-.if \\n(qK \{\
-. nr Kl \\n(Kl-1
-. if \\n(Kl==0 \&\\*(qK.
-. if \\n(Kl>0 \&\\*(qK,
-.\}
-.if \\n(dK \{\
-. nr Kl \\n(Kl-1
-. if \\n(Kl==0 \&\\*(dK.
-. if \\n(Kl>0 \&\\*(dK,
-.\}
-.if \\n(oK \{\
-. nr Kl \\n(Kl-1
-. if \\n(Kl==0 \&\\*(oK.
-. if \\n(Kl>0 \&\\*(oK,
-.\}
-.if \\n(Kl>0 .tm unresolved reference problem
-..
-.de aK
-.nr aK \\n(aK+1
-.ie (\\n(uK-\\n(aK)==0 \{\&and \\*(U\\n(aK,
-.\}
-.el \{\&\\*(U\\n(aK,
-. aK
-.\}
-..
-.de %A
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .%A Author_name (#\\n(.c)
-. el \{\
-. nr uK \\n(uK+1
-. nr Kl \\n(Kl+1
-. ds rS U\\n(uK
-. ds mN %A
-. aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. rR
-.\}
-..
-.de %B
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .%B Book Name (#\\n(.c)
-. el \{\
-. ds mN %B
-. if \\n(rS>0 \{\
-. nr bK \\n(bK+1
-. nr Kl \\n(Kl+1
-. ds rS bK
-. \}
-. ds A1 \\$1
-. ds A2 \\$2
-. ds A3 \\$3
-. ds A4 \\$4
-. ds A5 \\$5
-. ds A6 \\$6
-. ds A7 \\$7
-. ds A8 \\$8
-. ds A9 \\$9
-. nr fV \\n(.$
-. fV
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. ie \\n(rS==0 \{\
-. as b1 \&\\*(eM
-. nR
-. \}
-. el .rR
-.\}
-..
-.de %D
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .%D Date (#\\n(.c)
-. el \{\
-. ds mN %D
-. nr dK \\n(dK+1
-. nr Kl \\n(Kl+1
-. ds rS dK
-. ds A1 \\$1
-. ds A2 \\$2
-. ds A3 \\$3
-. ds A4 \\$4
-. ds A5 \\$5
-. ds A6 \\$6
-. ds A7 \\$7
-. ds A8 \\$8
-. ds A9 \\$9
-. nr fV \\n(.$
-. fV
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. rR
-.\}
-..
-.de %J
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .%J Journal Name (#\\n(.c)
-. el \{\
-. ds mN %J
-. nr jK \\n(jK+1
-. ds rS jK
-. nr Kl \\n(Kl+1
-. ds A1 \\$1
-. ds A2 \\$2
-. ds A3 \\$3
-. ds A4 \\$4
-. ds A5 \\$5
-. ds A6 \\$6
-. ds A7 \\$7
-. ds A8 \\$8
-. ds A9 \\$9
-. nr fV \\n(.$
-. fV
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. rR
-.\}
-..
-.de %N
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .%N issue number (#\\n(.c)
-. el \{\
-. nr nK \\n(nK+1
-. nr Kl \\n(Kl+1
-. ds rS nK
-. ds mN %N
-. aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. rR
-.\}
-..
-.de %O
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .%O optional information ... \\*(Pu (#\\n(.c)
-. el \{\
-. ds mN %O
-. nr oK \\n(oK+1
-. nr Kl \\n(Kl+1
-. ds rS oK
-. ds A1 \\$1
-. ds A2 \\$2
-. ds A3 \\$3
-. ds A4 \\$4
-. ds A5 \\$5
-. ds A6 \\$6
-. ds A7 \\$7
-. ds A8 \\$8
-. ds A9 \\$9
-. nr fV \\n(.$
-. fV
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. rR
-.\}
-..
-.de %P
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .%P page numbers ... \\*(Pu (#\\n(.c)
-. el \{\
-. ds mN %P
-. nr pK \\n(pK+1
-. nr Kl \\n(Kl+1
-. ds rS pK
-. ds A1 \\$1
-. ds A2 \\$2
-. ds A3 \\$3
-. ds A4 \\$4
-. ds A5 \\$5
-. ds A6 \\$6
-. ds A7 \\$7
-. ds A8 \\$8
-. ds A9 \\$9
-. nr fV \\n(.$
-. fV
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. rR
-.\}
-..
-.de %Q
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .%Q Corporate or Foreign Author (#\\n(.c)
-. el \{\
-. ds mN %Q
-. nr qK \\n(qK+1
-. nr Kl \\n(Kl+1
-. ds rS qK
-. ds A1 \\$1
-. ds A2 \\$2
-. ds A3 \\$3
-. ds A4 \\$4
-. ds A5 \\$5
-. ds A6 \\$6
-. ds A7 \\$7
-. ds A8 \\$8
-. ds A9 \\$9
-. nr fV \\n(.$
-. fV
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. rR
-.\}
-..
-.de %R
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .%R reference report (#\\n(.c)
-. el \{\
-. ds mN %R
-. nr rK \\n(rK+1
-. nr Kl \\n(Kl+1
-. ds rS rK
-. ds A1 \\$1
-. ds A2 \\$2
-. ds A3 \\$3
-. ds A4 \\$4
-. ds A5 \\$5
-. ds A6 \\$6
-. ds A7 \\$7
-. ds A8 \\$8
-. ds A9 \\$9
-. nr fV \\n(.$
-. fV
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. rR
-.\}
-..
-.de %T
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .%T (#\\n(.c)
-. el \{\
-. ds mN %T
-. if \\n(rS>0 \{\
-. nr tK \\n(tK+1
-. nr Kl \\n(Kl+1
-. ds rS tK
-. \}
-. ds A1 \\$1
-. ds A2 \\$2
-. ds A3 \\$3
-. ds A4 \\$4
-. ds A5 \\$5
-. ds A6 \\$6
-. ds A7 \\$7
-. ds A8 \\$8
-. ds A9 \\$9
-. nr fV \\n(.$
-. fV
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. ie \\n(rS==0 \{\
-. as b1 \&\\*(eM
-. nR
-. \}
-. el .rR
-.\}
-..
-.de %V
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .%V Volume , ... \\*(Pu (#\\n(.c)
-. el \{\
-. ds mN %V
-. nr vK \\n(vK+1
-. nr Kl \\n(Kl+1
-. ds rS vK
-. aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. rR
-.\}
-..
-.de rR
-.hy 0
-.nr jM \\n(C\\n(aP
-.ie \\n(jM==1 \{\
-. ie "\\*(A\\n(aP"Tn" \{\
-. nN
-. \}
-. el \{\
-. if \\n(aC>8 .tm Usage: \\*(mN - maximum 8 arguments (#\\n(.c)
-. aI rR 1
-. \\*(A\\n(aP
-. \}
-.\}
-.el \{\
-. nr jN \\n(aP
-. ie \\n(jM==2 .as b1 \&\\*(A\\n(aP
-. el .as b1 \&\\*(A\\n(aP
-. ie \\n(aC==\\n(aP \{\
-. rD
-. \}
-. el \{\
-. nr aP \\n(aP+1
-. as b1 \&\\*(S\\n(jN
-. rR
-. \}
-.\}
-.rr jM jN
-..
-.de rD
-.as \\*(rS \\*(b1
-.ds b1
-.ds rS
-.aY
-..
-.de Hf
-.Pp
-File:
-.Pa \\$1
-.Pp
-.nr cF \\n(.f
-.nr cZ \\n(.s
-.ie t \{\
-\&\\*(lI
-.br
-.ta +9n 18n 27n 36n 45n 54n 63n 72n
-.\}
-.el \{\
-.ta +8n 16n 24n 32n 40n 48n 56n 64n 72n
-.\}
-.nf
-.so \\$1
-.fi
-.ft \\n(cF
-.fz \\n(cZ
-.Pp
-..
-.nr aN 0
-.de An
-.if \\n(nY==1 \{\
-. ie \\n(aN==1 \{\
-. br
-. \}
-. el \{\
-. nr aN 1
-. \}
-.\}
-.if \\n(aC==0 \{\
-. ie \\n(.$==0 .tm Usage: .An author_name ... \\*(Pu (#\\n(.c)
-. el \{\
-. ds mN An
-. aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
-. \}
-.\}
-.if \\n(aC>\\n(aP \{\
-. nr aP \\n(aP+1
-. nr cF \\n(.f
-. nr cZ \\n(.s
-. nR
-.\}
-..
-.de Sf
-.tm .Sf defunct, use prefix or Ns
-..
-.ds rV "function returns the value 0 if successful; otherwise the value -1 is returned and the global variable \\*(vAerrno\fP is set to indicate the error.
-.de Rv
-.ie \\n(.$==0 \{\
-.tm Usage: .Rv [-std] (#\\n(.c)
-.\}
-.el \{\
-. ds mN Rv
-. if "\\$1"-std" \{\
-. nr cH \\*(cH
-. if (\\n(cH<2):(\\n(cH>3) .tm Usage: .Rv -std sections 2 and 3 only
-. br
-\&The
-.Fn \\$2
-\&\\*(rV
-. \}
-.\}
-..
+++ /dev/null
-/*
- * 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.
- */
-
-/* based on @(#)tn3270.c 8.1 (Berkeley) 6/6/93 */
-
-#include <sys/types.h>
-#include <arpa/telnet.h>
-
-#include "general.h"
-
-#include "defines.h"
-#include "ring.h"
-#include "externs.h"
-#include "fdset.h"
-
-#if defined(TN3270)
-
-#include "../ctlr/screen.h"
-#include "../general/globals.h"
-
-#include "../sys_curses/telextrn.h"
-#include "../ctlr/externs.h"
-
-#if defined(unix)
-int
- HaveInput, /* There is input available to scan */
- cursesdata, /* Do we dump curses data? */
- sigiocount; /* Number of times we got a SIGIO */
-
-char tline[200];
-char *transcom = 0; /* transparent mode command (default: none) */
-#endif /* defined(unix) */
-
-char Ibuf[8*BUFSIZ], *Ifrontp, *Ibackp;
-
-static char sb_terminal[] = { IAC, SB,
- TELOPT_TTYPE, TELQUAL_IS,
- 'I', 'B', 'M', '-', '3', '2', '7', '8', '-', '2',
- IAC, SE };
-#define SBTERMMODEL 13
-
-static int
- Sent3270TerminalType; /* Have we said we are a 3270? */
-
-#endif /* defined(TN3270) */
-
-
- void
-init_3270()
-{
-#if defined(TN3270)
-#if defined(unix)
- HaveInput = 0;
- sigiocount = 0;
-#endif /* defined(unix) */
- Sent3270TerminalType = 0;
- Ifrontp = Ibackp = Ibuf;
- init_ctlr(); /* Initialize some things */
- init_keyboard();
- init_screen();
- init_system();
-#endif /* defined(TN3270) */
-}
-
-\f
-#if defined(TN3270)
-
-/*
- * DataToNetwork - queue up some data to go to network. If "done" is set,
- * then when last byte is queued, we add on an IAC EOR sequence (so,
- * don't call us with "done" until you want that done...)
- *
- * We actually do send all the data to the network buffer, since our
- * only client needs for us to do that.
- */
-
- int
-DataToNetwork(buffer, count, done)
- register char *buffer; /* where the data is */
- register int count; /* how much to send */
- int done; /* is this the last of a logical block */
-{
- register int loop, c;
- int origCount;
-
- origCount = count;
-
- while (count) {
- /* If not enough room for EORs, IACs, etc., wait */
- if (NETROOM() < 6) {
- fd_set o;
-
- FD_ZERO(&o);
- netflush();
- while (NETROOM() < 6) {
- FD_SET(net, &o);
- (void) select(net+1, (fd_set *) 0, &o, (fd_set *) 0,
- (struct timeval *) 0);
- netflush();
- }
- }
- c = ring_empty_count(&netoring);
- if (c > count) {
- c = count;
- }
- loop = c;
- while (loop) {
- if (((unsigned char)*buffer) == IAC) {
- break;
- }
- buffer++;
- loop--;
- }
- if ((c = c-loop)) {
- ring_supply_data(&netoring, buffer-c, c);
- count -= c;
- }
- if (loop) {
- NET2ADD(IAC, IAC);
- count--;
- buffer++;
- }
- }
-
- if (done) {
- NET2ADD(IAC, EOR);
- netflush(); /* try to move along as quickly as ... */
- }
- return(origCount - count);
-}
-
-
-#if defined(unix)
- void
-inputAvailable(signo)
- int signo;
-{
- HaveInput = 1;
- sigiocount++;
-}
-#endif /* defined(unix) */
-
- void
-outputPurge()
-{
- (void) ttyflush(1);
-}
-
-
-/*
- * The following routines are places where the various tn3270
- * routines make calls into telnet.c.
- */
-
-/*
- * DataToTerminal - queue up some data to go to terminal.
- *
- * Note: there are people who call us and depend on our processing
- * *all* the data at one time (thus the select).
- */
-
- int
-DataToTerminal(buffer, count)
- register char *buffer; /* where the data is */
- register int count; /* how much to send */
-{
- register int c;
- int origCount;
-
- origCount = count;
-
- while (count) {
- if (TTYROOM() == 0) {
-#if defined(unix)
- fd_set o;
-
- FD_ZERO(&o);
-#endif /* defined(unix) */
- (void) ttyflush(0);
- while (TTYROOM() == 0) {
-#if defined(unix)
- FD_SET(tout, &o);
- (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
- (struct timeval *) 0);
-#endif /* defined(unix) */
- (void) ttyflush(0);
- }
- }
- c = TTYROOM();
- if (c > count) {
- c = count;
- }
- ring_supply_data(&ttyoring, buffer, c);
- count -= c;
- buffer += c;
- }
- return(origCount);
-}
-\f
-
-/*
- * Push3270 - Try to send data along the 3270 output (to screen) direction.
- */
-
- int
-Push3270()
-{
- int save = ring_full_count(&netiring);
-
- if (save) {
- if (Ifrontp+save > Ibuf+sizeof Ibuf) {
- if (Ibackp != Ibuf) {
- memcpy(Ibuf, Ibackp, Ifrontp-Ibackp);
- Ifrontp -= (Ibackp-Ibuf);
- Ibackp = Ibuf;
- }
- }
- if (Ifrontp+save < Ibuf+sizeof Ibuf) {
- (void)telrcv();
- }
- }
- return save != ring_full_count(&netiring);
-}
-
-
-/*
- * Finish3270 - get the last dregs of 3270 data out to the terminal
- * before quitting.
- */
-
- void
-Finish3270()
-{
- while (Push3270() || !DoTerminalOutput()) {
-#if defined(unix)
- HaveInput = 0;
-#endif /* defined(unix) */
- ;
- }
-}
-
-
-/* StringToTerminal - output a null terminated string to the terminal */
-
- void
-StringToTerminal(s)
- char *s;
-{
- int count;
-
- count = strlen(s);
- if (count) {
- (void) DataToTerminal(s, count); /* we know it always goes... */
- }
-}
-
-
-#if ((!defined(NOT43)) || defined(PUTCHAR))
-/* _putchar - output a single character to the terminal. This name is so that
- * curses(3x) can call us to send out data.
- */
-
- void
-_putchar(c)
- char c;
-{
-#if defined(sun) /* SunOS 4.0 bug */
- c &= 0x7f;
-#endif /* defined(sun) */
- if (cursesdata) {
- Dump('>', &c, 1);
- }
- if (!TTYROOM()) {
- (void) DataToTerminal(&c, 1);
- } else {
- TTYADD(c);
- }
-}
-#endif /* ((!defined(NOT43)) || defined(PUTCHAR)) */
-
- void
-SetIn3270()
-{
- if (Sent3270TerminalType && my_want_state_is_will(TELOPT_BINARY)
- && my_want_state_is_do(TELOPT_BINARY) && !donebinarytoggle) {
- if (!In3270) {
- In3270 = 1;
- Init3270(); /* Initialize 3270 functions */
- /* initialize terminal key mapping */
- InitTerminal(); /* Start terminal going */
- setconnmode(0);
- }
- } else {
- if (In3270) {
- StopScreen(1);
- In3270 = 0;
- Stop3270(); /* Tell 3270 we aren't here anymore */
- setconnmode(0);
- }
- }
-}
-
-/*
- * tn3270_ttype()
- *
- * Send a response to a terminal type negotiation.
- *
- * Return '0' if no more responses to send; '1' if a response sent.
- */
-
- int
-tn3270_ttype()
-{
- /*
- * Try to send a 3270 type terminal name. Decide which one based
- * on the format of our screen, and (in the future) color
- * capaiblities.
- */
- InitTerminal(); /* Sets MaxNumberColumns, MaxNumberLines */
- if ((MaxNumberLines >= 24) && (MaxNumberColumns >= 80)) {
- Sent3270TerminalType = 1;
- if ((MaxNumberLines >= 27) && (MaxNumberColumns >= 132)) {
- MaxNumberLines = 27;
- MaxNumberColumns = 132;
- sb_terminal[SBTERMMODEL] = '5';
- } else if (MaxNumberLines >= 43) {
- MaxNumberLines = 43;
- MaxNumberColumns = 80;
- sb_terminal[SBTERMMODEL] = '4';
- } else if (MaxNumberLines >= 32) {
- MaxNumberLines = 32;
- MaxNumberColumns = 80;
- sb_terminal[SBTERMMODEL] = '3';
- } else {
- MaxNumberLines = 24;
- MaxNumberColumns = 80;
- sb_terminal[SBTERMMODEL] = '2';
- }
- NumberLines = 24; /* before we start out... */
- NumberColumns = 80;
- ScreenSize = NumberLines*NumberColumns;
- if ((MaxNumberLines*MaxNumberColumns) > MAXSCREENSIZE) {
- ExitString("Programming error: MAXSCREENSIZE too small.\n",
- 1);
- /*NOTREACHED*/
- }
- printsub('>', sb_terminal+2, sizeof sb_terminal-2);
- ring_supply_data(&netoring, sb_terminal, sizeof sb_terminal);
- return 1;
- } else {
- return 0;
- }
-}
-
-#if defined(unix)
- int
-settranscom(argc, argv)
- int argc;
- char *argv[];
-{
- int i;
-
- if (argc == 1 && transcom) {
- transcom = 0;
- }
- if (argc == 1) {
- return 1;
- }
- transcom = tline;
- (void) strncpy(transcom, argv[1], sizeof(tline) - 1);
- tline[sizeof(tline) - 1] = '\0';
- for (i = 2; i < argc; ++i) {
- (void) strncat(transcom, " ", sizeof(tline) - 1 - (transcom - tline));
- (void) strncat(transcom, argv[i], sizeof(tline) - 1 - (transcom - tline));
- }
- return 1;
-}
-#endif /* defined(unix) */
-
-#endif /* defined(TN3270) */
+++ /dev/null
-/*
- * 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.
- *
- * @(#)types.h 8.1 (Berkeley) 6/6/93
- */
-
-typedef struct {
- char *modedescriptions;
- char modetype;
-} Modelist;
-
-extern Modelist modelist[];
-
-typedef struct {
- int
- system, /* what the current time is */
- echotoggle, /* last time user entered echo character */
- modenegotiated, /* last time operating mode negotiated */
- didnetreceive, /* last time we read data from network */
- gotDM; /* when did we last see a data mark */
-} Clocks;
-
-extern Clocks clocks;
+++ /dev/null
-/*
- * 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.
- */
-
-/* based on @(#)utilities.c 8.1 (Berkeley) 6/6/93 */
-
-#define TELOPTS
-#define TELCMDS
-#define SLC_NAMES
-#include <arpa/telnet.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-
-#include <ctype.h>
-
-#include "general.h"
-
-#include "fdset.h"
-
-#include "ring.h"
-
-#include "defines.h"
-
-#include "externs.h"
-
-#ifdef AUTHENTICATION
-#include <libtelnet/auth.h>
-#endif
-
-#ifdef ENCRYPTION
-#include <libtelnet/encrypt.h>
-#endif
-
-#include <k5-platform.h>
-
-FILE *NetTrace = 0; /* Not in bss, since needs to stay */
-int prettydump;
-
-/*
- * upcase()
- *
- * Upcase (in place) the argument.
- */
-
- void
-upcase(argument)
- register char *argument;
-{
- register int c;
-
- while ((c = *argument) != 0) {
- if (islower(c)) {
- *argument = toupper(c);
- }
- argument++;
- }
-}
-
-/*
- * SetSockOpt()
- *
- * Compensate for differences in 4.2 and 4.3 systems.
- */
-
- int
-SetSockOpt(fd, level, option, yesno)
- int fd, level, option, yesno;
-{
-#ifndef NOT43
- return setsockopt(fd, level, option,
- (char *)&yesno, sizeof yesno);
-#else /* NOT43 */
- if (yesno == 0) { /* Can't do that in 4.2! */
- fprintf(stderr, "Error: attempt to turn off an option 0x%x.\n",
- option);
- return -1;
- }
- return setsockopt(fd, level, option, 0, 0);
-#endif /* NOT43 */
-}
-\f
-/*
- * The following are routines used to print out debugging information.
- */
-
-unsigned char NetTraceFile[256] = "(standard output)";
-
- void
-SetNetTrace(file)
- register char *file;
-{
- if (NetTrace && NetTrace != stdout)
- fclose(NetTrace);
- if (file && (strcmp(file, "-") != 0)) {
- NetTrace = fopen(file, "w");
- if (NetTrace) {
- strncpy((char *)NetTraceFile, file, sizeof(NetTraceFile) - 1);
- NetTraceFile[sizeof(NetTraceFile) - 1] = '\0';
- return;
- }
- fprintf(stderr, "Cannot open %s.\n", file);
- }
- NetTrace = stdout;
- strncpy((char *)NetTraceFile, "(standard output)", sizeof(NetTraceFile) - 1);
- NetTraceFile[sizeof(NetTraceFile) - 1] = '\0';
-}
-
- void
-Dump(direction, buffer, length)
- char direction;
- unsigned char *buffer;
- int length;
-{
-# define BYTES_PER_LINE 32
-# define min(x,y) ((x<y)? x:y)
- unsigned char *pThis;
- int offset;
-
- offset = 0;
-
- while (length) {
- /* print one line */
- fprintf(NetTrace, "%c 0x%x\t", direction, offset);
- pThis = buffer;
- if (prettydump) {
- buffer = buffer + min(length, BYTES_PER_LINE/2);
- while (pThis < buffer) {
- fprintf(NetTrace, "%c%.2x",
- (((*pThis)&0xff) == 0xff) ? '*' : ' ',
- (*pThis)&0xff);
- pThis++;
- }
- length -= BYTES_PER_LINE/2;
- offset += BYTES_PER_LINE/2;
- } else {
- buffer = buffer + min(length, BYTES_PER_LINE);
- while (pThis < buffer) {
- fprintf(NetTrace, "%.2x", (*pThis)&0xff);
- pThis++;
- }
- length -= BYTES_PER_LINE;
- offset += BYTES_PER_LINE;
- }
- if (NetTrace == stdout) {
- fprintf(NetTrace, "\r\n");
- } else {
- fprintf(NetTrace, "\n");
- }
- if (length < 0) {
- fflush(NetTrace);
- return;
- }
- /* find next unique line */
- }
- fflush(NetTrace);
-}
-
-
- void
-printoption(direction, cmd, option)
- char *direction;
- int cmd, option;
-{
- if (!showoptions)
- return;
- if (cmd == IAC) {
- if (TELCMD_OK(option))
- fprintf(NetTrace, "%s IAC %s", direction, TELCMD(option));
- else
- fprintf(NetTrace, "%s IAC %d", direction, option);
- } else {
- register char *fmt;
- fmt = (cmd == WILL) ? "WILL" : (cmd == WONT) ? "WONT" :
- (cmd == DO) ? "DO" : (cmd == DONT) ? "DONT" : 0;
- if (fmt) {
- fprintf(NetTrace, "%s %s ", direction, fmt);
- if (TELOPT_OK(option))
- fprintf(NetTrace, "%s", TELOPT(option));
- else if (option == TELOPT_EXOPL)
- fprintf(NetTrace, "EXOPL");
- else
- fprintf(NetTrace, "%d", option);
- } else
- fprintf(NetTrace, "%s %d %d", direction, cmd, option);
- }
- if (NetTrace == stdout) {
- fprintf(NetTrace, "\r\n");
- fflush(NetTrace);
- } else {
- fprintf(NetTrace, "\n");
- }
- return;
-}
-
- void
-optionstatus()
-{
- register int i;
- extern char will_wont_resp[], do_dont_resp[];
-
- for (i = 0; i < 256; i++) {
- if (do_dont_resp[i]) {
- if (TELOPT_OK(i))
- printf("resp DO_DONT %s: %d\n", TELOPT(i), do_dont_resp[i]);
- else if (TELCMD_OK(i))
- printf("resp DO_DONT %s: %d\n", TELCMD(i), do_dont_resp[i]);
- else
- printf("resp DO_DONT %d: %d\n", i,
- do_dont_resp[i]);
- if (my_want_state_is_do(i)) {
- if (TELOPT_OK(i))
- printf("want DO %s\n", TELOPT(i));
- else if (TELCMD_OK(i))
- printf("want DO %s\n", TELCMD(i));
- else
- printf("want DO %d\n", i);
- } else {
- if (TELOPT_OK(i))
- printf("want DONT %s\n", TELOPT(i));
- else if (TELCMD_OK(i))
- printf("want DONT %s\n", TELCMD(i));
- else
- printf("want DONT %d\n", i);
- }
- } else {
- if (my_state_is_do(i)) {
- if (TELOPT_OK(i))
- printf(" DO %s\n", TELOPT(i));
- else if (TELCMD_OK(i))
- printf(" DO %s\n", TELCMD(i));
- else
- printf(" DO %d\n", i);
- }
- }
- if (will_wont_resp[i]) {
- if (TELOPT_OK(i))
- printf("resp WILL_WONT %s: %d\n", TELOPT(i), will_wont_resp[i]);
- else if (TELCMD_OK(i))
- printf("resp WILL_WONT %s: %d\n", TELCMD(i), will_wont_resp[i]);
- else
- printf("resp WILL_WONT %d: %d\n",
- i, will_wont_resp[i]);
- if (my_want_state_is_will(i)) {
- if (TELOPT_OK(i))
- printf("want WILL %s\n", TELOPT(i));
- else if (TELCMD_OK(i))
- printf("want WILL %s\n", TELCMD(i));
- else
- printf("want WILL %d\n", i);
- } else {
- if (TELOPT_OK(i))
- printf("want WONT %s\n", TELOPT(i));
- else if (TELCMD_OK(i))
- printf("want WONT %s\n", TELCMD(i));
- else
- printf("want WONT %d\n", i);
- }
- } else {
- if (my_state_is_will(i)) {
- if (TELOPT_OK(i))
- printf(" WILL %s\n", TELOPT(i));
- else if (TELCMD_OK(i))
- printf(" WILL %s\n", TELCMD(i));
- else
- printf(" WILL %d\n", i);
- }
- }
- }
-
-}
-
- void
-printsub(direction, pointer, length)
- char direction; /* '<' or '>' */
- unsigned char *pointer; /* where suboption data sits */
- int length; /* length of suboption data */
-{
- register int i;
- unsigned char buf[512];
- extern int want_status_response;
-
- if (showoptions || direction == 0 ||
- (want_status_response && (pointer[0] == TELOPT_STATUS))) {
- if (direction) {
- fprintf(NetTrace, "%s IAC SB ",
- (direction == '<')? "RCVD":"SENT");
- if (length >= 3) {
- register int j;
-
- i = pointer[length-2];
- j = pointer[length-1];
-
- if (i != IAC || j != SE) {
- fprintf(NetTrace, "(terminated by ");
- if (TELOPT_OK(i))
- fprintf(NetTrace, "%s ", TELOPT(i));
- else if (TELCMD_OK(i))
- fprintf(NetTrace, "%s ", TELCMD(i));
- else
- fprintf(NetTrace, "%d ", i);
- if (TELOPT_OK(j))
- fprintf(NetTrace, "%s", TELOPT(j));
- else if (TELCMD_OK(j))
- fprintf(NetTrace, "%s", TELCMD(j));
- else
- fprintf(NetTrace, "%d", j);
- fprintf(NetTrace, ", not IAC SE!) ");
- }
- }
- length -= 2;
- }
- if (length < 1) {
- fprintf(NetTrace, "(Empty suboption??\?)");
- if (NetTrace == stdout)
- fflush(NetTrace);
- return;
- }
- switch (pointer[0]) {
- case TELOPT_TTYPE:
- fprintf(NetTrace, "TERMINAL-TYPE ");
- switch (pointer[1]) {
- case TELQUAL_IS:
- fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2);
- break;
- case TELQUAL_SEND:
- fprintf(NetTrace, "SEND");
- break;
- default:
- fprintf(NetTrace,
- "- unknown qualifier %d (0x%x).",
- pointer[1], pointer[1]);
- }
- break;
- case TELOPT_TSPEED:
- fprintf(NetTrace, "TERMINAL-SPEED");
- if (length < 2) {
- fprintf(NetTrace, " (empty suboption??\?)");
- break;
- }
- switch (pointer[1]) {
- case TELQUAL_IS:
- fprintf(NetTrace, " IS ");
- fprintf(NetTrace, "%.*s", length-2, (char *)pointer+2);
- break;
- default:
- if (pointer[1] == 1)
- fprintf(NetTrace, " SEND");
- else
- fprintf(NetTrace, " %d (unknown)", pointer[1]);
- for (i = 2; i < length; i++)
- fprintf(NetTrace, " ?%d?", pointer[i]);
- break;
- }
- break;
-
- case TELOPT_LFLOW:
- fprintf(NetTrace, "TOGGLE-FLOW-CONTROL");
- if (length < 2) {
- fprintf(NetTrace, " (empty suboption??\?)");
- break;
- }
- switch (pointer[1]) {
- case LFLOW_OFF:
- fprintf(NetTrace, " OFF"); break;
- case LFLOW_ON:
- fprintf(NetTrace, " ON"); break;
- case LFLOW_RESTART_ANY:
- fprintf(NetTrace, " RESTART-ANY"); break;
- case LFLOW_RESTART_XON:
- fprintf(NetTrace, " RESTART-XON"); break;
- default:
- fprintf(NetTrace, " %d (unknown)", pointer[1]);
- }
- for (i = 2; i < length; i++)
- fprintf(NetTrace, " ?%d?", pointer[i]);
- break;
-
- case TELOPT_NAWS:
- fprintf(NetTrace, "NAWS");
- if (length < 2) {
- fprintf(NetTrace, " (empty suboption??\?)");
- break;
- }
- if (length == 2) {
- fprintf(NetTrace, " ?%d?", pointer[1]);
- break;
- }
- fprintf(NetTrace, " %d %d (%d)",
- pointer[1], pointer[2],
- (int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2])));
- if (length == 4) {
- fprintf(NetTrace, " ?%d?", pointer[3]);
- break;
- }
- fprintf(NetTrace, " %d %d (%d)",
- pointer[3], pointer[4],
- (int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4])));
- for (i = 5; i < length; i++)
- fprintf(NetTrace, " ?%d?", pointer[i]);
- break;
-
-#if defined(AUTHENTICATION)
- case TELOPT_AUTHENTICATION:
- fprintf(NetTrace, "AUTHENTICATION");
- if (length < 2) {
- fprintf(NetTrace, " (empty suboption??\?)");
- break;
- }
- switch (pointer[1]) {
- case TELQUAL_REPLY:
- case TELQUAL_IS:
- fprintf(NetTrace, " %s ", (pointer[1] == TELQUAL_IS) ?
- "IS" : "REPLY");
- if (AUTHTYPE_NAME_OK(pointer[2]))
- fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[2]));
- else
- fprintf(NetTrace, "%d ", pointer[2]);
- if (length < 3) {
- fprintf(NetTrace, "(partial suboption??\?)");
- break;
- }
- fprintf(NetTrace, "%s|%s%s",
- ((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ?
- "CLIENT" : "SERVER",
- ((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ?
- "MUTUAL" : "ONE-WAY",
- ((pointer[3] & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_ON) ?
- "|ENCRYPT" : "");
- auth_printsub(&pointer[1], length - 1, buf, sizeof(buf));
- fprintf(NetTrace, "%s", buf);
- break;
-
- case TELQUAL_SEND:
- i = 2;
- fprintf(NetTrace, " SEND ");
- while (i < length) {
- if (AUTHTYPE_NAME_OK(pointer[i]))
- fprintf(NetTrace, "%s ", AUTHTYPE_NAME(pointer[i]));
- else
- fprintf(NetTrace, "%d ", pointer[i]);
- if (++i >= length) {
- fprintf(NetTrace, "(partial suboption??\?)");
- break;
- }
- fprintf(NetTrace, "%s|%s%s ",
- ((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ?
- "CLIENT" : "SERVER",
- ((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ?
- "MUTUAL" : "ONE-WAY",
- ((pointer[i] & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_ON) ?
- "|ENCRYPT" : "");
- ++i;
- }
- break;
-
- case TELQUAL_NAME:
- i = 2;
- fprintf(NetTrace, " NAME \"");
- while (i < length)
- putc(pointer[i++], NetTrace);
- putc('"', NetTrace);
- break;
-
- default:
- for (i = 2; i < length; i++)
- fprintf(NetTrace, " ?%d?", pointer[i]);
- break;
- }
- break;
-#endif
-
-#ifdef ENCRYPTION
- case TELOPT_ENCRYPT:
- fprintf(NetTrace, "ENCRYPT");
- if (length < 2) {
- fprintf(NetTrace, " (empty suboption??\?)");
- break;
- }
- switch (pointer[1]) {
- case ENCRYPT_START:
- fprintf(NetTrace, " START");
- break;
-
- case ENCRYPT_END:
- fprintf(NetTrace, " END");
- break;
-
- case ENCRYPT_REQSTART:
- fprintf(NetTrace, " REQUEST-START");
- break;
-
- case ENCRYPT_REQEND:
- fprintf(NetTrace, " REQUEST-END");
- break;
-
- case ENCRYPT_IS:
- case ENCRYPT_REPLY:
- fprintf(NetTrace, " %s ", (pointer[1] == ENCRYPT_IS) ?
- "IS" : "REPLY");
- if (length < 3) {
- fprintf(NetTrace, " (partial suboption??\?)");
- break;
- }
- if (ENCTYPE_NAME_OK(pointer[2]))
- fprintf(NetTrace, "%s ", ENCTYPE_NAME(pointer[2]));
- else
- fprintf(NetTrace, " %d (unknown)", pointer[2]);
-
- encrypt_printsub(&pointer[1], length - 1, buf, sizeof(buf));
- fprintf(NetTrace, "%s", buf);
- break;
-
- case ENCRYPT_SUPPORT:
- i = 2;
- fprintf(NetTrace, " SUPPORT ");
- while (i < length) {
- if (ENCTYPE_NAME_OK(pointer[i]))
- fprintf(NetTrace, "%s ", ENCTYPE_NAME(pointer[i]));
- else
- fprintf(NetTrace, "%d ", pointer[i]);
- i++;
- }
- break;
-
- case ENCRYPT_ENC_KEYID:
- fprintf(NetTrace, " ENC_KEYID ");
- goto encommon;
-
- case ENCRYPT_DEC_KEYID:
- fprintf(NetTrace, " DEC_KEYID ");
- goto encommon;
-
- default:
- fprintf(NetTrace, " %d (unknown)", pointer[1]);
- encommon:
- for (i = 2; i < length; i++)
- fprintf(NetTrace, " %d", pointer[i]);
- break;
- }
- break;
-#endif /* ENCRYPTION */
-
- case TELOPT_LINEMODE:
- fprintf(NetTrace, "LINEMODE ");
- if (length < 2) {
- fprintf(NetTrace, " (empty suboption??\?)");
- break;
- }
- switch (pointer[1]) {
- case WILL:
- fprintf(NetTrace, "WILL ");
- goto common;
- case WONT:
- fprintf(NetTrace, "WONT ");
- goto common;
- case DO:
- fprintf(NetTrace, "DO ");
- goto common;
- case DONT:
- fprintf(NetTrace, "DONT ");
- common:
- if (length < 3) {
- fprintf(NetTrace, "(no option??\?)");
- break;
- }
- switch (pointer[2]) {
- case LM_FORWARDMASK:
- fprintf(NetTrace, "Forward Mask");
- for (i = 3; i < length; i++)
- fprintf(NetTrace, " %x", pointer[i]);
- break;
- default:
- fprintf(NetTrace, "%d (unknown)", pointer[2]);
- for (i = 3; i < length; i++)
- fprintf(NetTrace, " %d", pointer[i]);
- break;
- }
- break;
-
- case LM_SLC:
- fprintf(NetTrace, "SLC");
- for (i = 2; i < length - 2; i += 3) {
- if (SLC_NAME_OK(pointer[i+SLC_FUNC]))
- fprintf(NetTrace, " %s", SLC_NAME(pointer[i+SLC_FUNC]));
- else
- fprintf(NetTrace, " %d", pointer[i+SLC_FUNC]);
- switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) {
- case SLC_NOSUPPORT:
- fprintf(NetTrace, " NOSUPPORT"); break;
- case SLC_CANTCHANGE:
- fprintf(NetTrace, " CANTCHANGE"); break;
- case SLC_VARIABLE:
- fprintf(NetTrace, " VARIABLE"); break;
- case SLC_DEFAULT:
- fprintf(NetTrace, " DEFAULT"); break;
- }
- fprintf(NetTrace, "%s%s%s",
- pointer[i+SLC_FLAGS]&SLC_ACK ? "|ACK" : "",
- pointer[i+SLC_FLAGS]&SLC_FLUSHIN ? "|FLUSHIN" : "",
- pointer[i+SLC_FLAGS]&SLC_FLUSHOUT ? "|FLUSHOUT" : "");
- if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN|
- SLC_FLUSHOUT| SLC_LEVELBITS))
- fprintf(NetTrace, "(0x%x)", pointer[i+SLC_FLAGS]);
- fprintf(NetTrace, " %d;", pointer[i+SLC_VALUE]);
- if ((pointer[i+SLC_VALUE] == IAC) &&
- (pointer[i+SLC_VALUE+1] == IAC))
- i++;
- }
- for (; i < length; i++)
- fprintf(NetTrace, " ?%d?", pointer[i]);
- break;
-
- case LM_MODE:
- fprintf(NetTrace, "MODE ");
- if (length < 3) {
- fprintf(NetTrace, "(no mode??\?)");
- break;
- }
- {
- char tbuf[64];
- snprintf(tbuf, sizeof(tbuf), "%s%s%s%s%s",
- pointer[2]&MODE_EDIT ? "|EDIT" : "",
- pointer[2]&MODE_TRAPSIG ? "|TRAPSIG" : "",
- pointer[2]&MODE_SOFT_TAB ? "|SOFT_TAB" : "",
- pointer[2]&MODE_LIT_ECHO ? "|LIT_ECHO" : "",
- pointer[2]&MODE_ACK ? "|ACK" : "");
- fprintf(NetTrace, "%s", tbuf[1] ? &tbuf[1] : "0");
- }
- if (pointer[2]&~(MODE_MASK))
- fprintf(NetTrace, " (0x%x)", pointer[2]);
- for (i = 3; i < length; i++)
- fprintf(NetTrace, " ?0x%x?", pointer[i]);
- break;
- default:
- fprintf(NetTrace, "%d (unknown)", pointer[1]);
- for (i = 2; i < length; i++)
- fprintf(NetTrace, " %d", pointer[i]);
- }
- break;
-
- case TELOPT_STATUS: {
- register char *cp;
- register int j, k;
-
- fprintf(NetTrace, "STATUS");
-
- switch (pointer[1]) {
- default:
- if (pointer[1] == TELQUAL_SEND)
- fprintf(NetTrace, " SEND");
- else
- fprintf(NetTrace, " %d (unknown)", pointer[1]);
- for (i = 2; i < length; i++)
- fprintf(NetTrace, " ?%d?", pointer[i]);
- break;
- case TELQUAL_IS:
- if (--want_status_response < 0)
- want_status_response = 0;
- if (NetTrace == stdout)
- fprintf(NetTrace, " IS\r\n");
- else
- fprintf(NetTrace, " IS\n");
-
- for (i = 2; i < length; i++) {
- switch(pointer[i]) {
- case DO: cp = "DO"; goto common2;
- case DONT: cp = "DONT"; goto common2;
- case WILL: cp = "WILL"; goto common2;
- case WONT: cp = "WONT"; goto common2;
- common2:
- i++;
- if (TELOPT_OK((int)pointer[i]))
- fprintf(NetTrace, " %s %s", cp, TELOPT(pointer[i]));
- else
- fprintf(NetTrace, " %s %d", cp, pointer[i]);
-
- if (NetTrace == stdout)
- fprintf(NetTrace, "\r\n");
- else
- fprintf(NetTrace, "\n");
- break;
-
- case SB:
- fprintf(NetTrace, " SB ");
- i++;
- j = k = i;
- while (j < length) {
- if (pointer[j] == SE) {
- if (j+1 == length)
- break;
- if (pointer[j+1] == SE)
- j++;
- else
- break;
- }
- pointer[k++] = pointer[j++];
- }
- printsub(0, &pointer[i], k - i);
- if (i < length) {
- fprintf(NetTrace, " SE");
- i = j;
- } else
- i = j - 1;
-
- if (NetTrace == stdout)
- fprintf(NetTrace, "\r\n");
- else
- fprintf(NetTrace, "\n");
-
- break;
-
- default:
- fprintf(NetTrace, " %d", pointer[i]);
- break;
- }
- }
- break;
- }
- break;
- }
-
- case TELOPT_XDISPLOC:
- fprintf(NetTrace, "X-DISPLAY-LOCATION ");
- switch (pointer[1]) {
- case TELQUAL_IS:
- fprintf(NetTrace, "IS \"%.*s\"", length-2, (char *)pointer+2);
- break;
- case TELQUAL_SEND:
- fprintf(NetTrace, "SEND");
- break;
- default:
- fprintf(NetTrace, "- unknown qualifier %d (0x%x).",
- pointer[1], pointer[1]);
- }
- break;
-
- case TELOPT_NEW_ENVIRON:
- fprintf(NetTrace, "NEW-ENVIRON ");
-#ifdef OLD_ENVIRON
- goto env_common1;
- case TELOPT_OLD_ENVIRON:
- fprintf(NetTrace, "OLD-ENVIRON");
- env_common1:
-#endif
- switch (pointer[1]) {
- case TELQUAL_IS:
- fprintf(NetTrace, "IS ");
- goto env_common;
- case TELQUAL_SEND:
- fprintf(NetTrace, "SEND ");
- goto env_common;
- case TELQUAL_INFO:
- fprintf(NetTrace, "INFO ");
- env_common:
- {
- register int noquote = 2;
-#if defined(ENV_HACK) && defined(OLD_ENVIRON)
- extern int old_env_var, old_env_value;
-#endif
- for (i = 2; i < length; i++ ) {
- switch (pointer[i]) {
- case NEW_ENV_VALUE:
-#ifdef OLD_ENVIRON
- /* case NEW_ENV_OVAR: */
- if (pointer[0] == TELOPT_OLD_ENVIRON) {
-# ifdef ENV_HACK
- if (old_env_var == OLD_ENV_VALUE)
- fprintf(NetTrace, "\" (VALUE) " + noquote);
- else
-# endif
- fprintf(NetTrace, "\" VAR " + noquote);
- } else
-#endif /* OLD_ENVIRON */
- fprintf(NetTrace, "\" VALUE " + noquote);
- noquote = 2;
- break;
-
- case NEW_ENV_VAR:
-#ifdef OLD_ENVIRON
- /* case OLD_ENV_VALUE: */
- if (pointer[0] == TELOPT_OLD_ENVIRON) {
-# ifdef ENV_HACK
- if (old_env_value == OLD_ENV_VAR)
- fprintf(NetTrace, "\" (VAR) " + noquote);
- else
-# endif
- fprintf(NetTrace, "\" VALUE " + noquote);
- } else
-#endif /* OLD_ENVIRON */
- fprintf(NetTrace, "\" VAR " + noquote);
- noquote = 2;
- break;
-
- case ENV_ESC:
- fprintf(NetTrace, "\" ESC " + noquote);
- noquote = 2;
- break;
-
- case ENV_USERVAR:
- fprintf(NetTrace, "\" USERVAR " + noquote);
- noquote = 2;
- break;
-
- default:
- if (isprint(pointer[i]) && pointer[i] != '"') {
- if (noquote) {
- putc('"', NetTrace);
- noquote = 0;
- }
- putc(pointer[i], NetTrace);
- } else {
- fprintf(NetTrace, "\" %03o " + noquote,
- pointer[i]);
- noquote = 2;
- }
- break;
- }
- }
- if (!noquote)
- putc('"', NetTrace);
- break;
- }
- }
- break;
-
- default:
- if (TELOPT_OK(pointer[0]))
- fprintf(NetTrace, "%s (unknown)", TELOPT(pointer[0]));
- else
- fprintf(NetTrace, "%d (unknown)", pointer[0]);
- for (i = 1; i < length; i++)
- fprintf(NetTrace, " %d", pointer[i]);
- break;
- }
- if (direction) {
- if (NetTrace == stdout)
- fprintf(NetTrace, "\r\n");
- else
- fprintf(NetTrace, "\n");
- }
- if (NetTrace == stdout)
- fflush(NetTrace);
- }
-}
-
-/* EmptyTerminal - called to make sure that the terminal buffer is empty.
- * Note that we consider the buffer to run all the
- * way to the kernel (thus the select).
- */
-
- void
-EmptyTerminal()
-{
-#if defined(unix)
- fd_set o;
-
- FD_ZERO(&o);
-#endif /* defined(unix) */
-
- if (TTYBYTES() == 0) {
-#if defined(unix)
- FD_SET(tout, &o);
- (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
- (struct timeval *) 0); /* wait for TTLOWAT */
-#endif /* defined(unix) */
- } else {
- while (TTYBYTES()) {
- (void) ttyflush(0);
-#if defined(unix)
- FD_SET(tout, &o);
- (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
- (struct timeval *) 0); /* wait for TTLOWAT */
-#endif /* defined(unix) */
- }
- }
-}
-
- void
-SetForExit()
-{
- setconnmode(0);
-#if defined(TN3270)
- if (In3270) {
- Finish3270();
- }
-#else /* defined(TN3270) */
- do {
- (void)telrcv(); /* Process any incoming data */
- EmptyTerminal();
- } while (ring_full_count(&netiring)); /* While there is any */
-#endif /* defined(TN3270) */
- setcommandmode();
- fflush(stdout);
- fflush(stderr);
-#if defined(TN3270)
- if (In3270) {
- StopScreen(1);
- }
-#endif /* defined(TN3270) */
- setconnmode(0);
- EmptyTerminal(); /* Flush the path to the tty */
- setcommandmode();
-}
-
- void
-Exit(returnCode)
- int returnCode;
-{
- SetForExit();
- exit(returnCode);
-}
-
- void
-ExitString(string, returnCode)
- char *string;
- int returnCode;
-{
- SetForExit();
- fwrite(string, 1, strlen(string), stderr);
- exit(returnCode);
-}
+++ /dev/null
-Issues to be dealt with in telnetd:
-
-Debug mode won't do ipv6.
-
-FIX: Rewrite listener setup code in main after argument parsing.
-\f
-Needs auditing.
+++ /dev/null
-thisconfigdir=..
-myfulldir=appl/telnet/telnetd
-mydir=telnetd
-BUILDTOP=$(REL)..$(S)..$(S)..
-# derived from the original Makefile.generic
-#
-# 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.
-#
-# @(#)Makefile.generic 5.5 (Berkeley) 3/1/91
-#
-
-AUTH_DEF=-DAUTHENTICATION -DENCRYPTION -DKRB5 -DFORWARD -UNO_LOGIN_F -ULOGIN_CAP_F -DLOGIN_PROGRAM=KRB5_PATH_LOGIN
-OTHERDEFS=-DKLUDGELINEMODE -DDIAGNOSTICS -DENV_HACK -DOLD_ENVIRON
-LOCALINCLUDES=-I.. -I$(srcdir)/..
-DEFINES = -DTELNET_BUFSIZE=65535 $(AUTH_DEF) $(OTHERDEFS)
-ARPA_TELNET= $(srcdir)/../arpa/telnet.h
-
-PROG_LIBPATH=-L$(TOPLIBD)
-PROG_RPATH=$(KRB5_LIBDIR)
-
-LIBS= @TELNETD_LIBS@
-
-SRCS= $(srcdir)/telnetd.c \
- $(srcdir)/termio-tn.c \
- $(srcdir)/termios-tn.c \
- $(srcdir)/state.c \
- $(srcdir)/termstat.c \
- $(srcdir)/slc.c \
- $(srcdir)/sys_term.c \
- $(srcdir)/utility.c \
- $(srcdir)/global.c \
- $(srcdir)/authenc.c \
- $(GETTYSRC)
-OBJS= telnetd.o \
- termio-tn.o \
- termios-tn.o \
- state.o \
- termstat.o \
- slc.o \
- sys_term.o \
- utility.o \
- global.o \
- authenc.o \
- $(GETTYOBJ)
-
-all:: telnetd
-
-telnetd: $(OBJS) $(PTY_DEPLIB) $(KRB5_BASE_DEPLIBS) ../libtelnet/libtelnet.a
- $(CC_LINK) -o $@ $(OBJS) ../libtelnet/libtelnet.a $(PTY_LIB) $(UTIL_LIB) $(KRB5_BASE_LIBS)
-
-clean::
- $(RM) telnetd
-
-install::
- for f in telnetd; do \
- $(INSTALL_PROGRAM) $$f \
- $(DESTDIR)$(SERVER_BINDIR)/`echo $$f|sed '$(transform)'`; \
- $(INSTALL_DATA) $(srcdir)/$$f.8 \
- ${DESTDIR}$(SERVER_MANDIR)/`echo $$f|sed '$(transform)'`.8; \
- done
-
-authenc.o: telnetd.h
-global.o: defs.h ext.h $(ARPA_TELNET)
-slc.o: telnetd.h defs.h ext.h $(ARPA_TELNET)
-state.o: telnetd.h defs.h ext.h $(ARPA_TELNET)
-sys_term.o: telnetd.h pathnames.h defs.h ext.h $(ARPA_TELNET)
-telnetd.o: telnetd.h defs.h ext.h $(ARPA_TELNET)
-termstat.o: telnetd.h defs.h ext.h $(ARPA_TELNET)
-utility.o: telnetd.h defs.h ext.h $(ARPA_TELNET)
+++ /dev/null
-/*-
- * Copyright (c) 1991, 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.
- */
-
-/* based on @(#)authenc.c 8.1 (Berkeley) 6/4/93 */
-
-#if defined(AUTHENTICATION) || defined(ENCRYPTION)
-#include "telnetd.h"
-#include <libtelnet/misc.h>
-
-int
-net_write(str, len)
- unsigned char *str;
- int len;
-{
- if (len < 0)
- return 0;
- return netwrite(str, (size_t) len);
-}
-
-void
-net_encrypt()
-{
-#ifdef ENCRYPTION
- char *s = (nclearto > nbackp) ? nclearto : nbackp;
- if (s < nfrontp && encrypt_output) {
- (*encrypt_output)((unsigned char *)s, nfrontp - s);
- }
- nclearto = nfrontp;
-#endif /* ENCRYPTION */
-}
-
- 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 /* defined(AUTHENTICATION) || defined(ENCRYPTION) */
+++ /dev/null
-/*
- * Copyright (c) 1989, 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.
- *
- * @(#)defs.h 8.1 (Berkeley) 6/4/93
- */
-
-/*
- * Telnet server defines
- */
-#include <sys/types.h>
-#include <sys/param.h>
-
-#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>
-
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-#include <sys/ioctl.h>
-#ifdef HAVE_SYS_FILIO_H
-#include <sys/filio.h>
-#endif
-
-#include <netinet/in.h>
-
-#include <arpa/telnet.h>
-
-/* for socklen() */
-#include "socket-utils.h"
-
-#include <stdio.h>
-#ifdef __STDC__
-#include <stdlib.h>
-#endif
-#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>
-#ifndef HAVE_STRING_H
-#include <strings.h>
-#else
-#include <string.h>
-#endif
-
-#ifndef USE_TERMIO
-#include <sgtty.h>
-#else
-# ifdef SYSV_TERMIO
-# include <termio.h>
-# else
-# include <termios.h>
-# endif
-#endif
-#if !defined(USE_TERMIO) || defined(NO_CC_T)
-typedef unsigned char cc_t;
-#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 */
-
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif
-#endif /* CRAY */
-
-#ifdef __hpux
-#include <sys/ptyio.h>
-#endif
-
-#if defined(__alpha) && defined(STREAMSPTY)
-#undef STREAMSPTY
-#endif
-
-#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 0x04
-#define KLUDGE_OK 0x03
-#define NO_AUTOKLUDGE 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
-
-extern char *line;
-
-#ifdef ENCRYPTION
-extern void (*encrypt_output) (unsigned char *, int);
-extern int (*decrypt_input) (int);
-#endif /* ENCRYPTION */
+++ /dev/null
-#
-# Generated makefile dependencies follow.
-#
-$(OUTPRE)telnetd.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/libpty.h \
- $(COM_ERR_DEPS) $(SRCTOP)/include/fake-addrinfo.h $(SRCTOP)/include/k5-platform.h \
- $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/krb5.h \
- $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- $(srcdir)/../arpa/telnet.h $(srcdir)/../libtelnet/auth-proto.h \
- $(srcdir)/../libtelnet/auth.h $(srcdir)/../libtelnet/enc-proto.h \
- $(srcdir)/../libtelnet/encrypt.h $(srcdir)/../libtelnet/misc-proto.h \
- defs.h ext.h pathnames.h telnetd.c telnetd.h
-$(OUTPRE)termio-tn.$(OBJEXT): termio-tn.c
-$(OUTPRE)termios-tn.$(OBJEXT): termios-tn.c
-$(OUTPRE)state.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- $(srcdir)/../arpa/telnet.h $(srcdir)/../libtelnet/auth-proto.h \
- $(srcdir)/../libtelnet/auth.h $(srcdir)/../libtelnet/enc-proto.h \
- $(srcdir)/../libtelnet/encrypt.h defs.h ext.h state.c \
- telnetd.h
-$(OUTPRE)termstat.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- $(srcdir)/../arpa/telnet.h defs.h ext.h telnetd.h termstat.c
-$(OUTPRE)slc.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- $(srcdir)/../arpa/telnet.h defs.h ext.h slc.c telnetd.h
-$(OUTPRE)sys_term.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/libpty.h \
- $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
- $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \
- $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \
- $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \
- $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/authdata_plugin.h \
- $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \
- $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- $(srcdir)/../arpa/telnet.h $(srcdir)/../libtelnet/auth-proto.h \
- $(srcdir)/../libtelnet/auth.h defs.h ext.h pathnames.h \
- sys_term.c telnetd.h
-$(OUTPRE)utility.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- $(srcdir)/../arpa/telnet.h $(srcdir)/../libtelnet/auth-proto.h \
- $(srcdir)/../libtelnet/auth.h $(srcdir)/../libtelnet/enc-proto.h \
- $(srcdir)/../libtelnet/encrypt.h defs.h ext.h telnetd.h \
- utility.c
-$(OUTPRE)global.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- $(srcdir)/../arpa/telnet.h defs.h ext.h global.c
-$(OUTPRE)authenc.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- $(srcdir)/../arpa/telnet.h $(srcdir)/../libtelnet/misc-proto.h \
- $(srcdir)/../libtelnet/misc.h authenc.c defs.h ext.h \
- telnetd.h
+++ /dev/null
-/*
- * Copyright (c) 1989, 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.
- *
- * @(#)ext.h 8.1 (Berkeley) 6/4/93
- */
-
-/*
- * 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 */
-extern int restartany; /* restart output on any character 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(AUTHENTICATION)
-extern int auth_level;
-#endif
-extern int auth_negotiated; /* Have we finished all authentication negotiation we plan to finish?*/
-extern slcfun slctab[NSLC + 1]; /* slc mapping table */
-
-extern char terminaltype[41];
-
-/*
- * 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 */
-
-#ifdef ENCRYPTION
-extern int must_encrypt;
-#endif
-
-extern void
- _termstat (void),
- add_slc (int, int, int),
- check_slc (void),
- change_slc (int, int, int),
- cleanup (int),
- clientstat (int, int, int),
- copy_termbuf (char *, int),
- deferslc (void),
- defer_terminit (void),
- do_opt_slc (unsigned char *, int),
- doeof (void),
- dooption (int),
- dontoption (int),
- edithost (char *, char *),
- fatal (int, const char *),
- fatalperror (int, const char *),
- get_slc_defaults (void),
- init_env (void),
- init_termbuf (void),
- interrupt (void),
- localstat (void),
- flowstat (void),
- netclear (void),
- netflush (void),
-#ifdef DIAGNOSTICS
- printoption (char *, int),
- printdata (char *, char *, int),
- printsub (int, unsigned char *, int),
-#endif
- ptyflush (void),
- putchr (int),
- putf (char *, char *),
- recv_ayt (void),
- send_do (int, int),
- send_dont (int, int),
- send_slc (void),
- send_status (void),
- send_will (int, int),
- send_wont (int, int),
- sendbrk (void),
- sendsusp (void),
- set_termbuf (void),
- start_login (char *, int, char *),
- start_slc (int),
- startslave (char *, int, char *),
- suboption (void),
- telrcv (void),
- ttloop (void),
-#if defined(AUTHENTICATION)
- ttsuck (void),
-#endif
- tty_binaryin (int),
- tty_binaryout (int);
-
-extern int
- end_slc (unsigned char **),
- getnpty (void),
-#ifndef convex
- getpty (int *),
-#endif
- login_tty (int),
- spcset (int, cc_t *, cc_t **),
- stilloob (int),
- terminit (void),
- termstat (void),
- tty_flowmode (void),
- tty_restartany (void),
- tty_isbinaryin (void),
- tty_isbinaryout (void),
- tty_iscrnl (void),
- tty_isecho (void),
- tty_isediting (void),
- tty_islitecho (void),
- tty_isnewmap (void),
- tty_israw (void),
- tty_issofttab (void),
- tty_istrapsig (void),
- tty_linemode (void),
- readstream_termio(int, char *, char *, char *, int *),
- readstream_termios(int, char *, char *, char *, int *);
-
-extern void
- tty_rspeed (int),
- tty_setecho (int),
- tty_setedit (int),
- tty_setlinemode (int),
- tty_setlitecho (int),
- tty_setsig (int),
- tty_setsofttab (int),
- tty_tspeed (int),
- willoption (int),
- wontoption (int);
-
-extern void netprintf (const char *, ...)
-#if !defined(__cplusplus) && (__GNUC__ > 2)
- __attribute__((__format__(__printf__, 1, 2)))
-#endif
- ;
-extern void netprintf_urg (const char *fmt, ...)
-#if !defined(__cplusplus) && (__GNUC__ > 2)
- __attribute__((__format__(__printf__, 1, 2)))
-#endif
- ;
-extern void netprintf_noflush (const char *fmt, ...)
-#if !defined(__cplusplus) && (__GNUC__ > 2)
- __attribute__((__format__(__printf__, 1, 2)))
-#endif
- ;
-extern int netwrite (const unsigned char *, size_t);
-extern void netputs (const char *);
-
-#ifdef ENCRYPTION
-extern char *nclearto;
-#endif /* ENCRYPTION */
-
-
-/*
- * The following are some clocks used to decide how to interpret
- * the relationship between various variables.
- */
-
-extern struct {
- int
- system, /* what the current time is */
- echotoggle, /* last time user entered echo character */
- modenegotiated, /* last time operating mode negotiated */
- didnetreceive, /* last time we read data from network */
- ttypesubopt, /* ttype subopt is received */
- tspeedsubopt, /* tspeed subopt is received */
- environsubopt, /* environ subopt is received */
- oenvironsubopt, /* old environ subopt is received */
- xdisplocsubopt, /* xdisploc subopt is received */
- baseline, /* time started to do timed action */
- gotDM; /* when did we last see a data mark */
-} clocks;
-
-
-#if defined(CRAY2) && defined(UNICOS5)
-extern int needtermstat;
-#endif
-
-#ifdef NEED_UNSETENV_PROTO
-extern void unsetenv(const char *);
-#endif
-#ifdef NEED_SETENV_PROTO
-extern void setenv(const char *, const char *, int);
-#endif
+++ /dev/null
-/*
- * Copyright (c) 1989, 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.
- */
-
-/* based on @(#)global.c 8.1 (Berkeley) 6/4/93 */
-
-/*
- * Allocate global variables. We do this
- * by including the header file that defines
- * them all as externs, but first we define
- * the keyword "extern" to be nothing, so that
- * we will actually allocate the space.
- */
-
-#include "defs.h"
-#define extern
-#include "ext.h"
+++ /dev/null
-/*
- * Copyright (c) 1989, 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.
- *
- * @(#)pathnames.h 8.1 (Berkeley) 6/4/93
- */
-
-#if BSD > 43
-
-# include <paths.h>
-
-# ifndef _PATH_LOGIN
-# define _PATH_LOGIN "/usr/bin/login"
-# endif
-
-#else
-
-# define _PATH_TTY "/dev/tty"
-# ifndef _PATH_LOGIN
-# define _PATH_LOGIN "/bin/login"
-# endif
-
-#endif
-
-#ifdef BFTPDAEMON
-#define BFTPPATH "/usr/ucb/bftp"
-#endif /* BFTPDAEMON */
+++ /dev/null
-/*
- * Copyright (c) 1989, 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.
- */
-
-/* based on @(#)slc.c 8.1 (Berkeley) 6/4/93 */
-
-#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()
-{
- register 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);
- }
-
-} /* end of send_slc */
-
-/*
- * default_slc
- *
- * Set pty special characters to all the defaults.
- */
- void
-default_slc()
-{
- register 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;
-
-} /* end of default_slc */
-#endif /* LINEMODE */
-
-/*
- * get_slc_defaults
- *
- * Initialize the slc mapping table.
- */
- void
-get_slc_defaults()
-{
- register 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;
- }
-
-} /* end of get_slc_defaults */
-
-#ifdef LINEMODE
-/*
- * add_slc
- *
- * Add an slc triplet to the slc buffer.
- */
- void
-add_slc(func, flag, val)
- register char func, flag;
- register 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;
-
-} /* end of add_slc */
-
-/*
- * 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(getit)
- register int getit;
-{
-
- slcchange = 0;
- if (getit)
- init_termbuf();
- (void) snprintf((char *)slcbuf, sizeof(slcbuf), "%c%c%c%c",
- IAC, SB, TELOPT_LINEMODE, LM_SLC);
- slcptr = slcbuf + 4;
-
-} /* end of start_slc */
-
-/*
- * end_slc
- *
- * Finish up the slc negotiation. If something to send, then send it.
- */
- int
-end_slc(bufp)
- register unsigned char **bufp;
-{
- register int len;
- void netflush();
-
- /*
- * 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 {
- *slcptr++ = IAC;
- *slcptr++ = SE;
- *slcptr = 0;
- len = slcptr - slcbuf;
- netwrite(slcbuf, len);
- netflush(); /* force it out immediately */
- DIAG(TD_OPTIONS, printsub('>', slcbuf+2, len-2););
- }
- }
- return (0);
-
-} /* end of end_slc */
-
-/*
- * process_slc
- *
- * Figure out what to do about the client's slc
- */
- void
-process_slc(func, flag, val)
- register unsigned char func, flag;
- register 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);
- }
-
-} /* end of process_slc */
-
-/*
- * 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(func, flag, val)
- register char func, flag;
- register 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);
- }
-
-} /* end of change_slc */
-
-#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()
-{
- register 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 /* defined(USE_TERMIO) && defined(SYSV_TERMIO) */
- 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);
- }
- }
-
-} /* check_slc */
-
-/*
- * 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(ptr, len)
- register unsigned char *ptr;
- register int len;
-{
- register unsigned char func, flag;
- cc_t val;
- register 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 == (unsigned char *)0) {
- def_slclen = len;
- def_slcbuf = (unsigned char *)malloc((unsigned)len);
- if (def_slcbuf == (unsigned char *)0)
- return; /* too bad */
- memcpy(def_slcbuf, ptr, len);
- }
- }
-
-} /* end of do_opt_slc */
-
-/*
- * deferslc
- *
- * Do slc stuff that was deferred.
- */
- void
-deferslc()
-{
- if (def_slcbuf) {
- start_slc(1);
- do_opt_slc(def_slcbuf, def_slclen);
- (void) end_slc(0);
- free(def_slcbuf);
- def_slcbuf = (unsigned char *)0;
- def_slclen = 0;
- }
-
-} /* end of deferslc */
-
-#endif /* LINEMODE */
+++ /dev/null
-/*
- * Copyright (c) 1989, 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.
- */
-
-/* based on @(#)state.c 8.1 (Berkeley) 6/4/93 */
-
-#include "telnetd.h"
-#if defined(AUTHENTICATION)
-#include <libtelnet/auth.h>
-#endif
-#if defined(ENCRYPTION)
-#include <libtelnet/encrypt.h>
-#endif
-
-unsigned char doopt[] = { IAC, DO, '%', 'c', 0 };
-unsigned char dont[] = { IAC, DONT, '%', 'c', 0 };
-unsigned char will[] = { IAC, WILL, '%', 'c', 0 };
-unsigned char wont[] = { IAC, WONT, '%', 'c', 0 };
-int not42 = 1;
-
-static int envvarok (char *);
-
-/*
- * Buffer for sub-options, and macros
- * for suboptions buffer manipulations
- */
-unsigned char subbuffer[TELNET_BUFSIZE], *subpointer= subbuffer, *subend= subbuffer;
-
-#define SB_CLEAR() subpointer = subbuffer
-#define SB_TERM() { subend = subpointer; SB_CLEAR(); }
-#define SB_ACCUM(c) if (subpointer < (subbuffer+sizeof subbuffer)) { \
- *subpointer++ = (c); \
- }
-#define SB_GET() ((*subpointer++)&0xff)
-#define SB_EOF() (subpointer >= subend)
-#define SB_LEN() (subend - subpointer)
-
-#ifdef ENV_HACK
-unsigned char *subsave;
-#define SB_SAVE() subsave = subpointer;
-#define SB_RESTORE() subpointer = subsave;
-#endif
-
-
-/*
- * State for recv fsm
- */
-#define TS_DATA 0 /* base state */
-#define TS_IAC 1 /* look for double IAC's */
-#define TS_CR 2 /* CR-LF ->'s CR */
-#define TS_SB 3 /* throw away begin's... */
-#define TS_SE 4 /* ...end's (suboption negotiation) */
-#define TS_WILL 5 /* will option negotiation */
-#define TS_WONT 6 /* wont " */
-#define TS_DO 7 /* do " */
-#define TS_DONT 8 /* dont " */
-
-static void sb_auth_complete()
-{
- if (!auth_negotiated) {
- static char *error =
- "An environment option was sent before authentication negotiation completed.\r\nThis may create a security hazard. Connection dropped.\r\n";
- netputs(error);
- netflush();
- exit(1);
- }
-}
-
- void
-telrcv()
-{
- register int c;
- static int state = TS_DATA;
-#if defined(CRAY2) && defined(UNICOS5)
- char *opfrontp = pfrontp;
-#endif
-
- while (ncc > 0) {
- if ((&ptyobuf[BUFSIZ] - pfrontp) < 1)
- break;
- c = *netip++ & 0377, ncc--;
-#ifdef ENCRYPTION
- if (decrypt_input)
- c = (*decrypt_input)(c);
-#endif /* ENCRYPTION */
- switch (state) {
-
- case TS_CR:
- state = TS_DATA;
- /* Strip off \n or \0 after a \r */
- if ((c == 0) || (c == '\n')) {
- break;
- }
- /* FALL THROUGH */
-
- case TS_DATA:
- if (c == IAC) {
- state = TS_IAC;
- break;
- }
- /*
- * We now map \r\n ==> \r for pragmatic reasons.
- * Many client implementations send \r\n when
- * the user hits the CarriageReturn key.
- *
- * We USED to map \r\n ==> \n, since \r\n says
- * that we want to be in column 1 of the next
- * printable line, and \n is the standard
- * unix way of saying that (\r is only good
- * if CRMOD is set, which it normally is).
- */
- if ((c == '\r') && his_state_is_wont(TELOPT_BINARY)) {
- int nc = *netip;
-#ifdef ENCRYPTION
- if (decrypt_input)
- nc = (*decrypt_input)(nc & 0xff);
-#endif /* ENCRYPTION */
-#ifdef LINEMODE
- /*
- * If we are operating in linemode,
- * convert to local end-of-line.
- */
- if (linemode && (ncc > 0) && (('\n' == nc) ||
- ((0 == nc) && tty_iscrnl())) ) {
- netip++; ncc--;
- c = '\n';
- } else
-#endif
- {
-#ifdef ENCRYPTION
- if (decrypt_input)
- (void)(*decrypt_input)(-1);
-#endif /* ENCRYPTION */
- state = TS_CR;
- }
- }
- *pfrontp++ = c;
- break;
-
- case TS_IAC:
-gotiac: switch (c) {
-
- /*
- * Send the process on the pty side an
- * interrupt. Do this with a NULL or
- * interrupt char; depending on the tty mode.
- */
- case IP:
- DIAG(TD_OPTIONS,
- printoption("td: recv IAC", c));
- interrupt();
- break;
-
- case BREAK:
- DIAG(TD_OPTIONS,
- printoption("td: recv IAC", c));
- sendbrk();
- break;
-
- /*
- * Are You There?
- */
- case AYT:
- DIAG(TD_OPTIONS,
- printoption("td: recv IAC", c));
- recv_ayt();
- break;
-
- /*
- * Abort Output
- */
- case AO:
- {
- DIAG(TD_OPTIONS,
- printoption("td: recv IAC", c));
- ptyflush(); /* half-hearted */
- init_termbuf();
-
- if (slctab[SLC_AO].sptr &&
- *slctab[SLC_AO].sptr != (cc_t)(_POSIX_VDISABLE)) {
- *pfrontp++ =
- (unsigned char)*slctab[SLC_AO].sptr;
- }
-
- netclear(); /* clear buffer back */
- netprintf_urg("%c%c", IAC, DM);
- DIAG(TD_OPTIONS,
- printoption("td: send IAC", DM));
- break;
- }
-
- /*
- * Erase Character and
- * Erase Line
- */
- case EC:
- case EL:
- {
- cc_t ch;
-
- DIAG(TD_OPTIONS,
- printoption("td: recv IAC", c));
- ptyflush(); /* half-hearted */
- init_termbuf();
- if (c == EC)
- ch = *slctab[SLC_EC].sptr;
- else
- ch = *slctab[SLC_EL].sptr;
- if (ch != (cc_t)(_POSIX_VDISABLE))
- *pfrontp++ = (unsigned char)ch;
- break;
- }
-
- /*
- * Check for urgent data...
- */
- case DM:
- DIAG(TD_OPTIONS,
- printoption("td: recv IAC", c));
- SYNCHing = stilloob(net);
- settimer(gotDM);
- break;
-
-
- /*
- * Begin option subnegotiation...
- */
- case SB:
- state = TS_SB;
- SB_CLEAR();
- continue;
-
- case WILL:
- state = TS_WILL;
- continue;
-
- case WONT:
- state = TS_WONT;
- continue;
-
- case DO:
- state = TS_DO;
- continue;
-
- case DONT:
- state = TS_DONT;
- continue;
- case EOR:
- if (his_state_is_will(TELOPT_EOR))
- doeof();
- break;
-
- /*
- * Handle RFC 10xx Telnet linemode option additions
- * to command stream (EOF, SUSP, ABORT).
- */
- case xEOF:
- doeof();
- break;
-
- case SUSP:
- sendsusp();
- break;
-
- case ABORT:
- sendbrk();
- break;
-
- case IAC:
- *pfrontp++ = c;
- break;
- }
- state = TS_DATA;
- break;
-
- case TS_SB:
- if (c == IAC) {
- state = TS_SE;
- } else {
- SB_ACCUM(c);
- }
- break;
-
- case TS_SE:
- if (c != SE) {
- if (c != IAC) {
- /*
- * bad form of suboption negotiation.
- * handle it in such a way as to avoid
- * damage to local state. Parse
- * suboption buffer found so far,
- * then treat remaining stream as
- * another command sequence.
- */
-
- /* for DIAGNOSTICS */
- SB_ACCUM(IAC);
- SB_ACCUM(c);
- subpointer -= 2;
-
- SB_TERM();
- suboption();
- state = TS_IAC;
- goto gotiac;
- }
- SB_ACCUM(c);
- state = TS_SB;
- } else {
- /* for DIAGNOSTICS */
- SB_ACCUM(IAC);
- SB_ACCUM(SE);
- subpointer -= 2;
-
- SB_TERM();
- suboption(); /* handle sub-option */
- state = TS_DATA;
- }
- break;
-
- case TS_WILL:
- willoption(c);
- state = TS_DATA;
- continue;
-
- case TS_WONT:
- wontoption(c);
- state = TS_DATA;
- continue;
-
- case TS_DO:
- dooption(c);
- state = TS_DATA;
- continue;
-
- case TS_DONT:
- dontoption(c);
- state = TS_DATA;
- continue;
-
- default:
- syslog(LOG_ERR, "telnetd: panic state=%d", state);
- printf("telnetd: panic state=%d\n", state);
- exit(1);
- }
- }
-#if defined(CRAY2) && defined(UNICOS5)
- if (!linemode) {
- char xptyobuf[BUFSIZ+NETSLOP];
- char xbuf2[BUFSIZ];
- register char *cp;
- int n = pfrontp - opfrontp, oc;
- memcpy(xptyobuf, opfrontp, n);
- pfrontp = opfrontp;
- pfrontp += term_input(xptyobuf, pfrontp, n, BUFSIZ+NETSLOP,
- xbuf2, &oc, BUFSIZ);
- for (cp = xbuf2; oc > 0; --oc) {
- if (*cp == IAC)
- netprintf("%c%c", *cp++, IAC);
- else
- netprintf("%c", *cp++);
- }
- }
-#endif /* defined(CRAY2) && defined(UNICOS5) */
-} /* end of telrcv */
-
-/*
- * The will/wont/do/dont state machines are based on Dave Borman's
- * Telnet option processing state machine.
- *
- * These correspond to the following states:
- * my_state = the last negotiated state
- * want_state = what I want the state to go to
- * want_resp = how many requests I have sent
- * All state defaults are negative, and resp defaults to 0.
- *
- * When initiating a request to change state to new_state:
- *
- * if ((want_resp == 0 && new_state == my_state) || want_state == new_state) {
- * do nothing;
- * } else {
- * want_state = new_state;
- * send new_state;
- * want_resp++;
- * }
- *
- * When receiving new_state:
- *
- * if (want_resp) {
- * want_resp--;
- * if (want_resp && (new_state == my_state))
- * want_resp--;
- * }
- * if ((want_resp == 0) && (new_state != want_state)) {
- * if (ok_to_switch_to new_state)
- * want_state = new_state;
- * else
- * want_resp++;
- * send want_state;
- * }
- * my_state = new_state;
- *
- * Note that new_state is implied in these functions by the function itself.
- * will and do imply positive new_state, wont and dont imply negative.
- *
- * Finally, there is one catch. If we send a negative response to a
- * positive request, my_state will be the positive while want_state will
- * remain negative. my_state will revert to negative when the negative
- * acknowlegment arrives from the peer. Thus, my_state generally tells
- * us not only the last negotiated state, but also tells us what the peer
- * wants to be doing as well. It is important to understand this difference
- * as we may wish to be processing data streams based on our desired state
- * (want_state) or based on what the peer thinks the state is (my_state).
- *
- * This all works fine because if the peer sends a positive request, the data
- * that we receive prior to negative acknowlegment will probably be affected
- * by the positive state, and we can process it as such (if we can; if we
- * can't then it really doesn't matter). If it is that important, then the
- * peer probably should be buffering until this option state negotiation
- * is complete.
- *
- */
- void
-send_do(option, init)
- int option, init;
-{
- if (init) {
- if ((do_dont_resp[option] == 0 && his_state_is_will(option)) ||
- his_want_state_is_will(option))
- return;
- /*
- * Special case for TELOPT_TM: We send a DO, but pretend
- * that we sent a DONT, so that we can send more DOs if
- * we want to.
- */
- if (option == TELOPT_TM)
- set_his_want_state_wont(option);
- else
- set_his_want_state_will(option);
- do_dont_resp[option]++;
- }
- netprintf((char *)doopt, option);
-
- DIAG(TD_OPTIONS, printoption("td: send do", option));
-}
-
-#ifdef AUTHENTICATION
-extern void auth_request();
-#endif
-#ifdef LINEMODE
-static void doclientstat(void);
-#endif
-#ifdef ENCRYPTION
-extern void encrypt_send_support();
-#endif /* ENCRYPTION */
-
- void
-willoption(option)
- int option;
-{
- int changeok = 0;
- void (*func)() = 0;
-
- /*
- * process input from peer.
- */
-
- DIAG(TD_OPTIONS, printoption("td: recv will", option));
-
- if (do_dont_resp[option]) {
- do_dont_resp[option]--;
- if (do_dont_resp[option] && his_state_is_will(option))
- do_dont_resp[option]--;
- }
- if (do_dont_resp[option] == 0) {
- if (his_want_state_is_wont(option)) {
- switch (option) {
-
- case TELOPT_BINARY:
- init_termbuf();
- tty_binaryin(1);
- set_termbuf();
- changeok++;
- break;
-
- case TELOPT_ECHO:
- /*
- * See comments below for more info.
- */
- not42 = 0; /* looks like a 4.2 system */
- break;
-
- case TELOPT_TM:
-#if defined(LINEMODE) && defined(KLUDGELINEMODE)
- /*
- * This telnetd implementation does not really
- * support timing marks, it just uses them to
- * support the kludge linemode stuff. If we
- * receive a will or wont TM in response to our
- * do TM request that may have been sent to
- * determine kludge linemode support, process
- * it, otherwise TM should get a negative
- * response back.
- */
- /*
- * Handle the linemode kludge stuff.
- * If we are not currently supporting any
- * linemode at all, then we assume that this
- * is the client telling us to use kludge
- * linemode in response to our query. Set the
- * linemode type that is to be supported, note
- * that the client wishes to use linemode, and
- * eat the will TM as though it never arrived.
- */
- if (lmodetype < KLUDGE_LINEMODE) {
- lmodetype = KLUDGE_LINEMODE;
- clientstat(TELOPT_LINEMODE, WILL, 0);
- send_wont(TELOPT_SGA, 1);
- } else if (lmodetype == NO_AUTOKLUDGE) {
- lmodetype = KLUDGE_OK;
- }
-#endif /* defined(LINEMODE) && defined(KLUDGELINEMODE) */
- /*
- * We never respond to a WILL TM, and
- * we leave the state WONT.
- */
- return;
-
- case TELOPT_LFLOW:
- /*
- * If we are going to support flow control
- * option, then don't worry peer that we can't
- * change the flow control characters.
- */
- slctab[SLC_XON].defset.flag &= ~SLC_LEVELBITS;
- slctab[SLC_XON].defset.flag |= SLC_DEFAULT;
- slctab[SLC_XOFF].defset.flag &= ~SLC_LEVELBITS;
- slctab[SLC_XOFF].defset.flag |= SLC_DEFAULT;
- case TELOPT_TTYPE:
- case TELOPT_SGA:
- case TELOPT_NAWS:
- case TELOPT_TSPEED:
- case TELOPT_XDISPLOC:
- case TELOPT_NEW_ENVIRON:
- case TELOPT_OLD_ENVIRON:
- changeok++;
- break;
-
-#ifdef LINEMODE
- case TELOPT_LINEMODE:
-# ifdef KLUDGELINEMODE
- /*
- * Note client's desire to use linemode.
- */
- lmodetype = REAL_LINEMODE;
-# endif /* KLUDGELINEMODE */
- func = doclientstat;
- changeok++;
- break;
-#endif /* LINEMODE */
-
-#ifdef AUTHENTICATION
- case TELOPT_AUTHENTICATION:
- func = auth_request;
- changeok++;
- break;
-#endif
-
-#ifdef ENCRYPTION
- case TELOPT_ENCRYPT:
- func = encrypt_send_support;
- changeok++;
- break;
-#endif /* ENCRYPTION */
-
- default:
- break;
- }
- if (changeok) {
- set_his_want_state_will(option);
- send_do(option, 0);
- } else {
- do_dont_resp[option]++;
- send_dont(option, 0);
- }
- } else {
- /*
- * Option processing that should happen when
- * we receive conformation of a change in
- * state that we had requested.
- */
- switch (option) {
- case TELOPT_ECHO:
- not42 = 0; /* looks like a 4.2 system */
- /*
- * Egads, he responded "WILL ECHO". Turn
- * it off right now!
- */
- send_dont(option, 1);
- /*
- * "WILL ECHO". Kludge upon kludge!
- * A 4.2 client is now echoing user input at
- * the tty. This is probably undesireable and
- * it should be stopped. The client will
- * respond WONT TM to the DO TM that we send to
- * check for kludge linemode. When the WONT TM
- * arrives, linemode will be turned off and a
- * change propogated to the pty. This change
- * will cause us to process the new pty state
- * in localstat(), which will notice that
- * linemode is off and send a WILL ECHO
- * so that we are properly in character mode and
- * all is well.
- */
- break;
-#ifdef LINEMODE
- case TELOPT_LINEMODE:
-# ifdef KLUDGELINEMODE
- /*
- * Note client's desire to use linemode.
- */
- lmodetype = REAL_LINEMODE;
-# endif /* KLUDGELINEMODE */
- func = doclientstat;
- break;
-#endif /* LINEMODE */
-
-#ifdef AUTHENTICATION
- case TELOPT_AUTHENTICATION:
- func = auth_request;
- break;
-#endif
-
-#ifdef ENCRYPTION
- case TELOPT_ENCRYPT:
- func = encrypt_send_support;
- break;
-#endif /* ENCRYPTION */
- case TELOPT_LFLOW:
- func = flowstat;
- break;
- }
- }
- }
- set_his_state_will(option);
- if (func)
- (*func)();
-} /* end of willoption */
-
- void
-send_dont(option, init)
- int option, init;
-{
- if (init) {
- if ((do_dont_resp[option] == 0 && his_state_is_wont(option)) ||
- his_want_state_is_wont(option))
- return;
- set_his_want_state_wont(option);
- do_dont_resp[option]++;
- }
- netprintf((char *)dont, option);
-
- DIAG(TD_OPTIONS, printoption("td: send dont", option));
-}
-
- void
-wontoption(option)
- int option;
-{
- /*
- * Process client input.
- */
-
- DIAG(TD_OPTIONS, printoption("td: recv wont", option));
-
- if (do_dont_resp[option]) {
- do_dont_resp[option]--;
- if (do_dont_resp[option] && his_state_is_wont(option))
- do_dont_resp[option]--;
- }
- if (do_dont_resp[option] == 0) {
- if (his_want_state_is_will(option)) {
- /* it is always ok to change to negative state */
- switch (option) {
- case TELOPT_ECHO:
- not42 = 1; /* doesn't seem to be a 4.2 system */
- break;
-
- case TELOPT_BINARY:
- init_termbuf();
- tty_binaryin(0);
- set_termbuf();
- break;
-
-#ifdef LINEMODE
- case TELOPT_LINEMODE:
-# ifdef KLUDGELINEMODE
- /*
- * If real linemode is supported, then client is
- * asking to turn linemode off.
- */
- if (lmodetype != REAL_LINEMODE)
- break;
- lmodetype = KLUDGE_LINEMODE;
-# endif /* KLUDGELINEMODE */
- clientstat(TELOPT_LINEMODE, WONT, 0);
- break;
-#endif /* LINEMODE */
-
- case TELOPT_TM:
- /*
- * If we get a WONT TM, and had sent a DO TM,
- * don't respond with a DONT TM, just leave it
- * as is. Short circut the state machine to
- * achive this.
- */
- set_his_want_state_wont(TELOPT_TM);
- return;
-
- case TELOPT_LFLOW:
- /*
- * If we are not going to support flow control
- * option, then let peer know that we can't
- * change the flow control characters.
- */
- slctab[SLC_XON].defset.flag &= ~SLC_LEVELBITS;
- slctab[SLC_XON].defset.flag |= SLC_CANTCHANGE;
- slctab[SLC_XOFF].defset.flag &= ~SLC_LEVELBITS;
- slctab[SLC_XOFF].defset.flag |= SLC_CANTCHANGE;
- break;
-
-#if defined(AUTHENTICATION)
- case TELOPT_AUTHENTICATION:
- auth_finished(0, AUTH_REJECT);
- break;
-#endif
-
- /*
- * For options that we might spin waiting for
- * sub-negotiation, if the client turns off the
- * option rather than responding to the request,
- * we have to treat it here as if we got a response
- * to the sub-negotiation, (by updating the timers)
- * so that we'll break out of the loop.
- */
- case TELOPT_TTYPE:
- settimer(ttypesubopt);
- break;
-
- case TELOPT_TSPEED:
- settimer(tspeedsubopt);
- break;
-
- case TELOPT_XDISPLOC:
- settimer(xdisplocsubopt);
- break;
-
- case TELOPT_OLD_ENVIRON:
- settimer(oenvironsubopt);
- break;
-
- case TELOPT_NEW_ENVIRON:
- settimer(environsubopt);
- break;
-
- default:
- break;
- }
- set_his_want_state_wont(option);
- if (his_state_is_will(option))
- send_dont(option, 0);
- } else {
- switch (option) {
- case TELOPT_TM:
-#if defined(LINEMODE) && defined(KLUDGELINEMODE)
- if (lmodetype < NO_AUTOKLUDGE) {
- lmodetype = NO_LINEMODE;
- clientstat(TELOPT_LINEMODE, WONT, 0);
- send_will(TELOPT_SGA, 1);
- send_will(TELOPT_ECHO, 1);
- }
-#endif /* defined(LINEMODE) && defined(KLUDGELINEMODE) */
- break;
-
-#if defined(AUTHENTICATION)
- case TELOPT_AUTHENTICATION:
- auth_finished(0, AUTH_REJECT);
- break;
-#endif
- default:
- break;
- }
- }
- }
- set_his_state_wont(option);
-
-} /* end of wontoption */
-
- void
-send_will(option, init)
- int option, init;
-{
- if (init) {
- if ((will_wont_resp[option] == 0 && my_state_is_will(option))||
- my_want_state_is_will(option))
- return;
- set_my_want_state_will(option);
- will_wont_resp[option]++;
- }
- netprintf((char *)will, option);
-
- DIAG(TD_OPTIONS, printoption("td: send will", option));
-}
-
-#if !defined(LINEMODE) || !defined(KLUDGELINEMODE)
-/*
- * When we get a DONT SGA, we will try once to turn it
- * back on. If the other side responds DONT SGA, we
- * leave it at that. This is so that when we talk to
- * clients that understand KLUDGELINEMODE but not LINEMODE,
- * we'll keep them in char-at-a-time mode.
- */
-int turn_on_sga = 0;
-#endif
-
- void
-dooption(option)
- int option;
-{
- int changeok = 0;
-
- /*
- * Process client input.
- */
-
- DIAG(TD_OPTIONS, printoption("td: recv do", option));
-
- if (will_wont_resp[option]) {
- will_wont_resp[option]--;
- if (will_wont_resp[option] && my_state_is_will(option))
- will_wont_resp[option]--;
- }
- if ((will_wont_resp[option] == 0) && (my_want_state_is_wont(option))) {
- switch (option) {
- case TELOPT_ECHO:
-#ifdef LINEMODE
-# ifdef KLUDGELINEMODE
- if (lmodetype == NO_LINEMODE)
-# else
- if (his_state_is_wont(TELOPT_LINEMODE))
-# endif
-#endif
- {
- init_termbuf();
- tty_setecho(1);
- set_termbuf();
- }
- changeok++;
- break;
-
- case TELOPT_BINARY:
- init_termbuf();
- tty_binaryout(1);
- set_termbuf();
- changeok++;
- break;
-
- case TELOPT_SGA:
-#if defined(LINEMODE) && defined(KLUDGELINEMODE)
- /*
- * If kludge linemode is in use, then we must
- * process an incoming do SGA for linemode
- * purposes.
- */
- if (lmodetype == KLUDGE_LINEMODE) {
- /*
- * Receipt of "do SGA" in kludge
- * linemode is the peer asking us to
- * turn off linemode. Make note of
- * the request.
- */
- clientstat(TELOPT_LINEMODE, WONT, 0);
- /*
- * If linemode did not get turned off
- * then don't tell peer that we did.
- * Breaking here forces a wont SGA to
- * be returned.
- */
- if (linemode)
- break;
- }
-#else
- turn_on_sga = 0;
-#endif /* defined(LINEMODE) && defined(KLUDGELINEMODE) */
- changeok++;
- break;
-
- case TELOPT_STATUS:
- changeok++;
- break;
-
- case TELOPT_TM:
- /*
- * Special case for TM. We send a WILL, but
- * pretend we sent a WONT.
- */
- send_will(option, 0);
- set_my_want_state_wont(option);
- set_my_state_wont(option);
- return;
-
- case TELOPT_LOGOUT:
- /*
- * When we get a LOGOUT option, respond
- * with a WILL LOGOUT, make sure that
- * it gets written out to the network,
- * and then just go away...
- */
- set_my_want_state_will(TELOPT_LOGOUT);
- send_will(TELOPT_LOGOUT, 0);
- set_my_state_will(TELOPT_LOGOUT);
- (void)netflush();
- (void)signal(SIGCHLD, SIG_DFL);
- cleanup(0);
- /* NOT REACHED */
- break;
-
-#ifdef ENCRYPTION
- case TELOPT_ENCRYPT:
- changeok++;
- break;
-#endif /* ENCRYPTION */
- case TELOPT_LINEMODE:
- case TELOPT_TTYPE:
- case TELOPT_NAWS:
- case TELOPT_TSPEED:
- case TELOPT_LFLOW:
- case TELOPT_XDISPLOC:
-#ifdef TELOPT_ENVIRON
- case TELOPT_NEW_ENVIRON:
-#endif
- case TELOPT_OLD_ENVIRON:
- default:
- break;
- }
- if (changeok) {
- set_my_want_state_will(option);
- send_will(option, 0);
- } else {
- will_wont_resp[option]++;
- send_wont(option, 0);
- }
- }
- set_my_state_will(option);
-
-} /* end of dooption */
-
- void
-send_wont(option, init)
- int option, init;
-{
- if (init) {
- if ((will_wont_resp[option] == 0 && my_state_is_wont(option)) ||
- my_want_state_is_wont(option))
- return;
- set_my_want_state_wont(option);
- will_wont_resp[option]++;
- }
- netprintf((char *)wont, option);
-
- DIAG(TD_OPTIONS, printoption("td: send wont", option));
-}
-
- void
-dontoption(option)
- int option;
-{
- /*
- * Process client input.
- */
-
-
- DIAG(TD_OPTIONS, printoption("td: recv dont", option));
-
- if (will_wont_resp[option]) {
- will_wont_resp[option]--;
- if (will_wont_resp[option] && my_state_is_wont(option))
- will_wont_resp[option]--;
- }
- if ((will_wont_resp[option] == 0) && (my_want_state_is_will(option))) {
- switch (option) {
- case TELOPT_BINARY:
- init_termbuf();
- tty_binaryout(0);
- set_termbuf();
- break;
-
- case TELOPT_ECHO: /* we should stop echoing */
-#ifdef LINEMODE
-# ifdef KLUDGELINEMODE
- if ((lmodetype != REAL_LINEMODE) &&
- (lmodetype != KLUDGE_LINEMODE))
-# else
- if (his_state_is_wont(TELOPT_LINEMODE))
-# endif
-#endif
- {
- init_termbuf();
- tty_setecho(0);
- set_termbuf();
- }
- break;
-
- case TELOPT_SGA:
-#if defined(LINEMODE) && defined(KLUDGELINEMODE)
- /*
- * If kludge linemode is in use, then we
- * must process an incoming do SGA for
- * linemode purposes.
- */
- if ((lmodetype == KLUDGE_LINEMODE) ||
- (lmodetype == KLUDGE_OK)) {
- /*
- * The client is asking us to turn
- * linemode on.
- */
- lmodetype = KLUDGE_LINEMODE;
- clientstat(TELOPT_LINEMODE, WILL, 0);
- /*
- * If we did not turn line mode on,
- * then what do we say? Will SGA?
- * This violates design of telnet.
- * Gross. Very Gross.
- */
- }
- break;
-#else
- set_my_want_state_wont(option);
- if (my_state_is_will(option))
- send_wont(option, 0);
- set_my_state_wont(option);
- if (turn_on_sga ^= 1)
- send_will(option, 1);
- return;
-#endif /* defined(LINEMODE) && defined(KLUDGELINEMODE) */
-
- default:
- break;
- }
-
- set_my_want_state_wont(option);
- if (my_state_is_will(option))
- send_wont(option, 0);
- }
- set_my_state_wont(option);
-
-} /* end of dontoption */
-
-#ifdef ENV_HACK
-int env_ovar = -1;
-int env_ovalue = -1;
-#else /* ENV_HACK */
-# define env_ovar OLD_ENV_VAR
-# define env_ovalue OLD_ENV_VALUE
-#endif /* ENV_HACK */
-
-/*
- * suboption()
- *
- * Look at the sub-option buffer, and try to be helpful to the other
- * side.
- *
- * Currently we recognize:
- *
- * Terminal type is
- * Linemode
- * Window size
- * Terminal speed
- */
- void
-suboption()
-{
- register int subchar;
-
- DIAG(TD_OPTIONS, {netflush(); printsub('<', subpointer, SB_LEN()+2);});
-
- subchar = SB_GET();
- switch (subchar) {
- case TELOPT_TSPEED: {
- register int xspeed, rspeed;
-
- if (his_state_is_wont(TELOPT_TSPEED)) /* Ignore if option disabled */
- break;
-
- sb_auth_complete();
-
- settimer(tspeedsubopt);
-
- if (SB_EOF() || SB_GET() != TELQUAL_IS)
- return;
-
- xspeed = atoi((char *)subpointer);
-
- while (SB_GET() != ',' && !SB_EOF());
- if (SB_EOF())
- return;
-
- rspeed = atoi((char *)subpointer);
- clientstat(TELOPT_TSPEED, xspeed, rspeed);
-
- break;
-
- } /* end of case TELOPT_TSPEED */
-
- case TELOPT_TTYPE: { /* Yaaaay! */
- char *tt;
-
- if (his_state_is_wont(TELOPT_TTYPE)) /* Ignore if option disabled */
- break;
- sb_auth_complete();
- settimer(ttypesubopt);
-
- if (SB_EOF() || SB_GET() != TELQUAL_IS) {
- return; /* ??? XXX but, this is the most robust */
- }
-
- tt = terminaltype;
-
- while ((tt < (terminaltype + sizeof(terminaltype) - 1)) && !SB_EOF()) {
- register int c;
-
- c = SB_GET();
- if (isupper(c)) {
- c = tolower(c);
- }
- *tt++ = c; /* accumulate name */
- }
- *tt = 0;
- break;
- } /* end of case TELOPT_TTYPE */
-
- case TELOPT_NAWS: {
- register int xwinsize, ywinsize;
-
- if (his_state_is_wont(TELOPT_NAWS)) /* Ignore if option disabled */
- break;
-
- if (SB_EOF())
- return;
- xwinsize = SB_GET() << 8;
- if (SB_EOF())
- return;
- xwinsize |= SB_GET();
- if (SB_EOF())
- return;
- ywinsize = SB_GET() << 8;
- if (SB_EOF())
- return;
- ywinsize |= SB_GET();
- clientstat(TELOPT_NAWS, xwinsize, ywinsize);
-
- break;
-
- } /* end of case TELOPT_NAWS */
-
-#ifdef LINEMODE
- case TELOPT_LINEMODE: {
- register int request;
-
- if (his_state_is_wont(TELOPT_LINEMODE)) /* Ignore if option disabled */
- break;
- /*
- * Process linemode suboptions.
- */
- if (SB_EOF())
- break; /* garbage was sent */
- request = SB_GET(); /* get will/wont */
-
- if (SB_EOF())
- break; /* another garbage check */
-
- if (request == LM_SLC) { /* SLC is not preceeded by WILL or WONT */
- /*
- * Process suboption buffer of slc's
- */
- start_slc(1);
- do_opt_slc(subpointer, subend - subpointer);
- (void) end_slc(0);
- break;
- } else if (request == LM_MODE) {
- if (SB_EOF())
- return;
- useeditmode = SB_GET(); /* get mode flag */
- clientstat(LM_MODE, 0, 0);
- break;
- }
-
- if (SB_EOF())
- break;
- switch (SB_GET()) { /* what suboption? */
- case LM_FORWARDMASK:
- /*
- * According to spec, only server can send request for
- * forwardmask, and client can only return a positive response.
- * So don't worry about it.
- */
-
- default:
- break;
- }
- break;
- } /* end of case TELOPT_LINEMODE */
-#endif
- case TELOPT_STATUS: {
- int mode;
-
- if (SB_EOF())
- break;
- mode = SB_GET();
- switch (mode) {
- case TELQUAL_SEND:
- if (my_state_is_will(TELOPT_STATUS))
- send_status();
- break;
-
- case TELQUAL_IS:
- break;
-
- default:
- break;
- }
- break;
- } /* end of case TELOPT_STATUS */
-
- case TELOPT_XDISPLOC: {
- if (SB_EOF() || SB_GET() != TELQUAL_IS)
- return;
- sb_auth_complete();
- settimer(xdisplocsubopt);
- subpointer[SB_LEN()] = '\0';
- (void)setenv("DISPLAY", (char *)subpointer, 1);
- break;
- } /* end of case TELOPT_XDISPLOC */
-
-#ifdef TELOPT_NEW_ENVIRON
- case TELOPT_NEW_ENVIRON:
-#endif
- case TELOPT_OLD_ENVIRON: {
- register int c;
- register char *cp, *varp, *valp;
-
- if (SB_EOF())
- return;
- sb_auth_complete();
- c = SB_GET();
- if (c == TELQUAL_IS) {
- if (subchar == TELOPT_OLD_ENVIRON)
- settimer(oenvironsubopt);
- else
- settimer(environsubopt);
- } else if (c != TELQUAL_INFO) {
- return;
- }
-
-#ifdef TELOPT_NEW_ENVIRON
- if (subchar == TELOPT_NEW_ENVIRON) {
- while (!SB_EOF()) {
- c = SB_GET();
- if ((c == NEW_ENV_VAR) || (c == ENV_USERVAR))
- break;
- }
- } else
-#endif
- {
-#ifdef ENV_HACK
- /*
- * We only want to do this if we haven't already decided
- * whether or not the other side has its VALUE and VAR
- * reversed.
- */
- if (env_ovar < 0) {
- register int last = -1; /* invalid value */
- int empty = 0;
- int got_var = 0, got_value = 0, got_uservar = 0;
-
- /*
- * The other side might have its VALUE and VAR values
- * reversed. To be interoperable, we need to determine
- * which way it is. If the first recognized character
- * is a VAR or VALUE, then that will tell us what
- * type of client it is. If the fist recognized
- * character is a USERVAR, then we continue scanning
- * the suboption looking for two consecutive
- * VAR or VALUE fields. We should not get two
- * consecutive VALUE fields, so finding two
- * consecutive VALUE or VAR fields will tell us
- * what the client is.
- */
- SB_SAVE();
- while (!SB_EOF()) {
- c = SB_GET();
- switch(c) {
- case OLD_ENV_VAR:
- if (last < 0 || last == OLD_ENV_VAR
- || (empty && (last == OLD_ENV_VALUE)))
- goto env_ovar_ok;
- got_var++;
- last = OLD_ENV_VAR;
- break;
- case OLD_ENV_VALUE:
- if (last < 0 || last == OLD_ENV_VALUE
- || (empty && (last == OLD_ENV_VAR)))
- goto env_ovar_wrong;
- got_value++;
- last = OLD_ENV_VALUE;
- break;
- case ENV_USERVAR:
- /* count strings of USERVAR as one */
- if (last != ENV_USERVAR)
- got_uservar++;
- if (empty) {
- if (last == OLD_ENV_VALUE)
- goto env_ovar_ok;
- if (last == OLD_ENV_VAR)
- goto env_ovar_wrong;
- }
- last = ENV_USERVAR;
- break;
- case ENV_ESC:
- if (!SB_EOF())
- c = SB_GET();
- /* FALL THROUGH */
- default:
- empty = 0;
- continue;
- }
- empty = 1;
- }
- if (empty) {
- if (last == OLD_ENV_VALUE)
- goto env_ovar_ok;
- if (last == OLD_ENV_VAR)
- goto env_ovar_wrong;
- }
- /*
- * Ok, the first thing was a USERVAR, and there
- * are not two consecutive VAR or VALUE commands,
- * and none of the VAR or VALUE commands are empty.
- * If the client has sent us a well-formed option,
- * then the number of VALUEs received should always
- * be less than or equal to the number of VARs and
- * USERVARs received.
- *
- * If we got exactly as many VALUEs as VARs and
- * USERVARs, the client has the same definitions.
- *
- * If we got exactly as many VARs as VALUEs and
- * USERVARS, the client has reversed definitions.
- */
- if (got_uservar + got_var == got_value) {
- env_ovar_ok:
- env_ovar = OLD_ENV_VAR;
- env_ovalue = OLD_ENV_VALUE;
- } else if (got_uservar + got_value == got_var) {
- env_ovar_wrong:
- env_ovar = OLD_ENV_VALUE;
- env_ovalue = OLD_ENV_VAR;
- DIAG(TD_OPTIONS,
- netputs("ENVIRON VALUE and VAR are reversed!\r\n"));
- }
- }
- SB_RESTORE();
-#endif
-
- while (!SB_EOF()) {
- c = SB_GET();
- if ((c == env_ovar) || (c == ENV_USERVAR))
- break;
- }
- }
-
- if (SB_EOF())
- return;
-
- cp = varp = (char *)subpointer;
- valp = 0;
-
- while (!SB_EOF()) {
- c = SB_GET();
- if (subchar == TELOPT_OLD_ENVIRON) {
- if (c == env_ovar)
- c = NEW_ENV_VAR;
- else if (c == env_ovalue)
- c = NEW_ENV_VALUE;
- }
- switch (c) {
-
- case NEW_ENV_VALUE:
- *cp = '\0';
- cp = valp = (char *)subpointer;
- break;
-
- case NEW_ENV_VAR:
- case ENV_USERVAR:
- *cp = '\0';
- if (envvarok(varp)) {
- if (valp)
- (void)setenv(varp, valp, 1);
- else
- unsetenv(varp);
- }
- cp = varp = (char *)subpointer;
- valp = 0;
- break;
-
- case ENV_ESC:
- if (SB_EOF())
- break;
- c = SB_GET();
- /* FALL THROUGH */
- default:
- *cp++ = c;
- break;
- }
- }
- *cp = '\0';
- if (envvarok(varp)) {
- if (valp)
- (void)setenv(varp, valp, 1);
- else
- unsetenv(varp);
- }
- break;
- } /* end of case TELOPT_NEW_ENVIRON */
-#if defined(AUTHENTICATION)
- case TELOPT_AUTHENTICATION:
- if (SB_EOF())
- break;
- switch(SB_GET()) {
- case TELQUAL_SEND:
- case TELQUAL_REPLY:
- /*
- * These are sent by us and cannot be sent by
- * the client.
- */
- break;
- case TELQUAL_IS:
- if (!auth_negotiated)
- auth_is(subpointer, SB_LEN());
- break;
- case TELQUAL_NAME:
- if (!auth_negotiated)
- auth_name(subpointer, SB_LEN());
- break;
- }
- break;
-#endif
-#ifdef ENCRYPTION
- case TELOPT_ENCRYPT:
- if (SB_EOF())
- break;
- switch(SB_GET()) {
- case ENCRYPT_SUPPORT:
- encrypt_support(subpointer, SB_LEN());
- break;
- case ENCRYPT_IS:
- encrypt_is(subpointer, SB_LEN());
- break;
- case ENCRYPT_REPLY:
- encrypt_reply(subpointer, SB_LEN());
- break;
- case ENCRYPT_START:
- encrypt_start(subpointer, SB_LEN());
- break;
- case ENCRYPT_END:
- encrypt_end();
- break;
- case ENCRYPT_REQSTART:
- encrypt_request_start(subpointer, SB_LEN());
- break;
- case ENCRYPT_REQEND:
- /*
- * We can always send an REQEND so that we cannot
- * get stuck encrypting. We should only get this
- * if we have been able to get in the correct mode
- * anyhow.
- */
- encrypt_request_end();
- break;
- case ENCRYPT_ENC_KEYID:
- encrypt_enc_keyid(subpointer, SB_LEN());
- break;
- case ENCRYPT_DEC_KEYID:
- encrypt_dec_keyid(subpointer, SB_LEN());
- break;
- default:
- break;
- }
- break;
-#endif /* ENCRYPTION */
-
- default:
- break;
- } /* end of switch */
-
-} /* end of suboption */
-
-#ifdef LINEMODE
-static void
-doclientstat()
-{
- clientstat(TELOPT_LINEMODE, WILL, 0);
-}
-#endif
-
-#define ADD(c) *ncp++ = c;
-#define ADD_DATA(c) { *ncp++ = c; if (c == SE) *ncp++ = c; }
- void
-send_status()
-{
- unsigned char statusbuf[256];
- register unsigned char *ncp;
- register unsigned char i;
-
- ncp = statusbuf;
-
- netflush(); /* get rid of anything waiting to go out */
-
- ADD(IAC);
- ADD(SB);
- ADD(TELOPT_STATUS);
- ADD(TELQUAL_IS);
-
- /*
- * We check the want_state rather than the current state,
- * because if we received a DO/WILL for an option that we
- * don't support, and the other side didn't send a DONT/WONT
- * in response to our WONT/DONT, then the "state" will be
- * WILL/DO, and the "want_state" will be WONT/DONT. We
- * need to go by the latter.
- */
- for (i = 0; i < (unsigned char)NTELOPTS; i++) {
- if (my_want_state_is_will(i)) {
- ADD(WILL);
- ADD_DATA(i);
- if (i == IAC)
- ADD(IAC);
- }
- if (his_want_state_is_will(i)) {
- ADD(DO);
- ADD_DATA(i);
- if (i == IAC)
- ADD(IAC);
- }
- }
-
- if (his_want_state_is_will(TELOPT_LFLOW)) {
- ADD(SB);
- ADD(TELOPT_LFLOW);
- if (flowmode) {
- ADD(LFLOW_ON);
- } else {
- ADD(LFLOW_OFF);
- }
- ADD(SE);
-
- if (restartany >= 0) {
- ADD(SB)
- ADD(TELOPT_LFLOW);
- if (restartany) {
- ADD(LFLOW_RESTART_ANY);
- } else {
- ADD(LFLOW_RESTART_XON);
- }
- ADD(SE)
- ADD(SB);
- }
- }
-
-#ifdef LINEMODE
- if (his_want_state_is_will(TELOPT_LINEMODE)) {
- unsigned char *cp, *cpe;
- int len;
-
- ADD(SB);
- ADD(TELOPT_LINEMODE);
- ADD(LM_MODE);
- ADD_DATA(editmode);
- if (editmode == IAC)
- ADD(IAC);
- ADD(SE);
-
- ADD(SB);
- ADD(TELOPT_LINEMODE);
- ADD(LM_SLC);
- start_slc(0);
- send_slc();
- len = end_slc(&cp);
- for (cpe = cp + len; cp < cpe; cp++)
- ADD_DATA(*cp);
- ADD(SE);
- }
-#endif /* LINEMODE */
-
- ADD(IAC);
- ADD(SE);
-
- netwrite(statusbuf, (unsigned) (ncp - statusbuf));
- netflush(); /* Send it on its way */
-
- DIAG(TD_OPTIONS,
- {printsub('>', statusbuf, ncp - statusbuf); netflush();});
-}
-
-static int envvarok(varp)
- char *varp;
-{
- if (!strchr(varp, '=') &&
- strcmp(varp, "TERMCAP") && /* to prevent a security hole */
- strcmp(varp, "TERMINFO") && /* with tgetent */
- strcmp(varp, "TERMPATH") &&
- strcmp(varp, "HOME") && /* to prevent the tegetent bug */
- strncmp(varp, "LD_", strlen("LD_")) && /* most systems */
- strncmp(varp, "_RLD_", strlen("_RLD_")) && /* irix */
- strncmp(varp, "KRB5", strlen("KRB5")) && /* v5 */
- /* The above is a catch-all for now. Here are some of the
- specific ones we must avoid passing, at least until we
- can prove it can be done safely. Keep this list around
- in case someone wants to remove the catch-all. */
- strcmp(varp, "KRB5_CONFIG") && /* v5 */
- strcmp(varp, "KRB5CCNAME") && /* v5 */
- strcmp(varp, "KRB5_KTNAME") && /* v5 */
- strcmp(varp, "KRBTKFILE") && /* v4 */
- strcmp(varp, "KRB_CONF") && /* cns v4 */
- strcmp(varp, "KRB_REALMS") && /* cns v4 */
- strcmp(varp, "LIBPATH") && /* AIX */
- strcmp(varp, "RESOLV_HOST_CONF") && /* linux */
- strcmp(varp, "NLSPATH") && /* locale stuff */
- strncmp(varp, "LC_", strlen("LC_")) && /* locale stuff */
- strcmp(varp, "IFS") &&
- (varp[0] != '-')) {
- return 1;
- } else {
- syslog(LOG_INFO, "Rejected the attempt to modify the environment variable \"%s\"", varp);
- return 0;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 1989, 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.
- */
-
-/* baesd on @(#)sys_term.c 8.1 (Berkeley) 6/4/93 */
-
-#include "telnetd.h"
-#include "pathnames.h"
-#include <com_err.h>
-
-#ifndef LOGIN_PROGRAM
-#define LOGIN_PROGRAM _PATH_LOGIN
-#endif
-
-#include <libpty.h>
-#if defined(AUTHENTICATION)
-#include <libtelnet/auth.h>
-#endif
-
-#if defined(KRB5)
-#include "k5-int.h"
-#endif
-
-char *login_program = LOGIN_PROGRAM;
-
-#ifdef NEWINIT
-#include <initreq.h>
-int utmp_len = MAXHOSTNAMELEN; /* sizeof(init_request.host) */
-#else /* NEWINIT*/
-
-#ifdef HAVE_UTMP_H
-#include <utmp.h>
-#endif
-
-#ifdef _PATH_WTMP
-char wtmpf[] = _PATH_WTMP;
-#else
-char wtmpf[] = "/usr/adm/wtmp";
-#endif
-
-#ifdef _PATH_UTMP
-char utmpf[] = _PATH_UTMP;
-#else
-char utmpf[] = "/etc/utmp";
-#endif
-
-# ifdef CRAY
-#include <tmpdir.h>
-#include <sys/wait.h>
-# if defined(_SC_CRAY_SECURE_SYS) && !defined(SCM_SECURITY)
- /*
- * UNICOS 6.0/6.1 do not have SCM_SECURITY defined, so we can
- * use it to tell us to turn off all the socket security code,
- * since that is only used in UNICOS 7.0 and later.
- */
-# undef _SC_CRAY_SECURE_SYS
-# endif
-
-# if defined(_SC_CRAY_SECURE_SYS)
-#include <sys/sysv.h>
-#include <sys/secstat.h>
-extern int secflag;
-extern struct sysv sysv;
-# endif /* _SC_CRAY_SECURE_SYS */
-# endif /* CRAY */
-#endif /* NEWINIT */
-
-#ifdef STREAMSPTY
-#ifdef HAVE_SAC_H
-#include <sac.h>
-#endif
-#include <sys/stropts.h>
-#endif
-
-#define SCPYN(a, b) (void) strncpy(a, b, sizeof(a))
-#define SCMPN(a, b) strncmp(a, b, sizeof(a))
-
-#ifdef HAVE_SYS_STREAM_H
-#include <sys/stream.h>
-#endif
-#ifdef __hpux
-#include <sys/resource.h>
-#include <sys/proc.h>
-#endif
- /* For what platforms do we really need sys/tty.h? */
-#ifdef HAVE_SYS_TTY_H
-#include <sys/tty.h>
-#endif
-
-#ifdef t_erase
-#undef t_erase
-#undef t_kill
-#undef t_intrc
-#undef t_quitc
-#undef t_startc
-#undef t_stopc
-#undef t_eofc
-#undef t_brkc
-#undef t_suspc
-#undef t_dsuspc
-#undef t_rprntc
-#undef t_flushc
-#undef t_werasc
-#undef t_lnextc
-#endif
-
-#if defined(UNICOS5) && defined(CRAY2) && !defined(EXTPROC)
-# define EXTPROC 0400
-#endif
-
-#ifndef USE_TERMIO
-struct termbuf {
- struct sgttyb sg;
- struct tchars tc;
- struct ltchars ltc;
- int state;
- int lflags;
-} termbuf, termbuf2;
-# define cfsetospeed(tp, val) (tp)->sg.sg_ospeed = (val)
-# define cfsetispeed(tp, val) (tp)->sg.sg_ispeed = (val)
-# define cfgetospeed(tp) (tp)->sg.sg_ospeed
-# define cfgetispeed(tp) (tp)->sg.sg_ispeed
-#else /* USE_TERMIO */
-# ifdef SYSV_TERMIO
-# define termios termio
-# endif
-# ifndef TCSANOW
-# ifdef TCSETS
-# define TCSANOW TCSETS
-# define TCSADRAIN TCSETSW
-# define tcgetattr(f, t) ioctl(f, TCGETS, (char *)t)
-# else
-# ifdef TCSETA
-# define TCSANOW TCSETA
-# define TCSADRAIN TCSETAW
-# define tcgetattr(f, t) ioctl(f, TCGETA, (char *)t)
-# else
-# define TCSANOW TIOCSETA
-# define TCSADRAIN TIOCSETAW
-# define tcgetattr(f, t) ioctl(f, TIOCGETA, (char *)t)
-# endif
-# endif
-# define tcsetattr(f, a, t) ioctl(f, a, t)
-# define cfsetospeed(tp, val) (tp)->c_cflag &= ~CBAUD; \
- (tp)->c_cflag |= (val)
-# define cfgetospeed(tp) ((tp)->c_cflag & CBAUD)
-# ifdef CIBAUD
-# define cfsetispeed(tp, val) (tp)->c_cflag &= ~CIBAUD; \
- (tp)->c_cflag |= ((val)<<IBSHIFT)
-# define cfgetispeed(tp) (((tp)->c_cflag & CIBAUD)>>IBSHIFT)
-# else
-# define cfsetispeed(tp, val) (tp)->c_cflag &= ~CBAUD; \
- (tp)->c_cflag |= (val)
-# define cfgetispeed(tp) ((tp)->c_cflag & CBAUD)
-# endif
-# endif /* TCSANOW */
-struct termios termbuf, termbuf2; /* pty control structure */
-# ifdef STREAMSPTY
-int ttyfd = -1;
-# endif
-#endif /* USE_TERMIO */
-
-#ifndef SETPGRP_TWOARG
-#define setpgrp(a,b) setpgrp()
-#endif
-
-int dup_tty(int);
-static char **addarg(char **, char *);
-
-/*
- * init_termbuf()
- * copy_termbuf(cp)
- * set_termbuf()
- *
- * These three routines are used to get and set the "termbuf" structure
- * to and from the kernel. init_termbuf() gets the current settings.
- * copy_termbuf() hands in a new "termbuf" to write to the kernel, and
- * set_termbuf() writes the structure into the kernel.
- */
-
- void
-init_termbuf()
-{
-#ifndef USE_TERMIO
- (void) ioctl(pty, TIOCGETP, (char *)&termbuf.sg);
- (void) ioctl(pty, TIOCGETC, (char *)&termbuf.tc);
- (void) ioctl(pty, TIOCGLTC, (char *)&termbuf.ltc);
-# ifdef TIOCGSTATE
- (void) ioctl(pty, TIOCGSTATE, (char *)&termbuf.state);
-# endif
-#else
-# ifdef STREAMSPTY
- (void) tcgetattr(ttyfd, &termbuf);
-# else
- (void) tcgetattr(pty, &termbuf);
-# endif
-#endif
- termbuf2 = termbuf;
-}
-
-#if defined(LINEMODE) && defined(TIOCPKT_IOCTL)
- void
-copy_termbuf(cp, len)
- char *cp;
- int len;
-{
- if (len > sizeof(termbuf))
- len = sizeof(termbuf);
- memcpy(&termbuf, cp, len);
- termbuf2 = termbuf;
-}
-#endif /* defined(LINEMODE) && defined(TIOCPKT_IOCTL) */
-
- void
-set_termbuf()
-{
- /*
- * Only make the necessary changes.
- */
-#ifndef USE_TERMIO
- if (memcmp((char *)&termbuf.sg, (char *)&termbuf2.sg, sizeof(termbuf.sg)))
- (void) ioctl(pty, TIOCSETN, (char *)&termbuf.sg);
- if (memcmp((char *)&termbuf.tc, (char *)&termbuf2.tc, sizeof(termbuf.tc)))
- (void) ioctl(pty, TIOCSETC, (char *)&termbuf.tc);
- if (memcmp((char *)&termbuf.ltc, (char *)&termbuf2.ltc,
- sizeof(termbuf.ltc)))
- (void) ioctl(pty, TIOCSLTC, (char *)&termbuf.ltc);
- if (termbuf.lflags != termbuf2.lflags)
- (void) ioctl(pty, TIOCLSET, (char *)&termbuf.lflags);
-#else /* USE_TERMIO */
- if (memcmp((char *)&termbuf, (char *)&termbuf2, sizeof(termbuf)))
-# ifdef STREAMSPTY
- (void) tcsetattr(ttyfd, TCSANOW, &termbuf);
-# else
- (void) tcsetattr(pty, TCSANOW, &termbuf);
-# endif
-# if defined(CRAY2) && defined(UNICOS5)
- needtermstat = 1;
-# endif
-#endif /* USE_TERMIO */
-}
-
-
-/*
- * spcset(func, valp, valpp)
- *
- * This function takes various special characters (func), and
- * sets *valp to the current value of that character, and
- * *valpp to point to where in the "termbuf" structure that
- * value is kept.
- *
- * It returns the SLC_ level of support for this function.
- */
-
-#ifndef USE_TERMIO
- int
-spcset(func, valp, valpp)
- int func;
- cc_t *valp;
- cc_t **valpp;
-{
- switch(func) {
- case SLC_EOF:
- *valp = termbuf.tc.t_eofc;
- *valpp = (cc_t *)&termbuf.tc.t_eofc;
- return(SLC_VARIABLE);
- case SLC_EC:
- *valp = termbuf.sg.sg_erase;
- *valpp = (cc_t *)&termbuf.sg.sg_erase;
- return(SLC_VARIABLE);
- case SLC_EL:
- *valp = termbuf.sg.sg_kill;
- *valpp = (cc_t *)&termbuf.sg.sg_kill;
- return(SLC_VARIABLE);
- case SLC_IP:
- *valp = termbuf.tc.t_intrc;
- *valpp = (cc_t *)&termbuf.tc.t_intrc;
- return(SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
- case SLC_ABORT:
- *valp = termbuf.tc.t_quitc;
- *valpp = (cc_t *)&termbuf.tc.t_quitc;
- return(SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
- case SLC_XON:
- *valp = termbuf.tc.t_startc;
- *valpp = (cc_t *)&termbuf.tc.t_startc;
- return(SLC_VARIABLE);
- case SLC_XOFF:
- *valp = termbuf.tc.t_stopc;
- *valpp = (cc_t *)&termbuf.tc.t_stopc;
- return(SLC_VARIABLE);
- case SLC_AO:
- *valp = termbuf.ltc.t_flushc;
- *valpp = (cc_t *)&termbuf.ltc.t_flushc;
- return(SLC_VARIABLE);
- case SLC_SUSP:
- *valp = termbuf.ltc.t_suspc;
- *valpp = (cc_t *)&termbuf.ltc.t_suspc;
- return(SLC_VARIABLE);
- case SLC_EW:
- *valp = termbuf.ltc.t_werasc;
- *valpp = (cc_t *)&termbuf.ltc.t_werasc;
- return(SLC_VARIABLE);
- case SLC_RP:
- *valp = termbuf.ltc.t_rprntc;
- *valpp = (cc_t *)&termbuf.ltc.t_rprntc;
- return(SLC_VARIABLE);
- case SLC_LNEXT:
- *valp = termbuf.ltc.t_lnextc;
- *valpp = (cc_t *)&termbuf.ltc.t_lnextc;
- return(SLC_VARIABLE);
- case SLC_FORW1:
- *valp = termbuf.tc.t_brkc;
- *valpp = (cc_t *)&termbuf.ltc.t_lnextc;
- return(SLC_VARIABLE);
- case SLC_BRK:
- case SLC_SYNCH:
- case SLC_AYT:
- case SLC_EOR:
- *valp = (cc_t)0;
- *valpp = (cc_t *)0;
- return(SLC_DEFAULT);
- default:
- *valp = (cc_t)0;
- *valpp = (cc_t *)0;
- return(SLC_NOSUPPORT);
- }
-}
-
-#else /* USE_TERMIO */
-
- int
-spcset(func, valp, valpp)
- int func;
- cc_t *valp;
- cc_t **valpp;
-{
-
-#define setval(a, b) *valp = termbuf.c_cc[a]; \
- *valpp = &termbuf.c_cc[a]; \
- return(b);
-#define defval(a) *valp = ((cc_t)a); *valpp = (cc_t *)0; return(SLC_DEFAULT);
-
- switch(func) {
- case SLC_EOF:
- setval(VEOF, SLC_VARIABLE);
- case SLC_EC:
- setval(VERASE, SLC_VARIABLE);
- case SLC_EL:
- setval(VKILL, SLC_VARIABLE);
- case SLC_IP:
- setval(VINTR, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
- case SLC_ABORT:
- setval(VQUIT, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
- case SLC_XON:
-#ifdef VSTART
- setval(VSTART, SLC_VARIABLE);
-#else
- defval(0x13);
-#endif
- case SLC_XOFF:
-#ifdef VSTOP
- setval(VSTOP, SLC_VARIABLE);
-#else
- defval(0x11);
-#endif
- case SLC_EW:
-#ifdef VWERASE
- setval(VWERASE, SLC_VARIABLE);
-#else
- defval(0);
-#endif
- case SLC_RP:
-#ifdef VREPRINT
- setval(VREPRINT, SLC_VARIABLE);
-#else
- defval(0);
-#endif
- case SLC_LNEXT:
-#ifdef VLNEXT
- setval(VLNEXT, SLC_VARIABLE);
-#else
- defval(0);
-#endif
- case SLC_AO:
-#if !defined(VDISCARD) && defined(VFLUSHO)
-# define VDISCARD VFLUSHO
-#endif
-#ifdef VDISCARD
- setval(VDISCARD, SLC_VARIABLE|SLC_FLUSHOUT);
-#else
- defval(0);
-#endif
- case SLC_SUSP:
-#ifdef VSUSP
- setval(VSUSP, SLC_VARIABLE|SLC_FLUSHIN);
-#else
- defval(0);
-#endif
-#ifdef VEOL
- case SLC_FORW1:
- setval(VEOL, SLC_VARIABLE);
-#endif
-#ifdef VEOL2
- case SLC_FORW2:
- setval(VEOL2, SLC_VARIABLE);
-#endif
- case SLC_AYT:
-#ifdef VSTATUS
- setval(VSTATUS, SLC_VARIABLE);
-#else
- defval(0);
-#endif
-
- case SLC_BRK:
- case SLC_SYNCH:
- case SLC_EOR:
- defval(0);
-
- default:
- *valp = 0;
- *valpp = 0;
- return(SLC_NOSUPPORT);
- }
-}
-#endif /* USE_TERMIO */
-
-#ifdef CRAY
-/*
- * getnpty()
- *
- * Return the number of pty's configured into the system.
- */
- int
-getnpty()
-{
-#ifdef _SC_CRAY_NPTY
- int numptys;
-
- if ((numptys = sysconf(_SC_CRAY_NPTY)) != -1)
- return numptys;
- else
-#endif /* _SC_CRAY_NPTY */
- return 128;
-}
-#endif /* CRAY */
-
-#ifndef convex
-/*
- * getpty()
- *
- * Allocate a pty. As a side effect, the external character
- * array "line" contains the name of the slave side.
- *
- * Returns the file descriptor of the opened pty.
- */
-static char Xline[17];
-char *line = Xline;
-
-#ifdef CRAY
-char *myline = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
-#endif /* CRAY */
-
-
-#endif /* convex */
-
-static pid_t slavepid = 0;
-
-#ifdef LINEMODE
-/*
- * tty_flowmode() Find out if flow control is enabled or disabled.
- * tty_linemode() Find out if linemode (external processing) is enabled.
- * tty_setlinemod(on) Turn on/off linemode.
- * tty_isecho() Find out if echoing is turned on.
- * tty_setecho(on) Enable/disable character echoing.
- * tty_israw() Find out if terminal is in RAW mode.
- * tty_binaryin(on) Turn on/off BINARY on input.
- * tty_binaryout(on) Turn on/off BINARY on output.
- * tty_isediting() Find out if line editing is enabled.
- * tty_istrapsig() Find out if signal trapping is enabled.
- * tty_setedit(on) Turn on/off line editing.
- * tty_setsig(on) Turn on/off signal trapping.
- * tty_issofttab() Find out if tab expansion is enabled.
- * tty_setsofttab(on) Turn on/off soft tab expansion.
- * tty_islitecho() Find out if typed control chars are echoed literally
- * tty_setlitecho() Turn on/off literal echo of control chars
- * tty_tspeed(val) Set transmit speed to val.
- * tty_rspeed(val) Set receive speed to val.
- */
-
-#ifdef convex
-static int linestate;
-#endif
-
- int
-tty_linemode()
-{
-#ifndef convex
-#ifndef USE_TERMIO
- return(termbuf.state & TS_EXTPROC);
-#else
- return(termbuf.c_lflag & EXTPROC);
-#endif
-#else
- return(linestate);
-#endif
-}
-
- void
-tty_setlinemode(on)
- int on;
-{
-#ifdef TIOCEXT
-# ifndef convex
- set_termbuf();
-# else
- linestate = on;
-# endif
- (void) ioctl(pty, TIOCEXT, (char *)&on);
-# ifndef convex
- init_termbuf();
-# endif
-#else /* !TIOCEXT */
-# ifdef EXTPROC
- if (on)
- termbuf.c_lflag |= EXTPROC;
- else
- termbuf.c_lflag &= ~EXTPROC;
-# endif
-#endif /* TIOCEXT */
-}
-#endif /* LINEMODE */
-
- int
-tty_isecho()
-{
-#ifndef USE_TERMIO
- return (termbuf.sg.sg_flags & ECHO);
-#else
- return (termbuf.c_lflag & ECHO);
-#endif
-}
-
- int
-tty_flowmode()
-{
-#ifndef USE_TERMIO
- return(((termbuf.tc.t_startc) > 0 && (termbuf.tc.t_stopc) > 0) ? 1 : 0);
-#else
- return((termbuf.c_iflag & IXON) ? 1 : 0);
-#endif
-}
-
- int
-tty_restartany()
-{
-#ifndef USE_TERMIO
-# ifdef DECCTQ
- return((termbuf.lflags & DECCTQ) ? 0 : 1);
-# else
- return(-1);
-# endif
-#else
- return((termbuf.c_iflag & IXANY) ? 1 : 0);
-#endif
-}
-
- void
-tty_setecho(on)
- int on;
-{
-#ifndef USE_TERMIO
- if (on)
- termbuf.sg.sg_flags |= ECHO|CRMOD;
- else
- termbuf.sg.sg_flags &= ~(ECHO|CRMOD);
-#else
- if (on)
- termbuf.c_lflag |= ECHO;
- else
- termbuf.c_lflag &= ~ECHO;
-#endif
-}
-
- int
-tty_israw()
-{
-#ifndef USE_TERMIO
- return(termbuf.sg.sg_flags & RAW);
-#else
- return(!(termbuf.c_lflag & ICANON));
-#endif
-}
-
-#if defined (AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R)
- int
-tty_setraw(on)
-{
-# ifndef USE_TERMIO
- if (on)
- termbuf.sg.sg_flags |= RAW;
- else
- termbuf.sg.sg_flags &= ~RAW;
-# else
- if (on)
- termbuf.c_lflag &= ~ICANON;
- else
- termbuf.c_lflag |= ICANON;
-# endif
-}
-#endif
-
- void
-tty_binaryin(on)
- int on;
-{
-#ifndef USE_TERMIO
- if (on)
- termbuf.lflags |= LPASS8;
- else
- termbuf.lflags &= ~LPASS8;
-#else
- if (on) {
- termbuf.c_iflag &= ~ISTRIP;
- } else {
- termbuf.c_iflag |= ISTRIP;
- }
-#endif
-}
-
- void
-tty_binaryout(on)
- int on;
-{
-#ifndef USE_TERMIO
- if (on)
- termbuf.lflags |= LLITOUT;
- else
- termbuf.lflags &= ~LLITOUT;
-#else
- if (on) {
- termbuf.c_cflag &= ~(CSIZE|PARENB);
- termbuf.c_cflag |= CS8;
- termbuf.c_oflag &= ~OPOST;
- } else {
- termbuf.c_cflag &= ~CSIZE;
- termbuf.c_cflag |= CS7|PARENB;
- termbuf.c_oflag |= OPOST;
- }
-#endif
-}
-
- int
-tty_isbinaryin()
-{
-#ifndef USE_TERMIO
- return(termbuf.lflags & LPASS8);
-#else
- return(!(termbuf.c_iflag & ISTRIP));
-#endif
-}
-
- int
-tty_isbinaryout()
-{
-#ifndef USE_TERMIO
- return(termbuf.lflags & LLITOUT);
-#else
- return(!(termbuf.c_oflag&OPOST));
-#endif
-}
-
-#ifdef LINEMODE
- int
-tty_isediting()
-{
-#ifndef USE_TERMIO
- return(!(termbuf.sg.sg_flags & (CBREAK|RAW)));
-#else
- return(termbuf.c_lflag & ICANON);
-#endif
-}
-
- int
-tty_istrapsig()
-{
-#ifndef USE_TERMIO
- return(!(termbuf.sg.sg_flags&RAW));
-#else
- return(termbuf.c_lflag & ISIG);
-#endif
-}
-
- void
-tty_setedit(on)
- int on;
-{
-#ifndef USE_TERMIO
- if (on)
- termbuf.sg.sg_flags &= ~CBREAK;
- else
- termbuf.sg.sg_flags |= CBREAK;
-#else
- if (on)
- termbuf.c_lflag |= ICANON;
- else
- termbuf.c_lflag &= ~ICANON;
-#endif
-}
-
- void
-tty_setsig(on)
- int on;
-{
-#ifndef USE_TERMIO
- if (on)
- ;
-#else
- if (on)
- termbuf.c_lflag |= ISIG;
- else
- termbuf.c_lflag &= ~ISIG;
-#endif
-}
-#endif /* LINEMODE */
-
- int
-tty_issofttab()
-{
-#ifndef USE_TERMIO
- return (termbuf.sg.sg_flags & XTABS);
-#else
-# ifdef OXTABS
- return (termbuf.c_oflag & OXTABS);
-# endif
-# ifdef TABDLY
- return ((termbuf.c_oflag & TABDLY) == TAB3);
-# endif
-#endif
-}
-
- void
-tty_setsofttab(on)
- int on;
-{
-#ifndef USE_TERMIO
- if (on)
- termbuf.sg.sg_flags |= XTABS;
- else
- termbuf.sg.sg_flags &= ~XTABS;
-#else
- if (on) {
-# ifdef OXTABS
- termbuf.c_oflag |= OXTABS;
-# endif
-# ifdef TABDLY
- termbuf.c_oflag &= ~TABDLY;
- termbuf.c_oflag |= TAB3;
-# endif
- } else {
-# ifdef OXTABS
- termbuf.c_oflag &= ~OXTABS;
-# endif
-# ifdef TABDLY
- termbuf.c_oflag &= ~TABDLY;
- termbuf.c_oflag |= TAB0;
-# endif
- }
-#endif
-}
-
- int
-tty_islitecho()
-{
-#ifndef USE_TERMIO
- return (!(termbuf.lflags & LCTLECH));
-#else
-# ifdef ECHOCTL
- return (!(termbuf.c_lflag & ECHOCTL));
-# endif
-# ifdef TCTLECH
- return (!(termbuf.c_lflag & TCTLECH));
-# endif
-# if !defined(ECHOCTL) && !defined(TCTLECH)
- return (0); /* assumes ctl chars are echoed '^x' */
-# endif
-#endif
-}
-
- void
-tty_setlitecho(on)
- int on;
-{
-#ifndef USE_TERMIO
- if (on)
- termbuf.lflags &= ~LCTLECH;
- else
- termbuf.lflags |= LCTLECH;
-#else
-# ifdef ECHOCTL
- if (on)
- termbuf.c_lflag &= ~ECHOCTL;
- else
- termbuf.c_lflag |= ECHOCTL;
-# endif
-# ifdef TCTLECH
- if (on)
- termbuf.c_lflag &= ~TCTLECH;
- else
- termbuf.c_lflag |= TCTLECH;
-# endif
-#endif
-}
-
- int
-tty_iscrnl()
-{
-#ifndef USE_TERMIO
- return (termbuf.sg.sg_flags & CRMOD);
-#else
- return (termbuf.c_iflag & ICRNL);
-#endif
-}
-
-/*
- * A table of available terminal speeds
- */
-struct termspeeds {
- int speed;
- speed_t value;
-} termspeeds[] = {
- { 0, B0 }, { 50, B50 }, { 75, B75 },
- { 110, B110 }, { 134, B134 }, { 150, B150 },
- { 200, B200 }, { 300, B300 }, { 600, B600 },
- { 1200, B1200 }, { 1800, B1800 }, { 2400, B2400 },
- { 4800, B4800 }, { 9600, B9600 }, { 19200, B9600 },
- { 38400, B9600 }, { -1, B9600 }
-};
-
- void
-tty_tspeed(val)
- int val;
-{
- register struct termspeeds *tp;
-
- for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++)
- ;
- cfsetospeed(&termbuf, tp->value);
-}
-
- void
-tty_rspeed(val)
- int val;
-{
- register struct termspeeds *tp;
-
- for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++)
- ;
- cfsetispeed(&termbuf, tp->value);
-}
-
-#if defined(CRAY2) && defined(UNICOS5)
- int
-tty_isnewmap()
-{
- return((termbuf.c_oflag & OPOST) && (termbuf.c_oflag & ONLCR) &&
- !(termbuf.c_oflag & ONLRET));
-}
-#endif
-
-
-#ifndef NEWINIT
-#endif
-
-/*
- * getptyslave()
- *
- * Open the slave side of the pty, and do any initialization
- * that is necessary. The return value is a file descriptor
- * for the slave side.
- */
-static void
-getptyslave()
-{
- int t = -1;
- long retval;
-
-#if !defined(CRAY) || !defined(NEWINIT)
-# ifdef LINEMODE
- int waslm;
-# endif
-# ifdef TIOCGWINSZ
- struct winsize ws;
- extern int def_row, def_col;
-# endif
- extern int def_tspeed, def_rspeed;
- /*
- * Opening the slave side may cause initilization of the
- * kernel tty structure. We need remember the state of
- * if linemode was turned on
- * terminal window size
- * terminal speed
- * so that we can re-set them if we need to.
- */
-# ifdef LINEMODE
- waslm = tty_linemode();
-# endif
-
- if ( (retval = pty_open_slave (line, &t)) != 0 )
- {
- fatalperror(net, error_message(retval));
- }
-
-#ifdef STREAMSPTY
-#ifdef USE_TERMIO
- ttyfd = t;
-#endif
- if (ioctl(pty, I_PUSH, "pckt") < 0) {
-#ifndef _AIX
- fatal(net, "I_PUSH pckt");
-#endif
- }
-#endif
-
- /*
- * set up the tty modes as we like them to be.
- */
- init_termbuf();
-# ifdef TIOCGWINSZ
- if (def_row || def_col) {
- memset(&ws, 0, sizeof(ws));
- ws.ws_col = def_col;
- ws.ws_row = def_row;
- (void)ioctl(t, TIOCSWINSZ, (char *)&ws);
- }
-# endif
-
- /*
- * Settings for sgtty based systems
- */
-# ifndef USE_TERMIO
- termbuf.sg.sg_flags |= CRMOD|ANYP|ECHO|XTABS;
-# endif /* USE_TERMIO */
-
- /*
- * Settings for UNICOS (and HPUX)
- */
-# if defined(CRAY) || defined(__hpux)
- termbuf.c_oflag = OPOST|ONLCR|TAB3;
- termbuf.c_iflag = IGNPAR|ISTRIP|ICRNL|IXON;
- termbuf.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;
- termbuf.c_cflag = EXTB|HUPCL|CS8;
-# endif
-
- /*
- * Settings for all other termios/termio based
- * systems, other than 4.4BSD. In 4.4BSD the
- * kernel does the initial terminal setup.
- */
-# if defined(USE_TERMIO) && !(defined(CRAY) || defined(__hpux)) && (BSD <= 43)
-# ifndef OXTABS
-# define OXTABS 0
-# endif
- termbuf.c_lflag |= ECHO|ICANON|IEXTEN|ISIG;
- termbuf.c_oflag |= ONLCR|OXTABS|OPOST;
- termbuf.c_iflag |= ICRNL|IGNPAR;
-termbuf.c_cflag |= HUPCL;
- termbuf.c_iflag &= ~IXOFF;
-# endif /* defined(USE_TERMIO) && !defined(CRAY) && (BSD <= 43) */
- tty_rspeed((def_rspeed > 0) ? def_rspeed : 9600);
- tty_tspeed((def_tspeed > 0) ? def_tspeed : 9600);
-# ifdef LINEMODE
- if (waslm)
- tty_setlinemode(1);
-# endif /* LINEMODE */
-
- /*
- * Set the tty modes, and make this our controlling tty.
- */
- set_termbuf();
- if (dup_tty(t) == -1)
- fatalperror(net, "dup_tty");
-#endif /* !defined(CRAY) || !defined(NEWINIT) */
- if (net > 2)
- (void) close(net);
-#if defined(AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R)
- /*
- * Leave the pty open so that we can write out the rlogin
- * protocol for /bin/login, if the authentication works.
- */
-#else
- if (pty > 2) {
- (void) close(pty);
- pty = -1;
- }
-#endif
-}
-
-#if !defined(CRAY) || !defined(NEWINIT)
-#ifndef O_NOCTTY
-#define O_NOCTTY 0
-#endif
-#endif /* !defined(CRAY) || !defined(NEWINIT) */
-
-
-
- int
-dup_tty(t)
- int t;
-{
- if (t != 0)
- (void) dup2(t, 0);
- if (t != 1)
- (void) dup2(t, 1);
- if (t != 2)
- (void) dup2(t, 2);
- if (t > 2)
- close(t);
- return(0);
-}
-
-
-#ifdef NEWINIT
-char *gen_id = "fe";
-#endif
-
-/*
- * startslave(host)
- *
- * Given a hostname, do whatever
- * is necessary to startup the login process on the slave side of the pty.
- */
-
-
-/* ARGSUSED */
- void
-startslave(host, autologin, autoname)
- char *host;
- int autologin;
- char *autoname;
-{
- int syncpipe[2];
- register int i;
-#ifdef NEWINIT
- extern char *ptyip;
- struct init_request request;
- void nologinproc();
- register int n;
-#endif /* NEWINIT */
-
- if ( pipe(syncpipe) < 0 )
- fatal(net, "failed getting synchronization pipe");
-
-#if defined(AUTHENTICATION)
- if (!autoname || !autoname[0])
- autologin = 0;
-
- if (autologin < auth_level) {
- fatal(net, "Authorization failed");
- exit(1);
- }
-#endif
-
-#ifndef NEWINIT
-
- if ((i = fork()) < 0)
- fatalperror(net, "fork");
- if (i) {
- char c;
-
- void sigjob (int);
- slavepid = i; /* So we can clean it up later */
-#ifdef CRAY
- (void) signal(WJSIGNAL, sigjob);
-#endif
-
- /* Wait for child before writing to parent side of pty.*/
- (void) close(syncpipe[1]);
- if ( read(syncpipe[0], &c, 1) == 0 ) {
- /* Slave side died */
- fatal ( net, "Slave failed to initialize");
- }
-
- close(syncpipe[0]);
-
- } else {
-
- pty_update_utmp (PTY_LOGIN_PROCESS, getpid(), "LOGIN", line,
- host, PTY_TTYSLOT_USABLE);
- getptyslave();
-
- /* Notify our parent we're ready to continue.*/
- write(syncpipe[1],"y",1);
- close(syncpipe[0]);
- close(syncpipe[1]);
-
- start_login(host, autologin, autoname);
- /*NOTREACHED*/
- }
-#else /* NEWINIT */
-
- /*
- * Init will start up login process if we ask nicely. We only wait
- * for it to start up and begin normal telnet operation.
- */
- if ((i = open(INIT_FIFO, O_WRONLY)) < 0) {
- char tbuf[128];
- (void) snprintf(tbuf, sizeof(tbuf), "Can't open %s\n",
- INIT_FIFO);
- fatalperror(net, tbuf);
- }
- memset(&request, 0, sizeof(request));
- request.magic = INIT_MAGIC;
- SCPYN(request.gen_id, gen_id);
- SCPYN(request.tty_id, &line[8]);
- SCPYN(request.host, host);
- SCPYN(request.term_type, *terminaltype ? terminaltype : "network");
-#if !defined(UNICOS5)
- request.signal = SIGCLD;
- request.pid = getpid();
-#endif
-#ifdef BFTPDAEMON
- /*
- * Are we working as the bftp daemon?
- */
- if (bftpd) {
- SCPYN(request.exec_name, BFTPPATH);
- }
-#endif /* BFTPDAEMON */
- if (write(i, (char *)&request, sizeof(request)) < 0) {
- char tbuf[128];
- (void) snprintf(tbuf, sizeof(tbuf), "Can't write to %s\n",
- INIT_FIFO);
- fatalperror(net, tbuf);
- }
- (void) close(i);
- (void) signal(SIGALRM, nologinproc);
- for (i = 0; ; i++) {
- char tbuf[128];
- alarm(15);
- n = read(pty, ptyip, BUFSIZ);
- if (i == 3 || n >= 0 || !gotalarm)
- break;
- gotalarm = 0;
- snprintf(tbuf, sizeof(tbuf), "telnetd: waiting for /etc/init to start login process on %s\r\n", line);
- (void) write(net, tbuf, strlen(tbuf));
- }
- if (n < 0 && gotalarm)
- fatal(net, "/etc/init didn't start login process");
- pcc += n;
- alarm(0);
- (void) signal(SIGALRM, SIG_DFL);
-
- return;
-#endif /* NEWINIT */
-}
-
-char *envinit[3];
-extern char **environ;
-
- void
-init_env()
-{
- extern char *getenv();
- char **envp;
-
- envp = envinit;
- if ((*envp = getenv("TZ")))
- *envp++ -= 3;
-#if defined(CRAY) || defined(__hpux)
- else
- *envp++ = "TZ=GMT0";
-#endif
- *envp = 0;
- environ = envinit;
-}
-
-#ifndef NEWINIT
-
-/*
- * start_login(host)
- *
- * Assuming that we are now running as a child processes, this
- * function will turn us into the login process.
- */
-
- void
-start_login(host, autologin, name)
- char *host;
- int autologin;
- char *name;
-{
- register char **argv;
- extern char *getenv();
-
-#ifdef SOLARIS
- char *term;
- char termbuf[64];
-#endif
-
-
- /*
- * -h : pass on name of host.
- * WARNING: -h is accepted by login if and only if
- * getuid() == 0.
- * -p : don't clobber the environment (so terminal type stays set).
- *
- * -f : force this login, he has already been authenticated
- */
- argv = addarg(0, "login");
-
-#if !defined(NO_LOGIN_H)
-
-# if defined (AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R)
- /*
- * Don't add the "-h host" option if we are going
- * to be adding the "-r host" option down below...
- */
- if ((auth_level < 0) || (autologin != AUTH_VALID))
-# endif
- {
- argv = addarg(argv, "-h");
- argv = addarg(argv, host);
-#ifdef SOLARIS
- /*
- * SVR4 version of -h takes TERM= as second arg, or -
- */
- term = getenv("TERM");
- if (term == NULL || term[0] == 0) {
- term = "-";
- } else {
- snprintf(termbuf, sizeof(termbuf), "TERM=%s", term);
- term = termbuf;
- }
- argv = addarg(argv, term);
-#endif
- }
-#endif
-#if !defined(NO_LOGIN_P)
- argv = addarg(argv, "-p");
-#endif
-#ifdef BFTPDAEMON
- /*
- * Are we working as the bftp daemon? If so, then ask login
- * to start bftp instead of shell.
- */
- if (bftpd) {
- argv = addarg(argv, "-e");
- argv = addarg(argv, BFTPPATH);
- } else
-#endif
-#if defined (SecurID)
- /*
- * don't worry about the -f that might get sent.
- * A -s is supposed to override it anyhow.
- */
- if (require_SecurID)
- argv = addarg(argv, "-s");
-#endif
-#if defined (AUTHENTICATION)
- if (auth_level >= 0 && autologin == AUTH_VALID) {
- if (name[0] == '-') {
- /*
- * Authenticated and authorized to log in to an
- * account starting with '-'? Even if that
- * unlikely case comes to pass, the current login
- * program will not parse the resulting command
- * line properly.
- */
- syslog(LOG_ERR, "user name cannot start with '-'");
- fatal(net, "user name cannot start with '-'");
- exit(1);
- }
-# if !defined(NO_LOGIN_F)
-#if defined(LOGIN_CAP_F)
- argv = addarg(argv, "-F");
-#else
- argv = addarg(argv, "-f");
-#endif
- argv = addarg(argv, "--");
- argv = addarg(argv, name);
-# else
-# if defined(LOGIN_R)
- /*
- * We don't have support for "login -f", but we
- * can fool /bin/login into thinking that we are
- * rlogind, and allow us to log in without a
- * password. The rlogin protocol expects
- * local-user\0remote-user\0term/speed\0
- */
-
- if (pty > 2) {
- register char *cp;
- char speed[1024];
- int isecho, israw, xpty, len;
- extern int def_rspeed;
-# ifndef LOGIN_HOST
- /*
- * Tell login that we are coming from "localhost".
- * If we passed in the real host name, then the
- * user would have to allow .rhost access from
- * every machine that they want authenticated
- * access to work from, which sort of defeats
- * the purpose of an authenticated login...
- * So, we tell login that the session is coming
- * from "localhost", and the user will only have
- * to have "localhost" in their .rhost file.
- */
-# define LOGIN_HOST "localhost"
-# endif
- argv = addarg(argv, "-r");
- argv = addarg(argv, LOGIN_HOST);
-
- xpty = pty;
-# ifndef STREAMSPTY
- pty = 0;
-# else
- ttyfd = 0;
-# endif
- init_termbuf();
- isecho = tty_isecho();
- israw = tty_israw();
- if (isecho || !israw) {
- tty_setecho(0); /* Turn off echo */
- tty_setraw(1); /* Turn on raw */
- set_termbuf();
- }
- len = strlen(name)+1;
- write(xpty, name, len);
- write(xpty, name, len);
- memset(speed, 0, sizeof(speed));
- snprintf(speed, sizeof(speed), "%s/%d",
- (cp = getenv("TERM")) ? cp : "",
- (def_rspeed > 0) ? def_rspeed : 9600);
- len = strlen(speed)+1;
- write(xpty, speed, len);
-
- if (isecho || !israw) {
- init_termbuf();
- tty_setecho(isecho);
- tty_setraw(israw);
- set_termbuf();
- if (!israw) {
- /*
- * Write a newline to ensure
- * that login will be able to
- * read the line...
- */
- write(xpty, "\n", 1);
- }
- }
- pty = xpty;
- }
-# else
- argv = addarg(argv, "--");
- argv = addarg(argv, name);
-# endif
-# endif
- } else
-#endif
- if (getenv("USER")) {
- char *user = getenv("USER");
- if (user[0] == '-') {
- /* "telnet -l-x ..." */
- syslog(LOG_ERR, "user name cannot start with '-'");
- fatal(net, "user name cannot start with '-'");
- exit(1);
- }
- argv = addarg(argv, "--");
- argv = addarg(argv, user);
-#if defined(LOGIN_ARGS) && defined(NO_LOGIN_P)
- {
- register char **cpp;
- for (cpp = environ; *cpp; cpp++)
- if ((*cpp)[0] != '-')
- argv = addarg(argv, *cpp);
- }
-#endif
- /*
- * Assume that login will set the USER variable
- * correctly. For SysV systems, this means that
- * USER will no longer be set, just LOGNAME by
- * login. (The problem is that if the auto-login
- * fails, and the user then specifies a different
- * account name, he can get logged in with both
- * LOGNAME and USER in his environment, but the
- * USER value will be wrong.
- */
- unsetenv("USER");
- }
-#if defined(AUTHENTICATION) && defined(NO_LOGIN_F) && defined(LOGIN_R)
- if (pty > 2)
- close(pty);
-#endif
- closelog();
- execv(login_program, argv);
-
- syslog(LOG_ERR, "%s: %m", login_program);
- fatalperror(net, login_program);
- /*NOTREACHED*/
-}
-
-/*
- * This code returns a pointer to the first element of the array and
- * expects the same to be called with.
- * Therefore the -1 reference is legal.
- */
-
-static char **
-addarg(argv, val)
- register char **argv;
- register char *val;
-{
- register char **cpp;
-
- if (argv == NULL) {
- /*
- * 10 entries, a leading length, and a null
- */
- argv = (char **)malloc(sizeof(*argv) * 12);
- if (argv == NULL)
- return(NULL);
- *argv++ = (char *)10;
- *argv = (char *)0;
- }
- for (cpp = argv; *cpp; cpp++)
- ;
- if (cpp == &argv[(long)argv[-1]]) {
- --argv;
- *argv = (char *)((long)(*argv) + 10);
- argv = (char **)realloc(argv, sizeof(*argv) * ((long)(*argv) + 2));
- if (argv == NULL)
- return(NULL);
- argv++;
- cpp = &argv[(long)argv[-1] - 10];
- }
- *cpp++ = val;
- *cpp = 0;
- return(argv);
-}
-#endif /* NEWINIT */
-
-/*
- * cleanup()
- *
- * This is the routine to call when we are all through, to
- * clean up anything that needs to be cleaned up.
- */
- /* ARGSUSED */
- void
-cleanup(sig)
- int sig;
-{
- pty_cleanup(line,slavepid,1);
-#ifdef KRB5
- kerberos5_cleanup();
-#endif
-
- (void) shutdown(net, 2);
- exit(1);
-}
+++ /dev/null
-/*
- * 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 lint
-char copyright[] =
-"@(#) Copyright (c) 1989 Regents of the University of California.\n\
- All rights reserved.\n";
-#endif /* not lint */
-
-/* based on @(#)telnetd.c 5.51 (Berkeley) 1/21/93 */
-
-#include "telnetd.h"
-#include "pathnames.h"
-
-#if defined(_SC_CRAY_SECURE_SYS)
-#include <sys/sysv.h>
-#include <libpty.h>
-#include <sys/secdev.h>
-int secflag;
-char tty_dev[16];
-struct secdev dv;
-struct sysv sysv;
-struct socket_security ss;
-#endif /* _SC_CRAY_SECURE_SYS */
-
-#if defined(AUTHENTICATION)
-#include <libtelnet/auth.h>
-int auth_level = 0;
-#endif
-#if defined(SecurID)
-int require_SecurID = 0;
-#endif
-
-extern int utmp_len;
-int registerd_host_only = 0;
-
-#ifdef STREAMSPTY
-# include <stropts.h>
-# include <termio.h>
-/* make sure we don't get the bsd version */
-# include "/usr/include/sys/tty.h"
-# include <sys/ptyvar.h>
-
-/*
- * Because of the way ptyibuf is used with streams messages, we need
- * ptyibuf+1 to be on a full-word boundary. The following wierdness
- * is simply to make that happen.
- */
-char ptyibufbuf[BUFSIZ+4];
-char *ptyibuf = ptyibufbuf+3;
-char *ptyip = ptyibufbuf+3;
-char ptyibuf2[BUFSIZ];
-unsigned char ctlbuf[BUFSIZ];
-struct strbuf strbufc, strbufd;
-
-int readstream();
-
-#else /* ! STREAMPTY */
-
-/*
- * I/O data buffers,
- * pointers, and counters.
- */
-char ptyibuf[BUFSIZ], *ptyip = ptyibuf;
-char ptyibuf2[BUFSIZ];
-
-#endif /* ! STREAMPTY */
-
-int hostinfo = 1; /* do we print login banner? */
-
-#ifdef CRAY
-extern int newmap; /* nonzero if \n maps to ^M^J */
-int lowpty = 0, highpty; /* low, high pty numbers */
-#endif /* CRAY */
-
-int debug = 0;
-int keepalive = 1;
-char *progname;
-
-extern void usage (void);
-
-main(argc, argv)
- char *argv[];
-{
- struct sockaddr_in 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;
-#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:")) != -1) {
- 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 HAVE_GETTOSBYNAME
- 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("ktelnet", "tcp");
- if (sp == 0) {
- fprintf(stderr, "telnetd: tcp/ktelnet: 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);
-
- memset(&dv, 0, 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 */
-
- 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");
- _exit(1);
- }
- if (keepalive &&
- setsockopt(0, SOL_SOCKET, SO_KEEPALIVE,
- (char *)&on, sizeof (on)) < 0) {
- syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
- }
-
-#if defined(IPPROTO_IP) && defined(IP_TOS)
- {
-# if defined(HAVE_GETTOSBYNAME)
- struct tosent *tp;
- if (tos < 0 && (tp = gettosbyname("telnet", "tcp")))
- tos = tp->t_tos;
-# endif
- if (tos < 0)
- tos = 020; /* Low Delay bit */
- if (tos
- && (setsockopt(0, IPPROTO_IP, IP_TOS,
- (char *)&tos, sizeof(tos)) < 0)
- && (errno != ENOPROTOOPT) )
- syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
- }
-#endif /* defined(IPPROTO_IP) && defined(IP_TOS) */
- net = 0;
- doit(&from);
- /* NOTREACHED */
-} /* end of main */
-
- void
-usage()
-{
- fprintf(stderr, "Usage: telnetd");
-#ifdef AUTHENTICATION
- fprintf(stderr, " [-a (debug|other|user|valid|off)]\n\t");
-#endif
-#ifdef BFTPDAEMON
- fprintf(stderr, " [-B]");
-#endif
- fprintf(stderr, " [-debug]");
-#ifdef DIAGNOSTICS
- fprintf(stderr, " [-D (options|report|exercise|netdata|ptydata)]\n\t");
-#endif
-#ifdef AUTHENTICATION
- fprintf(stderr, " [-edebug]");
-#endif
- fprintf(stderr, " [-h]");
-#if defined(CRAY) && defined(NEWINIT)
- fprintf(stderr, " [-Iinitid]");
-#endif
-#ifdef LINEMODE
- fprintf(stderr, " [-l]");
-#endif
- fprintf(stderr, " [-n]");
-#ifdef CRAY
- fprintf(stderr, " [-r[lowpty]-[highpty]]");
-#endif
-#ifdef SecurID
- fprintf(stderr, " [-s]");
-#endif
-#ifdef AUTHENTICATION
- fprintf(stderr, " [-X auth-type]");
-#endif
- fprintf(stderr, " [-u utmp_hostname_length] [-U]");
- fprintf(stderr, " [port]\n");
- exit(1);
-}
-
-/*
- * getterminaltype
- *
- * Ask the other end to send along its terminal type and speed.
- * Output is the variable terminaltype filled in.
- */
-static char ttytype_sbbuf[] = { IAC, SB, TELOPT_TTYPE, TELQUAL_SEND, IAC, SE };
-
- int
-getterminaltype(name)
- char *name;
-{
- int retval = -1;
- void _gettermname();
-
- settimer(baseline);
-#if defined(AUTHENTICATION)
- /*
- * Handle the Authentication option before we do anything else.
- */
- send_do(TELOPT_AUTHENTICATION, 1);
- while (his_will_wont_is_changing(TELOPT_AUTHENTICATION))
- ttloop();
- if (his_state_is_will(TELOPT_AUTHENTICATION)) {
- retval = auth_wait(name);
- }
-#endif
-
-#if defined(ENCRYPTION)
- send_will(TELOPT_ENCRYPT, 1);
-#endif
- send_do(TELOPT_TTYPE, 1);
- send_do(TELOPT_TSPEED, 1);
- send_do(TELOPT_XDISPLOC, 1);
- send_do(TELOPT_ENVIRON, 1);
- while (
-#if defined(ENCRYPTION)
- his_do_dont_is_changing(TELOPT_ENCRYPT) ||
-#endif
- 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_ENVIRON)) {
- ttloop();
- }
-#if defined(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
- if (his_state_is_will(TELOPT_TSPEED)) {
- static char sbbuf[] = { IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE };
-
- if(nfrontp - netobuf + sizeof(sbbuf) < sizeof(netobuf)) {
- memcpy(nfrontp, sbbuf, sizeof(sbbuf));
- nfrontp += sizeof(sbbuf);
- }
- }
- if (his_state_is_will(TELOPT_XDISPLOC)) {
- static char sbbuf[] = { IAC, SB, TELOPT_XDISPLOC, TELQUAL_SEND, IAC, SE };
-
- if(nfrontp - netobuf + sizeof(sbbuf) < sizeof(netobuf)) {
- memcpy(nfrontp, sbbuf, sizeof(sbbuf));
- nfrontp += sizeof(sbbuf);
- }
- }
- if (his_state_is_will(TELOPT_ENVIRON)) {
- static char sbbuf[] = { IAC, SB, TELOPT_ENVIRON, TELQUAL_SEND, IAC, SE };
-
- if(nfrontp - netobuf + sizeof(sbbuf) < sizeof(netobuf)) {
- memcpy(nfrontp, sbbuf, sizeof(sbbuf));
- nfrontp += sizeof(sbbuf);
- }
- }
- if (his_state_is_will(TELOPT_TTYPE)) {
-
- if(nfrontp - netobuf + sizeof(ttytype_sbbuf) < sizeof(netobuf)) {
- memcpy(nfrontp, ttytype_sbbuf, sizeof(ttytype_sbbuf));
- nfrontp += sizeof(ttytype_sbbuf);
- }
- }
- if (his_state_is_will(TELOPT_TSPEED)) {
- while (sequenceIs(tspeedsubopt, baseline))
- ttloop();
- }
- if (his_state_is_will(TELOPT_XDISPLOC)) {
- while (sequenceIs(xdisplocsubopt, baseline))
- ttloop();
- }
- if (his_state_is_will(TELOPT_ENVIRON)) {
- while (sequenceIs(environsubopt, baseline))
- ttloop();
- }
- if (his_state_is_will(TELOPT_TTYPE)) {
- char first[256], last[256];
-
- while (sequenceIs(ttypesubopt, baseline))
- ttloop();
-
- /*
- * If the other side has already disabled the option, then
- * 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) - 1);
- first[sizeof(first) - 1] = '\0';
- for(;;) {
- /*
- * Save the unknown name, and request the next name.
- */
- (void) strncpy(last, terminaltype, sizeof(last) - 1);
- last[sizeof(last) - 1] = '\0';
- _gettermname();
- if (terminaltypeok(terminaltype))
- break;
- if ((strncmp(last, terminaltype, sizeof(last)) == 0) ||
- his_state_is_wont(TELOPT_TTYPE)) {
- /*
- * We've hit the end. If this is the same as
- * the first name, just go with it.
- */
- if (strncmp(first, terminaltype, sizeof(first)) == 0)
- break;
- /*
- * Get the terminal name one more time, so that
- * RFC1091 compliant telnets will cycle back to
- * the start of the list.
- */
- _gettermname();
- if (strncmp(first, terminaltype, sizeof(first)) != 0)
- (void) strncpy(terminaltype, first, sizeof(terminaltype) - 1);
- terminaltype[sizeof(terminaltype) - 1] = '\0';
- break;
- }
- }
- }
- }
- return(retval);
-} /* end of getterminaltype */
-
- void
-_gettermname()
-{
- /*
- * If the client turned off the option,
- * we can't send another request, so we
- * just return.
- */
- if (his_state_is_wont(TELOPT_TTYPE))
- return;
- settimer(baseline);
- memcpy(nfrontp, ttytype_sbbuf, sizeof(ttytype_sbbuf));
- nfrontp += sizeof(ttytype_sbbuf);
- while (sequenceIs(ttypesubopt, baseline))
- ttloop();
-}
-
- int
-terminaltypeok(s)
- char *s;
-{
- char buf[1024];
-
- if (terminaltype == NULL)
- return(1);
-
- /*
- * tgetent() will return 1 if the type is known, and
- * 0 if it is not known. If it returns -1, it couldn't
- * open the database. But if we can't open the database,
- * it won't help to say we failed, because we won't be
- * able to verify anything else. So, we treat -1 like 1.
- */
- if (tgetent(buf, s) == 0)
- return(0);
- return(1);
-}
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
-#endif /* MAXHOSTNAMELEN */
-
-char *hostname;
-char host_name[MAXHOSTNAMELEN];
-char remote_host_name[MAXHOSTNAMELEN];
-
-#ifndef convex
-extern void telnet (int, int);
-#else
-extern void telnet (int, int, char *);
-#endif
-
-/*
- * Get a pty, scan input lines.
- */
-doit(who)
- struct sockaddr_in *who;
-{
- char *host, *inet_ntoa();
- int t;
- struct hostent *hp;
- int level;
- char user_name[256];
-
- /*
- * Find an available pty to use.
- */
- if ( (retval = pty_getpty(&pty, line, sizeof(line)) < 0 ) {
- com_err(retval, "telnetd", "");
-
- if (pty < 0)
- fatal(net, "All network ports in use");
-
-#if defined(_SC_CRAY_SECURE_SYS)
- /*
- * set ttyp line security label
- */
- if (secflag) {
- extern char *myline;
- if (setdevs(myline, &dv) < 0)
- fatal(net, "cannot set pty 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) <= ((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));
- hostname = host_name;
-
-#if defined(AUTHENTICATION) || defined(ENCRYPTION)
- auth_encrypt_init(hostname, host, "TELNETD", 1);
-#endif
-
- init_env();
- /*
- * get terminal type.
- */
- *user_name = 0;
- level = getterminaltype(user_name);
- setenv("TERM", terminaltype ? terminaltype : "network", 1);
-
- /*
- * Start up the login process on the slave side of the terminal
- */
-
- startslave(host, level, user_name);
- telnet(net, pty); /* begin server processing */
- /*NOTREACHED*/
-} /* end of doit */
-
-#if defined(CRAY2) && defined(UNICOS5) && defined(UNICOS50)
- int
-Xterm_output(ibufp, obuf, icountp, ocount)
- char **ibufp, *obuf;
- int *icountp, ocount;
-{
- int ret;
- ret = term_output(*ibufp, obuf, *icountp, ocount);
- *ibufp += *icountp;
- *icountp = 0;
- return(ret);
-}
-#define term_output Xterm_output
-#endif /* defined(CRAY2) && defined(UNICOS5) && defined(UNICOS50) */
-
-/*
- * Main loop. Select from pty and network, and
- * 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 defent[TABBUFSIZ];
- char defstrs[TABBUFSIZ];
-#undef TABBUFSIZ
- char *HE;
- char *HN;
- char *IM;
- void netflush();
-
- /*
- * Initialize the slc mapping table.
- */
- get_slc_defaults();
-
- /*
- * Do some tests where it is desireable to wait for a response.
- * Rather than doing them slowly, one at a time, do them all
- * at once.
- */
- if (my_state_is_wont(TELOPT_SGA))
- send_will(TELOPT_SGA, 1);
- /*
- * Is the client side a 4.2 (NOT 4.3) system? We need to know this
- * because 4.2 clients are unable to deal with TCP urgent data.
- *
- * To find out, we send out a "DO ECHO". If the remote system
- * answers "WILL ECHO" it is probably a 4.2 client, and we note
- * that fact ("WILL ECHO" ==> that the client will echo what
- * WE, the server, sends it; it does NOT mean that the client will
- * echo the terminal input).
- */
- send_do(TELOPT_ECHO, 1);
-
-#ifdef LINEMODE
- if (his_state_is_wont(TELOPT_LINEMODE)) {
- /* Query the peer for linemode support by trying to negotiate
- * the linemode option.
- */
- linemode = 0;
- editmode = 0;
- send_do(TELOPT_LINEMODE, 1); /* send do linemode */
- }
-#endif /* LINEMODE */
-
- /*
- * Send along a couple of other options that we wish to negotiate.
- */
- send_do(TELOPT_NAWS, 1);
- send_will(TELOPT_STATUS, 1);
- flowmode = 1; /* default flow control state */
- restartany = -1; /* uninitialized... */
- send_do(TELOPT_LFLOW, 1);
-
- /*
- * Spin, waiting for a response from the DO ECHO. However,
- * some REALLY DUMB telnets out there might not respond
- * to the DO ECHO. So, we spin looking for NAWS, (most dumb
- * telnets so far seem to respond with WONT for a DO that
- * they don't understand...) because by the time we get the
- * response, it will already have processed the DO ECHO.
- * Kludge upon kludge.
- */
- while (his_will_wont_is_changing(TELOPT_NAWS))
- ttloop();
-
- /*
- * But...
- * The client might have sent a WILL NAWS as part of its
- * startup code; if so, we'll be here before we get the
- * response to the DO ECHO. We'll make the assumption
- * that any implementation that understands about NAWS
- * is a modern enough implementation that it will respond
- * to our DO ECHO request; hence we'll do another spin
- * waiting for the ECHO option to settle down, which is
- * what we wanted to do in the first place...
- */
- if (his_want_state_is_will(TELOPT_ECHO) &&
- his_state_is_will(TELOPT_NAWS)) {
- while (his_will_wont_is_changing(TELOPT_ECHO))
- ttloop();
- }
- /*
- * On the off chance that the telnet client is broken and does not
- * respond to the DO ECHO we sent, (after all, we did send the
- * DO NAWS negotiation after the DO ECHO, and we won't get here
- * until a response to the DO NAWS comes back) simulate the
- * receipt of a will echo. This will also send a WONT ECHO
- * to the client, since we assume that the client failed to
- * respond because it believes that it is already in DO ECHO
- * 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);});
- willoption(TELOPT_ECHO);
- }
-
- /*
- * Finally, to clean things up, we turn on our echo. This
- * will break stupid 4.2 telnets out of local terminal echo.
- */
-
- if (my_state_is_wont(TELOPT_ECHO))
- send_will(TELOPT_ECHO, 1);
-
-#ifndef STREAMSPTY
- /*
- * Turn on packet mode
- */
- (void) ioctl(p, TIOCPKT, (char *)&on);
-#endif
-
-#if defined(LINEMODE) && defined(KLUDGELINEMODE)
- /*
- * Continuing line mode support. If client does not support
- * real linemode, attempt to negotiate kludge linemode by sending
- * the do timing mark sequence.
- */
- if (lmodetype < REAL_LINEMODE)
- send_do(TELOPT_TM, 1);
-#endif /* defined(LINEMODE) && defined(KLUDGELINEMODE) */
-
- /*
- * Call telrcv() once to pick up anything received during
- * terminal type negotiation, 4.2/4.3 determination, and
- * linemode negotiation.
- */
- telrcv();
-
- (void) ioctl(f, FIONBIO, (char *)&on);
- (void) ioctl(p, FIONBIO, (char *)&on);
-#if defined(CRAY2) && defined(UNICOS5)
- init_termdriver(f, p, interrupt, sendbrk);
-#endif
-
-#if defined(SO_OOBINLINE)
- (void) setsockopt(net, SOL_SOCKET, SO_OOBINLINE,
- (char *)&on, sizeof(on));
-#endif /* defined(SO_OOBINLINE) */
-
-#ifdef SIGTSTP
- (void) signal(SIGTSTP, SIG_IGN);
-#endif
-#ifdef SIGTTOU
- /*
- * Ignoring SIGTTOU keeps the kernel from blocking us
- * in ttioct() in /sys/tty.c.
- */
- (void) signal(SIGTTOU, SIG_IGN);
-#endif
-
- (void) signal(SIGCHLD, cleanup);
-
-#if defined(CRAY2) && defined(UNICOS5)
- /*
- * Cray-2 will send a signal when pty modes are changed by slave
- * side. Set up signal handler now.
- */
- if ((int)signal(SIGUSR1, termstat) < 0)
- perror("signal");
- else if (ioctl(p, TCSIGME, (char *)SIGUSR1) < 0)
- perror("ioctl:TCSIGME");
- /*
- * Make processing loop check terminal characteristics early on.
- */
- termstat();
-#endif
-
-#ifdef TIOCNOTTY
- {
- register int t;
- t = open(_PATH_TTY, O_RDWR);
- if (t >= 0) {
- (void) ioctl(t, TIOCNOTTY, (char *)0);
- (void) close(t);
- }
- }
-#endif
-
-#if defined(CRAY) && defined(NEWINIT) && defined(TIOCSCTTY)
- (void) setsid();
- ioctl(p, TIOCSCTTY, 0);
-#endif
-
- /*
- * Show banner that getty never gave.
- *
- * We put the banner in the pty input buffer. This way, it
- * gets carriage return null processing, etc., just like all
- * other pty --> client data.
- */
-
-#if !defined(CRAY) || !defined(NEWINIT)
- if (getenv("USER"))
- hostinfo = 0;
-#endif
-
- if (getent(defent, "default") == 1) {
- char *getstr();
- char *cp=defstrs;
-
- HE = getstr("he", &cp);
- HN = getstr("hn", &cp);
- IM = getstr("im", &cp);
- if (HN && *HN) {
- (void) strncpy(host_name, HN, sizeof(host_name) - 1);
- host_name[sizeof(host_name) - 1] = '\0';
- }
- if (IM == 0)
- IM = "";
- } else {
- IM = DEFAULT_IM;
- HE = 0;
- }
- edithost(HE, host_name);
- if (hostinfo && *IM)
- putf(IM, ptyibuf2);
-
- if (pcc)
- (void) strncat(ptyibuf2, ptyip, pcc+1);
- ptyip = ptyibuf2;
- pcc = strlen(ptyip);
-#ifdef LINEMODE
- /*
- * Last check to make sure all our states are correct.
- */
- init_termbuf();
- localstat();
-#endif /* LINEMODE */
-
- DIAG(TD_REPORT,
- {sprintf(nfrontp, "td: Entering processing loop\r\n");
- nfrontp += strlen(nfrontp);});
-
-#ifdef convex
- startslave(host);
-#endif
-
- for (;;) {
- fd_set ibits, obits, xbits;
- register int c;
-
- if (ncc < 0 && pcc < 0)
- break;
-
-#if defined(CRAY2) && defined(UNICOS5)
- if (needtermstat)
- _termstat();
-#endif /* defined(CRAY2) && defined(UNICOS5) */
- FD_ZERO(&ibits);
- FD_ZERO(&obits);
- FD_ZERO(&xbits);
- /*
- * Never look for input if there's still
- * stuff in the corresponding output buffer
- */
- if (nfrontp - nbackp || pcc > 0) {
- FD_SET(f, &obits);
- } else {
- FD_SET(p, &ibits);
- }
- if (pfrontp - pbackp || ncc > 0) {
- FD_SET(p, &obits);
- } else {
- FD_SET(f, &ibits);
- }
- if (!SYNCHing) {
- FD_SET(f, &xbits);
- }
- if ((c = select(16, &ibits, &obits, &xbits,
- (struct timeval *)0)) < 1) {
- if (c == -1) {
- if (errno == EINTR) {
- continue;
- }
- }
- sleep(5);
- continue;
- }
-
- /*
- * Any urgent data?
- */
- if (FD_ISSET(net, &xbits)) {
- SYNCHing = 1;
- }
-
- /*
- * Something to read from the network...
- */
- if (FD_ISSET(net, &ibits)) {
-#if !defined(SO_OOBINLINE)
- /*
- * In 4.2 (and 4.3 beta) systems, the
- * OOB indication and data handling in the kernel
- * is such that if two separate TCP Urgent requests
- * come in, one byte of TCP data will be overlaid.
- * This is fatal for Telnet, but we try to live
- * with it.
- *
- * In addition, in 4.2 (and...), a special protocol
- * is needed to pick up the TCP Urgent data in
- * the correct sequence.
- *
- * What we do is: if we think we are in urgent
- * mode, we look to see if we are "at the mark".
- * If we are, we do an OOB receive. If we run
- * this twice, we will do the OOB receive twice,
- * but the second will fail, since the second
- * time we were "at the mark", but there wasn't
- * any data there (the kernel doesn't reset
- * "at the mark" until we do a normal read).
- * Once we've read the OOB data, we go ahead
- * and do normal reads.
- *
- * There is also another problem, which is that
- * since the OOB byte we read doesn't put us
- * out of OOB state, and since that byte is most
- * likely the TELNET DM (data mark), we would
- * stay in the TELNET SYNCH (SYNCHing) state.
- * So, clocks to the rescue. If we've "just"
- * received a DM, then we test for the
- * presence of OOB data when the receive OOB
- * fails (and AFTER we did the normal mode read
- * to clear "at the mark").
- */
- if (SYNCHing) {
- int atmark;
-
- (void) ioctl(net, SIOCATMARK, (char *)&atmark);
- if (atmark) {
- ncc = recv(net, netibuf, sizeof (netibuf), MSG_OOB);
- if ((ncc == -1) && (errno == EINVAL)) {
- ncc = read(net, netibuf, sizeof (netibuf));
- if (sequenceIs(didnetreceive, gotDM)) {
- SYNCHing = stilloob(net);
- }
- }
- } else {
- ncc = read(net, netibuf, sizeof (netibuf));
- }
- } else {
- ncc = read(net, netibuf, sizeof (netibuf));
- }
- settimer(didnetreceive);
-#else /* !defined(SO_OOBINLINE)) */
- ncc = read(net, netibuf, sizeof (netibuf));
-#endif /* !defined(SO_OOBINLINE)) */
- if (ncc < 0 && errno == EWOULDBLOCK)
- ncc = 0;
- else {
- if (ncc <= 0) {
- break;
- }
- netip = netibuf;
- }
- DIAG((TD_REPORT | TD_NETDATA),
- {sprintf(nfrontp, "td: netread %d chars\r\n", ncc);
- nfrontp += strlen(nfrontp);});
- DIAG(TD_NETDATA, printdata("nd", netip, ncc));
- }
-
- /*
- * Something to read from the pty...
- */
- if (FD_ISSET(p, &ibits)) {
-#ifndef STREAMSPTY
- pcc = read(p, ptyibuf, BUFSIZ);
-#else
- pcc = readstream(p, ptyibuf, BUFSIZ);
-#endif
- /*
- * On some systems, if we try to read something
- * off the master side before the slave side is
- * opened, we get EIO.
- */
- if (pcc < 0 && (errno == EWOULDBLOCK ||
-#ifdef EAGAIN
- errno == EAGAIN ||
-#endif
- errno == EIO)) {
- pcc = 0;
- } else {
- if (pcc <= 0)
- break;
-#if !defined(CRAY2) || !defined(UNICOS5)
-#ifdef LINEMODE
- /*
- * If ioctl from pty, pass it through net
- */
- if (ptyibuf[0] & TIOCPKT_IOCTL) {
- copy_termbuf(ptyibuf+1, pcc-1);
- localstat();
- pcc = 1;
- }
-#endif /* LINEMODE */
- if (ptyibuf[0] & TIOCPKT_FLUSHWRITE) {
- netclear(); /* clear buffer back */
-#ifndef NO_URGENT
- /*
- * There are client telnets on some
- * operating systems get screwed up
- * royally if we send them urgent
- * mode data.
- */
- *nfrontp++ = IAC;
- *nfrontp++ = DM;
- neturg = nfrontp-1; /* off by one XXX */
-#endif
- }
- if (his_state_is_will(TELOPT_LFLOW) &&
- (ptyibuf[0] &
- (TIOCPKT_NOSTOP|TIOCPKT_DOSTOP))) {
- int newflow =
- ptyibuf[0] & TIOCPKT_DOSTOP ? 1 : 0;
- if (newflow != flowmode) {
- flowmode = newflow;
- (void) sprintf(nfrontp,
- "%c%c%c%c%c%c",
- IAC, SB, TELOPT_LFLOW,
- flowmode ? LFLOW_ON
- : LFLOW_OFF,
- IAC, SE);
- nfrontp += 6;
- }
- }
- pcc--;
- ptyip = ptyibuf+1;
-#else /* defined(CRAY2) && defined(UNICOS5) */
- if (!uselinemode) {
- unpcc = pcc;
- unptyip = ptyibuf;
- pcc = term_output(&unptyip, ptyibuf2,
- &unpcc, BUFSIZ);
- ptyip = ptyibuf2;
- } else
- ptyip = ptyibuf;
-#endif /* defined(CRAY2) && defined(UNICOS5) */
- }
- }
-
- while (pcc > 0) {
- if ((&netobuf[BUFSIZ] - nfrontp) < 2)
- break;
- c = *ptyip++ & 0377, pcc--;
- if (c == IAC)
- *nfrontp++ = c;
-#if defined(CRAY2) && defined(UNICOS5)
- else if (c == '\n' &&
- my_state_is_wont(TELOPT_BINARY) && newmap)
- *nfrontp++ = '\r';
-#endif /* defined(CRAY2) && defined(UNICOS5) */
- *nfrontp++ = c;
- if ((c == '\r') && (my_state_is_wont(TELOPT_BINARY))) {
- if (pcc > 0 && ((*ptyip & 0377) == '\n')) {
- *nfrontp++ = *ptyip++ & 0377;
- pcc--;
- } else
- *nfrontp++ = '\0';
- }
- }
-#if defined(CRAY2) && defined(UNICOS5)
- /*
- * If chars were left over from the terminal driver,
- * note their existence.
- */
- if (!uselinemode && unpcc) {
- pcc = unpcc;
- unpcc = 0;
- ptyip = unptyip;
- }
-#endif /* defined(CRAY2) && defined(UNICOS5) */
-
- if (FD_ISSET(f, &obits) && (nfrontp - nbackp) > 0)
- netflush();
- if (ncc > 0)
- telrcv();
- if (FD_ISSET(p, &obits) && (pfrontp - pbackp) > 0)
- ptyflush();
- }
- cleanup(0);
-} /* end of telnet */
-
-#ifndef TCSIG
-# ifdef TIOCSIG
-# define TCSIG TIOCSIG
-# endif
-#endif
-
-#ifdef STREAMSPTY
-
-int flowison = -1; /* current state of flow: -1 is unknown */
-
-int readstream(p, ibuf, bufsize)
- int p;
- char *ibuf;
- int bufsize;
-{
- int flags = 0;
- int ret = 0;
- struct termios *tsp;
- struct termio *tp;
- struct iocblk *ip;
- char vstop, vstart;
- int ixon;
- int newflow;
-
- strbufc.maxlen = BUFSIZ;
- strbufc.buf = ctlbuf;
- strbufd.maxlen = bufsize-1;
- strbufd.len = 0;
- strbufd.buf = ibuf+1;
- ibuf[0] = 0;
-
- ret = getmsg(p, &strbufc, &strbufd, &flags);
- if (ret < 0) /* error of some sort -- probably EAGAIN */
- return(-1);
-
- if (strbufc.len <= 0 || ctlbuf[0] == M_DATA) {
- /* data message */
- if (strbufd.len > 0) { /* real data */
- return(strbufd.len + 1); /* count header char */
- } else {
- /* nothing there */
- errno = EAGAIN;
- return(-1);
- }
- }
-
- /*
- * It's a control message. Return 1, to look at the flag we set
- */
-
- switch (ctlbuf[0]) {
- case M_FLUSH:
- if (ibuf[1] & FLUSHW)
- ibuf[0] = TIOCPKT_FLUSHWRITE;
- return(1);
-
- case M_IOCTL:
- ip = (struct iocblk *) (ibuf+1);
-
- switch (ip->ioc_cmd) {
- case TCSETS:
- case TCSETSW:
- case TCSETSF:
- tsp = (struct termios *)
- (ibuf+1 + sizeof(struct iocblk));
- vstop = tsp->c_cc[VSTOP];
- vstart = tsp->c_cc[VSTART];
- ixon = tsp->c_iflag & IXON;
- break;
- case TCSETA:
- case TCSETAW:
- case TCSETAF:
- tp = (struct termio *) (ibuf+1 + sizeof(struct iocblk));
- vstop = tp->c_cc[VSTOP];
- vstart = tp->c_cc[VSTART];
- ixon = tp->c_iflag & IXON;
- break;
- default:
- errno = EAGAIN;
- return(-1);
- }
-
- newflow = (ixon && (vstart == 021) && (vstop == 023)) ? 1 : 0;
- if (newflow != flowison) { /* it's a change */
- flowison = newflow;
- ibuf[0] = newflow ? TIOCPKT_DOSTOP : TIOCPKT_NOSTOP;
- return(1);
- }
- }
-
- /* nothing worth doing anything about */
- errno = EAGAIN;
- return(-1);
-}
-#endif /* STREAMSPTY */
-
-/*
- * Send interrupt to process on other side of pty.
- * If it is in raw mode, just write NULL;
- * otherwise, write intr char.
- */
- void
-interrupt()
-{
- ptyflush(); /* half-hearted */
-
-#ifdef TCSIG
- (void) ioctl(pty, TCSIG, (char *)SIGINT);
-#else /* TCSIG */
- init_termbuf();
- *pfrontp++ = slctab[SLC_IP].sptr ?
- (unsigned char)*slctab[SLC_IP].sptr : '\177';
-#endif /* TCSIG */
-}
-
-/*
- * Send quit to process on other side of pty.
- * If it is in raw mode, just write NULL;
- * otherwise, write quit char.
- */
- void
-sendbrk()
-{
- ptyflush(); /* half-hearted */
-#ifdef TCSIG
- (void) ioctl(pty, TCSIG, (char *)SIGQUIT);
-#else /* TCSIG */
- init_termbuf();
- *pfrontp++ = slctab[SLC_ABORT].sptr ?
- (unsigned char)*slctab[SLC_ABORT].sptr : '\034';
-#endif /* TCSIG */
-}
-
- void
-sendsusp()
-{
-#ifdef SIGTSTP
- ptyflush(); /* half-hearted */
-# ifdef TCSIG
- (void) ioctl(pty, TCSIG, (char *)SIGTSTP);
-# else /* TCSIG */
- *pfrontp++ = slctab[SLC_SUSP].sptr ?
- (unsigned char)*slctab[SLC_SUSP].sptr : '\032';
-# endif /* TCSIG */
-#endif /* SIGTSTP */
-}
-
-/*
- * When we get an AYT, if ^T is enabled, use that. Otherwise,
- * just send back "[Yes]".
- */
- void
-recv_ayt()
-{
-#if defined(SIGINFO) && defined(TCSIG)
- if (slctab[SLC_AYT].sptr && *slctab[SLC_AYT].sptr != _POSIX_VDISABLE) {
- (void) ioctl(pty, TCSIG, (char *)SIGINFO);
- return;
- }
-#endif
- (void) strncpy(nfrontp, "\r\n[Yes]\r\n",
- sizeof(netobuf) - 1 - (nfrontp - netobuf));
- nfrontp += 9;
- *nfrontp = '\0';
-}
-
- void
-doeof()
-{
- 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';
-}
+++ /dev/null
-%!PS-Adobe-3.0
-%%Creator: groff version 1.08
-%%DocumentNeededResources: font Times-Roman
-%%+ font Times-Bold
-%%+ font Courier-Bold
-%%+ font Courier-Oblique
-%%+ font Courier
-%%DocumentSuppliedResources: procset grops 1.08 0
-%%Pages: 5
-%%PageOrder: Ascend
-%%Orientation: Portrait
-%%EndComments
-%%BeginProlog
-%%BeginResource: procset grops 1.08 0
-/setpacking where{
-pop
-currentpacking
-true setpacking
-}if
-/grops 120 dict dup begin
-/SC 32 def
-/A/show load def
-/B{0 SC 3 -1 roll widthshow}bind def
-/C{0 exch ashow}bind def
-/D{0 exch 0 SC 5 2 roll awidthshow}bind def
-/E{0 rmoveto show}bind def
-/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def
-/G{0 rmoveto 0 exch ashow}bind def
-/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/I{0 exch rmoveto show}bind def
-/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def
-/K{0 exch rmoveto 0 exch ashow}bind def
-/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/M{rmoveto show}bind def
-/N{rmoveto 0 SC 3 -1 roll widthshow}bind def
-/O{rmoveto 0 exch ashow}bind def
-/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/Q{moveto show}bind def
-/R{moveto 0 SC 3 -1 roll widthshow}bind def
-/S{moveto 0 exch ashow}bind def
-/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/SF{
-findfont exch
-[exch dup 0 exch 0 exch neg 0 0]makefont
-dup setfont
-[exch/setfont cvx]cvx bind def
-}bind def
-/MF{
-findfont
-[5 2 roll
-0 3 1 roll
-neg 0 0]makefont
-dup setfont
-[exch/setfont cvx]cvx bind def
-}bind def
-/level0 0 def
-/RES 0 def
-/PL 0 def
-/LS 0 def
-/PLG{
-gsave newpath clippath pathbbox grestore
-exch pop add exch pop
-}bind def
-/BP{
-/level0 save def
-1 setlinecap
-1 setlinejoin
-72 RES div dup scale
-LS{
-90 rotate
-}{
-0 PL translate
-}ifelse
-1 -1 scale
-}bind def
-/EP{
-level0 restore
-showpage
-}bind def
-/DA{
-newpath arcn stroke
-}bind def
-/SN{
-transform
-.25 sub exch .25 sub exch
-round .25 add exch round .25 add exch
-itransform
-}bind def
-/DL{
-SN
-moveto
-SN
-lineto stroke
-}bind def
-/DC{
-newpath 0 360 arc closepath
-}bind def
-/TM matrix def
-/DE{
-TM currentmatrix pop
-translate scale newpath 0 0 .5 0 360 arc closepath
-TM setmatrix
-}bind def
-/RC/rcurveto load def
-/RL/rlineto load def
-/ST/stroke load def
-/MT/moveto load def
-/CL/closepath load def
-/FL{
-currentgray exch setgray fill setgray
-}bind def
-/BL/fill load def
-/LW/setlinewidth load def
-/RE{
-findfont
-dup maxlength 1 index/FontName known not{1 add}if dict begin
-{
-1 index/FID ne{def}{pop pop}ifelse
-}forall
-/Encoding exch def
-dup/FontName exch def
-currentdict end definefont pop
-}bind def
-/DEFS 0 def
-/EBEGIN{
-moveto
-DEFS begin
-}bind def
-/EEND/end load def
-/CNT 0 def
-/level1 0 def
-/PBEGIN{
-/level1 save def
-translate
-div 3 1 roll div exch scale
-neg exch neg exch translate
-0 setgray
-0 setlinecap
-1 setlinewidth
-0 setlinejoin
-10 setmiterlimit
-[]0 setdash
-/setstrokeadjust where{
-pop
-false setstrokeadjust
-}if
-/setoverprint where{
-pop
-false setoverprint
-}if
-newpath
-/CNT countdictstack def
-userdict begin
-/showpage{}def
-}bind def
-/PEND{
-clear
-countdictstack CNT sub{end}repeat
-level1 restore
-}bind def
-end def
-/setpacking where{
-pop
-setpacking
-}if
-%%EndResource
-%%IncludeResource: font Times-Roman
-%%IncludeResource: font Times-Bold
-%%IncludeResource: font Courier-Bold
-%%IncludeResource: font Courier-Oblique
-%%IncludeResource: font Courier
-grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL
-792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron
-/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef
-/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space
-/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft
-/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four
-/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C
-/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash
-/bracketright/circumflex/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q
-/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase
-/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger
-/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut
-/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash
-/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar
-/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus
-/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu
-/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright
-/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde
-/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute
-/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
-/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
-/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute
-/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve
-/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex
-/udieresis/yacute/thorn/ydieresis]def/Courier@0 ENC0/Courier RE
-/Courier-Oblique@0 ENC0/Courier-Oblique RE/Courier-Bold@0 ENC0/Courier-Bold RE
-/Times-Bold@0 ENC0/Times-Bold RE/Times-Roman@0 ENC0/Times-Roman RE
-%%EndProlog
-%%Page: 1 1
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF -.834(TELNETD \( 8 \))72 48 R(BSD System Manager')
-241.42 48 Q 2.5(sM)-.55 G 105.272(anual TELNETD)348.92 48 R 1.666(\(8\))1.666 G
-/F1 10/Times-Bold@0 SF -.2(NA)72 108 S(ME).2 E/F2 10/Courier-Bold@0 SF(telnetd)
-102 120 Q F0 2.5<ad44>2.5 G(ARP)161.46 120 Q(A)-.92 E/F3 9/Times-Roman@0 SF
-(TELNET)2.5 E F0(protocol serv)2.5 E(er)-.15 E F1(SYNOPSIS)72 144 Q F2
-(/usr/libexec/telnetd)102 156 Q F0([)3.333 E F2<ad61>2.499 E/F4 10
-/Courier-Oblique@0 SF(authmode)6 E F0 3.333(][).833 G F2<ad42>-.834 E F0 3.333
-(][).833 G F2<ad44>-.834 E F4(debugmode)6 E F0 3.333(][).833 G F2(\255edebug)
--.834 E F0 3.333(][).833 G F2<ad68>-.834 E F0(]).833 E([)228.833 168 Q F2<ad49>
-2.499 E F4(initid)A F0 3.333(][).833 G F2<ad6c>-.834 E F0 3.333(][).833 G F2
-<ad6b>-.834 E F0 3.333(][).833 G F2<ad6e>-.834 E F0 3.333(][).833 G F2<ad72>
--.834 E F4(lowpty-highpty)A F0 3.333(][).833 G F2<ad73>-.834 E F0 3.333(][).833
-G F2<ad53>-.834 E F4(tos)228 180 Q F0 3.333(][).833 G F2<ad75>-.834 E F4(len)6
-E F0 3.333(][).833 G F2<ad55>-.834 E F0 3.333(][).833 G F2<ad58>-.834 E F4
-(authtype)6 E F0 3.333(][).833 G F2(\255debug)-.834 E F0([)6.833 E F4(port).833
-E F0 .833(]]).833 G F1(DESCRIPTION)72 204 Q F0(The)102 216 Q F2(telnetd)3.044 E
-F0 .544(command is a serv)3.044 F .544(er which supports the)-.15 F F3 -.36(DA)
-3.044 G(RP).36 E(A)-.828 E F0(standard)3.044 E F3(TELNET)3.044 E F0 .543
-(virtual terminal protocol.)3.044 F F2(Telnetd)102 228 Q F0 .221
-(is normally in)2.721 F -.2(vo)-.4 G -.1(ke).2 G 2.721(db).1 G 2.721(yt)234.184
-228 S .221(he internet serv)244.685 228 R .221(er \(see)-.15 F/F5 10/Courier@0
-SF(inetd)2.721 E F0 2.942(\(8\)\) for)B .221(requests to connect to the)2.721 F
-F3(TELNET)2.721 E F0 .673(port as indicated by the)102 240 R F5(/etc/services)
-3.173 E F0 .673(\214le \(see)3.173 F F5(services)3.173 E F0 3.846(\(5\)\). The)
-B F2(\255debug)4.839 E F0 .672(option may be used to)3.173 F .145(start up)102
-252 R F2(telnetd)2.645 E F0(manually)2.645 E 2.645(,i)-.65 G .145
-(nstead of through)223.65 252 R F5(inetd)2.645 E F0 2.79(\(8\). If)B .145
-(started up this w)2.645 F(ay)-.1 E(,)-.65 E F4(port)2.645 E F0 .145
-(may be speci\214ed to)2.645 F(run)102 264 Q F2(telnetd)2.5 E F0
-(on an alternate)2.5 E F3(TCP)2.5 E F0(port number)2.5 E(.)-.55 E(The)102 282 Q
-F2(telnetd)2.5 E F0(command accepts the follo)2.5 E(wing options:)-.25 E F2
-<ad61>103.666 300 Q F4(authmode)6 E F0 .106(This option may be used for specif\
-ying what mode should be used for authentication.)173 312 R(Note)5.106 E 2.778
-(that this option is only useful if)173 324 R F2(telnetd)5.279 E F0 2.779
-(has been compiled with support for the)5.279 F F5(AUTHENTICATION)173 336 Q F0
-2.5(option. There)2.5 F(are se)2.5 E -.15(ve)-.25 G(ral v).15 E(alid v)-.25 E
-(alues for)-.25 E F4(authmode:)2.5 E F0(deb)173 354 Q 8.26(ug T)-.2 F
-(urns on authentication deb)-.45 E(ugging code.)-.2 E 15.84(user Only)173 372 R
-(allo)2.923 E 2.923(wc)-.25 G .423(onnections when the remote user can pro)
-260.256 372 R .422(vide v)-.15 F .422(alid authentication in-)-.25 F 1.277
-(formation to identify the remote user)208 384 R 3.777(,a)-.4 G 1.277
-(nd is allo)372.181 384 R 1.277(wed access to the speci\214ed ac-)-.25 F
-(count without pro)208 396 Q(viding a passw)-.15 E(ord.)-.1 E -.25(va)173 414 S
-12.75(lid Only).25 F(allo)2.923 E 2.923(wc)-.25 G .423
-(onnections when the remote user can pro)260.256 414 R .422(vide v)-.15 F .422
-(alid authentication in-)-.25 F .742(formation to identify the remote user)208
-426 R 5.743(.T)-.55 G(he)372.995 426 Q F5(login)3.243 E F0 .743
-(\(1\) command will pro)B .743(vide an)-.15 F(y)-.15 E .53(additional user v)
-208 438 R .529(eri\214cation needed if the remote user is not allo)-.15 F .529
-(wed automatic ac-)-.25 F(cess to the speci\214ed account.)208 450 Q 11.95
-(other Only)173 468 R(allo)3.028 E 3.029(wc)-.25 G .529
-(onnections that supply some authentication information.)260.467 468 R .529
-(This option)5.529 F .079(is currently not supported by an)208 480 R 2.578(yo)
--.15 G 2.578(ft)347.752 480 S .078(he e)356.44 480 R .078
-(xisting authentication mechanisms, and is)-.15 F(thus the same as specifying)
-208 492 Q F2 -3.5(\255a valid)4.166 F F0(.)A 13.06(none This)173 510 R .869
-(is the def)3.369 F .869(ault state.)-.1 F .869
-(Authentication information is not required.)5.869 F .87(If no or in-)5.869 F
-(suf)208 522 Q .394(\214cient authentication information is pro)-.25 F .393
-(vided, then the)-.15 F F5(login)2.893 E F0 .393(\(1\) program will)B(pro)208
-534 Q(vide the necessary user v)-.15 E(eri\214cation.)-.15 E(of)173 552 Q 23.59
-(fT)-.25 G 1.385(his disables the authentication code.)214.11 552 R 1.385
-(All user v)6.385 F 1.385(eri\214cation will happen through)-.15 F(the)208 564
-Q F5(login)2.5 E F0(\(1\) program.)A F2<ad42>103.666 582 Q F0 .82
-(Speci\214es bftp serv)173 582 R .82(er mode.)-.15 F .819(In this mode,)5.82 F
-F2(telnetd)3.319 E F0 .819(causes login to start a)3.319 F F5(bftp)3.319 E F0
-.819(\(1\) ses-)B .747(sion rather than the user')173 594 R 3.247(sn)-.55 G
-.747(ormal shell.)286.995 594 R .748
-(In bftp daemon mode normal logins are not sup-)5.747 F
-(ported, and it must be used on a port other than the normal)173 606 Q F3
-(TELNET)2.5 E F0(port.)2.5 E F2<ad44>103.666 624 Q F4(debugmode)6 E F0 .827
-(This option may be used for deb)173 636 R .827(ugging purposes.)-.2 F .827
-(This allo)5.827 F(ws)-.25 E F2(telnetd)3.327 E F0 .827(to print out de-)3.327
-F -.2(bu)173 648 S .827(gging information to the connection, allo).2 F .827
-(wing the user to see what)-.25 F F2(telnetd)3.327 E F0 .827(is doing.)3.327 F
-(There are se)173 660 Q -.15(ve)-.25 G(ral possible v).15 E(alues for)-.25 E F4
-(debugmode:)2.5 E F2(options)173 678 Q F0(Prints information about the ne)226
-678 Q(gotiation of)-.15 E F3(TELNET)2.5 E F0(options.)2.5 E(4.2 Berk)72 750 Q
-(ele)-.1 E 2.5(yD)-.15 G(istrib)132.57 750 Q 95.71(ution February)-.2 F
-(3, 1994)2.5 E(1)535 750 Q EP
-%%Page: 2 2
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF -.834(TELNETD \( 8 \))72 48 R(BSD System Manager')
-241.42 48 Q 2.5(sM)-.55 G 105.272(anual TELNETD)348.92 48 R 1.666(\(8\))1.666 G
-/F1 10/Courier-Bold@0 SF(report)173 96 Q F0 2.438(Prints the)226 96 R F1
-(options)4.938 E F0 2.437(information, plus some additional information about)
-4.938 F(what processing is going on.)226 108 Q F1(netdata)173 126 Q F0
-(Displays the data stream recei)226 126 Q -.15(ve)-.25 G 2.5(db).15 G(y)367.51
-126 Q F1(telnetd.)2.5 E(ptydata)173 144 Q F0(Displays data written to the pty)
-226 144 Q(.)-.65 E F1(exercise)173 162 Q F0(Has not been implemented yet.)5 E
-F1(\255debug)103.666 180 Q F0(Enables deb)173 180 Q(ugging on each sock)-.2 E
-(et created by)-.1 E F1(telnetd)2.5 E F0(\(see)2.5 E/F2 10/Courier@0 SF
-(SO_DEBUG)2.5 E F0(in)2.5 E F2(socket)2.5 E F0(\(2\)\).)A F1(\255edebug)103.666
-198 Q F0(If)173 198 Q F1(telnetd)3.161 E F0 .662
-(has been compiled with support for data encryption, then the)3.161 F F1
-(\255edebug)4.828 E F0(op-)3.162 E(tion may be used to enable encryption deb)
-173 210 Q(ugging code.)-.2 E F1<ad68>103.666 228 Q F0(Disables the printing of\
- host-speci\214c information before login has been completed.)173 228 Q F1
-<ad49>103.666 246 Q/F3 10/Courier-Oblique@0 SF(initid)7.171 E F0 1.171
-(This option is only applicable to)174.171 246 R/F4 9/Times-Roman@0 SF(UNICOS)
-3.671 E F0 1.171(systems prior to 7.0.)3.671 F 1.17(It speci\214es the)6.171 F
-F2(ID)3.67 E F0(from)3.67 E F2(/etc/inittab)173 258 Q F0
-(to use when init starts login sessions.)2.5 E(The def)5 E(ault)-.1 E F2(ID)2.5
-E F0(is)2.5 E F2(fe.)2.5 E F1<ad6b>103.666 276 Q F0 .556
-(This option is only useful if)173 276 R F1(telnetd)3.056 E F0 .557
-(has been compiled with both linemode and kludge)3.056 F .521
-(linemode support.)173 288 R .521(If the)5.521 F F1<ad6b>4.687 E F0 .52
-(option is speci\214ed, then if the remote client does not support)3.02 F(the)
-173 300 Q F2(LINEMODE)3.697 E F0 1.197(option, then)3.697 F F1(telnetd)3.697 E
-F0 1.197(will operate in character at a time mode.)3.697 F 1.198(It will)6.198
-F .148(still support kludge linemode, b)173 312 R .147
-(ut will only go into kludge linemode if the remote client re-)-.2 F 2.06
-(quests it.)173 324 R 2.061(\(This is done by by the client sending)7.06 F F2
-2.061(DONT SUPPRESS-GO-AHEAD)4.561 F F0(and)4.561 E F2 .1(DONT ECHO)173 336 R
-F0 .1(.\) The)B F1<ad6b>4.266 E F0 .1
-(option is most useful when there are remote clients that do not sup-)2.6 F .67
-(port kludge linemode, b)173 348 R .67(ut pass the heuristic \(if the)-.2 F
-3.17(yr)-.15 G .67(espond with)390.88 348 R F2 .67(WILL TIMING-MARK)3.17 F F0
-(in response to a)173 360 Q F2(DO TIMING-MARK\))2.5 E F0
-(for kludge linemode support.)2.5 E F1<ad6c>103.666 378 Q F0 .672
-(Speci\214es line mode.)173 378 R -.35(Tr)5.672 G .671
-(ies to force clients to use line- at-a-time mode.).35 F .671(If the)5.671 F F2
-(LINEMODE)3.171 E F0(option is not supported, it will go into kludge linemode.)
-173 390 Q F1<ad6e>103.666 408 Q F0(Disable)173 408 Q F2(TCP)3.488 E F0 -.1(ke)
-3.488 G(ep-ali).1 E -.15(ve)-.25 G 3.488(s. Normally).15 F F1(telnetd)3.488 E
-F0 .988(enables the)3.488 F F4(TCP)3.489 E F0 -.1(ke)3.489 G(ep-ali).1 E 1.289
--.15(ve m)-.25 H .989(echanism to).15 F .602(probe connections that ha)173 420
-R .902 -.15(ve b)-.2 H .602
-(een idle for some period of time to determine if the client is).15 F 1.124
-(still there, so that idle connections from machines that ha)173 432 R 1.424
--.15(ve c)-.2 H 1.124(rashed or can no longer be).15 F
-(reached may be cleaned up.)173 444 Q F1<ad72>103.666 462 Q F3(lowpty-highpty)6
-E F0 .772(This option is only enabled when)173 474 R F1(telnetd)3.272 E F0 .771
-(is compiled for)3.271 F F2(UNICOS.)3.271 E F0 .771(It speci\214es an in-)3.271
-F(clusi)173 486 Q 3.232 -.15(ve r)-.25 H 2.932(ange of pseudo-terminal de).15 F
-2.932(vices to use.)-.25 F 2.933(If the system has sysconf v)7.933 F(ariable)
--.25 E F2(_SC_CRAY_NPTY)173 498 Q F0 1.486(con\214gured, the def)3.986 F 1.486
-(ault pty search range is 0 to)-.1 F F2(_SC_CRAY_NPTY;)3.986 E F0 .72
-(otherwise, the def)173 510 R .72(ault range is 0 to 128.)-.1 F(Either)5.72 E
-F3(lowpty)3.22 E F0(or)3.22 E F3(highpty)3.22 E F0 .72(may be omitted to)3.22 F
-(allo)173 522 Q 2.6(wc)-.25 G .1(hanging either end of the search range.)202.01
-522 R(If)5.1 E F3(lowpty)2.6 E F0 .1(is omitted, the - character is still)2.6 F
-(required so that)173 534 Q F1(telnetd)2.5 E F0(can dif)2.5 E(ferentiate)-.25 E
-F3(highpty)2.5 E F0(from)2.5 E F3(lowpty)2.5 E F0(.)A F1<ad73>103.666 552 Q F0
-1.391(This option is only enabled if)173 552 R F1(telnetd)3.891 E F0 1.391
-(is compiled with support for)3.891 F F4(SecurID)3.891 E F0 3.891(cards. It)
-3.891 F .787(causes the)173 564 R F1<ad73>4.953 E F0 .786
-(option to be passed on to)3.286 F F2(login)3.286 E F0 4.072(\(1\), and)B .786
-(thus is only useful if)3.286 F F2(login)3.286 E F0(\(1\))A .48(supports the)
-173 576 R F1<ad73>4.646 E F0 .48(\215ag to indicate that only)2.98 F F4
-(SecurID)2.98 E F0 -.25(va)2.98 G .481(lidated logins are allo).25 F .481
-(wed, and is usu-)-.25 F
-(ally useful for controlling remote logins from outside of a \214re)173 588 Q
--.1(wa)-.25 G(ll.).1 E F1<ad53>103.666 606 Q F3(tos)6 E F1<ad75>103.666 624 Q
-F3(len)6.628 E F0 .628
-(This option is used to specify the size of the \214eld in the)173.628 624 R F2
-(utmp)3.127 E F0 .627(structure that holds the re-)3.127 F 1(mote host name.)
-173 636 R 1(If the resolv)6 F 1(ed host name is longer than)-.15 F F3(len)3.5 E
-F0 3.5(,t)C 1(he dotted decimal v)441.99 636 R(alue)-.25 E .046
-(will be used instead.)173 648 R .046(This allo)5.046 F .046(ws hosts with v)
--.25 F .045(ery long host names that o)-.15 F -.15(ve)-.15 G(r\215o).15 E 2.545
-(wt)-.25 G .045(his \214eld to)497.68 648 R .996
-(still be uniquely identi\214ed.)173 660 R(Specifying)5.997 E F1(\255u0)5.163 E
-F0 .997(indicates that only dotted decimal addresses)3.497 F
-(should be put into the)173 672 Q F2(utmp)2.5 E F0(\214le.)2.5 E F1<ad55>
-103.666 690 Q F0 .422(This option causes)173 690 R F1(telnetd)2.922 E F0 .422
-(to refuse connections from addresses that cannot be mapped)2.922 F(4.2 Berk)72
-750 Q(ele)-.1 E 2.5(yD)-.15 G(istrib)132.57 750 Q 95.71(ution February)-.2 F
-(3, 1994)2.5 E(2)535 750 Q EP
-%%Page: 3 3
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF -.834(TELNETD \( 8 \))72 48 R(BSD System Manager')
-241.42 48 Q 2.5(sM)-.55 G 105.272(anual TELNETD)348.92 48 R 1.666(\(8\))1.666 G
-(back into a symbolic name via the)173 96 Q/F1 10/Courier@0 SF(gethostbyaddr)
-2.5 E F0(\(3\) routine.)A/F2 10/Courier-Bold@0 SF<ad58>103.666 114 Q/F3 10
-/Courier-Oblique@0 SF(authtype)6 E F0 .123(This option is only v)173 126 R .123
-(alid if)-.25 F F2(telnetd)2.623 E F0 .123(has been b)2.623 F .124
-(uilt with support for the authentication op-)-.2 F 2.968(tion. It)173 138 R
-.467(disables the use of)2.968 F F3(authtype)2.967 E F0 .467
-(authentication, and can be used to temporarily dis-)2.967 F
-(able a speci\214c authentication type without ha)173 150 Q(ving to recompile)
--.2 E F2(telnetd)2.5 E F0(.)A F2(Telnetd)102 168 Q F0 .851
-(operates by allocating a pseudo-terminal de)3.351 F .851(vice \(see)-.25 F F1
-(pty)3.351 E F0 4.202(\(4\)\) for)B 3.351(ac)3.351 G .852
-(lient, then creating a login)431.882 168 R .757(process which has the sla)102
-180 R 1.057 -.15(ve s)-.2 H .757(ide of the pseudo-terminal as).15 F F1(stdin)
-3.257 E F0(,)A F1(stdout)3.256 E F0(and)3.256 E F1(stderr)3.256 E F0(.)A F2
-(Telnetd)3.256 E F0(ma-)3.256 E .483
-(nipulates the master side of the pseudo-terminal, implementing the)102 192 R
-/F4 9/Times-Roman@0 SF(TELNET)2.984 E F0 .484(protocol and passing characters)
-2.984 F(between the remote client and the login process.)102 204 Q .538(When a)
-102 222 R F4(TELNET)3.038 E F0 .538(session is started up,)3.038 F F2(telnetd)
-3.038 E F0(sends)3.038 E F4(TELNET)3.038 E F0 .538
-(options to the client side indicating a will-)3.038 F(ingness to do the follo)
-102 234 Q(wing)-.25 E F4(TELNET)2.5 E F0
-(options, which are described in more detail belo)2.5 E(w:)-.25 E F1
-(DO AUTHENTICATION)132 252 Q(WILL ENCRYPT)132 264 Q(DO TERMINAL TYPE)132 276 Q
-(DO TSPEED)132 288 Q(DO XDISPLOC)132 300 Q(DO NEW-ENVIRON)132 312 Q(DO ENVIRON)
-132 324 Q(WILL SUPPRESS GO AHEAD)132 336 Q(DO ECHO)132 348 Q(DO LINEMODE)132
-360 Q(DO NAWS)132 372 Q(WILL STATUS)132 384 Q(DO LFLOW)132 396 Q
-(DO TIMING-MARK)132 408 Q F0 .468(The pseudo-terminal allocated to the client \
-is con\214gured to operate in cook)102 426 R .468(ed mode, and with)-.1 F F1
-.469(XTABS and)2.969 F(CRMOD)102 438 Q F0(enabled \(see)2.5 E F1(tty)2.5 E F0
-(\(4\)\).)A F2(Telnetd)102 456 Q F0(has support for enabling locally the follo)
-2.5 E(wing)-.25 E F4(TELNET)2.5 E F0(options:)2.5 E .558(WILL ECHO)102 474 R
-.558(When the)209.558 474 R F1(LINEMODE)3.057 E F0 .557(option is enabled, a)
-3.057 F F1 .557(WILL ECHO)3.057 F F0(or)3.057 E F1 .557(WONT ECHO)3.057 F F0
-.557(will be)3.057 F .487
-(sent to the client to indicate the current state of terminal echoing.)209 486
-R .487(When terminal)5.487 F .409(echo is not desired, a)209 498 R F1 .408
-(WILL ECHO)2.908 F F0 .408(is sent to indicate that)2.908 F F4(telnetd)2.908 E
-F0 .408(will tak)2.908 F 2.908(ec)-.1 G .408(are of)516.552 498 R 1.811
-(echoing an)209 510 R 4.311(yd)-.15 G 1.811
-(ata that needs to be echoed to the terminal, and then nothing is)268.572 510 R
-3.876(echoed. When)209 522 R 1.376(terminal echo is desired, a)3.876 F F1 1.375
-(WONT ECHO)3.875 F F0 1.375(is sent to indicate that)3.875 F F4(telnetd)209 534
-Q F0 .11(will not be doing an)2.61 F 2.61(yt)-.15 G .11
-(erminal echoing, so the client should do an)326.788 534 R 2.611(yt)-.15 G
-(erminal)509.45 534 Q(echoing that is needed.)209 546 Q .243(WILL BIN)102 564 R
-(AR)-.35 E 42.18(YI)-.65 G .243(ndicates that the client is willing to send a \
-8 bits of data, rather than the normal 7)212.573 564 R(bits of the Netw)209 576
-Q(ork V)-.1 E(irtual T)-.6 E(erminal.)-.7 E(WILL SGA)102 594 Q
-(Indicates that it will not be sending)209 594 Q F1(IAC GA,)2.5 E F0
-(go ahead, commands.)2.5 E .366(WILL ST)102 612 R -1.11(AT)-.93 G 41.27
-(US Indicates)1.11 F 2.866(aw)2.866 G .366
-(illingness to send the client, upon request, of the current status of all)
-262.858 612 R F4(TELNET)209 624 Q F0(options.)2.5 E .51(WILL TIMING-MARK)102
-642 R(Whene)209.51 642 Q -.15(ve)-.25 G 3.01(ra).15 G F1 .509(DO TIMING-MARK)
--.001 F F0 .509(command is recei)3.009 F -.15(ve)-.25 G .509(d, it is al).15 F
--.1(wa)-.1 G .509(ys responded to).1 F(with a)209 654 Q F1(WILL TIMING-MARK)2.5
-E F0 .726(WILL LOGOUT)102 672 R .726(When a)209.726 672 R F1 .726(DO LOGOUT)
-3.226 F F0 .726(is recei)3.226 F -.15(ve)-.25 G .726(d, a).15 F F1 .726
-(WILL LOGOUT)3.226 F F0 .726(is sent in response, and the)3.226 F(4.2 Berk)72
-750 Q(ele)-.1 E 2.5(yD)-.15 G(istrib)132.57 750 Q 95.71(ution February)-.2 F
-(3, 1994)2.5 E(3)535 750 Q EP
-%%Page: 4 4
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF -.834(TELNETD \( 8 \))72 48 R(BSD System Manager')
-241.42 48 Q 2.5(sM)-.55 G 105.272(anual TELNETD)348.92 48 R 1.666(\(8\))1.666 G
-/F1 9/Times-Roman@0 SF(TELNET)209 96 Q F0(session is shut do)2.5 E(wn.)-.25 E
-.118(WILL ENCR)102 114 R 32.1(YPT Only)-.65 F .118(sent if)2.618 F/F2 10
-/Courier-Bold@0 SF(telnetd)2.618 E F0 .118
-(is compiled with support for data encryption, and indicates)2.618 F 2.5(aw)209
-126 S(illingness to decrypt the data stream.)223.16 126 Q F2(Telnetd)102 144 Q
-F0(has support for enabling remotely the follo)2.5 E(wing)-.25 E F1(TELNET)2.5
-E F0(options:)2.5 E(DO BIN)102 162 Q(AR)-.35 E 52.73(YS)-.65 G
-(ent to indicate that)214.56 162 Q F1(telnetd)2.5 E F0(is willing to recei)2.5
-E .3 -.15(ve a)-.25 H 2.5(n8b).15 G(it data stream.)423.918 162 Q(DO LFLO)102
-180 Q 55.97(WR)-.35 G(equests that the client handle \215o)215.67 180 Q 2.5(wc)
--.25 G(ontrol characters remotely)358.18 180 Q(.)-.65 E .967(DO ECHO)102 198 R
-.967(This is not really supported, b)209.967 198 R .967
-(ut is sent to identify a 4.2BSD)-.2 F/F3 10/Courier@0 SF(telnet)3.468 E F0
-.968(\(1\) client,)B .365(which will improperly respond with)209 210 R F3 .365
-(WILL ECHO.)2.865 F F0 .365(If a)2.865 F F3 .365(WILL ECHO)2.865 F F0 .365
-(is recei)2.865 F -.15(ve)-.25 G(d,).15 E(a)209 222 Q F3(DONT ECHO)2.5 E F0
-(will be sent in response.)2.5 E .445(DO TERMIN)102 240 R 7.92
-(AL-TYPE Indicates)-.35 F 2.945(ad)2.945 G .445
-(esire to be able to request the name of the type of terminal that is at-)
-260.875 240 R(tached to the client side of the connection.)209 252 Q(DO SGA)102
-270 Q(Indicates that it does not need to recei)209 270 Q -.15(ve)-.25 G F3
-(IAC GA,)2.65 E F0(the go ahead command.)2.5 E .006(DO N)102 288 R -.9(AW)-.35
-G 61.87(SR).9 G .006(equests that the client inform the serv)215.676 288 R .005
-(er when the windo)-.15 F 2.505(w\()-.25 G .005(display\) size changes.)452.51
-288 R(DO TERMIN)102 306 Q(AL-SPEED)-.35 E 1.029(Indicates a desire to be able \
-to request information about the speed of the serial)209 318 R
-(line to which the client is attached.)209 330 Q .469(DO XDISPLOC)102 348 R
-.469(Indicates a desire to be able to request the name of the X windo)209.469
-348 R .468(ws display that is)-.25 F(associated with the telnet client.)209 360
-Q 1.008(DO NEW)102 378 R(-ENVIR)-.65 E 17.52(ON Indicates)-.4 F 3.508(ad)3.508
-G 1.008(esire to be able to request en)262.564 378 R 1.009(vironment v)-.4 F
-1.009(ariable information, as de-)-.25 F(scribed in RFC 1572.)209 390 Q 1.009
-(DO ENVIR)102 408 R 42.97(ON Indicates)-.4 F 3.509(ad)3.509 G 1.009
-(esire to be able to request en)262.567 408 R 1.008(vironment v)-.4 F 1.008
-(ariable information, as de-)-.25 F(scribed in RFC 1408.)209 420 Q .886
-(DO LINEMODE)102 438 R .886(Only sent if)209.886 438 R F2(telnetd)3.386 E F0
-.886(is compiled with support for linemode, and requests that)3.386 F
-(the client do line by line processing.)209 450 Q 1.292(DO TIMING-MARK)102 468
-R 1.292(Only sent if)210.292 468 R F2(telnetd)3.792 E F0 1.291
-(is compiled with support for both linemode and kludge)3.792 F 2.029
-(linemode, and the client responded with)209 480 R F3 2.029(WONT LINEMODE.)
-4.529 F F0 2.029(If the client re-)4.529 F 3.375(sponds with)209 492 R F3 3.375
-(WILL TM,)5.875 F F0 3.375(the it is assumed that the client supports kludge)
-5.875 F 2.5(linemode. Note)209 504 R(that the)2.5 E([)3.333 E F2<ad6b>2.499 E
-F0 2.5(]o).833 G(ption can be used to disable this.)338.205 504 Q(DO A)102 522
-Q(UTHENTICA)-.55 E(TION)-1.11 E .618(Only sent if)209 534 R F2(telnetd)3.118 E
-F0 .618(is compiled with support for authentication, and indicates)3.118 F 2.5
-(aw)209 546 S(illingness to recei)223.16 546 Q .3 -.15(ve a)-.25 H
-(uthentication information for automatic login.).15 E .118(DO ENCR)102 564 R
-42.65(YPT Only)-.65 F .118(sent if)2.618 F F2(telnetd)2.618 E F0 .118
-(is compiled with support for data encryption, and indicates)2.618 F 2.5(aw)209
-576 S(illingness to decrypt the data stream.)223.16 576 Q/F4 10/Times-Bold@0 SF
-(ENVIR)72 600 Q(ONMENT)-.3 E(FILES)72 612 Q F3(/etc/services)102 624 Q
-(/etc/inittab)102 636 Q F0(\(UNICOS systems only\))2.5 E F3(/etc/iptos)102 648
-Q F0(\(if supported\))2.5 E F3(/usr/ucb/bftp)102 660 Q F0(\(if supported\))2.5
-E(4.2 Berk)72 750 Q(ele)-.1 E 2.5(yD)-.15 G(istrib)132.57 750 Q 95.71
-(ution February)-.2 F(3, 1994)2.5 E(4)535 750 Q EP
-%%Page: 5 5
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF -.834(TELNETD \( 8 \))72 48 R(BSD System Manager')
-241.42 48 Q 2.5(sM)-.55 G 105.272(anual TELNETD)348.92 48 R 1.666(\(8\))1.666 G
-/F1 10/Times-Bold@0 SF(SEE ALSO)72 96 Q/F2 10/Courier@0 SF(telnet)102 108 Q F0
-(\(1\),)A F2(login)5 E F0(\(1\),)A F2(bftp)5 E F0(\(1\) \(if supported\))A F1
-(ST)72 132 Q(AND)-.9 E(ARDS)-.35 E/F3 10/Courier-Bold@0 SF(RFC-854)102 144 Q/F4
-9/Times-Roman@0 SF(TELNET)155 144 Q F0(PR)2.5 E -1.88 -.4(OT O)-.4 H
-(COL SPECIFICA).4 E(TION)-1.11 E F3(RFC-855)102 156 Q F0
-(TELNET OPTION SPECIFICA)155 156 Q(TIONS)-1.11 E F3(RFC-856)102 168 Q F0
-(TELNET BIN)155 168 Q(AR)-.35 E 2.5(YT)-.65 G(RANSMISSION)241.21 168 Q F3
-(RFC-857)102 180 Q F0(TELNET ECHO OPTION)155 180 Q F3(RFC-858)102 192 Q F0
-(TELNET SUPPRESS GO AHEAD OPTION)155 192 Q F3(RFC-859)102 204 Q F0(TELNET ST)
-155 204 Q -1.11(AT)-.93 G(US OPTION)1.11 E F3(RFC-860)102 216 Q F0
-(TELNET TIMING MARK OPTION)155 216 Q F3(RFC-861)102 228 Q F0
-(TELNET EXTENDED OPTIONS - LIST OPTION)155 228 Q F3(RFC-885)102 240 Q F0
-(TELNET END OF RECORD OPTION)155 240 Q F3(RFC-1073)102 252 Q F0 -.7(Te)5 G
-(lnet W).7 E(indo)-.4 E 2.5(wS)-.25 G(ize Option)224.2 252 Q F3(RFC-1079)102
-264 Q F0 -.7(Te)5 G(lnet T).7 E(erminal Speed Option)-.7 E F3(RFC-1091)102 276
-Q F0 -.7(Te)5 G(lnet T).7 E(erminal-T)-.7 E(ype Option)-.8 E F3(RFC-1096)102
-288 Q F0 -.7(Te)5 G(lnet X Display Location Option).7 E F3(RFC-1123)102 300 Q
-F0(Requirements for Internet Hosts -- Application and Support)5 E F3(RFC-1184)
-102 312 Q F0 -.7(Te)5 G(lnet Linemode Option).7 E F3(RFC-1372)102 324 Q F0 -.7
-(Te)5 G(lnet Remote Flo).7 E 2.5(wC)-.25 G(ontrol Option)245.44 324 Q F3
-(RFC-1416)102 336 Q F0 -.7(Te)5 G(lnet Authentication Option).7 E F3(RFC-1411)
-102 348 Q F0 -.7(Te)5 G(lnet Authentication: K).7 E(erberos V)-.25 E(ersion 4)
--1.11 E F3(RFC-1412)102 360 Q F0 -.7(Te)5 G(lnet Authentication: SPX).7 E F3
-(RFC-1571)102 372 Q F0 -.7(Te)5 G(lnet En).7 E
-(vironment Option Interoperability Issues)-.4 E F3(RFC-1572)102 384 Q F0 -.7
-(Te)5 G(lnet En).7 E(vironment Option)-.4 E F1 -.1(BU)72 408 S(GS).1 E F0(Some)
-102 420 Q F4(TELNET)2.5 E F0(commands are only partially implemented.)2.5 E
-.082(Because of b)102 438 R .082(ugs in the original 4.2 BSD)-.2 F F2(telnet)
-2.582 E F0(\(1\),)A F3(telnetd)5.164 E F0 .082
-(performs some dubious protocol e)2.582 F(xchanges)-.15 E(to try to disco)102
-450 Q -.15(ve)-.15 G 2.5(ri).15 G 2.5(ft)175.03 450 S
-(he remote client is, in f)183.64 450 Q(act, a 4.2 BSD)-.1 E F2(telnet)2.5 E F0
-(\(1\).)A(Binary mode has no common interpretation e)102 468 Q
-(xcept between similar operating systems \(Unix in this case\).)-.15 E
-(The terminal type name recei)102 486 Q -.15(ve)-.25 G 2.5(df).15 G
-(rom the remote client is con)239.06 486 Q -.15(ve)-.4 G(rted to lo).15 E
-(wer case.)-.25 E F3(Telnetd)102 504 Q F0(ne)2.5 E -.15(ve)-.25 G 2.5(rs).15 G
-(ends)174.7 504 Q F4(TELNET)2.5 E F2(IAC GA)2.5 E F0(\(go ahead\) commands.)2.5
-E(4.2 Berk)72 750 Q(ele)-.1 E 2.5(yD)-.15 G(istrib)132.57 750 Q 95.71
-(ution February)-.2 F(3, 1994)2.5 E(5)535 750 Q EP
-%%Trailer
-end
-%%EOF
+++ /dev/null
-TELNETD(8) BSD System Manager's Manual TELNETD(8)
-
-N\bNA\bAM\bME\bE
- t\bte\bel\bln\bne\bet\btd\bd - DARPA TELNET protocol server
-
-S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS
- /\b/u\bus\bsr\br/\b/l\bli\bib\bbe\bex\bxe\bec\bc/\b/t\bte\bel\bln\bne\bet\btd\bd [-\b-a\ba _\ba_\bu_\bt_\bh_\bm_\bo_\bd_\be] [-\b-B\bB] [-\b-D\bD _\bd_\be_\bb_\bu_\bg_\bm_\bo_\bd_\be] [-\b-e\bed\bde\beb\bbu\bug\bg] [-\b-h\bh]
- [-\b-I\bI_\bi_\bn_\bi_\bt_\bi_\bd] [-\b-l\bl] [-\b-k\bk] [-\b-n\bn] [-\b-r\br_\bl_\bo_\bw_\bp_\bt_\by_\b-_\bh_\bi_\bg_\bh_\bp_\bt_\by] [-\b-s\bs]
- [-\b-S\bS _\bt_\bo_\bs] [-\b-u\bu _\bl_\be_\bn] [-\b-U\bU] [-\b-X\bX _\ba_\bu_\bt_\bh_\bt_\by_\bp_\be] [-\b-d\bde\beb\bbu\bug\bg [_\bp_\bo_\br_\bt]]
-
-D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
- The t\bte\bel\bln\bne\bet\btd\bd command is a server which supports the DARPA standard TELNET
- virtual terminal protocol. T\bTe\bel\bln\bne\bet\btd\bd is normally invoked by the internet
- server (see inetd(8)) for requests to connect to the TELNET port as in-
- dicated by the _\b/_\be_\bt_\bc_\b/_\bs_\be_\br_\bv_\bi_\bc_\be_\bs file (see services(5)). The -\b-d\bde\beb\bbu\bug\bg option
- may be used to start up t\bte\bel\bln\bne\bet\btd\bd manually, instead of through inetd(8).
- If started up this way, _\bp_\bo_\br_\bt may be specified to run t\bte\bel\bln\bne\bet\btd\bd on an alter-
- nate TCP port number.
-
- The t\bte\bel\bln\bne\bet\btd\bd command accepts the following options:
-
- -\b-a\ba _\ba_\bu_\bt_\bh_\bm_\bo_\bd_\be This option may be used for specifying what mode should be
- used for authentication. Note that this option is only use-
- ful if t\bte\bel\bln\bne\bet\btd\bd has been compiled with support for the
- AUTHENTICATION option. There are several valid values for
- _\ba_\bu_\bt_\bh_\bm_\bo_\bd_\be_\b:
-
- debug Turns on authentication debugging code.
-
- user Only allow connections when the remote user can pro-
- vide valid authentication information to identify the
- remote user, and is allowed access to the specified
- account without providing a password.
-
- valid Only allow connections when the remote user can pro-
- vide valid authentication information to identify the
- remote user. The login(1) command will provide any
- additional user verification needed if the remote us-
- er is not allowed automatic access to the specified
- account.
-
- other Only allow connections that supply some authentica-
- tion information. This option is currently not sup-
- ported by any of the existing authentication mecha-
- nisms, and is thus the same as specifying -\b-a\ba v\bva\bal\bli\bid\bd.
-
- none This is the default state. Authentication informa-
- tion is not required. If no or insufficient authen-
- tication information is provided, then the login(1)
- program will provide the necessary user verification.
-
- off This disables the authentication code. All user ver-
- ification will happen through the login(1) program.
-
- -\b-B\bB Specifies bftp server mode. In this mode, t\bte\bel\bln\bne\bet\btd\bd causes
- login to start a bftp(1) session rather than the user's nor-
- mal shell. In bftp daemon mode normal logins are not sup-
- ported, and it must be used on a port other than the normal
- TELNET port.
-
- -\b-D\bD _\bd_\be_\bb_\bu_\bg_\bm_\bo_\bd_\be
- This option may be used for debugging purposes. This allows
- t\bte\bel\bln\bne\bet\btd\bd to print out debugging information to the connec-
- tion, allowing the user to see what t\bte\bel\bln\bne\bet\btd\bd is doing. There
-
- are several possible values for _\bd_\be_\bb_\bu_\bg_\bm_\bo_\bd_\be_\b:
-
- o\bop\bpt\bti\bio\bon\bns\bs Prints information about the negotiation of TELNET
- options.
-
- r\bre\bep\bpo\bor\brt\bt Prints the o\bop\bpt\bti\bio\bon\bns\bs information, plus some addi-
- tional information about what processing is going
- on.
-
- n\bne\bet\btd\bda\bat\bta\ba Displays the data stream received by t\bte\bel\bln\bne\bet\btd\bd.\b.
-
- p\bpt\bty\byd\bda\bat\bta\ba Displays data written to the pty.
-
- e\bex\bxe\ber\brc\bci\bis\bse\be Has not been implemented yet.
-
- -\b-d\bde\beb\bbu\bug\bg Enables debugging on each socket created by t\bte\bel\bln\bne\bet\btd\bd (see
- SO_DEBUG in socket(2)).
-
- -\b-e\bed\bde\beb\bbu\bug\bg If t\bte\bel\bln\bne\bet\btd\bd has been compiled with support for data encryp-
- tion, then the -\b-e\bed\bde\beb\bbu\bug\bg option may be used to enable encryp-
- tion debugging code.
-
- -\b-h\bh Disables the printing of host-specific information before
- login has been completed.
-
- -\b-I\bI _\bi_\bn_\bi_\bt_\bi_\bd This option is only applicable to UNICOS systems prior to
- 7.0. It specifies the ID from _\b/_\be_\bt_\bc_\b/_\bi_\bn_\bi_\bt_\bt_\ba_\bb to use when init
- starts login sessions. The default ID is fe.
-
- -\b-k\bk This option is only useful if t\bte\bel\bln\bne\bet\btd\bd has been compiled with
- both linemode and kludge linemode support. If the -\b-k\bk option
- is specified, then if the remote client does not support the
- LINEMODE option, then t\bte\bel\bln\bne\bet\btd\bd will operate in character at a
- time mode. It will still support kludge linemode, but will
- only go into kludge linemode if the remote client requests
- it. (This is done by by the client sending DONT SUPPRESS-
- GO-AHEAD and DONT ECHO.) The -\b-k\bk option is most useful when
- there are remote clients that do not support kludge
- linemode, but pass the heuristic (if they respond with WILL
- TIMING-MARK in response to a DO TIMING-MARK) for kludge
- linemode support.
-
- -\b-l\bl Specifies line mode. Tries to force clients to use line-
- at-a-time mode. If the LINEMODE option is not supported, it
- will go into kludge linemode.
-
- -\b-n\bn Disable TCP keep-alives. Normally t\bte\bel\bln\bne\bet\btd\bd enables the TCP
- keep-alive mechanism to probe connections that have been
- idle for some period of time to determine if the client is
- still there, so that idle connections from machines that
- have crashed or can no longer be reached may be cleaned up.
-
- -\b-r\br _\bl_\bo_\bw_\bp_\bt_\by_\b-_\bh_\bi_\bg_\bh_\bp_\bt_\by
- This option is only enabled when t\bte\bel\bln\bne\bet\btd\bd is compiled for
- UNICOS. It specifies an inclusive range of pseudo-terminal
- devices to use. If the system has sysconf variable
- _SC_CRAY_NPTY configured, the default pty search range is 0
- to _SC_CRAY_NPTY; otherwise, the default range is 0 to 128.
- Either _\bl_\bo_\bw_\bp_\bt_\by or _\bh_\bi_\bg_\bh_\bp_\bt_\by may be omitted to allow changing
- either end of the search range. If _\bl_\bo_\bw_\bp_\bt_\by is omitted, the -
- character is still required so that t\bte\bel\bln\bne\bet\btd\bd can differenti-
- ate _\bh_\bi_\bg_\bh_\bp_\bt_\by from _\bl_\bo_\bw_\bp_\bt_\by.
-
- -\b-s\bs This option is only enabled if t\bte\bel\bln\bne\bet\btd\bd is compiled with sup-
- port for SecurID cards. It causes the -\b-s\bs option to be
- passed on to login(1), and thus is only useful if login(1)
- supports the -\b-s\bs flag to indicate that only SecurID validated
- logins are allowed, and is usually useful for controlling
- remote logins from outside of a firewall.
-
- -\b-S\bS _\bt_\bo_\bs
-
- -\b-u\bu _\bl_\be_\bn This option is used to specify the size of the field in the
- utmp structure that holds the remote host name. If the re-
- solved host name is longer than _\bl_\be_\bn, the dotted decimal val-
- ue will be used instead. This allows hosts with very long
- host names that overflow this field to still be uniquely
- identified. Specifying -\b-u\bu0\b0 indicates that only dotted deci-
- mal addresses should be put into the _\bu_\bt_\bm_\bp file.
-
- -\b-U\bU This option causes t\bte\bel\bln\bne\bet\btd\bd to refuse connections from ad-
- dresses that cannot be mapped back into a symbolic name via
- the gethostbyaddr(3) routine.
-
- -\b-X\bX _\ba_\bu_\bt_\bh_\bt_\by_\bp_\be This option is only valid if t\bte\bel\bln\bne\bet\btd\bd has been built with
- support for the authentication option. It disables the use
- of _\ba_\bu_\bt_\bh_\bt_\by_\bp_\be authentication, and can be used to temporarily
- disable a specific authentication type without having to re-
- compile t\bte\bel\bln\bne\bet\btd\bd.
-
- T\bTe\bel\bln\bne\bet\btd\bd operates by allocating a pseudo-terminal device (see pty(4)) for
- a client, then creating a login process which has the slave side of the
- pseudo-terminal as stdin, stdout and stderr. T\bTe\bel\bln\bne\bet\btd\bd manipulates the mas-
- ter side of the pseudo-terminal, implementing the TELNET protocol and
- passing characters between the remote client and the login process.
-
- When a TELNET session is started up, t\bte\bel\bln\bne\bet\btd\bd sends TELNET options to the
- client side indicating a willingness to do the following TELNET options,
- which are described in more detail below:
-
- DO AUTHENTICATION
- WILL ENCRYPT
- DO TERMINAL TYPE
- DO TSPEED
- DO XDISPLOC
- DO NEW-ENVIRON
- DO ENVIRON
- WILL SUPPRESS GO AHEAD
- DO ECHO
- DO LINEMODE
- DO NAWS
- WILL STATUS
- DO LFLOW
- DO TIMING-MARK
-
- The pseudo-terminal allocated to the client is configured to operate in
- cooked mode, and with XTABS and CRMOD enabled (see tty(4)).
-
- T\bTe\bel\bln\bne\bet\btd\bd has support for enabling locally the following TELNET options:
-
- WILL ECHO When the LINEMODE option is enabled, a WILL ECHO or
- WONT ECHO will be sent to the client to indicate the
- current state of terminal echoing. When terminal echo
- is not desired, a WILL ECHO is sent to indicate that
- telnetd will take care of echoing any data that needs
- to be echoed to the terminal, and then nothing is
- echoed. When terminal echo is desired, a WONT ECHO is
- sent to indicate that telnetd will not be doing any
- terminal echoing, so the client should do any terminal
- echoing that is needed.
-
- WILL BINARY Indicates that the client is willing to send a 8 bits
- of data, rather than the normal 7 bits of the Network
- Virtual Terminal.
-
- WILL SGA Indicates that it will not be sending IAC GA, go
- ahead, commands.
-
- WILL STATUS Indicates a willingness to send the client, upon re-
- quest, of the current status of all TELNET options.
-
- WILL TIMING-MARK Whenever a DO TIMING-MARK command is received, it is
- always responded to with a WILL TIMING-MARK
-
- WILL LOGOUT When a DO LOGOUT is received, a WILL LOGOUT is sent in
- response, and the TELNET session is shut down.
-
- WILL ENCRYPT Only sent if t\bte\bel\bln\bne\bet\btd\bd is compiled with support for data
- encryption, and indicates a willingness to decrypt the
- data stream.
-
- T\bTe\bel\bln\bne\bet\btd\bd has support for enabling remotely the following TELNET options:
-
- DO BINARY Sent to indicate that telnetd is willing to receive an
- 8 bit data stream.
-
- DO LFLOW Requests that the client handle flow control charac-
- ters remotely.
-
- DO ECHO This is not really supported, but is sent to identify
- a 4.2BSD telnet(1) client, which will improperly re-
- spond with WILL ECHO. If a WILL ECHO is received, a
- DONT ECHO will be sent in response.
-
- DO TERMINAL-TYPE Indicates a desire to be able to request the name of
- the type of terminal that is attached to the client
- side of the connection.
-
- DO SGA Indicates that it does not need to receive IAC GA, the
- go ahead command.
-
- DO NAWS Requests that the client inform the server when the
- window (display) size changes.
-
- DO TERMINAL-SPEED Indicates a desire to be able to request information
- about the speed of the serial line to which the client
- is attached.
-
- DO XDISPLOC Indicates a desire to be able to request the name of
- the X windows display that is associated with the tel-
- net client.
-
- DO NEW-ENVIRON Indicates a desire to be able to request environment
- variable information, as described in RFC 1572.
-
- DO ENVIRON Indicates a desire to be able to request environment
- variable information, as described in RFC 1408.
-
- DO LINEMODE Only sent if t\bte\bel\bln\bne\bet\btd\bd is compiled with support for
- linemode, and requests that the client do line by line
- processing.
-
- DO TIMING-MARK Only sent if t\bte\bel\bln\bne\bet\btd\bd is compiled with support for both
- linemode and kludge linemode, and the client responded
- with WONT LINEMODE. If the client responds with WILL
- TM, the it is assumed that the client supports kludge
- linemode. Note that the [-\b-k\bk] option can be used to
-
- disable this.
-
- DO AUTHENTICATION Only sent if t\bte\bel\bln\bne\bet\btd\bd is compiled with support for au-
- thentication, and indicates a willingness to receive
- authentication information for automatic login.
-
- DO ENCRYPT Only sent if t\bte\bel\bln\bne\bet\btd\bd is compiled with support for data
- encryption, and indicates a willingness to decrypt the
- data stream.
-
-E\bEN\bNV\bVI\bIR\bRO\bON\bNM\bME\bEN\bNT\bT
-F\bFI\bIL\bLE\bES\bS
- _\b/_\be_\bt_\bc_\b/_\bs_\be_\br_\bv_\bi_\bc_\be_\bs
- _\b/_\be_\bt_\bc_\b/_\bi_\bn_\bi_\bt_\bt_\ba_\bb (UNICOS systems only)
- _\b/_\be_\bt_\bc_\b/_\bi_\bp_\bt_\bo_\bs (if supported)
- _\b/_\bu_\bs_\br_\b/_\bu_\bc_\bb_\b/_\bb_\bf_\bt_\bp (if supported)
-
-S\bSE\bEE\bE A\bAL\bLS\bSO\bO
- telnet(1), login(1), bftp(1) (if supported)
-
-S\bST\bTA\bAN\bND\bDA\bAR\bRD\bDS\bS
- R\bRF\bFC\bC-\b-8\b85\b54\b4 TELNET PROTOCOL SPECIFICATION
- R\bRF\bFC\bC-\b-8\b85\b55\b5 TELNET OPTION SPECIFICATIONS
- R\bRF\bFC\bC-\b-8\b85\b56\b6 TELNET BINARY TRANSMISSION
- R\bRF\bFC\bC-\b-8\b85\b57\b7 TELNET ECHO OPTION
- R\bRF\bFC\bC-\b-8\b85\b58\b8 TELNET SUPPRESS GO AHEAD OPTION
- R\bRF\bFC\bC-\b-8\b85\b59\b9 TELNET STATUS OPTION
- R\bRF\bFC\bC-\b-8\b86\b60\b0 TELNET TIMING MARK OPTION
- R\bRF\bFC\bC-\b-8\b86\b61\b1 TELNET EXTENDED OPTIONS - LIST OPTION
- R\bRF\bFC\bC-\b-8\b88\b85\b5 TELNET END OF RECORD OPTION
- R\bRF\bFC\bC-\b-1\b10\b07\b73\b3 Telnet Window Size Option
- R\bRF\bFC\bC-\b-1\b10\b07\b79\b9 Telnet Terminal Speed Option
- R\bRF\bFC\bC-\b-1\b10\b09\b91\b1 Telnet Terminal-Type Option
- R\bRF\bFC\bC-\b-1\b10\b09\b96\b6 Telnet X Display Location Option
- R\bRF\bFC\bC-\b-1\b11\b12\b23\b3 Requirements for Internet Hosts -- Application and Support
- R\bRF\bFC\bC-\b-1\b11\b18\b84\b4 Telnet Linemode Option
- R\bRF\bFC\bC-\b-1\b13\b37\b72\b2 Telnet Remote Flow Control Option
- R\bRF\bFC\bC-\b-1\b14\b41\b16\b6 Telnet Authentication Option
- R\bRF\bFC\bC-\b-1\b14\b41\b11\b1 Telnet Authentication: Kerberos Version 4
- R\bRF\bFC\bC-\b-1\b14\b41\b12\b2 Telnet Authentication: SPX
- R\bRF\bFC\bC-\b-1\b15\b57\b71\b1 Telnet Environment Option Interoperability Issues
- R\bRF\bFC\bC-\b-1\b15\b57\b72\b2 Telnet Environment Option
-
-B\bBU\bUG\bGS\bS
- Some TELNET commands are only partially implemented.
-
- Because of bugs in the original 4.2 BSD telnet(1), t\bte\bel\bln\bne\bet\btd\bd performs some
- dubious protocol exchanges to try to discover if the remote client is, in
- fact, a 4.2 BSD telnet(1).
-
- Binary mode has no common interpretation except between similar operating
- systems (Unix in this case).
-
- The terminal type name received from the remote client is converted to
- lower case.
-
- T\bTe\bel\bln\bne\bet\btd\bd never sends TELNET IAC GA (go ahead) commands.
-
-4.2 Berkeley Distribution February 3, 1994 5
+++ /dev/null
-.\" Copyright (c) 1983, 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.
-.\"
-.\" @(#)telnetd.8 8.2 (Berkeley) 2/3/94
-.\" "
-.TH TELNETD 8
-.SH NAME
-telnetd \-
-.SM DARPA TELNET
-protocol server
-.SH SYNOPSIS
-.B /usr/libexec/telnetd
-[\fB\-a\fP \fIauthmode\fP] [\fB\-B\fP] [\fB\-D\fP] [\fIdebugmode\fP]
-[\fB\-e\fP] [\fB\-h\fP] [\fB\-I\fP\fIinitid\fP] [\fB\-l\fP]
-[\fB\-k\fP] [\fB\-n\fP] [\fB\-r\fP\fIlowpty-highpty\fP] [\fB\-s\fP]
-[\fB\-S\fP \fItos\fP] [\fB\-U\fP] [\fB\-X\fP \fIauthtype\fP]
-[\fB\-w\fP [\fBip\fP|\fImaxhostlen\fP[\fB,\fP[\fBno\fP]\fBstriplocal\fP]]]
-[\fB\-debug\fP [\fIport\fP]]
-.SH DESCRIPTION
-The
-.B telnetd
-command is a server which supports the
-.SM DARPA
-standard
-.SM TELNET
-virtual terminal protocol.
-.B Telnetd
-is normally invoked by the internet server (see
-.BR inetd (8)
-for requests to connect to the
-.SM TELNET
-port as indicated by the
-.I /etc/services
-file (see
-.BR services (5)).
-The
-.B \-debug
-option may be used to start up
-.B telnetd
-manually, instead of through
-.IR inetd (8).
-If started up this way,
-.I port
-may be specified to run
-.B telnetd
-on an alternate
-.SM TCP
-port number.
-.PP
-The
-.B telnetd
-command accepts the following options:
-.TP
-\fB\-a\fP \fIauthmode\fP
-This option may be used for specifying what mode should be used for
-authentication. Note that this option is only useful if
-.B telnetd
-has been compiled with support for the
-.SM AUTHENTICATION
-option. There are several valid values for
-.IR authmode :
-.RS
-.TP
-.B debug
-Turns on authentication debugging code.
-.TP
-.B valid
-Only allow connections when the remote user can provide valid
-authentication information to identify the remote user, and is allowed
-access to the specified account without providing a password.
-.TP
-.B user
-Only allow connections when the remote user can provide valid
-authentication information to identify the remote user. The
-.IR login (1)
-command will provide any additional user verification needed if the
-remote user is not allowed automatic access to the specified account.
-.TP
-.B other
-Only allow connections that supply some authentication information.
-This option is currently not supported by any of the existing
-authentication mechanisms, and is thus the same as specifying
-.B \-a
-.BR valid .
-.TP
-.B none
-This is the default state. Authentication information is not required.
-If no or insufficient authentication information is provided, then the
-.IR login (1)
-program will provide the necessary user verification.
-.TP
-.B off
-This disables the authentication code. All user verification will
-happen through the
-.IR login (1)
-program.
-.RE
-.TP
-.B \-B
-Specifies bftp server mode. In this mode,
-.B telnetd
-causes login to start a
-.IR bftp (1)
-session rather than the user's normal shell. In bftp daemon mode,
-normal logins are not supported, and it must be used on a port other
-than the normal
-.SM TELNET
-port.
-.TP
-\fB\-D\fP \fIdebugmode\fP
-This option may be used for debugging purposes. This allows
-.B telnetd
-to print out debugging information to the connection, allowing the user
-to see what
-.B telnetd
-is doing. There are several possible values for
-.IR debugmode :
-.RS
-.TP
-.B options
-Prints information about the negotiation of
-.SM TELNET
-options.
-.TP
-.B report
-Prints the
-.B options
-information, plus some additional information about what processing is
-going on.
-.TP
-.B netdata
-Displays the data stream received by
-.B telnetd.
-.TP
-.B ptydata
-Displays data written to the pty.
-.TP
-.B encrypt
-Enables encryption debugging code.
-.TP
-.B exercise
-Has not been implemented yet.
-.RE
-.TP
-.B \-debug
-Enables debugging on each socket created by
-.B telnetd
-(see
-.SM SO_DEBUG
-in
-.IR socket (2)).
-.TP
-.B \-e
-This option causes
-.B telnetd
-to refuse unencrypted connections.
-.TP
-.B \-h
-Disables the printing of host-specific information before login has been
-completed.
-.TP
-\fB\-I\fP \fIinitid\fP
-This option is only applicable to
-.SM UNICOS
-systems prior to 7.0. It specifies the
-.SM ID
-from
-.I /etc/inittab
-to use when init starts login sessions. The default
-.SM ID
-is fe.
-.TP
-.B \-k
-This option is only useful if
-.B telnetd
-has been compiled with both linemode and kludge linemode support. If
-the
-.B \-k
-option is specified, then if the remote client does not support the
-.SM LINEMODE
-option, then
-.B telnetd
-will operate in character at a time mode. It will still support kludge
-linemode, but will only go into kludge linemode if the remote client
-requests it. (This is done by by the client sending
-.SM DONT SUPPRESS-GO-AHEAD
-and
-.SM DONT ECHO.)
-The
-.B \-k
-option is most useful when there are remote clients that do not support
-kludge linemode, but pass the heuristic (if they respond with
-.SM WILL TIMING-MARK
-in response to a
-.SM DO TIMING-MARK)
-for kludge linemode support.
-.TP
-.B \-l
-Specifies line mode. Tries to force clients to use line-at-a-time
-mode. If the
-.SM LINEMODE
-option is not supported, it will go into kludge linemode.
-.TP
-.B \-n
-Disable
-.SM TCP
-keep-alives. Normally
-.B telnetd
-enables the
-.SM TCP
-keep-alive mechanism to probe connections that have been idle for some
-period of time to determine if the client is still there, so that idle
-connections from machines that have crashed or can no longer be reached
-may be cleaned up.
-.TP
-\fB\-r\fP \fIlowpty-highpty\fP
-This option is only enabled when
-.B telnetd
-is compiled for
-.SM UNICOS.
-It specifies an inclusive range of pseudo-terminal devices to use. If
-the system has sysconf variable
-.SM _SC_CRAY_NPTY
-configured, the default pty search range is 0 to
-.SM _SC_CRAY_NPTY;
-otherwise, the default range is 0 to 128. Either
-.I lowpty
-or
-.I highpty
-may be omitted to allow changing either end of the search range. If
-.I lowpty
-is omitted, the - character is still required so that
-.B telnetd
-can differentiate
-.I highpty
-from
-.IR lowpty .
-.TP
-.B \-s
-This option is only enabled if
-.B telnetd
-is compiled with support for SecurID cards. It causes the
-.B \-s
-option to be passed on to
-.IR login (1),
-and thus is only useful if
-.IR login (1)
-supports the
-.B \-s
-flag to indicate that only SecurID validated logins are allowed, and is
-usually useful for controlling remote logins from outside of a firewall.
-.TP
-\fB\-S\fP \fItos\fP
-.TP
-.B \-U
-This option causes
-.B telnetd
-to refuse connections from addresses that cannot be mapped back into a
-symbolic name via the
-.IR gethostbyaddr (3)
-routine.
-.TP
-.B \-w \fP[\fBip\fP|\fImaxhostlen\fP[\fB,\fP[\fBno\fP]\fBstriplocal\fP]]
-Controls the form of the remote hostname passed to login(1).
-Specifying \fBip\fP results in the numeric IP address always being
-passed to login(1). Specifying a number, \fImaxhostlen\fP, sets the
-maximum length of the hostname passed to login(1) before it will be
-passed as a numeric IP address. If \fImaxhostlen\fP is 0, then the
-system default, as determined by the utmp or utmpx structures, is
-used. The \fBnostriplocal\fP and \fBstriplocal\fP options, which must
-be preceded by a comma, control whether or not the local host domain
-is stripped from the remote hostname. By default, the equivalent of
-\fBstriplocal\fP is in effect.
-.TP
-\fB\-X\fP \fIauthtype\fP
-This option is only valid if
-.B telnetd
-has been built with support for the authentication option. It disables
-the use of
-.I authtype
-authentication, and can be used to temporarily disable a specific
-authentication type without having to recompile
-.BR telnetd .
-.PP
-.B Telnetd
-operates by allocating a pseudo-terminal device (see
-.IR pty (4))
-for a client, then creating a login process which has the slave side of
-the pseudo-terminal as
-.IR stdin ,
-.I stdout
-and
-.IR stderr .
-.B Telnetd
-manipulates the master side of the pseudo-terminal, implementing the
-.SM TELNET
-protocol and passing characters between the remote client and the login
-process.
-.PP
-When a
-.SM TELNET
-session is started up,
-.B telnetd
-sends
-.SM TELNET
-options to the client side indicating a willingness to do the following
-.SM TELNET
-options, which are described in more detail below:
-.sp
-.nf
-.in +0.5i
-DO AUTHENTICATION
-WILL ENCRYPT
-DO TERMINAL TYPE
-DO TSPEED
-DO XDISPLOC
-DO NEW-ENVIRON
-DO ENVIRON
-WILL SUPPRESS GO AHEAD
-DO ECHO
-DO LINEMODE
-DO NAWS
-WILL STATUS
-DO LFLOW
-DO TIMING-MARK
-.in
-.fi
-.PP
-The pseudo-terminal allocated to the client is configured
-to operate in \*(lqcooked\*(rq mode, and with
-.SM XTABS
-and
-.SM CRMOD
-enabled (see
-.IR tty (4)).
-.PP
-.B Telnetd
-has support for enabling locally the following
-.SM TELNET
-options:
-.TP "\w'.SM WILL TIMING-MARK\ 'u"
-.SM WILL ECHO
-When the
-.SM LINEMODE
-option is enabled, a
-.SM WILL ECHO
-or
-.SM WONT ECHO
-will be sent to the client to indicate the current state of terminal
-echoing. When terminal echo is not desired, a
-.SM WILL ECHO
-is sent to indicate that
-.B telnetd
-will take care of echoing any data that needs to be echoed to the
-terminal, and then nothing is echoed. When terminal echo is desired, a
-.SM WONT ECHO
-is sent to indicate that
-.B telnetd
-will not be doing any terminal echoing, so the
-client should do any terminal echoing that is needed.
-.TP
-.SM WILL BINARY
-Indicates that the client is willing to send a 8 bits of data, rather
-than the normal 7 bits of the Network Virtual Terminal.
-.TP
-.SM WILL SGA
-Indicates that it will not be sending
-.SM IAC GA,
-go ahead, commands.
-.TP
-.SM WILL STATUS
-Indicates a willingness to send the client, upon request, of the current
-status of all
-.SM TELNET
-options.
-.TP
-.SM WILL TIMING-MARK
-Whenever a
-.SM DO TIMING-MARK
-command is received, it is always responded to with a
-.SM WILL TIMING-MARK
-.TP
-.SM WILL LOGOUT
-When a
-.SM DO LOGOUT
-is received, a
-.SM WILL LOGOUT
-is sent in response, and the
-.SM TELNET
-session is shut down.
-.TP
-.SM WILL ENCRYPT
-Only sent if
-.B telnetd
-is compiled with support for data encryption, and indicates a
-willingness to decrypt the data stream.
-.PP
-.B Telnetd
-has support for enabling remotely the following
-.SM TELNET
-options:
-.TP "\w'.SM DO TERMINAL-SPEED\ 'u"
-.SM DO BINARY
-Sent to indicate that
-.B telnetd
-is willing to receive an 8 bit data stream.
-.TP
-.SM DO LFLOW
-Requests that the client handle flow control characters remotely.
-.TP
-.SM DO ECHO
-This is not really supported, but is sent to identify a 4.2BSD
-.IR telnet (1)
-client, which will improperly respond with
-.SM WILL ECHO.
-If a
-.SM WILL ECHO
-is received, a
-.SM DONT ECHO
-will be sent in response.
-.TP
-.SM DO TERMINAL-TYPE
-Indicates a desire to be able to request the name of the type of
-terminal that is attached to the client side of the connection.
-.TP
-.SM DO SGA
-Indicates that it does not need to receive
-.SM IAC GA,
-the go ahead command.
-.TP
-.SM DO NAWS
-Requests that the client inform the server when the window (display)
-size changes.
-.TP
-.SM DO TERMINAL-SPEED
-Indicates a desire to be able to request information about the speed of
-the serial line to which the client is attached.
-.TP
-.SM DO XDISPLOC
-Indicates a desire to be able to request the name of the X windows
-display that is associated with the telnet client.
-.TP
-.SM DO NEW-ENVIRON
-Indicates a desire to be able to request environment variable
-information, as described in RFC 1572.
-.TP
-.SM DO ENVIRON
-Indicates a desire to be able to request environment variable
-information, as described in RFC 1408.
-.TP
-.SM DO LINEMODE
-Only sent if
-.B telnetd
-is compiled with support for linemode, and requests that the client do
-line by line processing.
-.TP
-.SM DO TIMING-MARK
-Only sent if
-.B telnetd
-is compiled with support for both linemode and kludge linemode, and the
-client responded with
-.SM WONT LINEMODE.
-If the client responds with
-.SM WILL TM,
-the it is assumed that the client supports kludge linemode. Note that
-the
-.B \-k
-option can be used to disable this.
-.TP
-.SM DO AUTHENTICATION
-Only sent if
-.B telnetd
-is compiled with support for authentication, and indicates a willingness
-to receive authentication information for automatic login.
-.TP
-.SM DO ENCRYPT
-Only sent if
-.B telnetd
-is compiled with support for data encryption, and indicates a
-willingness to decrypt the data stream.
-.SH FILES
-.I /etc/services
-.br
-.I /etc/inittab
-(UNICOS systems only)
-.br
-.I /etc/iptos
-(if supported)
-.br
-.I /usr/ucb/bftp
-(if supported)
-.SH "SEE ALSO"
-.IR telnet (1),
-.IR login (1),
-.IR bftp (1)
-(if supported)
-.SH STANDARDS
-.TP "\w'.B RFC-2000\ 'u"
-.B RFC-854
-TELNET PROTOCOL SPECIFICATION
-.sp -1
-.TP
-.B RFC-855
-TELNET OPTION SPECIFICATIONS
-.sp -1
-.TP
-.B RFC-856
-TELNET BINARY TRANSMISSION
-.sp -1
-.TP
-.B RFC-857
-TELNET ECHO OPTION
-.sp -1
-.TP
-.B RFC-858
-TELNET SUPPRESS GO AHEAD OPTION
-.sp -1
-.TP
-.B RFC-859
-TELNET STATUS OPTION
-.sp -1
-.TP
-.B RFC-860
-TELNET TIMING MARK OPTION
-.sp -1
-.TP
-.B RFC-861
-TELNET EXTENDED OPTIONS - LIST OPTION
-.sp -1
-.TP
-.B RFC-885
-TELNET END OF RECORD OPTION
-.sp -1
-.TP
-.B RFC-1073
-Telnet Window Size Option
-.sp -1
-.TP
-.B RFC-1079
-Telnet Terminal Speed Option
-.sp -1
-.TP
-.B RFC-1091
-Telnet Terminal-Type Option
-.sp -1
-.TP
-.B RFC-1096
-Telnet X Display Location Option
-.sp -1
-.TP
-.B RFC-1123
-Requirements for Internet Hosts -- Application and Support
-.sp -1
-.TP
-.B RFC-1184
-Telnet Linemode Option
-.sp -1
-.TP
-.B RFC-1372
-Telnet Remote Flow Control Option
-.sp -1
-.TP
-.B RFC-1416
-Telnet Authentication Option
-.sp -1
-.TP
-.B RFC-1411
-Telnet Authentication: Kerberos Version 4
-.sp -1
-.TP
-.B RFC-1412
-Telnet Authentication: SPX
-.sp -1
-.TP
-.B RFC-1571
-Telnet Environment Option Interoperability Issues
-.sp -1
-.TP
-.B RFC-1572
-Telnet Environment Option
-.SH BUGS
-Some
-.SM TELNET
-commands are only partially implemented.
-.PP
-Because of bugs in the original 4.2 BSD
-.IR telnet (1),
-.B telnetd
-performs some dubious protocol exchanges to try to discover if the
-remote client is, in fact, a 4.2 BSD
-.IR telnet (1).
-.PP
-Binary mode has no common interpretation except between similar
-operating systems (Unix in this case).
-.PP
-The terminal type name received from the remote client is converted to
-lower case.
-.PP
-.B Telnetd
-never sends
-.SM TELNET
-.SM IAC GA
-(go ahead) commands.
+++ /dev/null
-/*
- * Copyright (c) 1989, 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 lint
-static char copyright[] =
-"@(#) Copyright (c) 1989, 1993\n\
- The Regents of the University of California. All rights reserved.\n";
-#endif /* not lint */
-
-/* based on @(#)telnetd.c 8.1 (Berkeley) 6/4/93 */
-
-#include "telnetd.h"
-#include "pathnames.h"
-
-extern int getent(char *, char *);
-extern int tgetent(char *, char *);
-
-#if defined(_SC_CRAY_SECURE_SYS) && !defined(SCM_SECURITY)
-/*
- * UNICOS 6.0/6.1 do not have SCM_SECURITY defined, so we can
- * use it to tell us to turn off all the socket security code,
- * since that is only used in UNICOS 7.0 and later.
- */
-# undef _SC_CRAY_SECURE_SYS
-#endif
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <libpty.h>
-#include <com_err.h>
-#if defined(_SC_CRAY_SECURE_SYS)
-#include <sys/sysv.h>
-#include <sys/secdev.h>
-# ifdef SO_SEC_MULTI /* 8.0 code */
-#include <sys/secparm.h>
-#include <sys/usrv.h>
-# endif /* SO_SEC_MULTI */
-int secflag;
-char tty_dev[16];
-struct secdev dv;
-struct sysv sysv;
-# ifdef SO_SEC_MULTI /* 8.0 code */
-struct socksec ss;
-# else /* SO_SEC_MULTI */ /* 7.0 code */
-struct socket_security ss;
-# endif /* SO_SEC_MULTI */
-#endif /* _SC_CRAY_SECURE_SYS */
-
-#include "fake-addrinfo.h"
-
-#ifdef KRB5
-#include "krb5.h"
-#endif
-
-#if defined(AUTHENTICATION)
-#include <libtelnet/auth.h>
-#include <libtelnet/auth-proto.h>
-#endif
-#ifdef ENCRYPTION
-#include <libtelnet/encrypt.h>
-#include <libtelnet/enc-proto.h>
-#endif
-#if defined(AUTHENTICATION) || defined(ENCRYPTION)
-#include <libtelnet/misc-proto.h>
-#endif
-
-int registerd_host_only = 0;
-
-#ifdef STREAMSPTY
-#include <sys/stream.h>
-# include <stropts.h>
-# include <termio.h>
-/* make sure we don't get the bsd version */
-#ifdef HAVE_SYS_TTY_H
-# include "/usr/include/sys/tty.h"
-#endif
-#ifdef HAVE_SYS_PTYVAR_H
-# include <sys/ptyvar.h>
-#endif
-
-/*
- * Because of the way ptyibuf is used with streams messages, we need
- * ptyibuf+1 to be on a full-word boundary. The following wierdness
- * is simply to make that happen.
- */
-long ptyibufbuf[BUFSIZ/sizeof(long)+1];
-char *ptyibuf = ((char *)&ptyibufbuf[1])-1;
-char *ptyip = ((char *)&ptyibufbuf[1])-1;
-char ptyibuf2[BUFSIZ];
-unsigned char ctlbuf[BUFSIZ];
-struct strbuf strbufc, strbufd;
-
-int readstream();
-
-#else /* ! STREAMPTY */
-
-/*
- * I/O data buffers,
- * pointers, and counters.
- */
-char ptyibuf[BUFSIZ], *ptyip = ptyibuf;
-char ptyibuf2[BUFSIZ];
-
-#endif /* ! STREAMPTY */
-
-static void doit (struct sockaddr *);
-int terminaltypeok (char *);
-static void _gettermname(void);
-
-int hostinfo = 1; /* do we print login banner? */
-
-#ifdef CRAY
-extern int newmap; /* nonzero if \n maps to ^M^J */
-int lowpty = 0, highpty; /* low, high pty numbers */
-#endif /* CRAY */
-
-int debug = 0;
-int keepalive = 1;
-char *progname;
-
-int maxhostlen = 0;
-int always_ip = 0;
-int stripdomain = 1;
-
-extern void usage (void);
-
-/*
- * The string to pass to getopt(). We do it this way so
- * that only the actual options that we support will be
- * passed off to getopt().
- */
-char valid_opts[] = {
- 'd', ':', 'h', 'k', 'L', ':', 'n', 'S', ':', 'U',
- 'w', ':',
-#ifdef AUTHENTICATION
- 'a', ':', 'X', ':',
-#endif
-#ifdef BFTPDAEMON
- 'B',
-#endif
-#ifdef DIAGNOSTICS
- 'D', ':',
-#endif
-#ifdef ENCRYPTION
- 'e',
-#endif
-#if defined(CRAY) && defined(NEWINIT)
- 'I', ':',
-#endif
-#ifdef LINEMODE
- 'l',
-#endif
-#ifdef CRAY
- 'r', ':',
-#endif
-#ifdef SecurID
- 's',
-#endif
-#ifdef KRB5
- 'R', ':', 't', ':',
-#endif
- '\0'
-};
-
-#include <sys/utsname.h>
-static char *
-get_default_IM()
-{
- struct utsname name;
- static char banner[1024];
-
- if (uname(&name) < 0)
- snprintf(banner, sizeof(banner),
- "\r\nError getting hostname: %s\r\n",
- strerror(errno));
- else {
-#if defined(_AIX)
- snprintf(banner, sizeof(banner),
- "\r\n %%h (%s release %s.%s) (%%t)\r\n\r\n",
- name.sysname, name.version, name.release);
-#else
- snprintf(banner, sizeof(banner),
- "\r\n %%h (%s release %s %s) (%%t)\r\n\r\n",
- name.sysname, name.release, name.version);
-#endif
- }
- return banner;
-}
-
-int
-main(argc, argv)
- int argc;
- char *argv[];
-{
- struct sockaddr_storage from;
- int on = 1;
- socklen_t 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;
-
-#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, valid_opts)) != -1) {
- 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 if (!strcmp(optarg, "encrypt")) {
- extern int encrypt_debug_mode;
- encrypt_debug_mode = 1;
- } else {
- usage();
- /* NOT REACHED */
- }
- break;
-#endif /* DIAGNOSTICS */
-
-#ifdef ENCRYPTION
- case 'e':
- must_encrypt = 1;
- 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 'L':
- {
- extern char *login_program;
-
- login_program = optarg;
- 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 KRB5
- case 'R':
- {
- extern krb5_context telnet_context;
- krb5_error_code retval;
-
- if (telnet_context == 0) {
- retval = krb5_init_context(&telnet_context);
- if (retval) {
- com_err("telnetd", retval,
- "while initializing krb5");
- exit(1);
- }
- }
- krb5_set_default_realm(telnet_context, optarg);
- break;
- }
-#endif /* KRB5 */
-
-#ifdef SecurID
- case 's':
- /* SecurID required */
- require_SecurID = 1;
- break;
-#endif /* SecurID */
- case 'S':
-#ifdef HAVE_GETTOSBYNAME
- 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;
-
-#ifdef KRB5
- case 't':
- {
- extern char *telnet_srvtab;
-
- telnet_srvtab = optarg;
- break;
- }
-#endif /* KRB5 */
-
-
- case 'U':
- registerd_host_only = 1;
- break;
-
-#ifdef AUTHENTICATION
- case 'X':
- /*
- * Check for invalid authentication types
- */
- auth_disable_name(optarg);
- break;
-#endif /* AUTHENTICATION */
- case 'w':
- if (!strcmp(optarg, "ip"))
- always_ip = 1;
- else {
- char *cp;
- cp = strchr(optarg, ',');
- if (cp == NULL)
- maxhostlen = atoi(optarg);
- else if (*(++cp)) {
- if (!strcmp(cp, "striplocal"))
- stripdomain = 1;
- else if (!strcmp(cp, "nostriplocal"))
- stripdomain = 0;
- else {
- usage();
- }
- *(--cp) = '\0';
- maxhostlen = atoi(optarg);
- }
- }
- break;
- default:
- fprintf(stderr, "telnetd: %c: unknown option\n", ch);
- /* FALLTHROUGH */
- case '?':
- usage();
- /* NOTREACHED */
- }
- }
-
- argc -= optind;
- argv += optind;
-
- /* XXX Convert this to support getaddrinfo, ipv6, etc. */
- if (debug) {
- int s, ns;
- socklen_t foo;
- struct servent *sp;
- static struct sockaddr_in sin4 = { AF_INET };
-
- if (argc > 1) {
- usage();
- /* NOT REACHED */
- } else if (argc == 1) {
- if ((sp = getservbyname(*argv, "tcp"))) {
- sin4.sin_port = sp->s_port;
- } else {
- sin4.sin_port = atoi(*argv);
- if ((int)sin4.sin_port <= 0) {
- fprintf(stderr, "telnetd: %s: bad port #\n", *argv);
- usage();
- /* NOT REACHED */
- }
- sin4.sin_port = htons((u_short)sin4.sin_port);
- }
- } else {
- sp = getservbyname("telnet", "tcp");
- if (sp == 0) {
- fprintf(stderr, "telnetd: tcp/telnet: unknown service\n");
- exit(1);
- }
- sin4.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 *)&sin4, sizeof(sin4)) < 0) {
- perror("bind");
- exit(1);
- }
- if (listen(s, 1) < 0) {
- perror("listen");
- exit(1);
- }
- foo = sizeof(sin4);
- ns = accept(s, (struct sockaddr *)&sin4, &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 szss = sizeof(ss);
-#ifdef SO_SEC_MULTI /* 8.0 code */
- int sock_multi;
- int szi = sizeof(int);
-#endif /* SO_SEC_MULTI */
-
- memset(&dv, 0, 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}
- */
-#ifdef SO_SEC_MULTI /* 8.0 code */
- if ((getsockopt(0, SOL_SOCKET, SO_SECURITY,
- (char *)&ss, &szss) < 0) ||
- (getsockopt(0, SOL_SOCKET, SO_SEC_MULTI,
- (char *)&sock_multi, &szi) < 0)) {
- perror("getsockopt");
- exit(1);
- } else {
- dv.dv_actlvl = ss.ss_actlabel.lt_level;
- dv.dv_actcmp = ss.ss_actlabel.lt_compart;
- if (!sock_multi) {
- dv.dv_minlvl = dv.dv_maxlvl = dv.dv_actlvl;
- dv.dv_valcmp = dv.dv_actcmp;
- } else {
- dv.dv_minlvl = ss.ss_minlabel.lt_level;
- dv.dv_maxlvl = ss.ss_maxlabel.lt_level;
- dv.dv_valcmp = ss.ss_maxlabel.lt_compart;
- }
- dv.dv_devflg = 0;
- }
-#else /* SO_SEC_MULTI */ /* 7.0 code */
- if (getsockopt(0, SOL_SOCKET, SO_SECURITY,
- (char *)&ss, &szss) >= 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 /* SO_SEC_MULTI */
- }
-#endif /* _SC_CRAY_SECURE_SYS */
-
- openlog("telnetd", LOG_PID | LOG_ODELAY, LOG_DAEMON);
- fromlen = sizeof (from);
- memset(&from, 0, sizeof(from));
- if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
- fprintf(stderr, "%s: ", progname);
- perror("getpeername");
- _exit(1);
- }
- if (keepalive &&
- setsockopt(0, SOL_SOCKET, SO_KEEPALIVE,
- (char *)&on, sizeof (on)) < 0) {
- syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
- }
-
-#if defined(IPPROTO_IP) && defined(IP_TOS)
- if (fromlen == sizeof (struct in_addr)) {
-# if defined(HAVE_GETTOSBYNAME)
- struct tosent *tp;
- if (tos < 0 && (tp = gettosbyname("telnet", "tcp")))
- tos = tp->t_tos;
-# endif
- if (tos < 0)
- tos = 020; /* Low Delay bit */
- if (tos
- && (setsockopt(0, IPPROTO_IP, IP_TOS,
- (char *)&tos, sizeof(tos)) < 0)
- && (errno != ENOPROTOOPT) )
- syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
- }
-#endif /* defined(IPPROTO_IP) && defined(IP_TOS) */
- net = 0;
- doit((struct sockaddr *)&from);
-
- /* NOTREACHED */
- return 0;
-} /* end of main */
-
- void
-usage()
-{
- fprintf(stderr, "Usage: telnetd");
-#ifdef AUTHENTICATION
- fprintf(stderr, " [-a (debug|other|user|valid|off|none)]\n\t");
-#endif
-#ifdef BFTPDAEMON
- fprintf(stderr, " [-B]");
-#endif
- fprintf(stderr, " [-debug]");
-#ifdef DIAGNOSTICS
- fprintf(stderr, " [-D (options|report|exercise|netdata|ptydata)]\n\t");
-#endif
-#ifdef AUTHENTICATION
- fprintf(stderr, " [-edebug]");
-#endif
- fprintf(stderr, " [-h]");
-#if defined(CRAY) && defined(NEWINIT)
- fprintf(stderr, " [-Iinitid]");
-#endif
-#if defined(LINEMODE) && defined(KLUDGELINEMODE)
- fprintf(stderr, " [-k]");
-#endif
-#ifdef LINEMODE
- fprintf(stderr, " [-l]");
-#endif
- fprintf(stderr, " [-n]");
-#ifdef CRAY
- fprintf(stderr, " [-r[lowpty]-[highpty]]");
-#endif
- fprintf(stderr, "\n\t");
-#ifdef SecurID
- fprintf(stderr, " [-s]");
-#endif
-#ifdef HAVE_GETTOSBYNAME
- fprintf(stderr, " [-S tos]");
-#endif
-#ifdef AUTHENTICATION
- fprintf(stderr, " [-X auth-type]");
-#endif
- fprintf(stderr, " [-U]\n\t");
- fprintf(stderr, " [-w [ip|maxhostlen[,[no]striplocal]]]\n\t");
- fprintf(stderr, " [port]\n");
- exit(1);
-}
-
-static void encrypt_failure()
-{
- char *lerror_message;
-
- if (auth_must_encrypt())
- lerror_message = "Encryption was not successfully negotiated. Goodbye.\r\n\r\n";
- else
- lerror_message = "Unencrypted connection refused. Goodbye.\r\n\r\n";
-
- netputs(lerror_message);
- netflush();
- exit(1);
-}
-
-/*
- * getterminaltype
- *
- * Ask the other end to send along its terminal type and speed.
- * Output is the variable terminaltype filled in.
- */
-static unsigned char ttytype_sbbuf[] = {
- IAC, SB, TELOPT_TTYPE, TELQUAL_SEND, IAC, SE
-};
-
-static int
-getterminaltype(name)
- char *name;
-{
- settimer(baseline);
-#if defined(AUTHENTICATION)
- ttsuck();
- /*
- * Handle the Authentication option before we do anything else.
- */
- send_do(TELOPT_AUTHENTICATION, 1);
- while (his_will_wont_is_changing(TELOPT_AUTHENTICATION))
- ttloop();
- if (his_state_is_will(TELOPT_AUTHENTICATION)) {
- auth_wait(name);
- }
-#endif
-
-#ifdef ENCRYPTION
- send_will(TELOPT_ENCRYPT, 1);
- send_do(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) ||
- his_will_wont_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_NEW_ENVIRON) ||
- 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();
- }
- if (must_encrypt || auth_must_encrypt()) {
- time_t timeout = time(0) + 60;
-
- if (my_state_is_dont(TELOPT_ENCRYPT) ||
- my_state_is_wont(TELOPT_ENCRYPT) ||
- his_state_is_wont(TELOPT_AUTHENTICATION))
- encrypt_failure();
-
- while (!EncryptStartInput()) {
- if (time (0) > timeout)
- encrypt_failure();
- ttloop();
- }
-
- while (!EncryptStartOutput()) {
- if (time (0) > timeout)
- encrypt_failure();
- ttloop();
- }
-
- while (!encrypt_is_encrypting()) {
- if (time(0) > timeout)
- encrypt_failure();
- ttloop();
- }
- }
-#endif /* ENCRYPTION */
- /* Options like environment require authentication and encryption
- negotiation to be completed.*/
- auth_negotiated = 1;
- if (his_state_is_will(TELOPT_TSPEED)) {
- static unsigned char sb[] =
- { IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE };
- netwrite(sb, sizeof(sb));
- }
- if (his_state_is_will(TELOPT_XDISPLOC)) {
- static unsigned char sb[] =
- { IAC, SB, TELOPT_XDISPLOC, TELQUAL_SEND, IAC, SE };
- netwrite(sb, sizeof(sb));
- }
- if (his_state_is_will(TELOPT_NEW_ENVIRON)) {
- static unsigned char sb[] =
- { IAC, SB, TELOPT_NEW_ENVIRON, TELQUAL_SEND, IAC, SE };
- netwrite(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 };
- netwrite(sb, sizeof(sb));
- }
- if (his_state_is_will(TELOPT_TTYPE))
- netwrite(ttytype_sbbuf, sizeof(ttytype_sbbuf));
-
- if (his_state_is_will(TELOPT_TSPEED)) {
- while (sequenceIs(tspeedsubopt, baseline))
- ttloop();
- }
- if (his_state_is_will(TELOPT_XDISPLOC)) {
- while (sequenceIs(xdisplocsubopt, baseline))
- ttloop();
- }
- if (his_state_is_will(TELOPT_NEW_ENVIRON)) {
- while (sequenceIs(environsubopt, baseline))
- ttloop();
- }
- if (his_state_is_will(TELOPT_OLD_ENVIRON)) {
- while (sequenceIs(oenvironsubopt, baseline))
- ttloop();
- }
- if (his_state_is_will(TELOPT_TTYPE)) {
- char first[256], last[256];
-
- while (sequenceIs(ttypesubopt, baseline))
- ttloop();
-
- /*
- * If the other side has already disabled the option, then
- * 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) - 1);
- first[sizeof(first) - 1] = '\0';
- for(;;) {
- /*
- * Save the unknown name, and request the next name.
- */
- (void) strncpy(last, terminaltype, sizeof(last) - 1);
- last[sizeof(last) - 1] = '\0';
- _gettermname();
- if (terminaltypeok(terminaltype))
- break;
- if ((strncmp(last, terminaltype, sizeof(last)) == 0) ||
- his_state_is_wont(TELOPT_TTYPE)) {
- /*
- * We've hit the end. If this is the same as
- * the first name, just go with it.
- */
- if (strncmp(first, terminaltype, sizeof(first)) == 0)
- break;
- /*
- * Get the terminal name one more time, so that
- * RFC1091 compliant telnets will cycle back to
- * the start of the list.
- */
- _gettermname();
- if (strncmp(first, terminaltype, sizeof(first)) != 0) {
- (void) strncpy(terminaltype, first,
- sizeof(terminaltype) - 1);
- terminaltype[sizeof(terminaltype) - 1] = '\0';
- }
- break;
- }
- }
- }
- }
-#ifdef AUTHENTICATION
- return(auth_check(name));
-#else
- return(-1);
-#endif
-} /* end of getterminaltype */
-
-static void
-_gettermname()
-{
- /*
- * If the client turned off the option,
- * we can't send another request, so we
- * just return.
- */
- if (his_state_is_wont(TELOPT_TTYPE))
- return;
- settimer(baseline);
- netwrite(ttytype_sbbuf, sizeof(ttytype_sbbuf));
- while (sequenceIs(ttypesubopt, baseline))
- ttloop();
-}
-
- int
-terminaltypeok(s)
- char *s;
-{
- char buf[1024];
-
- if (!*s)
- return(1);
-
- /*
- * tgetent() will return 1 if the type is known, and
- * 0 if it is not known. If it returns -1, it couldn't
- * open the database. But if we can't open the database,
- * it won't help to say we failed, because we won't be
- * able to verify anything else. So, we treat -1 like 1.
- */
- if (tgetent(buf, s) == 0)
- return(0);
- return(1);
-}
-#if HAVE_ARPA_NAMESER_H
-#include <arpa/nameser.h>
-#endif
-
-#ifndef MAXDNAME
-#define MAXDNAME 256 /*per the rfc*/
-#endif
-
-char *hostname;
-char host_name[MAXDNAME];
-char remote_host_name[MAXDNAME];
-char *rhost_sane;
-
-#ifndef convex
-extern void telnet (int, int);
-#else
-extern void telnet (int, int, char *);
-#endif
-
-/*
- * Get a pty, scan input lines.
- */
-static void doit(who)
- struct sockaddr *who;
-{
- int level;
-#if defined(_SC_CRAY_SECURE_SYS)
- int ptynum;
-#endif
- char user_name[256];
- long retval;
- /*
- * Find an available pty to use.
- */
- pty_init();
-
-
- if ((retval = pty_getpty(&pty, line, 17)) != 0) {
- fatal(net, error_message(retval));
- }
-
-#if defined(_SC_CRAY_SECURE_SYS)
- /*
- * set ttyp line security label
- */
- if (secflag) {
- char slave_dev[16];
-/*xxx This code needs to be fixed to work without ptynum; I don't understand why they don't currently use line, so I don't really know how to fix.*/
- snprintf(tty_dev, sizeof(tty_dev), "/dev/pty/%03d", ptynum);
- if (setdevs(tty_dev, &dv) < 0)
- fatal(net, "cannot set pty security");
- snprintf(slave_dev, sizeof(slave_dev), "/dev/ttyp%03d", ptynum);
- if (setdevs(slave_dev, &dv) < 0)
- fatal(net, "cannot set tty security");
- }
-#endif /* _SC_CRAY_SECURE_SYS */
-
- retval = pty_make_sane_hostname((struct sockaddr *) who, maxhostlen,
- stripdomain, always_ip,
- &rhost_sane);
- if (retval) {
- fatal(net, error_message(retval));
- }
- if (registerd_host_only) {
- /* Get name of connected client -- but we don't actually
- use it. Just confirm that we can get it. */
- int aierror;
- char hostnamebuf[NI_MAXHOST];
- aierror = getnameinfo (who, socklen (who),
- hostnamebuf, sizeof (hostnamebuf), 0, 0,
- NI_NAMEREQD);
- if (aierror != 0) {
- fatal(net,
- "Couldn't resolve your address into a host name.\r\n"
- "Please contact your net administrator");
- }
- }
-
- (void) gethostname(host_name, sizeof (host_name));
- hostname = host_name;
-
-#if defined(AUTHENTICATION) || defined(ENCRYPTION)
- auth_encrypt_init(hostname, rhost_sane, "TELNETD", 1);
-#endif
-
- init_env();
-
-#ifdef SIGTTOU
- /*
- * Ignoring SIGTTOU keeps the kernel from blocking us.
- * we tweak the tty with an ioctl()
- * (in ttioct() in /sys/tty.c in a BSD kernel)
- */
- (void) signal(SIGTTOU, SIG_IGN);
-#endif
- /*
- * get terminal type.
- */
- *user_name = 0;
- level = getterminaltype(user_name);
- setenv("TERM", *terminaltype ? terminaltype : "network", 1);
-
-#if defined (AUTHENTICATION)
- if (level < 0 && auth_level > 0) {
- fatal (net, "No authentication provided");
- exit (-1);
- }
-#endif
- /*
- * Start up the login process on the slave side of the terminal
- */
-#ifndef convex
- startslave(rhost_sane, level, user_name);
-
-#if defined(_SC_CRAY_SECURE_SYS)
- if (secflag) {
- if (setulvl(dv.dv_actlvl) < 0)
- fatal(net,"cannot setulvl()");
- if (setucmp(dv.dv_actcmp) < 0)
- fatal(net, "cannot setucmp()");
- }
-#endif /* _SC_CRAY_SECURE_SYS */
-
- telnet(net, pty); /* begin server processing */
-#else
- telnet(net, pty, rhost_sane);
-#endif
- /*NOTREACHED*/
-} /* end of doit */
-
-#if defined(CRAY2) && defined(UNICOS5) && defined(UNICOS50)
- int
-Xterm_output(ibufp, obuf, icountp, ocount)
- char **ibufp, *obuf;
- int *icountp, ocount;
-{
- int ret;
- ret = term_output(*ibufp, obuf, *icountp, ocount);
- *ibufp += *icountp;
- *icountp = 0;
- return(ret);
-}
-#define term_output Xterm_output
-#endif /* defined(CRAY2) && defined(UNICOS5) && defined(UNICOS50) */
-
-/*
- * Main loop. Select from pty and network, and
- * 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 defent[TABBUFSIZ];
- char defstrs[TABBUFSIZ];
-#undef TABBUFSIZ
- char *HEstr;
- char *HN;
- char *IM;
- void netflush();
-
- /*
- * Initialize the slc mapping table.
- */
- get_slc_defaults();
-
- /*
- * Do some tests where it is desireable to wait for a response.
- * Rather than doing them slowly, one at a time, do them all
- * at once.
- */
- if (my_state_is_wont(TELOPT_SGA))
- send_will(TELOPT_SGA, 1);
- /*
- * Is the client side a 4.2 (NOT 4.3) system? We need to know this
- * because 4.2 clients are unable to deal with TCP urgent data.
- *
- * To find out, we send out a "DO ECHO". If the remote system
- * answers "WILL ECHO" it is probably a 4.2 client, and we note
- * that fact ("WILL ECHO" ==> that the client will echo what
- * WE, the server, sends it; it does NOT mean that the client will
- * echo the terminal input).
- */
- send_do(TELOPT_ECHO, 1);
-
-#ifdef LINEMODE
- if (his_state_is_wont(TELOPT_LINEMODE)) {
- /* Query the peer for linemode support by trying to negotiate
- * the linemode option.
- */
- linemode = 0;
- editmode = 0;
- send_do(TELOPT_LINEMODE, 1); /* send do linemode */
- }
-#endif /* LINEMODE */
-
- /*
- * Send along a couple of other options that we wish to negotiate.
- */
- send_do(TELOPT_NAWS, 1);
- send_will(TELOPT_STATUS, 1);
- flowmode = 1; /* default flow control state */
- restartany = -1; /* uninitialized... */
- send_do(TELOPT_LFLOW, 1);
-
- /*
- * Spin, waiting for a response from the DO ECHO. However,
- * some REALLY DUMB telnets out there might not respond
- * to the DO ECHO. So, we spin looking for NAWS, (most dumb
- * telnets so far seem to respond with WONT for a DO that
- * they don't understand...) because by the time we get the
- * response, it will already have processed the DO ECHO.
- * Kludge upon kludge.
- */
- while (his_will_wont_is_changing(TELOPT_NAWS))
- ttloop();
-
- /*
- * But...
- * The client might have sent a WILL NAWS as part of its
- * startup code; if so, we'll be here before we get the
- * response to the DO ECHO. We'll make the assumption
- * that any implementation that understands about NAWS
- * is a modern enough implementation that it will respond
- * to our DO ECHO request; hence we'll do another spin
- * waiting for the ECHO option to settle down, which is
- * what we wanted to do in the first place...
- */
- if (his_want_state_is_will(TELOPT_ECHO) &&
- his_state_is_will(TELOPT_NAWS)) {
- while (his_will_wont_is_changing(TELOPT_ECHO))
- ttloop();
- }
- /*
- * On the off chance that the telnet client is broken and does not
- * respond to the DO ECHO we sent, (after all, we did send the
- * DO NAWS negotiation after the DO ECHO, and we won't get here
- * until a response to the DO NAWS comes back) simulate the
- * receipt of a will echo. This will also send a WONT ECHO
- * to the client, since we assume that the client failed to
- * respond because it believes that it is already in DO ECHO
- * mode, which we do not want.
- */
- if (his_want_state_is_will(TELOPT_ECHO)) {
- DIAG(TD_OPTIONS, netputs("td: simulating recv\r\n"));
- willoption(TELOPT_ECHO);
- }
-
- /*
- * Finally, to clean things up, we turn on our echo. This
- * will break stupid 4.2 telnets out of local terminal echo.
- */
-
- if (my_state_is_wont(TELOPT_ECHO))
- send_will(TELOPT_ECHO, 1);
-
-#ifndef STREAMSPTY
- /*
- * Turn on packet mode
- */
- (void) ioctl(p, TIOCPKT, (char *)&on);
-#endif
-
-#if defined(LINEMODE) && defined(KLUDGELINEMODE)
- /*
- * Continuing line mode support. If client does not support
- * real linemode, attempt to negotiate kludge linemode by sending
- * the do timing mark sequence.
- */
- if (lmodetype < REAL_LINEMODE)
- send_do(TELOPT_TM, 1);
-#endif /* defined(LINEMODE) && defined(KLUDGELINEMODE) */
-
- /*
- * Call telrcv() once to pick up anything received during
- * terminal type negotiation, 4.2/4.3 determination, and
- * linemode negotiation.
- */
- telrcv();
-
- (void) ioctl(f, FIONBIO, (char *)&on);
- (void) ioctl(p, FIONBIO, (char *)&on);
-#if defined(CRAY2) && defined(UNICOS5)
- init_termdriver(f, p, interrupt, sendbrk);
-#endif
-
-#if defined(SO_OOBINLINE)
- (void) setsockopt(net, SOL_SOCKET, SO_OOBINLINE,
- (char *)&on, sizeof(on));
-#endif /* defined(SO_OOBINLINE) */
-
-#ifdef SIGTSTP
- (void) signal(SIGTSTP, SIG_IGN);
-#endif
-
- (void) signal(SIGCHLD, cleanup);
-
-#if defined(CRAY2) && defined(UNICOS5)
- /*
- * Cray-2 will send a signal when pty modes are changed by slave
- * side. Set up signal handler now.
- */
- if ((int)signal(SIGUSR1, termstat) < 0)
- perror("signal");
- else if (ioctl(p, TCSIGME, (char *)SIGUSR1) < 0)
- perror("ioctl:TCSIGME");
- /*
- * Make processing loop check terminal characteristics early on.
- */
- termstat();
-#endif
-
-#ifdef TIOCNOTTY
- {
- register int t;
- t = open(_PATH_TTY, O_RDWR);
- if (t >= 0) {
- (void) ioctl(t, TIOCNOTTY, (char *)0);
- (void) close(t);
- }
- }
-#endif
-
-#if defined(CRAY) && defined(NEWINIT) && defined(TIOCSCTTY)
- (void) setsid();
- ioctl(p, TIOCSCTTY, 0);
-#endif
-
- /*
- * Show banner that getty never gave.
- *
- * We put the banner in the pty input buffer. This way, it
- * gets carriage return null processing, etc., just like all
- * other pty --> client data.
- */
-
-#if !defined(CRAY) || !defined(NEWINIT)
- if (getenv("USER"))
- hostinfo = 0;
-#endif
-
- if (getent(defent, "default") == 1) {
- char *getstr();
- char *cp=defstrs;
-
- HEstr = getstr("he", &cp);
- HN = getstr("hn", &cp);
- IM = getstr("im", &cp);
- if (HN && *HN)
- (void) strncpy(host_name, HN, sizeof(host_name) - 1);
- host_name[sizeof(host_name) - 1] = '\0';
- if (IM == 0)
- IM = "";
- } else {
- IM = get_default_IM();
- HEstr = 0;
- }
- edithost(HEstr, host_name);
- if (hostinfo && *IM)
- putf(IM, ptyibuf2);
-
- if (pcc)
- (void) strncat(ptyibuf2, ptyip, pcc+1);
- ptyip = ptyibuf2;
- pcc = strlen(ptyip);
-#ifdef LINEMODE
- /*
- * Last check to make sure all our states are correct.
- */
- init_termbuf();
- localstat();
-#endif /* LINEMODE */
-
- DIAG(TD_REPORT, netputs("td: Entering processing loop\r\n"));
-
-#ifdef convex
- startslave(host);
-#endif
-
- for (;;) {
- fd_set ibits, obits, xbits;
- register int c;
-
- if (ncc < 0 && pcc < 0)
- break;
-
-#if defined(CRAY2) && defined(UNICOS5)
- if (needtermstat)
- _termstat();
-#endif /* defined(CRAY2) && defined(UNICOS5) */
- FD_ZERO(&ibits);
- FD_ZERO(&obits);
- FD_ZERO(&xbits);
- /*
- * Never look for input if there's still
- * stuff in the corresponding output buffer
- */
- if (nfrontp - nbackp || pcc > 0) {
- FD_SET(f, &obits);
- } else {
- FD_SET(p, &ibits);
- }
- if (pfrontp - pbackp || ncc > 0) {
- FD_SET(p, &obits);
- } else {
- FD_SET(f, &ibits);
- }
- if (!SYNCHing) {
- FD_SET(f, &xbits);
- }
- if ((c = select(16, &ibits, &obits, &xbits,
- (struct timeval *)0)) < 1) {
- if (c == -1) {
- if (errno == EINTR) {
- continue;
- }
- }
- sleep(5);
- continue;
- }
-
- /*
- * Any urgent data?
- */
- if (FD_ISSET(net, &xbits)) {
- SYNCHing = 1;
- }
-
- /*
- * Something to read from the network...
- */
- if (FD_ISSET(net, &ibits)) {
-#if !defined(SO_OOBINLINE)
- /*
- * In 4.2 (and 4.3 beta) systems, the
- * OOB indication and data handling in the kernel
- * is such that if two separate TCP Urgent requests
- * come in, one byte of TCP data will be overlaid.
- * This is fatal for Telnet, but we try to live
- * with it.
- *
- * In addition, in 4.2 (and...), a special protocol
- * is needed to pick up the TCP Urgent data in
- * the correct sequence.
- *
- * What we do is: if we think we are in urgent
- * mode, we look to see if we are "at the mark".
- * If we are, we do an OOB receive. If we run
- * this twice, we will do the OOB receive twice,
- * but the second will fail, since the second
- * time we were "at the mark", but there wasn't
- * any data there (the kernel doesn't reset
- * "at the mark" until we do a normal read).
- * Once we've read the OOB data, we go ahead
- * and do normal reads.
- *
- * There is also another problem, which is that
- * since the OOB byte we read doesn't put us
- * out of OOB state, and since that byte is most
- * likely the TELNET DM (data mark), we would
- * stay in the TELNET SYNCH (SYNCHing) state.
- * So, clocks to the rescue. If we've "just"
- * received a DM, then we test for the
- * presence of OOB data when the receive OOB
- * fails (and AFTER we did the normal mode read
- * to clear "at the mark").
- */
- if (SYNCHing) {
- int atmark;
-
- (void) ioctl(net, SIOCATMARK, (char *)&atmark);
- if (atmark) {
- ncc = recv(net, netibuf, sizeof (netibuf), MSG_OOB);
- if ((ncc == -1) && (errno == EINVAL)) {
- ncc = read(net, netibuf, sizeof (netibuf));
- if (sequenceIs(didnetreceive, gotDM)) {
- SYNCHing = stilloob(net);
- }
- }
- } else {
- ncc = read(net, netibuf, sizeof (netibuf));
- }
- } else {
- ncc = read(net, netibuf, sizeof (netibuf));
- }
- settimer(didnetreceive);
-#else /* !defined(SO_OOBINLINE)) */
- ncc = read(net, netibuf, sizeof (netibuf));
-#endif /* !defined(SO_OOBINLINE)) */
- if (ncc < 0 && errno == EWOULDBLOCK)
- ncc = 0;
- else {
- if (ncc <= 0) {
- break;
- }
- netip = netibuf;
- }
- DIAG((TD_REPORT | TD_NETDATA),
- netprintf("td: netread %d chars\r\n", ncc));
- DIAG(TD_NETDATA, printdata("nd", netip, ncc));
- }
-
- /*
- * Something to read from the pty...
- */
- if (FD_ISSET(p, &ibits)) {
-#ifndef STREAMSPTY
- pcc = read(p, ptyibuf, BUFSIZ);
-#else
- pcc = readstream(p, ptyibuf, BUFSIZ);
-#endif
- /*
- * On some systems, if we try to read something
- * off the master side before the slave side is
- * opened, we get EIO.
- */
- if (pcc < 0 && (errno == EWOULDBLOCK ||
-#ifdef EAGAIN
- errno == EAGAIN ||
-#endif
- errno == EIO)) {
- pcc = 0;
- } else {
- if (pcc <= 0)
- break;
-#if !defined(CRAY2) || !defined(UNICOS5)
-#ifdef LINEMODE
- /*
- * If ioctl from pty, pass it through net
- */
- if (ptyibuf[0] & TIOCPKT_IOCTL) {
- copy_termbuf(ptyibuf+1, pcc-1);
- localstat();
- pcc = 1;
- }
-#endif /* LINEMODE */
- if (ptyibuf[0] & TIOCPKT_FLUSHWRITE) {
- netclear(); /* clear buffer back */
-#ifndef NO_URGENT
- /*
- * There are client telnets on some
- * operating systems get screwed up
- * royally if we send them urgent
- * mode data.
- */
- netprintf_urg("%c%c", IAC, DM);
-#endif
- }
- if (his_state_is_will(TELOPT_LFLOW) &&
- (ptyibuf[0] &
- (TIOCPKT_NOSTOP|TIOCPKT_DOSTOP))) {
- int newflow =
- ptyibuf[0] & TIOCPKT_DOSTOP ? 1 : 0;
- if (newflow != flowmode) {
- flowmode = newflow;
- netprintf("%c%c%c%c%c%c",
- IAC, SB, TELOPT_LFLOW,
- flowmode ? LFLOW_ON
- : LFLOW_OFF,
- IAC, SE);
- }
- }
- pcc--;
- ptyip = ptyibuf+1;
-#else /* defined(CRAY2) && defined(UNICOS5) */
- if (!uselinemode) {
- unpcc = pcc;
- unptyip = ptyibuf;
- pcc = term_output(&unptyip, ptyibuf2,
- &unpcc, BUFSIZ);
- ptyip = ptyibuf2;
- } else
- ptyip = ptyibuf;
-#endif /* defined(CRAY2) && defined(UNICOS5) */
- }
- }
-
- while (pcc > 0) {
- if ((&netobuf[BUFSIZ] - nfrontp) < 2)
- break;
- c = *ptyip++ & 0377, pcc--;
- if (c == IAC)
- netprintf("%c", c);
-#if defined(CRAY2) && defined(UNICOS5)
- else if (c == '\n' &&
- my_state_is_wont(TELOPT_BINARY) && newmap)
- netputs("\r");
-#endif /* defined(CRAY2) && defined(UNICOS5) */
- netprintf("%c", c);
- if ((c == '\r') && (my_state_is_wont(TELOPT_BINARY))) {
- if (pcc > 0 && ((*ptyip & 0377) == '\n')) {
- netprintf("%c", *ptyip++ & 0377);
- pcc--;
- } else
- netprintf("%c", '\0');
- }
- }
-#if defined(CRAY2) && defined(UNICOS5)
- /*
- * If chars were left over from the terminal driver,
- * note their existence.
- */
- if (!uselinemode && unpcc) {
- pcc = unpcc;
- unpcc = 0;
- ptyip = unptyip;
- }
-#endif /* defined(CRAY2) && defined(UNICOS5) */
-
- if (FD_ISSET(f, &obits) && (nfrontp - nbackp) > 0)
- netflush();
- if (ncc > 0)
- telrcv();
- if (FD_ISSET(p, &obits) && (pfrontp - pbackp) > 0)
- ptyflush();
- }
- (void) signal(SIGCHLD, SIG_DFL);
- cleanup(0);
-} /* end of telnet */
-
-#ifndef TCSIG
-# ifdef TIOCSIG
-# define TCSIG TIOCSIG
-# endif
-#endif
-
-#ifdef STREAMSPTY
-
-int flowison = -1; /* current state of flow: -1 is unknown */
-
-int readstream(p, ibuf, bufsize)
- int p;
- char *ibuf;
- int bufsize;
-{
- int flags = 0;
- int ret = 0;
- struct termios *tsp;
- struct termio *tp;
- struct iocblk *ip;
- char vstop, vstart;
- int ixon;
- int newflow;
-
- strbufc.maxlen = BUFSIZ;
- strbufc.buf = (char *)ctlbuf;
- strbufd.maxlen = bufsize-1;
- strbufd.len = 0;
- strbufd.buf = ibuf+1;
- ibuf[0] = 0;
-
- ret = getmsg(p, &strbufc, &strbufd, &flags);
- if (ret < 0) /* error of some sort -- probably EAGAIN */
- return(-1);
-
- if (strbufc.len <= 0 || ctlbuf[0] == M_DATA) {
- /* data message */
- if (strbufd.len > 0) { /* real data */
- return(strbufd.len + 1); /* count header char */
- } else {
- /* nothing there */
- errno = EAGAIN;
- return(-1);
- }
- }
-
- /*
- * It's a control message. Return 1, to look at the flag we set
- */
-
- switch (ctlbuf[0]) {
- case M_FLUSH:
- if (ibuf[1] & FLUSHW)
- ibuf[0] = TIOCPKT_FLUSHWRITE;
- return(1);
-
- case M_IOCTL:
- ip = (struct iocblk *) (ibuf+1);
- if (readstream_termio(ip->ioc_cmd, ibuf,
- &vstop, &vstart, &ixon)) {
- if (readstream_termios(ip->ioc_cmd, ibuf,
- &vstop, &vstart, &ixon)) {
- errno = EAGAIN;
- return(-1);
- }
- }
-
- newflow = (ixon && (vstart == 021) && (vstop == 023)) ? 1 : 0;
- if (newflow != flowison) { /* it's a change */
- flowison = newflow;
- ibuf[0] = newflow ? TIOCPKT_DOSTOP : TIOCPKT_NOSTOP;
- return(1);
- }
- }
-
- /* nothing worth doing anything about */
- errno = EAGAIN;
- return(-1);
-}
-#endif /* STREAMSPTY */
-
-/*
- * Send interrupt to process on other side of pty.
- * If it is in raw mode, just write NULL;
- * otherwise, write intr char.
- */
- void
-interrupt()
-{
- ptyflush(); /* half-hearted */
-
-#ifdef TCSIG
- (void) ioctl(pty, TCSIG, (char *)SIGINT);
-#else /* TCSIG */
- init_termbuf();
- *pfrontp++ = slctab[SLC_IP].sptr ?
- (unsigned char)*slctab[SLC_IP].sptr : '\177';
-#endif /* TCSIG */
-}
-
-/*
- * Send quit to process on other side of pty.
- * If it is in raw mode, just write NULL;
- * otherwise, write quit char.
- */
- void
-sendbrk()
-{
- ptyflush(); /* half-hearted */
-#ifdef TCSIG
- (void) ioctl(pty, TCSIG, (char *)SIGQUIT);
-#else /* TCSIG */
- init_termbuf();
- *pfrontp++ = slctab[SLC_ABORT].sptr ?
- (unsigned char)*slctab[SLC_ABORT].sptr : '\034';
-#endif /* TCSIG */
-}
-
- void
-sendsusp()
-{
-#ifdef SIGTSTP
- ptyflush(); /* half-hearted */
-# ifdef TCSIG
- (void) ioctl(pty, TCSIG, (char *)SIGTSTP);
-# else /* TCSIG */
- *pfrontp++ = slctab[SLC_SUSP].sptr ?
- (unsigned char)*slctab[SLC_SUSP].sptr : '\032';
-# endif /* TCSIG */
-#endif /* SIGTSTP */
-}
-
-/*
- * When we get an AYT, if ^T is enabled, use that. Otherwise,
- * just send back "[Yes]".
- */
-void
-recv_ayt()
-{
-#if defined(SIGINFO) && defined(TCSIG)
- if (slctab[SLC_AYT].sptr && *slctab[SLC_AYT].sptr != _POSIX_VDISABLE) {
- (void) ioctl(pty, TCSIG, (char *)SIGINFO);
- return;
- }
-#endif
- netputs("\r\n[Yes]\r\n");
-}
-
- void
-doeof()
-{
- 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';
-}
+++ /dev/null
-/*
- * Copyright (c) 1989, 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.
- *
- * @(#)telnetd.h 8.1 (Berkeley) 6/4/93
- */
-
-
-#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;
+++ /dev/null
-/* handle having mutually exclusive termio vs. termios */
-/* return 0 if handled */
-#ifdef STREAMSPTY
-#include <sys/types.h>
-#include <sys/stream.h>
-#include <sys/ioctl.h>
-#include <termio.h>
-
-#include "defs.h"
-#include "ext.h"
-
-int readstream_termio(cmd, ibuf, vstop, vstart, ixon)
- int cmd;
- char *ibuf;
- char *vstop, *vstart;
- int *ixon;
-{
- struct termio *tp;
- switch (cmd) {
- case TCSETA:
- case TCSETAW:
- case TCSETAF:
- tp = (struct termio *) (ibuf+1 + sizeof(struct iocblk));
-#if 0 /* VSTOP/VSTART only in termios!? */
- *vstop = tp->c_cc[VSTOP];
- *vstart = tp->c_cc[VSTART];
-#endif
- *ixon = tp->c_iflag & IXON;
- return 0;
- }
- return -1;
-}
-
-#else
-int silence_warnings_about_empty_source_file_termio = 42;
-#endif /* STREAMSPTY */
+++ /dev/null
-/* handle having mutually exclusive termio vs. termios */
-/* return 0 if handled */
-#ifdef STREAMSPTY
-#include <sys/types.h>
-#include <sys/stream.h>
-#include <sys/ioctl.h>
-#include <termios.h>
-#if !defined(TCSETS) && defined(_AIX) /* kludge for AIX */
-#include <termio.h>
-#endif
-
-#include "defs.h"
-#include "ext.h"
-
-int readstream_termios(cmd, ibuf, vstop, vstart, ixon)
- int cmd;
- char *ibuf;
- char *vstop, *vstart;
- int *ixon;
-{
- struct termios *tsp;
- switch (cmd) {
- case TCSETS:
- case TCSETSW:
- case TCSETSF:
- tsp = (struct termios *)
- (ibuf+1 + sizeof(struct iocblk));
- *vstop = tsp->c_cc[VSTOP];
- *vstart = tsp->c_cc[VSTART];
- *ixon = tsp->c_iflag & IXON;
- return 0;
- }
- return -1;
-}
-
-#else
-int silence_warnings_about_empty_source_file_termios = 42;
-#endif /* STREAMSPTY */
+++ /dev/null
-/*
- * Copyright (c) 1989, 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.
- */
-
-/* based on @(#)termstat.c 8.1 (Berkeley) 6/4/93 */
-
-#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
- * NO_KLUDGE : don't initiate kludge linemode.
- * 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,
- * and the "-k" (don't initiate kludge linemode) isn't set,
- * 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.
- */
- flowstat();
-
- /*
- * 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);
- }
-
-#ifdef ENCRYPTION
- /*
- * 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 /* ENCRYPTION */
-
- /*
- * 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;
-#ifdef KLUDGELINEMODE
- if (lmodetype == KLUDGE_OK)
- lmodetype = KLUDGE_LINEMODE;
-#endif
- }
-
- /*
- * 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 */
- netprintf("%c%c%c%c%c%c%c", IAC, SB,
- TELOPT_LINEMODE, LM_MODE, useeditmode,
- IAC, SE);
- 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) netprintf("%c%c%c%c%c%c%c", IAC, SB,
- TELOPT_LINEMODE, LM_MODE, useeditmode,
- IAC, SE);
- 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 */
-
-/*
- * flowstat
- *
- * Check for changes to flow control
- */
- void
-flowstat()
-{
- if (his_state_is_will(TELOPT_LFLOW)) {
- if (tty_flowmode() != flowmode) {
- flowmode = tty_flowmode();
- netprintf("%c%c%c%c%c%c",
- IAC, SB, TELOPT_LFLOW,
- flowmode ? LFLOW_ON : LFLOW_OFF,
- IAC, SE);
- }
- if (tty_restartany() != restartany) {
- restartany = tty_restartany();
- netprintf("%c%c%c%c%c%c",
- IAC, SB, TELOPT_LFLOW,
- restartany ? LFLOW_RESTART_ANY
- : LFLOW_RESTART_XON,
- IAC, SE);
- }
- }
-}
-
-/*
- * 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;
-{
- void netflush();
-
- /*
- * 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;
- netprintf("%c%c%c%c%c%c%c", IAC,
- SB, TELOPT_LINEMODE, LM_MODE,
- useeditmode, IAC, SE);
- editmode = useeditmode;
- }
-
-
- tty_setlinemode(uselinemode);
-
- linemode = uselinemode;
-
- if (!linemode)
- send_will(TELOPT_ECHO, 1);
- }
- 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) {
- netprintf("%c%c%c%c%c%c%c", IAC,
- SB, TELOPT_LINEMODE, LM_MODE,
- useeditmode|MODE_ACK,
- IAC, SE);
- }
-
- 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;
-
- memset(&ws, 0, 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 */
+++ /dev/null
-/*
- * Copyright (c) 1989, 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.
- */
-
-/* based on @(#)utility.c 8.1 (Berkeley) 6/4/93 */
-
-#include <stdarg.h>
-#define PRINTOPTIONS
-#include "telnetd.h"
-
-#ifdef HAVE_SYS_UTSNAME_H
-#include <sys/utsname.h>
-#endif
-
-#if defined(AUTHENTICATION)
-#include <libtelnet/auth.h>
-#endif
-#ifdef ENCRYPTION
-#include <libtelnet/encrypt.h>
-#endif
-
-/*
- * utility functions performing io related tasks
- */
-
-/*
- * ttloop
- *
- * A small subroutine to flush the network output buffer, get some data
- * from the network, and pass it through the telnet state machine. We
- * also flush the pty input buffer (by dropping its data) if it becomes
- * too full.
- */
-
- void
-ttloop()
-{
- void netflush();
-
- DIAG(TD_REPORT, netputs("td: ttloop\r\n"));
- if (nfrontp-nbackp) {
- netflush();
- }
-read_again:
- ncc = read(net, netibuf, sizeof netibuf);
- if (ncc < 0) {
- if (errno == EINTR)
- goto read_again;
- syslog(LOG_INFO, "ttloop: read: %m");
- exit(1);
- } else if (ncc == 0) {
- syslog(LOG_INFO, "ttloop: peer died: %m");
- exit(1);
- }
- DIAG(TD_REPORT, netprintf("td: ttloop read %d chars\r\n", ncc));
- netip = netibuf;
- telrcv(); /* state machine */
- if (ncc > 0) {
- pfrontp = pbackp = ptyobuf;
- telrcv();
- }
-} /* end of ttloop */
-
-/*
- * ttsuck - This is a horrible kludge to deal with a bug in
- * HostExplorer. HostExplorer thinks it knows how to do krb5 auth, but
- * it doesn't really. So if you offer it krb5 as an auth choice before
- * krb4, it will sabotage the connection. So we peek ahead into the
- * input stream to see if the client is a UNIX client, and then
- * (later) offer krb5 first only if it is. Since no Mac/PC telnet
- * clients do auto switching between krb4 and krb5 like the UNIX
- * client does, it doesn't matter what order they see the choices in
- * (except for HostExplorer).
- *
- * It is actually not possible to do this without looking ahead into
- * the input stream: the client and server both try to begin
- * auth/encryption negotiation as soon as possible, so if we let the
- * server process things normally, it will already have sent the list
- * of supported auth types before seeing the NEW-ENVIRON option. If
- * you change the code to hold off sending the list of supported auth
- * types until after it knows whether or not the remote side supports
- * NEW-ENVIRON, then the auth negotiation and encryption negotiation
- * race conditions won't interact properly, and encryption negotiation
- * will reliably fail.
- */
-
- void
-ttsuck()
-{
- extern int auth_client_non_unix;
- int nread;
- struct timeval tv;
- fd_set fds;
- char *p, match[] = {IAC, WILL, TELOPT_NEW_ENVIRON};
-
- if (nfrontp-nbackp) {
- netflush();
- }
- tv.tv_sec = 1;
- tv.tv_usec = 0;
- FD_SET(net, &fds);
-
- while (select(net + 1, &fds, NULL, NULL, &tv) == 1)
- {
- nread = read(net, netibuf + ncc, sizeof(netibuf) - ncc);
- if (nread <= 0)
- break;
- ncc += nread;
- }
-
- auth_client_non_unix = 1;
- for (p = netibuf; p < netibuf + ncc; p++)
- {
- if (!memcmp(p, match, sizeof(match)))
- {
- auth_client_non_unix = 0;
- break;
- }
- }
-
- if (ncc > 0)
- telrcv();
-}
-
-/*
- * Check a descriptor to see if out of band data exists on it.
- */
- int
-stilloob(s)
- int s; /* socket number */
-{
- static struct timeval timeout = { 0 };
- fd_set excepts;
- int value;
-
- do {
- FD_ZERO(&excepts);
- FD_SET(s, &excepts);
- value = select(s+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout);
- } while ((value == -1) && (errno == EINTR));
-
- if (value < 0) {
- fatalperror(pty, "select");
- }
- if (FD_ISSET(s, &excepts)) {
- return 1;
- } else {
- return 0;
- }
-}
-
- void
-ptyflush()
-{
- int n;
-
- if ((n = pfrontp - pbackp) > 0) {
- DIAG((TD_REPORT | TD_PTYDATA),
- netprintf("td: ptyflush %d chars\r\n", n));
- DIAG(TD_PTYDATA, printdata("pd", pbackp, n));
- n = write(pty, pbackp, (unsigned) n);
- }
- if (n < 0) {
- if (errno == EWOULDBLOCK || errno == EINTR)
- return;
- (void)signal(SIGCHLD, SIG_DFL);
- cleanup(0);
- }
- pbackp += n;
- if (pbackp == pfrontp)
- pbackp = pfrontp = ptyobuf;
-}
-
-/*
- * nextitem()
- *
- * Return the address of the next "item" in the TELNET data
- * stream. This will be the address of the next character if
- * the current address is a user data character, or it will
- * be the address of the character following the TELNET command
- * if the current address is a TELNET IAC ("I Am a Command")
- * character.
- */
-static char *
-nextitem(current)
- char *current;
-{
- if ((*current&0xff) != IAC) {
- return current+1;
- }
- switch (*(current+1)&0xff) {
- case DO:
- case DONT:
- case WILL:
- case WONT:
- return current+3;
- case SB: /* loop forever looking for the SE */
- {
- register char *look = current+2;
-
- for (;;) {
- if ((*look++&0xff) == IAC) {
- if ((*look++&0xff) == SE) {
- return look;
- }
- }
- }
- }
- default:
- return current+2;
- }
-} /* end of nextitem */
-
-
-/*
- * netclear()
- *
- * We are about to do a TELNET SYNCH operation. Clear
- * the path to the network.
- *
- * Things are a bit tricky since we may have sent the first
- * byte or so of a previous TELNET command into the network.
- * So, we have to scan the network buffer from the beginning
- * until we are up to where we want to be.
- *
- * A side effect of what we do, just to keep things
- * simple, is to clear the urgent data pointer. The principal
- * caller should be setting the urgent data pointer AFTER calling
- * us in any case.
- */
- void
-netclear()
-{
- register char *thisitem, *next;
- char *good;
-#define wewant(p) ((nfrontp > p) && ((*p&0xff) == IAC) && \
- ((*(p+1)&0xff) != EC) && ((*(p+1)&0xff) != EL))
-
-#ifdef ENCRYPTION
- thisitem = nclearto > netobuf ? nclearto : netobuf;
-#else /* ENCRYPTION */
- thisitem = netobuf;
-#endif /* ENCRYPTION */
-
- while ((next = nextitem(thisitem)) <= nbackp) {
- thisitem = next;
- }
-
- /* Now, thisitem is first before/at boundary. */
-
-#ifdef ENCRYPTION
- good = nclearto > netobuf ? nclearto : netobuf;
-#else /* ENCRYPTION */
- good = netobuf; /* where the good bytes go */
-#endif /* ENCRYPTION */
-
- while (nfrontp > thisitem) {
- if (wewant(thisitem)) {
- unsigned int length;
-
- next = thisitem;
- do {
- next = nextitem(next);
- } while (wewant(next) && (nfrontp > next));
- length = next-thisitem;
- memcpy(good, thisitem, length);
- good += length;
- thisitem = next;
- } else {
- thisitem = nextitem(thisitem);
- }
- }
-
- nbackp = netobuf;
- nfrontp = good; /* next byte to be sent */
- neturg = 0;
-} /* end of netclear */
-
-/*
- * netflush
- * Send as much data as possible to the network,
- * handling requests for urgent data.
- */
-void
-netflush()
-{
- int n;
- extern int not42;
-
- if ((n = nfrontp - nbackp) > 0) {
- DIAG(TD_REPORT, {netprintf_noflush("td: netflush %d chars\r\n", n);
- n = nfrontp - nbackp;});
-#ifdef ENCRYPTION
- if (encrypt_output) {
- char *s = nclearto ? nclearto : nbackp;
- if (nfrontp - s > 0) {
- (*encrypt_output)((unsigned char *)s, nfrontp-s);
- nclearto = nfrontp;
- }
- }
-#endif /* ENCRYPTION */
- /*
- * if no urgent data, or if the other side appears to be an
- * old 4.2 client (and thus unable to survive TCP urgent data),
- * write the entire buffer in non-OOB mode.
- */
- if ((neturg == 0) || (not42 == 0)) {
- n = write(net, nbackp, (unsigned) n); /* normal write */
- } else {
- n = neturg - nbackp;
- /*
- * In 4.2 (and 4.3) systems, there is some question about
- * what byte in a sendOOB operation is the "OOB" data.
- * To make ourselves compatible, we only send ONE byte
- * out of band, the one WE THINK should be OOB (though
- * we really have more the TCP philosophy of urgent data
- * rather than the Unix philosophy of OOB data).
- */
- if (n > 1) {
- n = send(net, nbackp, n-1, 0); /* send URGENT all by itself */
- } else {
- n = send(net, nbackp, n, MSG_OOB); /* URGENT data */
- }
- }
- }
- if (n < 0) {
- if (errno == EWOULDBLOCK || errno == EINTR)
- return;
- (void)signal(SIGCHLD, SIG_DFL);
- cleanup(0);
- }
- nbackp += n;
-#ifdef ENCRYPTION
- if (nbackp > nclearto)
- nclearto = 0;
-#endif /* ENCRYPTION */
- if (nbackp >= neturg) {
- neturg = 0;
- }
- if (nbackp == nfrontp) {
- nbackp = nfrontp = netobuf;
-#ifdef ENCRYPTION
- nclearto = 0;
-#endif /* ENCRYPTION */
- }
- return;
-} /* end of netflush */
-
-/*
- * L8_256(x) = log8(256**x), rounded up, including sign (for decimal
- * strings too). log8(256) = 8/3, but we use integer math to round
- * up.
- */
-#define L8_256(x) (((x * 8 + 2) / 3) + 1)
-
-/*
- * netprintf
- *
- * Do the equivalent of printf() to the NETOBUF "ring buffer",
- * possibly calling netflush() if needed.
- *
- * Thou shalt not call this with a "%s" format; use netputs instead.
- * We also don't deal with floating point widths in here.
- */
-static void
-netprintf_ext(int noflush, int seturg, const char *fmt, va_list args)
-#if !defined(__cplusplus) && (__GNUC__ > 2)
- __attribute__((__format__(__printf__, 3, 0)))
-#endif
- ;
-
-static void
-netprintf_ext(int noflush, int seturg, const char *fmt, va_list args)
-{
- size_t remain;
- size_t maxoutlen;
- char buf[BUFSIZ];
- const char *cp;
- int len;
-
- buf[0] = '\0'; /* nul-terminate */
- remain = sizeof(netobuf) - (nfrontp - netobuf);
- for (maxoutlen = 0, cp = fmt; *cp; cp++) {
- if (*cp == '%')
- /* Ok so this is slightly overkill... */
- maxoutlen += L8_256(sizeof(long));
- else
- maxoutlen++;
- }
- if (maxoutlen >= sizeof(buf))
- return; /* highly unlikely */
-
- len = vsnprintf(buf, sizeof(buf), fmt, args);
-
- /*
- * The return value from sprintf()-like functions may be the
- * number of characters that *would* have been output, not the
- * number actually output.
- */
- if (len <= 0 || len > sizeof(buf))
- return;
- if (remain < len && !noflush) {
- netflush();
- remain = sizeof(netobuf) - (nfrontp - netobuf);
- }
- if (remain < len)
- return; /* still not enough space? */
- memcpy(nfrontp, buf, (size_t)len);
- nfrontp += len;
- if (seturg)
- neturg = nfrontp - 1;
-}
-
-void
-netprintf(const char *fmt, ...)
-{
- va_list args;
-
- va_start(args, fmt);
- netprintf_ext(0, 0, fmt, args);
- va_end(args);
-}
-
-void
-netprintf_urg(const char *fmt, ...)
-{
- va_list args;
-
- va_start(args, fmt);
- netprintf_ext(0, 1, fmt, args);
- va_end(args);
-}
-
-void
-netprintf_noflush(const char *fmt, ...)
-{
- va_list args;
-
- va_start(args, fmt);
- netprintf_ext(1, 0, fmt, args);
- va_end(args);
-}
-
-/*
- * netwrite
- *
- * Copy BUF into the NETOBUF "ring buffer", possibly calling
- * netflush() if needed.
- */
-int
-netwrite(const unsigned char *buf, size_t len)
-{
- size_t remain;
-
- remain = sizeof(netobuf) - (nfrontp - netobuf);
- if (remain < len) {
- netflush();
- remain = sizeof(netobuf) - (nfrontp - netobuf);
- }
- if (remain < len)
- return 0;
- memcpy(nfrontp, buf, len);
- nfrontp += len;
- return len;
-}
-
-/*
- * netputs
- *
- * Write S to the NETOBUF "ring buffer". Does not write a '\n'.
- */
-void
-netputs(const char *s)
-{
- netwrite((const unsigned char *) s, strlen(s));
-}
-
-/*
- * miscellaneous functions doing a variety of little jobs follow ...
- */
-
-
- void
-fatal(f, msg)
- int f;
- const char *msg;
-{
- char buf[BUFSIZ];
-
- (void) snprintf(buf, sizeof(buf), "telnetd: %s.\r\n", msg);
-#ifdef ENCRYPTION
- if (encrypt_output) {
- /*
- * Better turn off encryption first....
- * Hope it flushes...
- */
- encrypt_send_end();
- netflush();
- }
-#endif /* ENCRYPTION */
- (void) write(f, buf, strlen(buf));
- sleep(1); /*XXX*/
- exit(1);
-}
-
- void
-fatalperror(f, msg)
- int f;
- const char *msg;
-{
- char buf[BUFSIZ], *strerror();
-
- (void) snprintf(buf, sizeof(buf), "%s: %s\r\n", msg, strerror(errno));
- fatal(f, buf);
-}
-
-char editedhost[32];
-
- void
-edithost(pat, host)
- register char *pat;
- register char *host;
-{
- register char *res = editedhost;
-
- if (!pat)
- pat = "";
- while (*pat) {
- switch (*pat) {
-
- case '#':
- if (*host)
- host++;
- break;
-
- case '@':
- if (*host)
- *res++ = *host++;
- break;
-
- default:
- *res++ = *pat;
- break;
- }
- if (res == &editedhost[sizeof editedhost - 1]) {
- *res = '\0';
- return;
- }
- pat++;
- }
- if (*host)
- (void) strncpy(res, host,
- sizeof editedhost - (res - editedhost) -1);
- else
- *res = '\0';
- editedhost[sizeof editedhost - 1] = '\0';
-}
-
-static char *putlocation;
-
-static void
-putstr(s)
- register char *s;
-{
-
- while (*s)
- putchr(*s++);
-}
-
- void
-putchr(cc)
- int cc;
-{
- *putlocation++ = cc;
-}
-
-/*
- * This is split on two lines so that SCCS will not see the M
- * between two % signs and expand it...
- */
-static char fmtstr[] = { "%l:%M\
-%P on %A, %d %B %Y" };
-
- void
-putf(cp, where)
- register char *cp;
- char *where;
-{
- char *slash;
- time_t t;
- char db[100];
-#ifdef HAVE_SYS_UTSNAME_H
- struct utsname utsinfo;
-
- (void) uname(&utsinfo);
-#endif
-
- putlocation = where;
-
- while (*cp) {
- if (*cp != '%') {
- putchr(*cp++);
- continue;
- }
- switch (*++cp) {
-
- case 't':
-#ifdef STREAMSPTY
- /* names are like /dev/pts/2 -- we want pts/2 */
- slash = strchr(line+1, '/');
-#else
- slash = strrchr(line, '/');
-#endif
- if (slash == (char *) 0)
- putstr(line);
- else
- putstr(&slash[1]);
- break;
-
- case 'h':
- putstr(editedhost);
- break;
-
- case 'd':
- (void)time(&t);
- (void)strftime(db, sizeof(db), fmtstr, localtime(&t));
- putstr(db);
- break;
-
-#ifdef HAVE_SYS_UTSNAME_H
- case 's':
- putstr(utsinfo.sysname);
- break;
-
- case 'm':
- putstr(utsinfo.machine);
- break;
-
- case 'r':
- putstr(utsinfo.release);
- break;
-
- case 'v':
- putstr(utsinfo.version);
- break;
-#endif
-
- case '%':
- putchr('%');
- break;
- }
- cp++;
- }
-}
-
-#ifdef DIAGNOSTICS
-/*
- * Print telnet options and commands in plain text, if possible.
- */
-void
-printoption(fmt, option)
- register char *fmt;
- register int option;
-{
- netputs(fmt);
- netputs(" ");
- if (TELOPT_OK(option)) {
- netputs(TELOPT(option));
- netputs("\r\n");
- } else if (TELCMD_OK(option)) {
- netputs(TELCMD(option));
- netputs("\r\n");
- } else {
- netprintf("%d\r\n", option);
- }
- return;
-}
-
-void
-printsub(direction, pointer, length)
- char direction; /* '<' or '>' */
- unsigned char *pointer; /* where suboption data sits */
- int length; /* length of suboption data */
-{
- register int i = 0;
- char buf[512];
-
- if (!(diagnostic & TD_OPTIONS))
- return;
-
- if (direction) {
- netputs("td: ");
- netputs(direction == '<' ? "recv" : "send");
- netputs(" suboption ");
- if (length >= 3) {
- register int j;
-
- i = pointer[length-2];
- j = pointer[length-1];
-
- if (i != IAC || j != SE) {
- netputs("(terminated by ");
- if (TELOPT_OK(i))
- netputs(TELOPT(i));
- else if (TELCMD_OK(i))
- netputs(TELCMD(i));
- else
- netprintf("%d", i);
- netputs(" ");
- if (TELOPT_OK(j))
- netputs(TELOPT(j));
- else if (TELCMD_OK(j))
- netputs(TELCMD(j));
- else
- netprintf("%d", j);
- netputs(", not IAC SE!) ");
- }
- }
- length -= 2;
- }
- if (length < 1) {
- netputs("(Empty suboption??\?)");
- return;
- }
- switch (pointer[0]) {
- case TELOPT_TTYPE:
- netputs("TERMINAL-TYPE ");
- switch (pointer[1]) {
- case TELQUAL_IS:
- netputs("IS \"");
- netwrite(pointer + 2, (size_t)(length - 2));
- netputs("\"");
- break;
- case TELQUAL_SEND:
- netputs("SEND");
- break;
- default:
- netprintf("- unknown qualifier %d (0x%x).",
- pointer[1], pointer[1]);
- }
- break;
- case TELOPT_TSPEED:
- netputs("TERMINAL-SPEED ");
- if (length < 2) {
- netputs("(empty suboption??\?)");
- break;
- }
- switch (pointer[1]) {
- case TELQUAL_IS:
- netputs("IS ");
- netwrite(pointer + 2, (size_t)(length - 2));
- break;
- default:
- if (pointer[1] == 1)
- netputs("SEND");
- else
- netprintf("%d (unknown)", pointer[1]);
- for (i = 2; i < length; i++)
- netprintf(" ?%d?", pointer[i]);
- break;
- }
- break;
-
- case TELOPT_LFLOW:
- netputs("TOGGLE-FLOW-CONTROL ");
- if (length < 2) {
- netputs("(empty suboption??\?)");
- break;
- }
- switch (pointer[1]) {
- case LFLOW_OFF:
- netputs("OFF"); break;
- case LFLOW_ON:
- netputs("ON"); break;
- case LFLOW_RESTART_ANY:
- netputs("RESTART-ANY"); break;
- case LFLOW_RESTART_XON:
- netputs("RESTART-XON"); break;
- default:
- netprintf("%d (unknown)", pointer[1]);
- }
- for (i = 2; i < length; i++)
- netprintf(" ?%d?", pointer[i]);
- break;
-
- case TELOPT_NAWS:
- netputs("NAWS");
- if (length < 2) {
- netputs(" (empty suboption??\?)");
- break;
- }
- if (length == 2) {
- netprintf(" ?%d?", pointer[1]);
- break;
- }
- netprintf(" %d %d (%d)",
- pointer[1], pointer[2],
- (int)((((unsigned int)pointer[1])<<8)|((unsigned int)pointer[2])));
- if (length == 4) {
- netprintf(" ?%d?", pointer[3]);
- break;
- }
- netprintf(" %d %d (%d)",
- pointer[3], pointer[4],
- (int)((((unsigned int)pointer[3])<<8)|((unsigned int)pointer[4])));
- for (i = 5; i < length; i++)
- netprintf(" ?%d?", pointer[i]);
- break;
-
- case TELOPT_LINEMODE:
- netputs("LINEMODE ");
- if (length < 2) {
- netputs("(empty suboption??\?)");
- break;
- }
- switch (pointer[1]) {
- case WILL:
- netputs("WILL ");
- goto common;
- case WONT:
- netputs("WONT ");
- goto common;
- case DO:
- netputs("DO ");
- goto common;
- case DONT:
- netputs("DONT ");
- common:
- if (length < 3) {
- netputs("(no option??\?)");
- break;
- }
- switch (pointer[2]) {
- case LM_FORWARDMASK:
- netputs("Forward Mask");
- for (i = 3; i < length; i++)
- netprintf(" %x", pointer[i]);
- break;
- default:
- netprintf("%d (unknown)", pointer[2]);
- for (i = 3; i < length; i++)
- netprintf(" %d", pointer[i]);
- break;
- }
- break;
-
- case LM_SLC:
- netputs("SLC");
- for (i = 2; i < length - 2; i += 3) {
- if (SLC_NAME_OK(pointer[i+SLC_FUNC])) {
- netputs(" ");
- netputs(SLC_NAME(pointer[i+SLC_FUNC]));
- } else
- netprintf(" %d", pointer[i+SLC_FUNC]);
- switch (pointer[i+SLC_FLAGS]&SLC_LEVELBITS) {
- case SLC_NOSUPPORT:
- netputs(" NOSUPPORT"); break;
- case SLC_CANTCHANGE:
- netputs(" CANTCHANGE"); break;
- case SLC_VARIABLE:
- netputs(" VARIABLE"); break;
- case SLC_DEFAULT:
- netputs(" DEFAULT"); break;
- }
- netputs(pointer[i+SLC_FLAGS]&SLC_ACK
- ? "|ACK" : "");
- netputs(pointer[i+SLC_FLAGS]&SLC_FLUSHIN
- ? "|FLUSHIN" : "");
- netputs(pointer[i+SLC_FLAGS]&SLC_FLUSHOUT
- ? "|FLUSHOUT" : "");
- if (pointer[i+SLC_FLAGS]& ~(SLC_ACK|SLC_FLUSHIN|
- SLC_FLUSHOUT| SLC_LEVELBITS)) {
- netprintf("(0x%x)", pointer[i+SLC_FLAGS]);
- }
- netprintf(" %d;", pointer[i+SLC_VALUE]);
- if ((pointer[i+SLC_VALUE] == IAC) &&
- (pointer[i+SLC_VALUE+1] == IAC))
- i++;
- }
- for (; i < length; i++)
- netprintf(" ?%d?", pointer[i]);
- break;
-
- case LM_MODE:
- netputs("MODE ");
- if (length < 3) {
- netputs("(no mode??\?)");
- break;
- }
- {
- int wrotemode = 0;
-
-#define NETPUTS_MODE(x) \
-do { \
- if (pointer[2] & (MODE_##x)) { \
- if (wrotemode) netputs("|"); \
- netputs(#x); \
- wrotemode++; \
- } \
-} while (0)
- NETPUTS_MODE(EDIT);
- NETPUTS_MODE(TRAPSIG);
- NETPUTS_MODE(SOFT_TAB);
- NETPUTS_MODE(LIT_ECHO);
- NETPUTS_MODE(ACK);
-#undef NETPUTS_MODE
- if (!wrotemode)
- netputs("0");
- }
- if (pointer[2] & ~(MODE_EDIT|MODE_TRAPSIG|MODE_ACK))
- netprintf(" (0x%x)", pointer[2]);
- for (i = 3; i < length; i++)
- netprintf(" ?0x%x?", pointer[i]);
- break;
- default:
- netprintf("%d (unknown)", pointer[1]);
- for (i = 2; i < length; i++)
- netprintf(" %d", pointer[i]);
- }
- break;
-
- case TELOPT_STATUS: {
- register char *cp;
- register int j, k;
-
- netputs("STATUS");
-
- switch (pointer[1]) {
- default:
- if (pointer[1] == TELQUAL_SEND)
- netputs(" SEND");
- else
- netprintf(" %d (unknown)", pointer[1]);
- for (i = 2; i < length; i++)
- netprintf(" ?%d?", pointer[i]);
- break;
- case TELQUAL_IS:
- netputs(" IS\r\n");
-
- for (i = 2; i < length; i++) {
- switch(pointer[i]) {
- case DO: cp = "DO"; goto common2;
- case DONT: cp = "DONT"; goto common2;
- case WILL: cp = "WILL"; goto common2;
- case WONT: cp = "WONT"; goto common2;
- common2:
- i++;
- netputs(" ");
- netputs(cp);
- netputs(" ");
- if (TELOPT_OK(pointer[i]))
- netputs(TELOPT(pointer[i]));
- else
- netprintf("%d", pointer[i]);
-
- netputs("\r\n");
- break;
-
- case SB:
- netputs(" SB ");
- i++;
- j = k = i;
- while (j < length) {
- if (pointer[j] == SE) {
- if (j+1 == length)
- break;
- if (pointer[j+1] == SE)
- j++;
- else
- break;
- }
- pointer[k++] = pointer[j++];
- }
- printsub(0, &pointer[i], k - i);
- if (i < length) {
- netputs(" SE");
- i = j;
- } else
- i = j - 1;
-
- netputs("\r\n");
-
- break;
-
- default:
- netprintf(" %d", pointer[i]);
- break;
- }
- }
- break;
- }
- break;
- }
-
- case TELOPT_XDISPLOC:
- netputs("X-DISPLAY-LOCATION ");
- switch (pointer[1]) {
- case TELQUAL_IS:
- netputs("IS \"");
- netwrite(pointer + 2, (size_t)(length - 2));
- netputs("\"");
- break;
- case TELQUAL_SEND:
- netputs("SEND");
- break;
- default:
- netprintf("- unknown qualifier %d (0x%x).",
- pointer[1], pointer[1]);
- }
- break;
-
- case TELOPT_NEW_ENVIRON:
- netputs("NEW-ENVIRON ");
- goto env_common1;
- case TELOPT_OLD_ENVIRON:
- netputs("OLD-ENVIRON ");
- env_common1:
- switch (pointer[1]) {
- case TELQUAL_IS:
- netputs("IS ");
- goto env_common;
- case TELQUAL_SEND:
- netputs("SEND ");
- goto env_common;
- case TELQUAL_INFO:
- netputs("INFO ");
- env_common:
- {
- register int noquote = 2;
- for (i = 2; i < length; i++ ) {
- switch (pointer[i]) {
- case NEW_ENV_VAR:
- netputs("\" VAR " + noquote);
- noquote = 2;
- break;
-
- case NEW_ENV_VALUE:
- netputs("\" VALUE " + noquote);
- noquote = 2;
- break;
-
- case ENV_ESC:
- netputs("\" ESC " + noquote);
- noquote = 2;
- break;
-
- case ENV_USERVAR:
- netputs("\" USERVAR " + noquote);
- noquote = 2;
- break;
-
- default:
- if (isprint(pointer[i]) && pointer[i] != '"') {
- if (noquote) {
- netputs("\"");
- noquote = 0;
- }
- netprintf("%c", pointer[i]);
- } else {
- netprintf("\" %03o " + noquote,
- pointer[i]);
- noquote = 2;
- }
- break;
- }
- }
- if (!noquote)
- netputs("\"");
- break;
- }
- }
- break;
-
-#if defined(AUTHENTICATION)
- case TELOPT_AUTHENTICATION:
- netputs("AUTHENTICATION");
-
- if (length < 2) {
- netputs(" (empty suboption??\?)");
- break;
- }
- switch (pointer[1]) {
- case TELQUAL_REPLY:
- case TELQUAL_IS:
- netputs((pointer[1] == TELQUAL_IS) ? " IS " : " REPLY ");
- if (AUTHTYPE_NAME_OK(pointer[2]))
- netputs(AUTHTYPE_NAME(pointer[2]));
- else
- netprintf(" %d ", pointer[2]);
- if (length < 3) {
- netputs("(partial suboption??\?)");
- break;
- }
- netputs(((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT)
- ? "CLIENT|" : "SERVER|");
- netputs(((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL)
- ? "MUTUAL" : "ONE-WAY");
- netputs(((pointer[3] & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_ON)
- ? "|ENCRYPT" : "");
-
- auth_printsub(&pointer[1], length - 1, (unsigned char *)buf,
- sizeof(buf));
- netputs(buf);
- break;
-
- case TELQUAL_SEND:
- i = 2;
- netputs(" SEND ");
- while (i < length) {
- if (AUTHTYPE_NAME_OK(pointer[i]))
- netputs(AUTHTYPE_NAME(pointer[i]));
- else
- netprintf("%d", pointer[i]);
- netputs(" ");
- if (++i >= length) {
- netputs("(partial suboption??\?)");
- break;
- }
- netputs(((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT)
- ? "CLIENT|" : "SERVER|");
- netputs(((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL)
- ? "MUTUAL" : "ONE-WAY");
- if ((pointer[3] & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_ON)
- netputs("|ENCRYPT");
- ++i;
- }
- break;
-
- case TELQUAL_NAME:
- i = 2;
- netputs(" NAME \"");
- while (i < length) {
- if (isprint(pointer[i]))
- netprintf("%c", pointer[i++]);
- else {
- netprintf("\\%03o", pointer[i++]);
- }
- }
- netputs("\"");
- break;
-
- default:
- for (i = 2; i < length; i++)
- netprintf(" ?%d?", pointer[i]);
- break;
- }
- break;
-#endif
-
-#ifdef ENCRYPTION
- case TELOPT_ENCRYPT:
- netputs("ENCRYPT");
- if (length < 2) {
- netputs(" (empty suboption??\?)");
- break;
- }
- switch (pointer[1]) {
- case ENCRYPT_START:
- netputs(" START");
- break;
-
- case ENCRYPT_END:
- netputs(" END");
- break;
-
- case ENCRYPT_REQSTART:
- netputs(" REQUEST-START");
- break;
-
- case ENCRYPT_REQEND:
- netputs(" REQUEST-END");
- break;
-
- case ENCRYPT_IS:
- case ENCRYPT_REPLY:
- netputs((pointer[1] == ENCRYPT_IS)
- ? " IS " : " REPLY ");
- if (length < 3) {
- netputs(" (partial suboption??\?)");
- nfrontp += strlen(nfrontp);
- break;
- }
- if (ENCTYPE_NAME_OK(pointer[2]))
- netputs(ENCTYPE_NAME(pointer[2]));
- else
- netprintf("%d (unknown)", pointer[2]);
- netputs(" ");
-
- encrypt_printsub(&pointer[1], length - 1,
- (unsigned char *) buf, sizeof(buf));
- netputs(buf);
- break;
-
- case ENCRYPT_SUPPORT:
- i = 2;
- netputs(" SUPPORT ");
- nfrontp += strlen(nfrontp);
- while (i < length) {
- if (ENCTYPE_NAME_OK(pointer[i]))
- netputs(ENCTYPE_NAME(pointer[i]));
- else
- netprintf("%d", pointer[i]);
- netputs(" ");
- i++;
- }
- break;
-
- case ENCRYPT_ENC_KEYID:
- netputs(" ENC_KEYID");
- goto encommon;
-
- case ENCRYPT_DEC_KEYID:
- netputs(" DEC_KEYID");
- goto encommon;
-
- default:
- netprintf(" %d (unknown)", pointer[1]);
- encommon:
- for (i = 2; i < length; i++)
- netprintf(" %d", pointer[i]);
- break;
- }
- break;
-#endif /* ENCRYPTION */
-
- default:
- if (TELOPT_OK(pointer[0]))
- netputs(TELOPT(pointer[0]));
- else
- netprintf("%d", pointer[0]);
- netputs(" (unknown)");
- for (i = 1; i < length; i++)
- netprintf(" %d", pointer[i]);
- break;
- }
- netputs("\r\n");
-}
-
-/*
- * Dump a data buffer in hex and ascii to the output data stream.
- */
- void
-printdata(tag, ptr, cnt)
- register char *tag;
- register char *ptr;
- register int cnt;
-{
- register int i;
- char xbuf[30];
-
- while (cnt) {
- /* add a line of output */
- netputs(tag);
- netputs(": ");
- for (i = 0; i < 20 && cnt; i++) {
- netprintf(nfrontp, "%02x", *ptr);
- nfrontp += strlen(nfrontp);
- if (isprint((int) *ptr)) {
- xbuf[i] = *ptr;
- } else {
- xbuf[i] = '.';
- }
- if (i % 2)
- netputs(" ");
- cnt--;
- ptr++;
- }
- xbuf[i] = '\0';
- netputs(" ");
- netputs(xbuf);
- netputs("\r\n");
- }
-}
-#endif /* DIAGNOSTICS */
AC_DEFINE(BROKEN_STREAMS_SOCKETS,1,[Define if socket can't be bound to 0.0.0.0])
fi
-AC_CONFIG_SUBDIRS(appl/libpty appl/bsd appl/gssftp appl/telnet)
-
AC_CONFIG_FILES(krb5-config, [chmod +x krb5-config])
V5_AC_OUTPUT_MAKEFILE(.
+++ /dev/null
-# Kerberos rlogin test.
-# This is a DejaGnu test script.
-# This script tests Kerberos rlogin.
-# Written by Ian Lance Taylor, Cygnus Support, <ian@cygnus.com>.
-
-# Find the programs we need. We use the binaries from the build tree
-# if they exist. If they do not, then they must be in PATH. We
-# expect $objdir to be .../kerberos/src.
-
-if ![info exists KRLOGIN] {
- set KRLOGIN [findfile $objdir/../../appl/bsd/rlogin]
-}
-
-if ![info exists KRLOGIND] {
- set KRLOGIND [findfile $objdir/../../appl/bsd/klogind]
-}
-
-if ![info exists LOGINKRB5] {
- set LOGINKRB5 [findfile $objdir/../../appl/bsd/login.krb5]
-}
-
-# Start up a root shell.
-if ![setup_root_shell rlogin] {
- return
-}
-
-# Make sure .k5login is reasonable.
-if ![check_k5login rlogin] {
- stop_root_shell
- return
-}
-
-# Set up the kerberos database.
-if {![get_hostname] \
- || ![setup_kerberos_files] \
- || ![setup_kerberos_env] \
- || ![setup_kerberos_db 0]} {
- stop_root_shell
- return
-}
-
-# A procedure to start up the rlogin daemon.
-
-proc start_rlogin_daemon { option } {
- global REALMNAME
- global KRLOGIND
- global LOGINKRB5
- global ROOT_PROMPT
- global tmppwd
- global hostname
- global rlogin_spawn_id
- global krlogind_pid
- global portbase
-
- # The -p argument tells it to accept a single connection, so we
- # don't need to use inetd. The 3543 is the port to listen at.
- # Note that tmppwd here is a shell variable, which is set in
- # setup_root_shell, not a TCL variable. The sh -c is to workaround
- # the broken controlling tty handling in hpux, and shouldn't hurt
- # anything else.
- send -i $rlogin_spawn_id "sh -c \"$KRLOGIND -k -c -D [expr 8 + $portbase] -S \$tmppwd/srvtab -M $REALMNAME -L $LOGINKRB5 $option\" &\r"
- expect {
- -i $rlogin_spawn_id
- -re "$ROOT_PROMPT" { }
- timeout {
- send_error "ERROR: timeout from rlogin $hostname -l root\n"
- return
- }
- eof {
- send_error "ERROR: eof from rlogin $hostname -l root\n"
- return
- }
- }
- send -i $rlogin_spawn_id "echo \$!\r"
- expect {
- -i $rlogin_spawn_id
- -re "\[0-9\]+" {
- set krlogind_pid $expect_out(0,string)
- verbose "krlogind process ID is $krlogind_pid"
- }
- timeout {
- send_error "ERROR: timeout from rlogin $hostname -l root\n"
- return
- }
- eof {
- send_error "ERROR: eof from rlogin $hostname -l root\n"
- return
- }
- }
- expect {
- -i $rlogin_spawn_id
- -re "$ROOT_PROMPT" { }
- timeout {
- send_error "ERROR: timeout from rlogin $hostname -l root\n"
- return
- }
- eof {
- send_error "ERROR: eof from rlogin $hostname -l root\n"
- return
- }
- }
-
- # Give the rlogin daemon a few seconds to get set up.
- sleep 2
-}
-
-# A procedure to stop the rlogin daemon.
-
-proc stop_rlogin_daemon { } {
- global krlogind_pid
-
- if [info exists krlogind_pid] {
- catch "exec kill $krlogind_pid"
- unset krlogind_pid
- }
-}
-
-# Wrap the tests in a procedure, so that we can kill the daemons if
-# we get some sort of error.
-
-proc rlogin_test { } {
- global REALMNAME
- global KRLOGIN
- global BINSH
- global SHELL_PROMPT
- global KEY
- global hostname
- global hostname
- global env
- global portbase
-
- # Start up the kerberos and kadmind daemons and get a srvtab and a
- # ticket file.
- if {![start_kerberos_daemons 0] \
- || ![add_kerberos_key host/$hostname 0] \
- || ![setup_srvtab 0] \
- || ![add_kerberos_key $env(USER) 0] \
- || ![kinit $env(USER) $env(USER)$KEY 0]} {
- return
- }
-
- # Start up the rlogin daemon.
- start_rlogin_daemon -k
-
- # Make an rlogin connection.
- spawn $KRLOGIN $hostname -k $REALMNAME -D [expr 8 + $portbase]
-
- expect_after {
- timeout {
- fail "$testname (timeout)"
- catch "expect_after"
- return
- }
- "onnection closed." {
- fail "$testname (connection closed)"
- catch "expect_after"
- return
- }
- eof {
- fail "$testname (eof)"
- catch "expect_after"
- return
- }
- }
-
- set testname "rlogin"
- expect {
- -re "$SHELL_PROMPT" {
- pass $testname
- }
- }
-
- # Switch to /bin/sh to try to avoid confusion from the shell
- # prompt.
- set testname "shell"
- send "$BINSH\r"
- expect "$BINSH"
- expect -re "$SHELL_PROMPT"
-
- set testname "date"
- send "date\r"
- expect "date"
- expect {
- -re "\[A-Za-z0-9 :\]+\[\r\n\]+" {
- if [check_date $expect_out(0,string)] {
- pass "date"
- } else {
- fail "date"
- }
- }
- }
- expect -re "$SHELL_PROMPT"
-
- set testname "exit"
- send "exit\r"
- expect -re "$SHELL_PROMPT"
- send "exit\r"
- expect {
- "onnection closed." {
- pass $testname
- }
- }
- # This last expect seems useless, but without it the rlogin process
- # sometimes hangs on HP-UX, in a tcsetattr call with TCSADRAIN.
- expect {
- "\r" { }
- }
-
- expect_after
-
- if [check_exit_status "exit status"] {
- pass "exit status"
- }
-
- # The rlogin daemon should have stopped, but we have no easy way
- # of checking whether it actually did. Kill it just in case.
- stop_rlogin_daemon
-
- # Try an encrypted connection.
- start_rlogin_daemon -e
- spawn $KRLOGIN $hostname -x -k $REALMNAME -D [expr 8 + $portbase]
-
- expect_after {
- timeout {
- fail "$testname (timeout)"
- catch "expect_after"
- return
- }
- "onnection closed" {
- fail "$testname (connection closed)"
- catch "expect_after"
- return
- }
- eof {
- fail "$testname (eof)"
- catch "expect_after"
- return
- }
- }
-
- set testname "encrypted rlogin"
- expect -re "encrypting .* transmissions"
- expect {
- -re "$SHELL_PROMPT" {
- pass $testname
- }
- }
-
- # Switch to /bin/sh to try to avoid confusion from the shell
- # prompt.
- set testname "shell"
- send "$BINSH\r"
- expect "$BINSH"
- expect -re "$SHELL_PROMPT"
-
- # Make sure the encryption is not destroying the text.
- set testname "echo"
- send "echo hello\r"
- expect "echo hello"
- expect "hello"
- expect {
- -re "$SHELL_PROMPT" {
- pass $testname
- }
- }
-
- # Send some characters which might cause an interrupt, and then
- # make sure we can still talk to the shell.
- set testname "interrupt characters"
- send "\003\177\034\r"
- expect -re "$SHELL_PROMPT"
- send "echo hello\r"
- expect "echo hello"
- expect "hello"
- expect {
- -re "$SHELL_PROMPT" {
- pass $testname
- }
- }
-
- set testname "~."
- send "~."
- expect {
- "Closed connection.\r" {
- pass $testname
- }
- "onnection closed" {
- pass $testname
- }
- }
-
- expect_after
-
- if [check_exit_status "exit status"] {
- pass "exit status"
- }
-
- # The rlogin daemon should have stopped, but we have no easy way
- # of checking whether it actually did. Kill it just in case.
- stop_rlogin_daemon
-}
-
-# Run the test. Logging in sometimes takes a while, so increase the
-# timeout.
-set oldtimeout $timeout
-set timeout 60
-set status [catch rlogin_test msg]
-set timeout $oldtimeout
-
-# Shut down the kerberos daemons, the rlogin daemon, and the root
-# process.
-stop_kerberos_daemons
-
-stop_rlogin_daemon
-
-stop_root_shell
-
-if { $status != 0 } {
- send_error "ERROR: error in rlogin.exp\n"
- send_error "$msg\n"
- exit 1
-}
+++ /dev/null
-# Kerberos telnet test.
-# This is a DejaGnu test script.
-# This script tests Kerberos telnet.
-# Written by Ian Lance Taylor, Cygnus Support, <ian@cygnus.com>.
-
-# Find the programs we need. We use the binaries from the build tree
-# if they exist. If they do not, then they must be in PATH. We
-# expect $objdir to be .../kerberos/src.
-
-if ![info exists TELNET] {
- set TELNET [findfile $objdir/../../appl/telnet/telnet/telnet]
-}
-
-if ![info exists TELNETD] {
- set TELNETD [findfile $objdir/../../appl/telnet/telnetd/telnetd]
-}
-
-if ![info exists LOGINKRB5] {
- set LOGINKRB5 [findfile $objdir/../../appl/bsd/login.krb5]
-}
-
-if ![regexp des- $supported_enctypes] {
- # Telnet needs a DES enctype.
- verbose "Skipping telnet tests for lack of DES support."
- return
-}
-
-# A procedure to start up the telnet daemon.
-
-proc start_telnet_daemon { args } {
- global REALMNAME
- global TELNETD
- global LOGINKRB5
- global ROOT_PROMPT
- global tmppwd
- global hostname
- global rlogin_spawn_id
- global telnetd_pid
- global portbase
-
- # Setup the shared library wrapper for login.krb5
- if ![file exists $tmppwd/login.wrap] {
- setup_wrapper $tmppwd/login.wrap "$LOGINKRB5 $*"
- }
-
- # The -debug argument tells it to accept a single connection, so
- # we don't need to use inetd. The portbase+8 is the port to listen at.
- # Note that tmppwd here is a shell variable, which is set in
- # setup_root_shell, not a TCL variable.
- send -i $rlogin_spawn_id "sh -c \"$TELNETD $args -debug -t \$tmppwd/srvtab -R $REALMNAME -L $tmppwd/login.wrap [expr 8 + $portbase]\" &\r"
- expect {
- -i $rlogin_spawn_id
- -re "$ROOT_PROMPT" { }
- timeout {
- send_error "ERROR: timeout from rlogin $hostname -l root\n"
- return
- }
- eof {
- send_error "ERROR: eof from rlogin $hostname -l root\n"
- return
- }
- }
- send -i $rlogin_spawn_id "echo \$!\r"
- expect {
- -i $rlogin_spawn_id
- -re "\[0-9\]+" {
- set telnetd_pid $expect_out(0,string)
- verbose "telnetd process ID is $telnetd_pid"
- }
- timeout {
- send_error "ERROR: timeout from rlogin $hostname -l root\n"
- return
- }
- eof {
- send_error "ERROR: eof from rlogin $hostname -l root\n"
- return
- }
- }
- expect {
- -i $rlogin_spawn_id
- -re "$ROOT_PROMPT" { }
- timeout {
- send_error "ERROR: timeout from rlogin $hostname -l root\n"
- return
- }
- eof {
- send_error "ERROR: eof from rlogin $hostname -l root\n"
- return
- }
- }
-
- # Give the telnet daemon a few seconds to get set up.
- sleep 2
-}
-
-# A procedure to stop the telnet daemon.
-
-proc stop_telnet_daemon { } {
- global telnetd_pid
-
- if [info exists telnetd_pid] {
- catch "exec kill $telnetd_pid"
- unset telnetd_pid
- }
-}
-
-# Wrap the tests in a procedure, so that we can kill the daemons if
-# we get some sort of error.
-
-proc telnet_test { } {
- global REALMNAME
- global TELNET
- global BINSH
- global SHELL_PROMPT
- global KEY
- global hostname
- global localhostname
- global env
- global portbase
-
- # Start up the kerberos and kadmind daemons and get a srvtab and a
- # ticket file.
- if {![start_kerberos_daemons 0] \
- || ![add_kerberos_key host/$hostname 0] \
- || ![setup_srvtab 0] \
- || ![add_kerberos_key $env(USER) 0] \
- || ![kinit $env(USER) $env(USER)$KEY 0]} {
- return
- }
-
- # Start up the telnet daemon.
- start_telnet_daemon
-
- # Start up our telnet connection. We first try it without
- # authentication, so the daemon should prompt for a login.
- spawn $TELNET -- $hostname -[expr 8 + $portbase]
- set telnet_pid [exp_pid]
-
- expect_after {
- timeout {
- fail "$testname (timeout)"
- catch "expect_after"
- return
- }
- eof {
- fail "$testname (eof)"
- catch "expect_after"
- return
- }
- }
-
- set testname "simple telnet"
- expect {
- "ogin: " {
- pass $testname
- }
- }
-
- # Move back to telnet command mode and make sure it seems
- # reasonable.
- set testname "telnet command mode"
- send "\035"
- expect {
- "telnet> " {
- pass $testname
- }
- }
-
- set testname "telnet status"
- send "status\r"
- # use -nocase because telnet may output the fqdn in upper-case;
- # however, -nocase requires the whole pattern to be in lower case
- expect {
- -nocase -re "connected to $localhostname.*operating in single character mode.*catching signals locally.*remote character echo.*flow control.*escape character is '.\]'" {
- pass $testname
- }
- }
-
- set testname "back to command mode"
-
- # For some reason, the telnet client doesn't necessarily reset the
- # terminal mode back to raw after exiting command mode.
- # Kick it somewhat by sending a CR.
- send "\r"
- expect "ogin: "
-
- send "\035"
- expect {
- "telnet> " {
- pass $testname
- }
- }
-
- set testname "quit"
- send "quit\r"
- expect {
- "Connection closed.\r" {
- pass $testname
- }
- }
-
- expect_after
-
-# on hpux 10.x, the child telnet will hang in an ioctl(). This will
-# wait a while for an EOF, and kill the process if it doesn't exit by
-# itself. The hang doesn't happen when telnet is run at the shell.
-
- expect {
- eof { }
- timeout {
- stop_telnet_daemon
- }
- }
-
- if ![check_exit_status "exit status"] {
- return
- }
-
- pass "exit status"
-
- # The telnet daemon should have stopped, but we have no easy way
- # of checking whether it actually did. Kill it just in case.
- stop_telnet_daemon
-
- # Try an authenticated connection.
- start_telnet_daemon
- spawn $TELNET -a -k $REALMNAME -- $hostname -[expr 8 + $portbase]
-
- expect_after {
- timeout {
- fail "$testname (timeout)"
- catch "expect_after"
- return
- }
- "Connection closed by foreign host.\r" {
- fail "$testname (connection closed)"
- catch "expect_after"
- return
- }
- eof {
- fail "$testname (eof)"
- catch "expect_after"
- return
- }
- }
-
- set testname "authenticated telnet"
- expect "Kerberos V5 accepts you"
- expect {
- -re "$SHELL_PROMPT" {
- pass $testname
- }
- }
-
- # Switch to /bin/sh to try to avoid confusion from the shell
- # prompt.
- set testname "shell"
- send "$BINSH\r"
- expect -re "$SHELL_PROMPT"
-
- set testname "date"
- send "date\r"
- expect "date"
- expect {
- -re "\[A-Za-z0-9 :\]+\[\r\n\]+" {
- if [check_date $expect_out(0,string)] {
- pass "date"
- } else {
- fail "date"
- }
- }
- }
- expect -re "$SHELL_PROMPT"
-
- set testname "exit"
- send "exit\r"
- expect -re "$SHELL_PROMPT"
- send "exit\r"
- expect {
- "Connection closed by foreign host.\r" {
- pass $testname
- }
- }
-
- expect_after
- catch "expect eof"
-
- # We can't use check_exit_status, because we expect an exit status
- # of 1.
- set status_list [wait -i $spawn_id]
- verbose "wait -i $spawn_id returned $status_list (klist)"
- if { [lindex $status_list 2] != 0 || [lindex $status_list 3] != 1 } {
- send_log "exit status: $status_list\n"
- verbose "exit status: $status_list"
- fail "exit status"
- } else {
- pass "exit status"
- }
-
- # The telnet daemon should have stopped, but we have no easy way
- # of checking whether it actually did. Kill it just in case.
- stop_telnet_daemon
-
- # Try an authenticated encrypted connection.
- start_telnet_daemon
- spawn $TELNET -a -x -k $REALMNAME -- $hostname -[expr 8 + $portbase]
-
- expect_after {
- timeout {
- fail $testname
- catch "expect_after"
- return
- }
- eof {
- fail $testname
- catch "expect_after"
- return
- }
- }
-
- set testname "encrypted telnet"
- expect "Kerberos V5 accepts you"
- expect {
- -re "$SHELL_PROMPT" {
- pass $testname
- }
- }
-
- # Make sure the encryption is not destroying the text.
- set testname "echo"
- send "echo hello\r"
- expect "echo hello"
- expect "hello"
- expect {
- -re "$SHELL_PROMPT" {
- pass $testname
- }
- }
-
- # Move back to telnet command mode and check the encryption status.
- set testname "encryption status"
- send "\035"
- expect "telnet> "
- send "status\r"
- expect {
- -re "Currently encrypting output with DES_CFB64.*Currently decrypting input with DES_CFB64" {
- pass $testname
- }
- }
-
- set testname "exit status"
- send "exit\r"
- expect "Connection closed by foreign host.\r"
-
- expect_after
- catch "expect eof"
-
- # We can't use check_exit_status, because we expect an exit status
- # of 1.
- set status_list [wait -i $spawn_id]
- verbose "wait -i $spawn_id returned $status_list (klist)"
- if { [lindex $status_list 2] != 0 || [lindex $status_list 3] != 1 } {
- send_log "exit status: $status_list\n"
- verbose "exit status: $status_list"
- fail "exit status"
- } else {
- pass "exit status"
- }
-
- # The telnet daemon should have stopped, but we have no easy way
- # of checking whether it actually did. Kill it just in case.
- stop_telnet_daemon
-
- set testname "reject unencrypted telnet"
- # Check rejection of unencrypted client when encryption is required
- start_telnet_daemon -e
-
- # unencrypted, unauthenticated
- spawn $TELNET -- $hostname -[expr 8 + $portbase]
- expect_after {
- timeout {
- fail $testname
- catch "expect_after"
- return
- }
- eof {
- fail $testname
- catch "expect_after"
- return
- }
- }
-
- expect {
- -re "Unencrypted connection refused.*\n" {
- pass $testname
- }
- }
- catch "expect_after"
- catch "expect eof"
- catch wait
-
- # The telnet daemon should have stopped, but we have no easy way
- # of checking whether it actually did. Kill it just in case.
- stop_telnet_daemon
-}
-
-run_once telnet {
- # Remove old wrapper script
- catch "exec rm -f $tmppwd/login.wrap"
-
- # Start up a root shell.
- if ![setup_root_shell telnet] {
- return
- }
-
- # Make sure .k5login is reasonable.
- if ![check_k5login rlogin] {
- stop_root_shell
- return
- }
-
- # Set up the kerberos database.
- if {![get_hostname] \
- || ![setup_kerberos_files] \
- || ![setup_kerberos_env] \
- || ![setup_kerberos_db 0]} {
- stop_root_shell
- return
- }
-
- # Run the test. Logging in sometimes takes a while, so increase the
- # timeout.
- set oldtimeout $timeout
- set timeout 60
- set status [catch telnet_test msg]
- set timeout $oldtimeout
-
- # Shut down the kerberos daemons, the telnet daemon, and the rlogin
- # process.
- stop_kerberos_daemons
-
- stop_telnet_daemon
-
- stop_root_shell
-
- if { $status != 0 } {
- send_error "ERROR: error in telnet.exp\n"
- send_error "$msg\n"
- exit 1
- }
-}
+++ /dev/null
-# Kerberos ftp test.
-# This is a DejaGnu test script.
-# This script tests Kerberos ftp.
-# Originally written by Ian Lance Taylor, Cygnus Support, <ian@cygnus.com>.
-# Modified bye Ezra Peisach for GSSAPI support.
-
-# Find the programs we need. We use the binaries from the build tree
-# if they exist. If they do not, then they must be in PATH. We
-# expect $objdir to be .../kerberos/build/tests/dejagnu
-
-if ![info exists FTP] {
- set FTP [findfile $objdir/../../appl/gssftp/ftp/ftp]
-}
-
-if ![info exists FTPD] {
- set FTPD [findfile $objdir/../../appl/gssftp/ftpd/ftpd]
-}
-
-# A procedure to start up the ftp daemon.
-
-proc start_ftp_daemon { } {
- global FTPD
- global tmppwd
- global ftpd_spawn_id
- global ftpd_pid
- global portbase
-
- # The -p argument tells it to accept a single connection, so we
- # don't need to use inetd. Portbase+8 is the port to listen at.
- # We rely on KRB5_KTNAME being set to the proper keyfile as there is
- # no way to cleanly set it with the gssapi API.
- # The -U argument tells it to use an alternate ftpusers file (using
- # /dev/null will allow root to login regardless of /etc/ftpusers).
- # The -a argument requires authorization, to mitigate any
- # vulnerability introduced by circumventing ftpusers.
- spawn $FTPD -p [expr 8 + $portbase] -a -U /dev/null -r $tmppwd/krb5.conf
- set ftpd_spawn_id $spawn_id
- set ftpd_pid [exp_pid]
-
- # Give the ftp daemon a few seconds to get set up.
- sleep 2
-}
-
-# A procedure to stop the ftp daemon.
-
-proc stop_ftp_daemon { } {
- global ftpd_spawn_id
- global ftpd_pid
-
- if [info exists ftpd_pid] {
- catch "close -i $ftpd_spawn_id"
- catch "exec kill $ftpd_pid"
- catch "wait -i $ftpd_spawn_id"
- unset ftpd_pid
- }
-}
-
-# Test that a file was copied correctly.
-proc check_file { filename {bigfile 0}} {
- if ![file exists $filename] {
- verbose "$filename does not exist"
- send_log "$filename does not exist\n"
- return 0
- }
-
- set file [open $filename r]
- if { [gets $file line] == -1 } {
- verbose "$filename is empty"
- send_log "$filename is empty\n"
- close $file
- return 0
- }
-
- if ![string match "This file is used for ftp testing." $line] {
- verbose "$filename contains $line"
- send_log "$filename contains $line\n"
- close $file
- return 0
- }
-
- if {$bigfile} {
- # + 1 for the newline
- seek $file 1048577 current
- if { [gets $file line] == -1 } {
- verbose "$filename is truncated"
- send_log "$filename is truncated\n"
- close $file
- return 0
- }
-
- if ![string match "This file is used for ftp testing." $line] {
- verbose "$filename contains $line"
- send_log "$filename contains $line\n"
- close $file
- return 0
- }
- }
-
- if { [gets $file line] != -1} {
- verbose "$filename is too long ($line)"
- send_log "$filename is too long ($line)\n"
- close $file
- return 0
- }
-
- close $file
-
- return 1
-}
-
-#
-# Restore environment variables possibly set.
-#
-proc ftp_restore_env { } {
- global env
- global ftp_save_ktname
-
- catch "unset env(KRB5_KTNAME)"
- if [info exists ftp_save_ktname] {
- set env(KRB5_KTNAME) $ftp_save_ktname
- unset ftp_save_ktname
- }
-}
-
-# Wrap the tests in a procedure, so that we can kill the daemons if
-# we get some sort of error.
-
-proc ftp_test { } {
- global FTP
- global KEY
- global REALMNAME
- global hostname
- global localhostname
- global env
- global ftpd_spawn_id
- global ftpd_pid
- global spawn_id
- global tmppwd
- global ftp_save_ktname
- global portbase
-
- # Start up the kerberos and kadmind daemons and get a srvtab and a
- # ticket file.
- if {![start_kerberos_daemons 0] \
- || ![add_random_key ftp/$hostname 0] \
- || ![modify_principal ftp/$hostname -kvno 254] \
- || ![setup_srvtab 0 ftp] \
- || ![xst $tmppwd/srvtab ftp/$hostname]
- || ![xst $tmppwd/srvtab ftp/$hostname]
- || ![xst $tmppwd/srvtab ftp/$hostname]
- || ![do_klist_kt $tmppwd/srvtab "gssftp keytab list"]
- || ![add_kerberos_key $env(USER) 0] \
- || ![kinit $env(USER) $env(USER)$KEY 0]} {
- return
- }
- # Force the host key to exist, so we get consistent errors below.
- catch "add_random_key host/$hostname 0"
-
- #
- # Save settings of KRB5_KTNAME
- #
- if [info exists env(KRB5_KTNAME)] {
- set ftp_save_ktname $env(KRB5_KTNAME)
- }
-
- #
- # set KRB5_KTNAME *incorrectly*
- #
- set env(KRB5_KTNAME) FILE:$tmppwd/srvtabxx
- verbose "KRB5_KTNAME=$env(KRB5_KTNAME)"
-
- # Force some auth errors.
- set testname "ftp auth errors"
-
- # Start the ftp daemon.
- start_ftp_daemon
-
- # Try connecting.
- spawn $FTP -d -v $hostname [expr 8 + $portbase]
- expect_after {
- -re "--->\[^\r\n\]*\r\n" { exp_continue }
- -re "encoding \[0-9\]* bytes MIC \[a-zA-Z0-9/+=\]*\r\n" { exp_continue }
- -re "sealed \[A-Z()\]*" { exp_continue }
- -re "secure_command\[A-Z()\]*" { exp_continue }
- timeout {
- fail "$testname (timeout)"
- catch "expect_after"
- return
- }
- eof {
- fail "$testname (eof)"
- catch "expect_after"
- return
- }
- }
- expect -nocase "connected to $hostname"
- expect -nocase -re "$localhostname.*ftp server .version \[0-9.\]*. ready."
- expect -re "Using authentication type GSSAPI; ADAT must follow"
- expect "GSSAPI accepted as authentication type"
- expect -re "Trying to authenticate to <ftp@.*>"
- # The ftp client doesn't print the gssapi error except on the last attempt.
-# expect "GSSAPI error major: Unspecified GSS failure."
-# expect -re "GSSAPI error minor: Key table file '.*' not found"
- expect -re "Trying to authenticate to <host@.*>"
- expect "GSSAPI error major: Unspecified GSS failure."
- expect -re "GSSAPI error minor: Key table file '.*' not found"
- expect -re "Name (.*): "
- close -i $spawn_id
- wait -i $spawn_id
- wait -i $ftpd_spawn_id
- catch "close -i $ftpd_spawn_id"
-
- #
- # set KRB5_KTNAME correctly now
- #
- set env(KRB5_KTNAME) FILE:$tmppwd/srvtab
- verbose "KRB5_KTNAME=$env(KRB5_KTNAME)"
-
- # Start the ftp daemon.
- start_ftp_daemon
-
- # Make an ftp client connection to it.
- spawn $FTP -d -v $hostname [expr 8 + $portbase]
-
- expect_after {
- "GSSAPI authentication failed" {
- fail "$testname (auth failed)"
- catch "expect_after"
- return
- }
- -re "--->\[^\r\n\]*\r\n" { exp_continue }
- -re "encoding \[0-9\]* bytes MIC \[a-zA-Z0-9/+=\]*\r\n" { exp_continue }
- -re "sealed \[A-Z()\]*" { exp_continue }
- -re "secure_command\[A-Z()\]*" { exp_continue }
- timeout {
- fail "$testname (timeout)"
- catch "expect_after"
- return
- }
- eof {
- fail "$testname (eof)"
- catch "expect_after"
- return
- }
- }
-
- set testname "ftp connection"
- expect -nocase "connected to $hostname"
- expect -nocase -re "$localhostname.*ftp server .version \[0-9.\]*. ready."
- expect -re "Using authentication type GSSAPI; ADAT must follow"
- expect "GSSAPI accepted as authentication type"
- expect {
- "GSSAPI authentication succeeded" { pass "ftp authentication" }
- eof { fail "ftp authentication" ; catch "expect_after" ; return }
- }
- expect -nocase "name ($hostname:$env(USER)): "
- send "$env(USER)\r"
- expect "GSSAPI user $env(USER)@$REALMNAME is authorized as $env(USER)"
- expect "Remote system type is UNIX."
- expect "Using binary mode to transfer files."
- expect "ftp> " {
- pass $testname
- }
-
- set testname "binary"
- send "binary\r"
- expect "ftp> " {
- pass $testname
- }
-
- set testname "status"
- send "status\r"
- expect -nocase "connected to $hostname."
- expect "Authentication type: GSSAPI"
- expect "ftp> " {
- pass $testname
- }
-
- set testname "ls"
- send "ls $tmppwd/ftp-test\r"
- expect -re "Opening ASCII mode data connection for .*ls."
- expect -re ".* $tmppwd/ftp-test"
- expect "ftp> " {
- pass $testname
- }
-
- set testname "nlist"
- send "nlist $tmppwd/ftp-test\r"
- expect -re "Opening ASCII mode data connection for file list."
- expect -re "$tmppwd/ftp-test"
- expect -re ".* Transfer complete."
- expect "ftp> " {
- pass $testname
- }
-
- set testname "ls missing"
- send "ls $tmppwd/ftp-testmiss\r"
- expect -re "Opening ASCII mode data connection for .*ls."
- expect {
- -re "$tmppwd/ftp-testmiss not found" {}
- -re "$tmppwd/ftp-testmiss: No such file or directory"
- }
- expect "ftp> " {
- pass $testname
- }
-
-
- set testname "get"
- catch "exec rm -f $tmppwd/copy"
- send "get $tmppwd/ftp-test $tmppwd/copy\r"
- expect "Opening BINARY mode data connection for $tmppwd/ftp-test"
- expect "Transfer complete"
- expect -re "\[0-9\]+ bytes received in \[0-9.e-\]+ seconds"
- expect "ftp> "
- if [check_file $tmppwd/copy] {
- pass $testname
- } else {
- fail $testname
- }
-
- set testname "put"
- catch "exec rm -f $tmppwd/copy"
- send "put $tmppwd/ftp-test $tmppwd/copy\r"
- expect "Opening BINARY mode data connection for $tmppwd/copy"
- expect "Transfer complete"
- expect -re "\[0-9\]+ bytes sent in \[0-9.e-\]+ seconds"
- expect "ftp> "
- if [check_file $tmppwd/copy] {
- pass $testname
- } else {
- fail $testname
- }
-
- set testname "cd"
- send "cd $tmppwd\r"
- expect "CWD command successful."
- expect "ftp> " {
- pass $testname
- }
-
- set testname "lcd"
- send "lcd $tmppwd\r"
- expect "Local directory now $tmppwd"
- expect "ftp> " {
- pass $testname
- }
-
- set testname "local get"
- catch "exec rm -f $tmppwd/copy"
- send "get ftp-test copy\r"
- expect "Opening BINARY mode data connection for ftp-test"
- expect "Transfer complete"
- expect -re "\[0-9\]+ bytes received in \[0-9.e-\]+ seconds"
- expect "ftp> "
- if [check_file $tmppwd/copy] {
- pass $testname
- } else {
- fail $testname
- }
-
- set testname "big local get"
- catch "exec rm -f $tmppwd/copy"
- send "get bigftp-test copy\r"
- expect "Opening BINARY mode data connection for bigftp-test"
- expect "Transfer complete"
- expect -re "\[0-9\]+ bytes received in \[0-9.e-\]+ seconds"
- expect "ftp> "
- if [check_file $tmppwd/copy 1] {
- pass $testname
- } else {
- fail $testname
- }
-
- set testname "start encryption"
- send "private\r"
- expect "Data channel protection level set to private"
- expect "ftp> " {
- pass $testname
- }
-
- set testname "status"
- send "status\r"
- expect "Protection Level: private"
- expect "ftp> " {
- pass $testname
- }
-
- set testname "encrypted get"
- catch "exec rm -f $tmppwd/copy"
- send "get ftp-test copy\r"
- expect "Opening BINARY mode data connection for ftp-test"
- expect "Transfer complete"
- expect -re "\[0-9\]+ bytes received in \[0-9.e-\]+ seconds"
- expect "ftp> "
- if [check_file $tmppwd/copy] {
- pass $testname
- } else {
- fail $testname
- }
-
- set testname "big encrypted get"
- catch "exec rm -f $tmppwd/copy"
- send "get bigftp-test copy\r"
- expect "Opening BINARY mode data connection for bigftp-test"
- expect {
- -timeout 300
- "Transfer complete" {}
- -re "Length .* of PROT buffer > PBSZ" {
- fail "$testname (PBSZ)"
- return 0
- }
- }
- expect -re "\[0-9\]+ bytes received in \[0-9.e+-\]+ seconds"
- expect "ftp> "
- if [check_file $tmppwd/copy 1] {
- pass $testname
- } else {
- fail $testname
- }
-
- set testname "close"
- send "close\r"
- expect "Goodbye."
- expect "ftp> "
- set status_list [wait -i $ftpd_spawn_id]
- verbose "wait -i $ftpd_spawn_id returned $status_list ($testname)"
- catch "close -i $ftpd_spawn_id"
- if { [lindex $status_list 2] != 0 || [lindex $status_list 3] != 0 } {
- send_log "exit status: $status_list\n"
- verbose "exit status: $status_list"
- fail $testname
- } else {
- pass $testname
- unset ftpd_pid
- }
-
- set testname "quit"
- send "quit\r"
- expect_after
- expect eof
- if [check_exit_status $testname] {
- pass $testname
- }
-}
-
-run_once gssftp {
- # Make sure .klogin is reasonable.
- if ![check_k5login ftp] {
- return
- }
-
- # Set up the kerberos database.
- if {![get_hostname] \
- || ![setup_kerberos_files] \
- || ![setup_kerberos_env] \
- || ![setup_kerberos_db 0]} {
- return
- }
-
- # Create a file to use for ftp testing.
- set file [open $tmppwd/ftp-test w]
- puts $file "This file is used for ftp testing."
- close $file
-
- # Create a large file to use for ftp testing. File needs to be
- # larger that 2^20 or 1MB for PBSZ testing.
- set file [open $tmppwd/bigftp-test w]
- puts $file "This file is used for ftp testing.\n"
- seek $file 1048576 current
- puts $file "This file is used for ftp testing."
- close $file
-
- # The ftp client will look in $HOME/.netrc for the user name to use.
- # To avoid confusing the testsuite, point $HOME at a directory where
- # we know there is no .netrc file.
- if [info exists env(HOME)] {
- set home $env(HOME)
- } elseif [info exists home] {
- unset home
- }
- set env(HOME) $tmppwd
-
- # Run the test. Logging in sometimes takes a while, so increase the
- # timeout.
- set oldtimeout $timeout
- set timeout 60
- set status [catch ftp_test msg]
- set timeout $oldtimeout
-
- # Shut down the kerberos daemons and the ftp daemon.
- stop_kerberos_daemons
-
- stop_ftp_daemon
-
- ftp_restore_env
-
- # Reset $HOME, for safety in case we are going to run more tests.
- if [info exists home] {
- set env(HOME) $home
- } else {
- unset env(HOME)
- }
-
- if { $status != 0 } {
- perror "error in gssftp.exp: $msg"
- }
-}
+++ /dev/null
-# Kerberos rcp test.
-# This is a DejaGnu test script.
-# This script tests Kerberos rcp.
-# Written by Ian Lance Taylor, Cygnus Support, <ian@cygnus.com>.
-
-# Find the programs we need. We use the binaries from the build tree
-# if they exist. If they do not, then they must be in PATH. We
-# expect $objdir to be .../kerberos/src.
-
-if ![info exists RCP] {
- set RCP [findfile $objdir/../../appl/bsd/rcp]
-}
-
-if ![info exists KRSHD] {
- set KRSHD [findfile $objdir/../../appl/bsd/kshd]
-}
-
-# Remove old wrapper script
- catch "exec rm -f $tmppwd/rcp"
-
-# Make sure .k5login is reasonable.
-if ![check_k5login rcp] {
- return
-}
-
-# Set up the kerberos database.
-if {![get_hostname] \
- || ![setup_kerberos_files] \
- || ![setup_kerberos_env] \
- || ![setup_kerberos_db 0]} {
- return
-}
-
-# A procedure to start up the rsh daemon (rcp talks to the rsh
-# daemon).
-
-proc start_rsh_daemon { } {
- global REALMNAME
- global KRSHD T_INETD
- global RCP
- global tmppwd
- global krshd_spawn_id
- global krshd_pid
- global portbase
-
- # Setup the shared library wrapper for login.krb5
- if ![file exists $tmppwd/rcp] {
- setup_wrapper $tmppwd/rcp "$RCP $*"
- }
-
-
- # The -L ENV_SET is for the I/S Athena brokeness in dot files where
- # LD_LIBRARY_PATH will be overridden causing the "exec csh -c rcp ..."
- # to fail as the .cshrc is read in. We do not use the -f option as
- # a users shell might be sh...
- # Later a proper fix would be to have kshd exec rcp directly
- # shell indirection...
- spawn $T_INETD [expr 8 + $portbase] $KRSHD $KRSHD -k -c -P $tmppwd -S $tmppwd/srvtab -M $REALMNAME -L ENV_SET
- set krshd_spawn_id $spawn_id
- set krshd_pid [exp_pid]
-
- expect {
- -ex "Ready!" { }
- eof { error "couldn't start t_inetd helper" }
- }
-}
-
-# A procedure to stop the rsh daemon.
-
-proc stop_rsh_daemon { } {
- global krshd_spawn_id
- global krshd_pid
-
- if [info exists krshd_pid] {
- catch "exec kill $krshd_pid"
- catch {
- expect {
- -i $krshd_spawn_id
- -re ..* { exp_continue }
- eof {}
- }
- }
- catch "close -i $krshd_spawn_id"
- catch "wait -i $krshd_spawn_id"
- unset krshd_pid
- }
-}
-
-# Create a file to use for rcp testing.
-set file [open $tmppwd/rcp-test w]
-puts $file "This file is used for rcp testing."
-close $file
-
-# Test that a file was copied correctly.
-proc check_file { filename } {
- if ![file exists $filename] {
- verbose "$filename does not exist"
- send_log "$filename does not exist\n"
- return 0
- }
-
- set file [open $filename r]
- if { [gets $file line] == -1 } {
- verbose "$filename is empty"
- send_log "$filename is empty\n"
- close $file
- return 0
- }
-
- if ![string match "This file is used for rcp testing." $line] {
- verbose "$filename contains $line"
- send_log "$filename contains $line\n"
- close $file
- return 0
- }
-
- if { [gets $file line] != -1} {
- verbose "$filename is too long ($line)"
- send_log "$filename is too long ($line)\n"
- close $file
- return 0
- }
-
- close $file
-
- return 1
-}
-
-# Test copying one file to another.
-proc rcp_one_test { testname options frompref topref } {
- global REALMNAME
- global RCP
- global tmppwd
- global portbase
-
- send_log "rm -f $tmppwd/copy\n"
- verbose "exec rm -f $tmppwd/copy"
- catch "exec rm -f $tmppwd/copy"
-
- set from [format "%s%s" $frompref $tmppwd/rcp-test]
- set to [format "%s%s" $topref $tmppwd/copy]
-
- send_log "$RCP $options -D [expr 8 + $portbase] -N -k $REALMNAME $from $to\n"
- verbose "$RCP $options -D [expr 8 + $portbase] -N -k $REALMNAME $from $to"
- catch "exec $RCP $options -D [expr 8 + $portbase] -N -k $REALMNAME $from $to" exec_output
-
- if ![string match "" $exec_output] {
- send_log "$exec_output\n"
- verbose "$exec_output"
- fail $testname
- return 0
- }
-
- if ![check_file $tmppwd/copy] {
- fail $testname
- return 0
- }
-
- pass $testname
-
- return 1
-}
-
-# Wrap the tests in a procedure, so that we can kill the daemons if
-# we get some sort of error.
-
-proc rcp_test { } {
- global RCP
- global KEY
- global hostname
- global hostname
- global env
-
- # Start up the kerberos and kadmind daemons and get a srvtab and a
- # ticket file.
- if {![start_kerberos_daemons 0] \
- || ![add_kerberos_key host/$hostname 0] \
- || ![setup_srvtab 0] \
- || ![add_kerberos_key $env(USER) 0] \
- || ![kinit $env(USER) $env(USER)$KEY 0]} {
- return
- }
-
- rcp_one_test "local rcp" "" "" ""
-
- start_rsh_daemon
- rcp_one_test "rcp from" "" "$hostname:" ""
- stop_rsh_daemon
-
- start_rsh_daemon
- rcp_one_test "rcp to" "" "" "$hostname:"
- stop_rsh_daemon
-
- # Doing rcp between two hosts actually just executes rsh rcp on
- # the source. We could test this, but we're not set up for it
- # right now. Also, it's pretty much covered by the other rcp
- # tests and by the rsh tests.
- # start_rsh_daemon
- # rcp_one_test "rcp between" "" "$hostname:" "$hostname:"
- # stop_rsh_daemon
-
- start_rsh_daemon
- rcp_one_test "encrypted rcp from" "-x -c $env(KRB5CCNAME) -C $env(KRB5_CONFIG)" "$hostname:" ""
- stop_rsh_daemon
-
- start_rsh_daemon
- rcp_one_test "encrypted rcp to" "-x -c $env(KRB5CCNAME) -C $env(KRB5_CONFIG)" "" "$hostname:"
- stop_rsh_daemon
-
- # Doing rcp between two hosts actually just executes rsh rcp on
- # the source. We could test this, but we're not set up for it
- # right now. Also, it's pretty much covered by the other rcp
- # tests and by the rsh tests.
- # start_rsh_daemon
- # rcp_one_test "encrypted rcp between" "-x" "$hostname:" "$hostname:"
- # stop_rsh_daemon
-}
-
-# Run the test.
-set status [catch rcp_test msg]
-
-# Shut down the kerberos daemons and the rsh daemon.
-stop_kerberos_daemons
-
-stop_rsh_daemon
-
-if { $status != 0 } {
- send_error "ERROR: error in rcp.exp\n"
- send_error "$msg\n"
- exit 1
-}
+++ /dev/null
-# Kerberos rsh test.
-# This is a DejaGnu test script.
-# This script tests Kerberos rsh.
-# Written by Ian Lance Taylor, Cygnus Support, <ian@cygnus.com>.
-
-# Find the programs we need. We use the binaries from the build tree
-# if they exist. If they do not, then they must be in PATH. We
-# expect $objdir to be .../kerberos/src.
-
-if ![info exists RSH] {
- set RSH [findfile $objdir/../../appl/bsd/rsh]
-}
-
-if ![info exists KRSHD] {
- set KRSHD [findfile $objdir/../../appl/bsd/kshd]
-}
-
-if ![info exists KLIST] {
- set KLIST [findfile $objdir/../../clients/klist/klist]
-}
-
-# Make sure .k5login is reasonable.
-if ![check_k5login rsh] {
- return
-}
-
-# Set up the kerberos database.
-if {![get_hostname] \
- || ![setup_kerberos_files] \
- || ![setup_kerberos_db 0]} {
- return
-}
-
-# A procedure to start up the rsh daemon.
-
-proc start_rsh_daemon { option } {
- global REALMNAME
- global KRSHD T_INETD
- global tmppwd
- global krshd_spawn_id
- global krshd_pid
- global portbase
-
- spawn $T_INETD [expr 8 + $portbase] $KRSHD $KRSHD -k -c -S $tmppwd/srvtab -M $REALMNAME -A $option
- set krshd_spawn_id $spawn_id
- set krshd_pid [exp_pid]
-
- expect {
- -ex "Ready!" { }
- eof { error "couldn't start t_inetd helper" }
- }
-}
-
-# A procedure to stop the rsh daemon.
-
-proc stop_rsh_daemon { } {
- global krshd_spawn_id
- global krshd_pid
-
- if [info exists krshd_pid] {
- catch "exec kill $krshd_pid"
- catch {
- expect {
- -i $krshd_spawn_id
- -re ..* { exp_continue }
- eof {}
- }
- }
- catch "close -i $krshd_spawn_id"
- catch "wait -i $krshd_spawn_id"
- unset krshd_pid
- }
-}
-
-# Wrap the tests in a procedure, so that we can kill the daemons if
-# we get some sort of error.
-
-proc rsh_test { } {
- global REALMNAME
- global KLIST
- global RSH
- global KEY
- global BINSH
- global hostname
- global env
- global spawn_id
- global tmppwd
- global portbase
-
- # Start up the kerberos and kadmind daemons and get a srvtab and a
- # ticket file.
- if {![start_kerberos_daemons 0] \
- || ![add_kerberos_key host/$hostname 0] \
- || ![setup_srvtab 0] \
- || ![add_kerberos_key $env(USER) 0] \
- || ![setup_kerberos_env client] \
- || ![kinit $env(USER) $env(USER)$KEY 0]} {
- return
- }
-
- # Start up the rsh daemon.
- start_rsh_daemon -k
-
- # Run rsh date.
- set testname "date"
- spawn $RSH $hostname -k $REALMNAME -D [expr 8 + $portbase] -A date
- expect {
- -re "\[A-Za-z0-9\]+ \[A-Za-z0-9\]+ +\[0-9\]+ \[0-9\]+:\[0-9\]+:\[0-9\]+ \[A-Za-z0-9\]+ \[0-9\]+\r\n" {
- set result $expect_out(0,string)
- }
- timeout {
- fail "$testname (timeout)"
- return
- }
- eof {
- fail "$testname (eof)"
- return
- }
- }
- expect eof
- if ![check_exit_status $testname] {
- return
- }
-
- if [check_date $result] {
- pass $testname
- } else {
- fail $testname
- }
-
- # The rsh daemon should have stopped, but we have no easy way
- # of checking whether it actually did. Kill it just in case.
- stop_rsh_daemon
-
- # Check encrypted rsh.
- set failed no
- start_rsh_daemon -ek
- set testname "encrypted rsh"
- spawn $RSH $hostname -x -k $REALMNAME -D [expr 8 + $portbase] -A echo hello
- expect {
- "hello" { expect eof }
- timeout {
- fail "$testname (timeout)"
- set failed yes
- }
- eof {
- fail "$testname (eof)"
- set failed yes
- }
- }
-
- catch "expect eof"
- if { $failed == "no" } {
- if ![check_exit_status $testname] {
- return
- }
- pass $testname
- stop_rsh_daemon
- } else {
- catch "wait -i $spawn_id"
- catch "close -i $spawn_id"
- stop_rsh_daemon
- }
-
- # Check ticket forwarding
- set failed no
- start_rsh_daemon -k
- set testname "rsh forwarding tickets"
-
- # We need a wrapper for klist in order to setup for shared library
- # runtime environment
- setup_wrapper $tmppwd/klist.wrap $KLIST
-
- spawn $RSH $hostname -f -k $REALMNAME -D [expr 8 + $portbase] -A $BINSH -c $tmppwd/klist.wrap
- expect {
- "Ticket cache:*\r" {
- expect eof
- }
- "klist: No credentials cache file found" {
- fail "$testname (not forwarded)"
- return
- }
- timeout {
- fail "$testname (timeout)"
- return
- }
- eof {
- fail "$testname (eof)"
- return
- }
- }
-
- if ![check_exit_status $testname] {
- return
- }
-
- pass $testname
-
- stop_rsh_daemon
-
- # Check encrypted ticket forwarding
- set failed no
- start_rsh_daemon -e
- set testname "encrypted rsh forwarding tickets"
- spawn $RSH $hostname -x -f -k $REALMNAME -D [expr 8 + $portbase] -A $BINSH -c $tmppwd/klist.wrap
- expect {
- "Ticket cache:*\r" {
- expect eof
- }
- "klist: No credentials cache file found" {
- fail "$testname (not forwarded)"
- return
- }
- timeout {
- fail "$testname (timeout)"
- return
- }
- eof {
- fail "$testname (eof)"
- return
- }
- }
-
- if ![check_exit_status $testname] {
- return
- }
-
- pass $testname
-
- stop_rsh_daemon
-
- # Check stderr
- start_rsh_daemon -k
- set testname "rsh to stderr"
- spawn $RSH $hostname -k $REALMNAME -D [expr 8 + $portbase] -A $BINSH -c "'echo hello 1>&2'"
- expect {
- "hello" { expect eof }
- timeout {
- fail "$testname (timeout)"
- return
- }
- eof {
- fail "$testname (eof)"
- return
- }
- }
-
- if ![check_exit_status $testname] {
- return
- }
-
- pass $testname
-
- stop_rsh_daemon
-
- start_rsh_daemon -e
- set testname "encrypted rsh to stderr"
- spawn $RSH $hostname -x -k $REALMNAME -D [expr 8 + $portbase] -A $BINSH -c "'echo hello 1>&2'"
- expect {
- "hello" { expect eof }
- timeout {
- fail "$testname (timeout)"
- return
- }
- eof {
- fail "$testname (eof)"
- return
- }
- }
-
- if ![check_exit_status $testname] {
- return
- }
-
- pass $testname
-
- # The rsh daemon should have stopped, but we have no easy way
- # of checking whether it actually did. Kill it just in case.
- stop_rsh_daemon
-}
-
-# Run the test.
-set status [catch rsh_test msg]
-
-# Shut down the kerberos daemons and the rsh daemon.
-stop_kerberos_daemons
-
-stop_rsh_daemon
-
-if { $status != 0 } {
- send_error "ERROR: error in rsh.exp\n"
- send_error "$msg\n"
- exit 1
-}