aboutsummaryrefslogtreecommitdiff
path: root/src/appl/libpty
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2006-04-11 19:53:48 +0000
committerKen Raeburn <raeburn@mit.edu>2006-04-11 19:53:48 +0000
commit8bcbe9ba5c1f2384272fe121721ab72ac70d3ca1 (patch)
tree2e84e7414e5a82d1350cf8e742ef7f15bc677ed9 /src/appl/libpty
parentd716f2b96aca06cd8b2fb84e9fe1f601de645c94 (diff)
downloadkrb5-8bcbe9ba5c1f2384272fe121721ab72ac70d3ca1.zip
krb5-8bcbe9ba5c1f2384272fe121721ab72ac70d3ca1.tar.gz
krb5-8bcbe9ba5c1f2384272fe121721ab72ac70d3ca1.tar.bz2
Move pty library from util/pty to appl/libpty; update Makefile.in and
configure.in files accordingly. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@17887 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/appl/libpty')
-rw-r--r--src/appl/libpty/.Sanitize52
-rw-r--r--src/appl/libpty/ChangeLog955
-rw-r--r--src/appl/libpty/Makefile.in157
-rw-r--r--src/appl/libpty/README108
-rw-r--r--src/appl/libpty/cleanup.c112
-rw-r--r--src/appl/libpty/configure.in269
-rw-r--r--src/appl/libpty/dump-utmp.c281
-rw-r--r--src/appl/libpty/getpty.c150
-rw-r--r--src/appl/libpty/init.c33
-rw-r--r--src/appl/libpty/init_slave.c100
-rw-r--r--src/appl/libpty/libpty.h54
-rw-r--r--src/appl/libpty/logwtmp.c112
-rw-r--r--src/appl/libpty/open_ctty.c67
-rw-r--r--src/appl/libpty/open_slave.c101
-rw-r--r--src/appl/libpty/pty-int.h138
-rw-r--r--src/appl/libpty/pty_err.et50
-rw-r--r--src/appl/libpty/pty_paranoia.c650
-rw-r--r--src/appl/libpty/sane_hostname.c116
-rw-r--r--src/appl/libpty/update_utmp.c706
-rw-r--r--src/appl/libpty/update_wtmp.c127
-rw-r--r--src/appl/libpty/vhangup.c50
-rw-r--r--src/appl/libpty/void_assoc.c49
22 files changed, 4437 insertions, 0 deletions
diff --git a/src/appl/libpty/.Sanitize b/src/appl/libpty/.Sanitize
new file mode 100644
index 0000000..d1b4efb
--- /dev/null
+++ b/src/appl/libpty/.Sanitize
@@ -0,0 +1,52 @@
+# Sanitize.in for Kerberos V5
+
+# Each directory to survive it's way into a release will need a file
+# like this one called "./.Sanitize". All keyword lines must exist,
+# and must exist in the order specified by this file. Each directory
+# in the tree will be processed, top down, in the following order.
+
+# Hash started lines like this one are comments and will be deleted
+# before anything else is done. Blank lines will also be squashed
+# out.
+
+# The lines between the "Do-first:" line and the "Things-to-keep:"
+# line are executed as a /bin/sh shell script before anything else is
+# done in this
+
+Do-first:
+
+# All files listed between the "Things-to-keep:" line and the
+# "Files-to-sed:" line will be kept. All other files will be removed.
+# Directories listed in this section will have their own Sanitize
+# called. Directories not listed will be removed in their entirety
+# with rm -rf.
+
+Things-to-keep:
+
+.cvsignore
+ChangeLog
+README
+Makefile.in
+configure.in
+configure
+cleanup.c
+dump-utmp.c
+getpty.c
+init_slave.c
+libpty.h
+init.c
+logwtmp.c
+open_ctty.c
+open_slave.c
+pty-int.h
+pty_err.et
+update_utmp.c
+update_wtmp.c
+vhangup.c
+void_assoc.c
+
+Things-to-lose:
+
+Do-last:
+
+# End of file.
diff --git a/src/appl/libpty/ChangeLog b/src/appl/libpty/ChangeLog
new file mode 100644
index 0000000..2e42f7c
--- /dev/null
+++ b/src/appl/libpty/ChangeLog
@@ -0,0 +1,955 @@
+2006-04-11 Ken Raeburn <raeburn@mit.edu>
+
+ * Move directory from util/pty to appl/libpty.
+ * Makefile.in (myfulldir, RELDIR): Updated.
+
+2006-04-05 Tom Yu <tlyu@mit.edu>
+
+ * configure.in: Add prerequisites for sys/ptyvar.h.
+
+2006-03-31 Ken Raeburn <raeburn@mit.edu>
+
+ * configure.in: Always provide three arguments to AC_DEFINE.
+
+2006-03-30 Ken Raeburn <raeburn@mit.edu>
+
+ * pty-int.h: Include autoconf.h.
+
+2006-03-11 Ken Raeburn <raeburn@mit.edu>
+
+ * Makefile.in (autoconf.h): Note location change.
+
+2005-08-20 Ken Raeburn <raeburn@mit.edu>
+
+ * configure.in: Use K5_AC_INIT instead of AC_INIT.
+
+2004-09-22 Tom Yu <tlyu@mit.edu>
+
+ * pty-int.h: Include util.h if present.
+
+2004-07-30 Tom Yu <tlyu@mit.edu>
+
+ * configure.in: Only sanity-check setutent() API if there is no
+ utmpx.h, since some setutent() implementations aren't sysV-derived,
+ e.g., NetBSD.
+
+2004-07-16 Ken Raeburn <raeburn@mit.edu>
+
+ * pty-int.h: Include port-sockets.h instead of netdb.h and
+ netinet/in.h.
+
+2004-06-16 Ken Raeburn <raeburn@mit.edu>
+
+ * Makefile.in (clean-mac): Target deleted.
+
+2004-06-11 Ken Raeburn <raeburn@mit.edu>
+
+ * pty-int.h (_AIX && _THREAD_SAFE): Undefine _THREAD_SAFE.
+
+2004-06-04 Ken Raeburn <raeburn@mit.edu>
+
+ * Makefile.in (LIBBASE): Renamed from LIB.
+
+2004-04-12 Ezra Peisach <epeisach@mit.edu>
+
+ * configure.in: Remove tests for strsave, sys_errlist,
+ krb5_sigtype, setjmp, dirent, F_SETOWN. These are left over from
+ the split from appl/bsd.
+
+2004-02-18 Ken Raeburn <raeburn@mit.edu>
+
+ * cleanup.c, init.c, init_slave.c, vhangup.c: Use ANSI style
+ function definitions.
+
+2003-03-03 Tom Yu <tlyu@mit.edu>
+
+ * configure.in: Delete unused ADD_DEF, probably left over from
+ appl/bsd.
+
+2003-01-10 Ken Raeburn <raeburn@mit.edu>
+
+ * configure.in: Don't explicitly invoke AC_PROG_INSTALL,
+ AC_PROG_ARCHIVE, AC_PROG_RANLIB.
+
+ * Makefile.in: Add AC_SUBST_FILE marker for lib_frag and libobj_frag.
+
+2002-12-06 Ezra Peisach <epeisach@bu.edu>
+
+ * configure.in: Quote the argument to AC_CHECK_HEADER. Autoconf
+ 2.57 was having problems.
+
+2002-08-29 Ken Raeburn <raeburn@mit.edu>
+
+ * Makefile.in: Revert $(S)=>/ change, for Windows support.
+
+ * pty_err.et: Add final "end" statement.
+
+2002-08-23 Ken Raeburn <raeburn@mit.edu>
+
+ * Makefile.in: Change $(S)=>/ and $(U)=>.. globally.
+
+2002-07-12 Ken Raeburn <raeburn@mit.edu>
+
+ * Makefile.in (install): Don't install libpty.h.
+ * configure.in: Always build static library only.
+
+2002-06-12 Ken Raeburn <raeburn@mit.edu>
+
+ * cleanup.c, getpty.c, init.c, init_slave.c, logwtmp.c,
+ open_ctty.c, open_slave.c, pty_paranoia.c, sane_hostname.c,
+ update_utmp.c, update_wtmp.c, vhangup.c, void_assoc.c: Include
+ "com_err.h" instead of <com_err.h>.
+
+ * pty-int.h: Don't include syslog.h.
+
+2002-05-24 Ken Raeburn <raeburn@mit.edu>
+
+ * sane_hostname.c (pty_make_sane_hostname): Always initialize
+ "ai".
+
+2002-03-26 Ken Raeburn <raeburn@mit.edu>
+
+ * sane_hostname.c: Include fake-addrinfo.h, not fake-addrinfo.c.
+ (FAI_PREFIX): Delete.
+
+2002-02-19 Ken Raeburn <raeburn@mit.edu>
+
+ * Makefile.in (LIBMINOR): Bump due to change in internals. (Tom's
+ change from 1.2.x branch.)
+
+2001-12-03 Sam Hartman <hartmans@mit.edu>
+
+ * README: s-pty_init_ets/pty_init/
+
+2001-11-28 Tom Yu <tlyu@mit.edu>
+
+ * update_utmp.c (PTY_GETUTXENT): Fix typo. Thanks to Shawn
+ Stepper. [fixes krb5-build/1020]
+
+2001-11-19 Tom Yu <tlyu@mit.edu>
+
+ * update_utmp.c (pty_update_utmp): Patch from Garry Zacheiss to
+ kludge around cases where we need to use more than 2 characters of
+ LINE in order to avoid conflicts in UT_ID.
+
+2001-10-18 Ezra Peisach <epeisach@mit.edu>
+
+ * sane_hostname.c (pty_make_sane_hostname): Do not declare addrbuf
+ twice, shadowing the first declaration.
+
+
+2001-10-02 Ezra Peisach <epeisach@mit.edu>
+
+ * Makefile.in (includes): Depend on
+ $(BUILDTOP)/include/krb5/autoconf.h. Automatic dependencies do not
+ work on systems in which shared libraries are build without static
+ ones.
+
+2001-09-11 Tom Yu <tlyu@mit.edu>
+
+ * configure.in: Cosmetic fix in utmpx.ut_exit check.
+
+Wed Sep 5 20:08:21 2001 Ezra Peisach <epeisach@mit.edu>
+
+ * Makefile.in ($(BUILDTOP)/include/krb5/autoconf.h): Add rules to
+ build include/krb5/autoconf.h - this file is wiped out during a
+ make clean and sane_hostname.c depends on it.
+
+2001-08-29 Ken Raeburn <raeburn@mit.edu>
+
+ * sane_hostname.c: Include socket-utils.h and fake-addrinfo.c.
+ (FAI_PREFIX): Define to krb5int_pty.
+ (sockaddrlen, do_ntoa): Deleted.
+ (pty_make_sane_hostname): Use socklen instead of sockaddrlen.
+ Delete support for not having getnameinfo. Move code for do_ntoa
+ inline.
+
+2001-07-02 Tom Yu <tlyu@mit.edu>
+
+ * update_utmp.c (pty_update_utmp): Remember to chop off leading
+ "/dev/" for the non-sysV case. Handle lseek() returning non-zero
+ yet non-negative values (it usually does... :-), so that we can
+ actually write somewhere not at the beginning of the utmp file if
+ necessary.
+
+2001-06-28 Ken Raeburn <raeburn@mit.edu>
+
+ * update_utmp.c (pty_update_utmp): Don't copy host if it's a null
+ pointer.
+
+ * dump-utmp.c (print_ut): Use size of ut_name field, not ut_user,
+ which may not exist, for width when printing ut_name field value.
+ Specify width when printing hostname, it may be unterminated.
+ (main): Move utp and utxp declarations closer to their usages, and
+ make both conditionalized so they're not declared if they're not
+ used.
+
+2001-06-21 Ezra Peisach <epeisach@mit.edu>
+
+ * libpty.h: Change variable line in prototype to tty_line to
+ prevent shadowing.
+
+2001-06-11 Ezra Peisach <epeisach@mit.edu>
+
+ * pty-int.h: Provide revoke() prototype if system headers lacking.
+
+ * logwtmp.c: Provide logwtmp() prototype if needed.
+
+ * configure.in: Check for system provided getutmp(), logwtmp() and
+ revoke() prototypes. Check for util.h, libutil.h.
+
+ * update_wtmp.c: Provide prototype for getutmp() if needed.
+
+2001-05-15 Tom Yu <tlyu@mit.edu>
+
+ * getpty.c: Make pty_getpty() into ptyint_getpty_ext(), which has
+ an extra argument that determines whether to call grantpt() and
+ unlockpt() on systems that support it. The new pty_getpty() will
+ simply call the extended version. This is to support some
+ wackiness needed by pty_paranoia.c tests.
+
+ * pty-int.h: Add prototype for ptyint_getpty_ext().
+
+ * pty_paranoia.c: Add rant about ptys and quirks therein. Needs
+ to be updated somewhat. Add some more paranoia for the case where
+ we actually succeed in opening the slave of a closed master and
+ then succeed in opening the same master. This program will get
+ rewritten at some point to actually see what things result in EOFs
+ and under what conditions data will actually get passed between
+ master and slave.
+
+2001-05-10 Tom Yu <tlyu@mit.edu>
+
+ * pty_paranoia.c: New file; do many paranoid checks about ctty
+ handling by the pty drivers.
+
+ * Makefile.in: Add rules for pty_paranoia and check-paranoia,
+ which runs pty_paranoia.
+
+ * configure.in: Define REVOKE_NEEDS_OPEN for Tru64. Add support
+ for program building and run flags for the sake of pty_paranoia.
+
+ * open_slave.c: Fix somewhat; AIX doesn't like opening the ctty
+ twice, so only do initial open if we special-case it in
+ configure.in, e.g. for Tru64.
+
+2001-05-08 Tom Yu <tlyu@mit.edu>
+
+ * logwtmp.c: Delete code under "#if 0". Fix reversed test for
+ loggingin. Don't forget to set the ut_tv or ut_time for the
+ entry.
+
+ * update_utmp.c: Update rant about Tru64; remove fetching of
+ ut_user from old entry. The existence of the old ut_user in the
+ logout entry in wtmp was confusing last.
+
+ * cleanup.c: Call update_utmp() with the correct pid to assist in
+ finding the old utmp entry.
+
+ * open_ctty.c: Reformat somewhat and revise comment.
+
+ * open_slave.c: Rework significantly. Primarily, keep a fd open
+ to the slave if we need to reopen the slave device following
+ vhangup() or revoke(), to accommodate various OS quirks.
+
+ * update_utmp.c: Revise history section somewhat to document more
+ HP-UX brokenness. Search via ut_pid before searching via
+ ut_line. Copy stuff around because entuxent() will clobber some
+ things.
+
+ * void_assoc.c: Revise comment and reformat somewhat.
+
+2001-05-04 Ezra Peisach <epeisach@mit.edu>
+
+ * open_slave.c (pty_open_slave): If revoke() present on system but
+ VHANG_FIRST is not defined, declare local variable.
+
+2001-05-04 Tom Yu <tlyu@mit.edu>
+
+ * dump-utmp.c: Fix some off-by-one errors. Handle cases where we
+ have utmpname() but not utmpname().
+
+ * pty-int.h: Fix typo; VHANG_first -> VHANG_FIRST.
+
+ * open_slave.c (pty_open_slave): Add workaround for Tru64 v5.0,
+ since its revoke() will fail if the slave isn't open already.
+
+2001-05-03 Ezra Peisach <epeisach@rna.mit.edu>
+
+ * sane_hostname.c (pty_make_sane_hostname): Preserve const
+ property of incomming parameter in casts.
+
+2001-05-03 Ezra Peisach <epeisach@mit.edu>
+
+ * cleanup.c (pty_cleanup): Delcare local variable only if
+ VHANG_LAST defined.
+
+ * logwtmp.c (pty_logwtmp): Only declare local variables if
+ logwtmp() not available on system.
+
+ * sane_hostname.c (sockaddrlen): Only define static function if
+ HAVE_GETNAMEINFO defined. (pty_make_sane_hostname) Declare goto
+ target only if code compiled in.
+
+2001-05-01 Ken Raeburn <raeburn@mit.edu>
+
+ * update_utmp.c (pty_update_utmp): Fix typo (OWRONLY ->
+ O_WRONLY).
+
+2001-05-01 Ezra Peisach <epeisach@mit.edu>
+
+ * update_wtmp.c (ptyint_update_wtmpx): Add missing semi-colon in
+ code path if PTY_UTMP_E_EXIT and PTY_UTMPX_E_EXIT exist.
+
+2001-04-30 Tom Yu <tlyu@mit.edu>
+
+ * configure.in: Fix some quoting of shell variables when passing
+ to "test". Reorder some logic in consistency checks to validate
+ cache variables against "yes" to account for possible empty or
+ nonexistent values.
+
+ * pty-int.h: Fix conditional prototype of update_wtmp().
+
+ * update_wtmp.c: Fix conditional compilation of update_wtmp() to
+ cover the case where we have setutxent() but don't have updwtmpx()
+ and WTMPX_FILE, as is the case on some Linux installations.
+
+2001-04-27 Tom Yu <tlyu@mit.edu>
+
+ * configure.in(K5_CHECK_UT_MEMBER): Fix typo in previous; make
+ sure to include the correct header when checking structure
+ members.
+
+ * configure.in: Many changes to support the rewriting of the utmp
+ pieces of libpty. Do a large amount of checking for consistency
+ of various utmp and utmpx APIs as currently understood. See rant
+ in update_utmp.c.
+
+ * dump-utmp.c: Rewrite; now has capability to use utmp{,x}name()
+ to extract entries from utmp and utmpx files. Adjusts field
+ widths when printing as appropriate.
+
+ * libpty.h: Update call signature for update_utmp() and logwtmp();
+ make prototypes unconditional.
+
+ * logwtmp.c: Rewrite. Use pututline() or pututxline() API
+ whenever possible.
+
+ * pty-int.h: Update call signatures for update_wtmp{,x}(); make
+ prototypes unconditional.
+
+ * sane_hostname.c: Use the autoconf-correct macro names.
+
+ * update_utmp.c: Rewrite. Basically, use functions from the
+ pututline() or pututxline() API whenever possible, to avoid
+ lossage. Inserted large rant about the conjectured history of BSD
+ utmp, sysV utmp, and utmpx, as well as documentation about some
+ known quirks.
+
+ * update_wtmp.c: Rewrite. Add new function ptyint_logwtmpx() that
+ takes a utmpx rather than a utmp, so it can fail to lose data
+ converting to and from utmp.
+
+2001-01-12 Tom Yu <tlyu@mit.edu>
+
+ * sane_hostname.c: Switch off of KRB5_USE_INET6 instead of
+ AF_INET6, which may be defined without a corresponding struct
+ sockaddr_in6.
+
+2000-12-06 Ken Raeburn <raeburn@mit.edu>
+
+ * sane_hostname.c (pty_make_sane_hostname, do_ntoa): Pass address
+ as const sockaddr pointer.
+ * libpty.h (pty_make_sane_hostname): Update prototype.
+
+ * sane_hostname.c (sockaddrlen, downcase): New function.
+ (do_ntoa, pty_make_sane_hostname): Reimplement using getnameinfo
+ and getaddrinfo if available.
+ * configure.in: Check for IPv6 support.
+
+2000-11-01 Ezra Peisach <epeisach@mit.edu>
+
+ * configure.in: Quote macro use inside AC_CHECK_LIB. Change
+ AC_FUNC_CHECK to AC_CHECK_FUNC, AC_HAVE_FUNCS to AC_CHECK_FUNCS
+ and AC_HEADER_CHECK to AC_CHECK_HEADER..
+
+2000-06-30 Ezra Peisach <epeisach@mit.edu>
+
+ * pty-int.h: Add getutmpx() prototype if needed.
+
+ * configure.in: If getutmpx() exists on the system, test if a
+ prototype is provided by the system headers.
+
+2000-06-28 Ezra Peisach <epeisach@mit.edu>
+
+ * getpty.c (pty_getpty): More conditionalizing variable defintion
+ based on OS features.
+
+ * cleanup.c (pty_cleanup): Add parenthesis about assignment in
+ conditional (gcc suggestion).
+
+ * pty-int.h: Include pty.h if it exists (for openpty prototype
+ under Linux).
+
+ * configure.in: Check for pty.h
+
+2000-06-26 Ezra Peisach <epeisach@mit.edu>
+
+ * libpty.h: If SOCK_DGRAM is not defined, provide a definition for
+ struct sockaddr_in to satisfy prototype. (based on similar
+ code in k5-int.h).
+
+ * update_wtmp.c (ptyint_update_wtmp), update_utmp.c
+ (pty_update_utmp), open_slave.c (pty_open_slave), getpty.c
+ (pty_getpty): conditionalize definition of variables based on code
+ paths that are included.
+
+
+
+1999-10-26 Tom Yu <tlyu@mit.edu>
+
+ * configure.in: Check for alpha*-dec-osf* instead of
+ alpha-dec-osf*.
+
+1999-10-26 Wilfredo Sanchez <tritan@mit.edu>
+
+ * Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES,
+ LOCAL_INCLUDES such that one can override CFLAGS from the command
+ line without losing CPP search patchs and defines. Some associated
+ Makefile cleanup.
+
+1999-08-03 Ken Raeburn <raeburn@mit.edu>
+
+ * update_utmp.c (pty_update_utmp): Use "co" instead of "cons" for
+ console line on Solaris. Patch from Larry Schwimmer
+ (schwim@whatmore.Stanford.EDU).
+
+ * Makefile.in (dump-utmp): Add a rule for building, never
+ automatically done.
+ (dump-utmp.o): Depends on dump-utmp.c.
+
+ Updates from Cygnus KerbNet:
+
+ * dump-utmp.c (ut_typename): Only define if
+ HAVE_STRUCT_UTMP_UT_TYPE is defined.
+ (main): Dump more info, and conditionalize it better.
+
+ * dump-utmp.c (ctime): Declare, to prevent crashes on Alpha.
+
+ * dump-utmp.c (UTMPX): Define if not defined but HAVE_UTMPX_H is
+ defined.
+ (ut_typename): Return shorter forms for some symbols.
+ (main): Require `-x' flag for [uw]tmpx file instead of guessing
+ from the name. Reject unknown `-' arguments. Print a message if
+ an error occurs while reading from utmpx file. Break up output
+ statements into smaller pieces. Conditionalize output of some
+ utmp fields on whether those fields are present. Print out exit
+ status fields and timestamp.
+
+Fri Apr 23 23:13:57 1999 Tom Yu <tlyu@mit.edu>
+
+ * update_utmp.c (pty_update_utmp): utx.ut_pid is a pid_t, and
+ ent.ut_pid is sometimes a short; accordingly, use pid rather than
+ ent.ut_pid, which might have gotten truncated. This fixes an Irix
+ problem found by <rbasch@mit.edu>.
+
+1999-04-14 <tytso@rsts-11.mit.edu>
+
+ * update_wtmp.c: Don't use updwtmpx() even if it exists for glibc
+ 2.1, since it's the same as updwtmp(), and glibc doesn't
+ define PATH_WTMPX. updwtmpx() is not part of the XPG
+ standard anyway. (Needed for RedHat 6.0.)
+
+Sun Mar 28 17:50:57 1999 Tom Yu <tlyu@mit.edu>
+
+ * update_wtmp.c: Define WTMPX_FILE to be _PATH_WTMPX in case we're
+ on a system that cleans up the namespace that way.
+
+Wed Feb 17 19:47:36 1999 Tom Yu <tlyu@mit.edu>
+
+ * sane_hostname.c (pty_make_sane_hostname): Remove unused
+ "char *scratch".
+
+Tue Feb 16 20:18:40 1999 Tom Yu <tlyu@mit.edu>
+
+ * sane_hostname.c: Re-order so that pty-int.h precedes libpty.h to
+ prevent conflicting definitions of struct sockaddr_in
+
+Thu Feb 11 22:24:03 1999 Tom Yu <tlyu@mit.edu>
+
+ * sane_hostname.c: Force maxlen to be 16 if it's less than 16,
+ since otherwise a numeric IP address won't fit.
+
+ * Makefile.in: Add sane_hostname.{o,c}; bump minor version.
+
+ * libpty.h: Add prototype for make_sane_hostname.
+
+ * sane_hostname.c: New file; add function to "sanitize" hostname
+ for logging purposes.
+
+1999-01-27 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * configure.in: Remove test CHECK_WAIT_TYPE since nothing is using
+ the results of that test (WAIT_USES_INT).
+
+1998-08-16 <hartmans@fundsxpress.com>
+
+ * Makefile.in (SHLIB_EXPDEPS): Depend on lib_comerr
+
+1998-07-05 <hartmans@fundsxpress.com>
+
+ * update_utmp.c (pty_update_utmp): If the ut_exit differs test
+ indicates the structures differ, and we don't have a special case,
+ do nothing rather than trying to copy the field. It's not worth
+ breaking the build over.
+
+Mon Apr 6 19:35:33 1998 Tom Yu <tlyu@voltage-multiplier.mit.edu>
+
+ * update_utmp.c (pty_update_utmp): Don't record LOGIN_PROCESS
+ entries, as they confuse last on some systems. [pty/569]
+
+Thu Mar 12 18:09:25 1998 Tom Yu <tlyu@mit.edu>
+
+ * update_utmp.c (pty_update_utmp): Fix bogus entry of
+ PTY_LOGIN_PROCESS types on BSD-ish systems. [pty/531]
+
+Wed Feb 18 16:33:58 1998 Tom Yu <tlyu@mit.edu>
+
+ * Makefile.in: Remove trailing slash from thisconfigdir. Fix up
+ BUILDTOP for new conventions.
+
+Mon Feb 2 16:18:08 1998 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Makefile.in: Define BUILDTOP and thisconfigdir in the Makefile
+
+ * configure.in, Makefile.in: Remove CopySrcHeader and CopyHeader
+ from configure.in and move equivalent functionality to
+ Makefile.in
+
+Sun Dec 7 00:05:28 1997 Tom Yu <tlyu@mit.edu>
+
+ * getpty.c (pty_getpty): Fix goof in previous, which introduced
+ another fencepost error.
+
+Thu Dec 4 21:48:12 1997 Tom Yu <tlyu@mit.edu>
+
+ * getpty.c (pty_getpty): Fix checks on string lengths to account
+ for terminating nul character. Some whitespace fixups.
+
+Wed Dec 3 17:16:44 1997 Tom Yu <tlyu@mit.edu>
+
+ * pty_err.et: Add PTY_OPEN_SLAVE_TOOSHORT error code.
+
+ * open_slave.c (pty_open_slave): Check to ensure that the slave
+ name is not NULL or zero-length.
+
+Tue Oct 28 13:28:54 1997 Ezra Peisach <epeisach@.mit.edu>
+
+ * pty-int.h: Do not prototype initialize_pty_error_table as
+ pty-err.h does as well.
+
+Fri Oct 24 09:12:43 1997 Ezra Peisach <epeisach@mit.edu>
+
+ * Makefile.in (CFILES): Add $(srcdir).
+
+Wed Oct 1 04:53:30 1997 Tom Yu <tlyu@mit.edu>
+
+ * configure.in: Default to a long rather than an int for a time_t
+ for paranoia reasons.
+
+Tue Jun 3 23:05:07 1997 Theodore Y. Ts'o <tytso@mit.edu>
+
+ * getpty.c (pty_getpty): Remove erroneous space from the HPUX open().
+
+Fri Apr 25 19:14:48 1997 Theodore Y. Ts'o <tytso@mit.edu>
+
+ * configure.in: Check for openpty() in -lutil. It's there on
+ FreeBSD and BSDI systems.
+
+Fri Feb 21 18:25:47 1997 Sam Hartman <hartmans@tertius.mit.edu>
+
+ * pty-int.h: No longer prototype error table init function.
+
+Thu Jan 16 18:47:12 1997 Tom Yu <tlyu@mit.edu>
+
+ * Makefile.in: Cause "clean" to dtrt.
+
+ * configure.in: Punt spurious call to KRB5_LIB_PARAMS.
+
+Sun Dec 29 21:32:41 1996 Tom Yu <tlyu@mit.edu>
+
+ * Makefile.in: Update to set STLIBOBJS instead of LIBSRCS; also
+ clean up a little bit.
+
+Fri Dec 27 17:09:46 1996 Tom Yu <tlyu@mit.edu>
+
+ * Makefile.in: Fix to use OBJS.ST rather than ./OBJS.ST.
+
+ * Makefile.in:
+ * configure.in: Changes to use new library build system.
+
+Thu Dec 5 22:43:35 1996 Theodore Y. Ts'o <tytso@mit.edu>
+
+ * update_utmp.c (pty_update_utmp): Apply platform specific patch
+ so that HPUX works. (Kludge for 1.0 release) [PR#40]
+
+Fri Nov 22 11:52:52 1996 Sam Hartman <hartmans@mit.edu>
+
+ * configure.in : Make sure time_t is define [203]
+ * update_wtmp.c (ptyint_update_wtmp): Use time_t for call to time(2). [203]
+
+Fri Nov 15 08:33:54 1996 Ezra Peisach <epeisach@mit.edu>
+
+ * update_utmp.c (pty_update_utmp): Handle case where utmp uses
+ ut_exit.e_exit and utmpx uses ut_exit.ut_exit.
+
+ * configure.in (UT_EXIT_STRUCTURE_DIFFER): If utmpx.h exists, and
+ getutmpx does not exist then test if the ut_exit part of
+ the utmp/utmpx structure is a structure and if their types
+ differ. (e_exit vs. ut_exit).
+
+Fri Nov 8 17:45:42 1996 Theodore Y. Ts'o <tytso@mit.edu>
+
+ * update_utmp.c (pty_update_utmp): Add code which attempts to
+ compensate for systems that don't have getutmpx()
+
+ * configure.in: Check for getutmpx(). Replace calls to
+ AC_FUNC_CHECK with AC_HAVE_FUNCS().
+
+Thu Jun 13 22:14:24 1996 Tom Yu <tlyu@voltage-multiplier.mit.edu>
+
+ * configure.in: remove ref to ET_RULES
+
+
+Thu Jun 13 14:12:16 1996 Sam Hartman <hartmans@mit.edu>
+
+ * update_wtmp.c (ptyint_update_wtmp): Only update wtmpx if we have
+ updwtmpx. This probably should be more general, but I'm not
+ really sure of HP caviats.
+
+ * configure.in : check for updwtmpx
+
+ * getpty.c (pty_getpty): Actually check for 256 ptys on SunOS and
+ other old-style systems.
+Tue Apr 16 22:06:36 1996 Ken Raeburn <raeburn@cygnus.com>
+
+ * dump-utmp.c: New file. Not automatically used by anything, but
+ may be useful for examining utmp/wtmp files when comparing
+ behavior against system software.
+
+ Sun Mar 31 02:04:28 1996 Ken Raeburn <raeburn@cygnus.com>
+
+ * update_utmp.c (pty_update_utmp): Always use id "cons" for
+ console. For HP-UX, omit "kl" prefix. Reindent for readability.
+ * update_wtmp.c (ptyint_update_wtmp): For HP-UX, copy ut_id and
+ ut_type from input utmp structure. Reindent for readability.
+
+ Wed Mar 27 21:14:33 1996 Marc Horowitz <marc@mit.edu>
+
+ * init_slave.c (pty_initialize_slave): Spurious signal stuff
+ which did nothing deleted.
+
+Tue Apr 16 13:43:43 1996 Sam Hartman <hartmans@mit.edu>
+
+ * configure.in : Don't use streams on HPUX.
+
+ * getpty.c (pty_getpty): Check /dev/ptym/clone for HPUX10, only
+ try /dev/ptmx if HAVE_STREAMS defined so we can bipass for HPUX9.
+
+Sun Apr 14 00:36:33 1996 Sam Hartman <hartmans@mit.edu>
+
+ * pty-int.h: Don't include sys/wait.h here.
+
+ * configure.in : Check for waitpid.
+
+Sat Apr 13 18:58:43 1996 Sam Hartman <hartmans@mit.edu>
+
+ * cleanup.c (pty_cleanup): If we are doing a vhangup, then fork
+ and dissociate on hangup. This makes the HP happy, because there
+ is no way to get rid of a controlling terminal besides setsid() on
+ the HP.
+
+Sun Mar 24 19:59:14 1996 Sam Hartman <hartmans@tertius.mit.edu>
+
+ * configure.in : Do streams handling by deciding what modules to
+ push for each system.
+
+ * init_slave.c (pty_initialize_slave): Better abstraction for
+ dealing with what modules get pushed on what streams system.
+ There is a list of modules controlled on a module-by-module basis
+ by configure.in, and the modules included in that list are pushed.
+
+ * void_assoc.c: Duplicate comment from open_ctty.c explaining that
+ it's OK to call void_association twice, and giving the caviats
+ about setsid.
+
+ * open_ctty.c (pty_open_ctty): Remove test to make sure /dev/tty
+ worked, so we can push the streams for the HP.
+
+ * open_slave.c (pty_open_slave): Test to see if /dev/tty works
+ only after calling pty_initialize_slave.
+
+Sat Mar 23 15:24:38 1996 Sam Hartman <hartmans@tertius.mit.edu>
+
+ * configure.in : Remove shadow passwords check because nothing in
+ libpty cares about the result; remove use of libkrb5, libkrb4,
+ libkadm; Check for _getpty
+
+ * getpty.c (pty_getpty): Support _getpty for Irix; Irix has
+ /dev/ptmx, but it doesn't work correctly at all. Also, Irix,
+ tends to create device nodes on the fly.
+
+ * pty-int.h: No need to include sys/socket.h
+
+Sat Feb 24 21:34:58 1996 Theodore Y. Ts'o <tytso@dcl>
+
+ * vhangup.c (ptyint_vhangup): Don't do call vhangup() if system
+ doesn't have it.
+
+Sat Jan 27 01:13:34 1996 Mark Eichin <eichin@cygnus.com>
+
+ * void_assoc.c (ptyint_void_association): if we don't have
+ TIOCNOTTY (HP/UX 9 for example) don't try to use it.
+
+Fri Jan 26 00:26:37 1996 Sam Hartman <hartmans@tertius.mit.edu>
+
+ * cleanup.c (pty_cleanup): Update utmp only if update_utmp is true.
+
+Tue Jan 16 13:52:22 1996 Sam Hartman <hartmans@tertius.mit.edu>
+
+ * void_assoc.c (ptyint_void_association): Move setsid call from
+ open_ctty to void_association.
+
+ * logwtmp.c (pty_logwtmp): Pass user argument to update_wtmp.
+
+ * update_utmp.c (update_utmp): Implement PTY_UTMP_USERNAME_VALID flag
+
+Mon Jan 15 15:48:37 1996 Sam Hartman (hartmans@justforfun)
+
+ * cleanup.c: Change to indiciate utmp user name is valid.
+
+ *
+
+Mon Jan 15 15:21:16 1996 Sam Hartman <hartmans@tertius.mit.edu>
+
+ * update_utmp.c (pty_update_utmp): Add flags field; use ttyslot
+ only if reasonable.
+
+Fri Jan 12 16:33:37 1996 Sam Hartman <hartmans@infocalypse>
+
+ * open_slave.c (pty_open_slave): Don't use fchmod or fchown; they
+ don't buy much security unless /dev is world-writable and may
+ prevent Solaris lossage.
+
+Thu Dec 21 00:12:58 1995 Sam Hartman <hartmans@portnoy>
+
+ * open_slave.c (pty_open_slave): Open with no delay.
+
+
+Wed Jan 10 22:20:04 1996 Theodore Y. Ts'o <tytso@dcl>
+
+ * open_slave.c (pty_open_slave): Added hack by Doug Engert to get
+ util/pty to work under Solaris. We should double check to
+ make sure this is a correct fix.
+
+
+Sun Nov 12 12:44:33 1995 Sam Hartman <hartmans@tertius.mit.edu>
+
+ * open_ctty.c (pty_open_ctty): Remove redundant Ultrix calls to setpgrp()
+
+Sun Oct 22 03:48:37 1995 Sam Hartman <hartmans@tertius.mit.edu>
+
+ * update_wtmp.c (ptyint_update_wtmp): Add comments explaining why ifdefs are right.
+
+Sun Oct 22 01:20:52 1995 Sam Hartman <hartmans@infocalypse>
+
+ * update_wtmp.c (ptyint_update_wtmp): Try utx not uts.
+
+Mon Oct 16 17:41:45 1995 Sam Hartman <hartmans@tertius.mit.edu>
+
+
+
+ * update_wtmp.c (ptyint_update_wtmp): Update to take host name, so
+ we can get the full host name if it is chopped in utmp.
+ * update_wtmp.c (ptyint_update_wtmp): Insert fallback path for Sunos and others, return defined value.
+
+
+
+
+ * update_utmp.c (pty_update_utmp): Incorperate utmpx handling patch from ramus@nersc.gov to deal with support for longer hostanmes in utmpx.
+
+
+*update_utmp.c: Add return statement and fallback path for Sunos.
+
+Sat Oct 14 20:49:40 1995 Sam Hartman <hartmans@tertius.mit.edu>
+Fri Aug 11 17:49:36 1995 Samuel D Hartman (hartmans@vorlon)
+
+
+Fri Sep 29 14:18:03 1995 Theodore Y. Ts'o <tytso@dcl>
+ * update_wtmp.c (ptyint_update_wtmp): If EMPTY not defined as a
+ utmp type, use DEAD_PROCESS.
+
+
+
+ * configure.in:
+ * Makefile.in: Use the SubdirLibraryRule defined in aclocal.m4 to
+ create the DONE file (and to properly clean it up).
+
+Mon Sep 25 16:42:36 1995 Theodore Y. Ts'o <tytso@dcl>
+
+ * Makefile.in: Removed "foo:: foo-$(WHAT)" lines from the
+ Makefile.
+
+Thu Sep 7 19:13:05 1995 Mark Eichin <eichin@cygnus.com>
+
+ * update_utmp.c: ultimately fall back to /etc/utmp for UTMP_FILE,
+ if it is still missing after all previous efforts.
+ * update_wtmp.c: /usr/adm/wtmp for WTMP_FILE likewise.
+
+Thu Aug 24 18:40:48 1995 Theodore Y. Ts'o <tytso@dcl>
+
+ * .Sanitize: Update file list
+
+Tue Aug 15 21:42:16 1995 <tytso@rsts-11.mit.edu>
+
+ * update_wtmp.c (ptyint_update_wtmp): If EMPTY is not defined,
+ then set ut.ut_type to 0 instead.
+
+
+
+Fri Aug 11 15:49:30 1995 Sam Hartman <hartmans@tertius.mit.edu>
+
+ * Makefile.in (CFILES): Rename initialize_slave.c to init_slave.c
+ so it isn't truncated in libpty.a.
+
+Fri Aug 11 01:12:03 1995 Sam Hartman <hartmans@infocalypse>
+
+ * initialize_slave.c (pty_initialize_slave): You really do need to
+ push and pop the streams on a Sun.
+
+Fri Aug 11 00:49:23 1995 Sam Hartman <hartmans@dragons-lair.MIT.EDU>
+
+ * configure.in (ac_cv_func_setsid): Pretend that Ultrix doesn't
+ have setsid, because if it does make the call then the pty never
+ becomes controlling tty.
+
+Thu Aug 10 09:47:07 1995 Sam Hartman <hartmans@dragons-lair.MIT.EDU>
+
+ * open_ctty.c (pty_open_ctty): Move setpgrp() after void_assoc call
+
+Wed Aug 9 00:16:40 1995 Sam Hartman <hartmans@tertius.mit.edu>
+
+ * pty-int.h (VHANG_first): Change defines so VHANG_FIRST doesn't
+ get defined under Ultrix because Ultrix can only establish
+ controlling terminal once per process and we need to get
+ controlling terminal again after vhangup().
+
+ * getpty.c (pty_getpty): Use the right test for slave buffer length.
+
+Tue Aug 8 22:20:33 1995 Tom Yu <tlyu@lothlorien.MIT.EDU>
+
+ * update_utmp.c (UTMP_FILE): _PATH_UTMP under NetBSD, not
+ _UTMP_PATH; also fix typo (missing '&' on reference to
+ ent)
+
+Tue Aug 8 20:47:01 1995 Tom Yu <tlyu@dragons-lair.MIT.EDU>
+
+ * update_utmp.c (pty_update_utmp): change #ifdef NO_UT_PID to
+ #ifndef
+
+Tue Aug 8 09:13:50 1995 Sam Hartman <hartmans@pao.mit.edu>
+
+ * open_slave.c (pty_open_slave): Dissociate from controlling
+ terminal before calling revoke.
+ (pty_open_slave): Don't ask for a controlling terminal unless we need it.
+
+Tue Aug 8 20:32:08 1995 Tom Yu <tlyu@dragons-lair.MIT.EDU>
+
+ * update_utmp.c: flush preprocessor directive to left margin.
+ * pty_err.et: Fix typo in error description.
+
+ * cleanup.c (pty_cleanup): Don't change slave before revoking it. Also return a value all the time, not just on systems without revoke.
+
+
+ * update_utmp.c (pty_update_utmp): Move #ifdef back to column 1.
+
+Mon Aug 7 17:41:39 1995 Sam Hartman <hartmans@tertius.mit.edu>
+
+ * cleanup.c (pty_cleanup): Call pty_update_utmp using new interface.
+
+ * update_utmp.c logwtmp.c : Call ptyint_update_wtmp not pty_update_wtmp.
+
+ * cleanup.c (pty_cleanup): We can't use pid_t because we need to
+ use something in libpty.h and we can't wait for pid_t to be
+ defined there because we may not have configure.
+
+ * update_wtmp.c (pty_update_wtmp): Rename to ptyint_update_wtmp.
+
+ * update_utmp.c (pty_update_utmp): Change interface so it doesn't take a struct utmp.
+
+ * libpty.h: Remove pty_update_wtmp as it's becoming an internal interface.
+
+Sat Aug 5 01:00:35 1995 Ezra Peisach <epeisach@kangaroo.mit.edu>
+
+ * open_slave.c (pty_open_slave): pty_open_ctty returns != 0 on
+ error, not less than.
+
+Fri Aug 4 13:59:11 1995 Theodore Y. Ts'o <tytso@dcl>
+
+ * libpty.h (pty_cleanup): Fix argument type of pid to patch that
+ used in the C file. Include <utmpx.h> if present. Only
+ include <utmp.h> if it is present.
+
+ * configure.in: Check for utmp.h and utmpx.h
+
+Fri Aug 4 00:59:20 1995 Tom Yu <tlyu@dragons-lair.MIT.EDU>
+
+ * Makefile.in: use libupdate so to not get multiple copies of
+ object files upon rebuild.
+
+ * vhangup.c (ptyint_vhangup): Make sure preprocessor directives
+ are at left margin.
+
+ * open_slave.c (pty_open_slave): Make sure preprocessor directives
+ are at left margin.
+
+ * open_ctty.c (pty_open_ctty): Make sure preprocessor directives
+ are at left margin.
+
+ * cleanup.c (pty_cleanup): Add missing declarations for retval and
+ fd. Also, align preprocessor directives with left margin.
+
+Thu Aug 3 15:04:34 1995 Sam Hartman <hartmans@tertius.mit.edu>
+
+ * configure.in: Check for vhangup and killpg.
+
+ * cleanup.c (pty_cleanup): Kill the process group associated with
+ the pty if using revoke. This won't always work, but will at
+ least attempt to remove processes associated with the pty.
+
+Wed Aug 2 11:59:19 1995 Sam Hartman <hartmans@tertius.mit.edu>
+
+ * init.c (pty_init): New file to handle initialization--currently only error tables.
+
+ * getpty.c (pty_getpty): Reverse sense of logic tests so they work.
+
+Tue Aug 1 08:20:06 1995 Sam Hartman <hartmans@tertius.mit.edu>
+
+ * cleanup.c (pty_cleanup): Allow pid to be zero (unknown).
+
+ * pty-int.h: Define VHANG_FIRST and VHANG_LAST based on presence
+ of vhangup.
+
+ * pty_err.et: Define PTY_GETPTY_SLAVE_TOOLONG
+
+ * getpty.c (pty_getpty): Close slave side if we call openpty.
+
+ (pty_getpty): Take length parameter; return error if it isn't big enough.
+
+
+
+Tue Aug 1 12:06:14 1995 Ezra Peisach <epeisach@kangaroo.mit.edu>
+
+ * open_ctty.c (pty_open_ctty): Fixed typo TIOCSTTY to TIOCSCTTY.
+
+
diff --git a/src/appl/libpty/Makefile.in b/src/appl/libpty/Makefile.in
new file mode 100644
index 0000000..3c3ca38
--- /dev/null
+++ b/src/appl/libpty/Makefile.in
@@ -0,0 +1,157 @@
+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) ./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:: 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)
+
+
+# @lib_frag@
+# @libobj_frag@
+
+# +++ Dependency line eater +++
+#
+# Makefile dependencies follow. This must be the last section in
+# the Makefile.in file
+#
+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/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/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
diff --git a/src/appl/libpty/README b/src/appl/libpty/README
new file mode 100644
index 0000000..f10dd2b
--- /dev/null
+++ b/src/appl/libpty/README
@@ -0,0 +1,108 @@
+ 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.
+
+
+
diff --git a/src/appl/libpty/cleanup.c b/src/appl/libpty/cleanup.c
new file mode 100644
index 0000000..57cc796
--- /dev/null
+++ b/src/appl/libpty/cleanup.c
@@ -0,0 +1,112 @@
+/*
+ * 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;
+}
diff --git a/src/appl/libpty/configure.in b/src/appl/libpty/configure.in
new file mode 100644
index 0000000..7600b1d
--- /dev/null
+++ b/src/appl/libpty/configure.in
@@ -0,0 +1,269 @@
+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_CHECK_LIB(security,main,
+ AC_DEFINE(HAVE_SETLUID,1,[Define if setluid is provided by the security library])
+ LOGINLIBS="$LOGINLIBS -lsecurity"
+ )
+ 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_SUBST(LOGINLIBS)
+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 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
+dnl KRB5_BUILD_LIBRARY_WITH_DEPS
+KRB5_BUILD_LIBRARY_STATIC
+KRB5_BUILD_LIBOBJS
+KRB5_BUILD_PROGRAM
+KRB5_RUN_FLAGS
+V5_AC_OUTPUT_MAKEFILE
diff --git a/src/appl/libpty/dump-utmp.c b/src/appl/libpty/dump-utmp.c
new file mode 100644
index 0000000..d4c303f
--- /dev/null
+++ b/src/appl/libpty/dump-utmp.c
@@ -0,0 +1,281 @@
+/*
+ * 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);
+}
diff --git a/src/appl/libpty/getpty.c b/src/appl/libpty/getpty.c
new file mode 100644
index 0000000..610a471
--- /dev/null
+++ b/src/appl/libpty/getpty.c
@@ -0,0 +1,150 @@
+/*
+ * 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"
+
+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 (strlen(slaveret) > slavelength - 1) {
+ close(*fd);
+ *fd = -1;
+ return PTY_GETPTY_SLAVE_TOOLONG;
+ }
+ else strcpy(slave, slaveret);
+ 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 (strlen(p) > slavelength - 1) {
+ close (*fd);
+ *fd = -1;
+ return PTY_GETPTY_SLAVE_TOOLONG;
+ }
+ strcpy(slave, p);
+ return 0;
+ }
+
+ if (fstat(*fd, &stb) < 0) {
+ close(*fd);
+ return PTY_GETPTY_FSTAT;
+ }
+ ptynum = (int)(stb.st_rdev&0xFF);
+ sprintf(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++) {
+ sprintf(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);
+}
diff --git a/src/appl/libpty/init.c b/src/appl/libpty/init.c
new file mode 100644
index 0000000..b48a1f8
--- /dev/null
+++ b/src/appl/libpty/init.c
@@ -0,0 +1,33 @@
+/*
+ * 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;
+}
diff --git a/src/appl/libpty/init_slave.c b/src/appl/libpty/init_slave.c
new file mode 100644
index 0000000..ce75076
--- /dev/null
+++ b/src/appl/libpty/init_slave.c
@@ -0,0 +1,100 @@
+/*
+ * 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;
+}
diff --git a/src/appl/libpty/libpty.h b/src/appl/libpty/libpty.h
new file mode 100644
index 0000000..d95c8fe
--- /dev/null
+++ b/src/appl/libpty/libpty.h
@@ -0,0 +1,54 @@
+/*
+ * 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
diff --git a/src/appl/libpty/logwtmp.c b/src/appl/libpty/logwtmp.c
new file mode 100644
index 0000000..21a35d3
--- /dev/null
+++ b/src/appl/libpty/logwtmp.c
@@ -0,0 +1,112 @@
+/*
+ * 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;
+ sprintf(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)) */
diff --git a/src/appl/libpty/open_ctty.c b/src/appl/libpty/open_ctty.c
new file mode 100644
index 0000000..5a1730b
--- /dev/null
+++ b/src/appl/libpty/open_ctty.c
@@ -0,0 +1,67 @@
+/*
+ * 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;
+}
diff --git a/src/appl/libpty/open_slave.c b/src/appl/libpty/open_slave.c
new file mode 100644
index 0000000..5bab6bc
--- /dev/null
+++ b/src/appl/libpty/open_slave.c
@@ -0,0 +1,101 @@
+/*
+ * 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;
+}
diff --git a/src/appl/libpty/pty-int.h b/src/appl/libpty/pty-int.h
new file mode 100644
index 0000000..b94a65c
--- /dev/null
+++ b/src/appl/libpty/pty-int.h
@@ -0,0 +1,138 @@
+/* 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
diff --git a/src/appl/libpty/pty_err.et b/src/appl/libpty/pty_err.et
new file mode 100644
index 0000000..770cce7
--- /dev/null
+++ b/src/appl/libpty/pty_err.et
@@ -0,0 +1,50 @@
+#
+# 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
diff --git a/src/appl/libpty/pty_paranoia.c b/src/appl/libpty/pty_paranoia.c
new file mode 100644
index 0000000..466a658
--- /dev/null
+++ b/src/appl/libpty/pty_paranoia.c
@@ -0,0 +1,650 @@
+/*
+ * 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);
+}
diff --git a/src/appl/libpty/sane_hostname.c b/src/appl/libpty/sane_hostname.c
new file mode 100644
index 0000000..8ef6de8
--- /dev/null
+++ b/src/appl/libpty/sane_hostname.c
@@ -0,0 +1,116 @@
+/*
+ * 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;
+}
diff --git a/src/appl/libpty/update_utmp.c b/src/appl/libpty/update_utmp.c
new file mode 100644
index 0000000..0045826
--- /dev/null
+++ b/src/appl/libpty/update_utmp.c
@@ -0,0 +1,706 @@
+/*
+ * 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.
+ *
+ * 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"
+
+#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. See the above history rant
+ * for further explanation.
+ */
+#if defined(HAVE_SETUTXENT) || defined(HAVE_SETUTENT)
+#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
+
+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
+ strcpy(utmp_id, cp);
+#else
+ if (len > 2 && *(cp - 1) != '/')
+ sprintf(utmp_id, "k%s", cp - 1);
+ else
+ sprintf(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
diff --git a/src/appl/libpty/update_wtmp.c b/src/appl/libpty/update_wtmp.c
new file mode 100644
index 0000000..988bae6
--- /dev/null
+++ b/src/appl/libpty/update_wtmp.c
@@ -0,0 +1,127 @@
+/*
+ * 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
diff --git a/src/appl/libpty/vhangup.c b/src/appl/libpty/vhangup.c
new file mode 100644
index 0000000..2924371
--- /dev/null
+++ b/src/appl/libpty/vhangup.c
@@ -0,0 +1,50 @@
+/*
+ * 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
+}
diff --git a/src/appl/libpty/void_assoc.c b/src/appl/libpty/void_assoc.c
new file mode 100644
index 0000000..a39c9c7
--- /dev/null
+++ b/src/appl/libpty/void_assoc.c
@@ -0,0 +1,49 @@
+/*
+ * 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;
+}