summaryrefslogtreecommitdiffstats
path: root/src/appl/libpty/update_utmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/appl/libpty/update_utmp.c')
-rw-r--r--src/appl/libpty/update_utmp.c724
1 files changed, 0 insertions, 724 deletions
diff --git a/src/appl/libpty/update_utmp.c b/src/appl/libpty/update_utmp.c
deleted file mode 100644
index bec57fa318..0000000000
--- a/src/appl/libpty/update_utmp.c
+++ /dev/null
@@ -1,724 +0,0 @@
-/*
- * pty_update_utmp: Update or create a utmp entry
- *
- * Copyright 1995, 2001 by the Massachusetts Institute of Technology.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that copyright notice and this permission
- * notice appear in supporting documentation, and that the name of
- * M.I.T. not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability
- * of this software for any purpose. It is provided "as is" without
- * express or implied warranty.
- */
-
-/*
- * Rant about the historical vagaries of utmp:
- * -------------------------------------------
- *
- * There exist many subtly incompatible incarnations of utmp, ranging
- * from BSD to System V to Unix98 and everywhere in between. This
- * rant attempts to collect in one place as much knowledge as possible
- * about this portability nightmare.
- *
- * BSD:
- * ----
- *
- * The simplest (and earliest? possibly dating back to Version 7...)
- * case is 4.x BSD utmp/wtmp. There are no auxiliary files. There is
- * only a struct utmp, declared in utmp.h. Its contents usually
- * include:
- *
- * char ut_line[]
- * char ut_name[]
- * char ut_host[]
- * long ut_time
- *
- * The meanings of these fields follow their names reasonbly well.
- * The ut_line field usually is the pathname of the tty device
- * associated with the login, with the leading "/dev/" stripped off.
- *
- * It is believed that ut_host is nul-terminated, while the other
- * strings are merely nul-padded.
- *
- * Generally, ut_name is an empty string for a logout record in both
- * utmp and wtmp. For entries made by the window system or other
- * terminal emulation stuff, ut_host is an empty string (at least
- * under SunOS 4.x, it seems). The macro nonuser() is used to
- * determine this if a utmp entry is made by the window system on at
- * least SunOS 4.x.
- *
- * The native login never clears its own utmp entry or writes its own
- * logout record; its parent (one of init, rlogind, telnetd, etc.)
- * should handle that. In theory, getty could do that, but getty
- * usually doesn't fork to exec login.
- *
- * Old (c. 1984) System V:
- * -----------------------
- *
- * This is partially conjecture, based on some reading of
- * /usr/xpg2include/utmp.h on a SunOS 4.x system. There appears to
- * only be a struct utmp, declared in utmp.h. It is likely used for
- * both utmp and wtmp files. It is quite likely that the utmp is only
- * supposed to be accessed via the getutline()/pututline() API. The
- * contents of struct utmp seem to include:
- *
- * char ut_user[]
- * char ut_id[]
- * char ut_line[]
- * short ut_pid
- * short ut_type
- * struct exit_status ut_exit
- * time_t ut_time
- *
- * On these systems, ut_name is often #define'ed to be ut_user to be
- * somewhat compatible with the BSD-style utmp. Note that there is
- * not necessarily a ut_host field in this utmp structure.
- *
- * The ut_id field bears some explanation. The systems that use this
- * style of utmp also use a sysV-ish init, which starts processes out
- * of /etc/inittab rather than /etc/ttys, and has the concept of
- * runlevels. The first field in each line of /etc/inittab contains a
- * unique ID field. init probably gets really confused if there are
- * conflicts here. Every process that init starts gets its own entry
- * written to utmp.
- *
- * It is possible for multiple entries to have the same ut_line but
- * different ut_id values, since the sysadmin will be responsible for
- * assigning values to ut_id. Usually, ut_id is four characters,
- * while the permissible unique ID values for entries in /etc/inittab
- * are constrained to two characters, but this is not always the
- * case. In the case where we are emulating the vendor's login
- * program and being run out of getty, we need to account for which
- * value of ut_id was used by the getty, since pututline() will search
- * based on ut_id and not ut_line for some reason.
- *
- * The ut_pid and ut_type fields are used for bookkeeping by init.
- * The ut_type field gets the value INIT_PROCESS for processes started
- * by init. It gets the value LOGIN_PROCESS if it is a process that
- * is prompting for a login name, and it gets the value USER_PROCESS
- * for an actual valid login. When the process dies, either init
- * cleans up after it and records a DEAD_PROCESS entry in utmp, or the
- * process itself does so. It's not completely clear which actually
- * happens, though it is quite possible that init only cleans up after
- * processes that it starts itself.
- *
- * Other values of ut_type exist; they're largely internal bookkeeping
- * for init's runlevels and such, and don't really interest this
- * library at all.
- *
- * The ut_exit field contains the following members:
- *
- * short e_termination
- * short e_exit
- *
- * It is not clear how these values are used; presumably they record
- * the process termination status of dead processes.
- *
- * There is no uniform API for manipulating wtmp on systems that use
- * this sort of utmp structure; it can be assumed that the structure
- * can be directly written to the wtmp file.
- *
- * Unix98:
- * -------
- *
- * This description also likely applies to later System V derivatives
- * as well as systems conforming to earlier X/Open standards such as
- * XPG4. There is a new header, utmpx.h, which defines a struct utmpx
- * and a new getutxline()/pututxline() API for accessing it. Some
- * systems actually have a utmpx file on disk; others use the utmpx
- * API to access a file named utmp, just to further confuse matters.
- *
- * The utmpx structure is guaranteed (by Unix98) to contain at least
- * the following:
- *
- * char ut_user[]
- * char ut_line[]
- * char ut_id[]
- * pid_t ut_pid
- * short ut_type
- * struct timeval ut_tv
- *
- * It is not guaranteed to contain, but often does contain, the
- * following:
- *
- * char ut_host[]
- * int ut_syslen
- * int ut_session
- * struct exit_status ut_exit
- *
- * The ut_syslen field, on systems that contain it, contains the
- * number of significant characters in ut_host, including the
- * terminating nul character.
- *
- * The main difference between this struct utmpx and the struct utmp
- * used by early sysV derivatives is the change from a time_t or long
- * for ut_time to a struct timeval for ut_tv.
- *
- * Comments in various header files imply that ut_session is used for
- * window systems, but it's not clear how. Perhaps it contains the
- * session ID of the session running the window system, e.g. the xdm
- * or X server on an X11 system.
- *
- * Most of the description of the earlier sysV format probably applies
- * here, with suitable changes of names. On systems that maintain
- * utmpx and utmp files in parallel, it is assumed that using the
- * pututxline() API is sufficient to keep them in sync. There are no
- * known counterexamples to this.
- *
- * Nevertheless, there are, on some systems, API functions getutmp()
- * and getutmpx() that appear to convert from struct utmpx to struct
- * utmp and vice versa. This could be useful when there is a wtmp
- * file but not a corresponding wtmpx file.
- *
- * Incidentally, ut_exit is sometimes present in the struct utmp but
- * not the struct utmpx for a given system. Sometimes, it exists in
- * both, but contains differently named members. It's probably one of
- * the least portable pieces in this whole mess.
- *
- * Known Quirks of Specific OSes:
- * ------------------------------
- *
- * Solaris 2.x:
- *
- * Has utmpd, which will automatically clean up utmpx, utmp, wtmpx,
- * wtmp after process termination, provided that pututxline() was
- * used.
- *
- * Solaris 8 seems to have a bug in utmpname() that causes
- * garbage filenames to be generated. Solaris 7 (and possibly Solaris
- * 8) have a bug in utmpxname() that prevents them from looking at
- * anything other than /var/adm/utmpx, it seems. For some reason,
- * though, utmpname() goes and looks at the corresponding utmpx file.
- *
- * Solaris 7 (and may be 8 as well) has a bug in pututline() that
- * interacts badly with prior invocation of getutline(): if
- * getutline() finds an entry, calling pututline() without first
- * calling setutent() will overwrite the record following the one that
- * was intended.
- *
- * Also, ut_exit in utmpx contains ut_e_termination and
- * ut_e_exit (otherwise it contains the expected e_termination and
- * e_exit) only if _XPG4_2 is defined and __EXTENSIONS__ is not, which
- * is not a compilation environment we're likely to encourage. The
- * ut_exit field of utmp contains the expected fields.
- *
- * If _XPG4_2 is not defined or __EXTENSIONS__ is defined, the
- * functions getutmp(), getutmpx(), updwtmp(), and updwtmpx() are
- * available, as well as the undocumented functions makeutx() and
- * modutx().
- *
- * All the files utmp, utmpx, wtmp, and wtmpx exist.
- *
- * HP-UX 10.x:
- *
- * There is a curious interaction between how we allocate pty masters
- * and how ttyname() works. It seems that if /dev/ptmx/clone is
- * opened, a call to ptsname() on the master fd gets a filename of the
- * form /dev/pty/tty[pqrs][0-9a-f], while ttyname() called on a fd
- * opened with that filename returns a filename of the form
- * /dev/tty[pqrs][0-9a-f] instead. These two filenames are actually
- * hardlinks to the same special device node, so it shouldn't be a
- * security problem.
- *
- * We can't call ttyname() in the parent because it would involve
- * possibly acquiring a controlling terminal (which would be
- * potentially problematic), so we have to resort to some trickery in
- * order to ensure that the ut_line in the wtmp logout and login
- * records match. If they don't match, various utilities such as last
- * will get confused. Of course it's likely an OS bug that ttyname()
- * and ptsname() are inconsistent in this way, but it's one that isn't
- * too painful to work around.
- *
- * It seems that the HP-UX native telnetd has problems similar to ours
- * in this area, though it manages to write the correct logout record
- * to wtmp somehow. It probably does basically what we do here:
- * search for a record with a matching ut_pid and grab its ut_line for
- * writing into the logout record. Interestingly enough, its
- * LOGIN_PROCESS record is of the form pty/tty[pqrs][0-9][a-f].
- *
- * Uses four-character unique IDs for /etc/inittab, which means that
- * programs not running out of init should use two-character ut_id
- * fields to avoid conflict.
- *
- * In utmpx, ut_exit contains __e_termination and __e_exit, while
- * ut_exit in utmp contains the expected fields.
- *
- * There is no wtmpx file, despite there being utmp and utmpx files.
- *
- * HP-UX 11.23:
- *
- * In addition to other HP-UX issues, 11.23 includes yet another utmp
- * management interface in utmps.h. This interface updates a umtpd
- * daemon which then manages local files. Directly accessing the files
- * through the existing, yet deprecated, utmp.h interface results in
- * nothing.
- *
- * Irix 6.x:
- *
- * In utmpx, ut_exit contains __e_termination and __e_exit, which get
- * #define aliases e_termination and e_exit if _NO_XOPEN4 is true.
- * Curiously enough, utmp.h declares ut_exit to have __e_termination
- * and __e_exit as well, but does #define e_termination
- * __e_termination, etc. if another header (utmpx.h) hasn't already
- * declared struct __exit_status. It seems that the default
- * compilation environment has the effect of making _NO_XOPEN4 true
- * though.
- *
- * If _NO_XOPEN4 is true, getutmp(), getutmpx(), updwtmp(), and
- * updwtmpx() are available, as well as the undocumented functions
- * makeutx() and modutx().
- *
- * All the files utmp, utmpx, wtmp, and wtmpx exist.
- *
- * Tru64 Unix 4.x:
- *
- * In utmpx, ut_exit contains ut_termination and ut_exit, while utmp
- * contains the expected fields. The files utmp and wtmp seem to
- * exist, but not utmpx or wtmpx.
- *
- * When writing a logout entry, the presence of a non-empty username
- * confuses last.
- *
- * AIX 4.3.x:
- *
- * The ut_exit field seems to exist in utmp, but not utmpx. The files
- * utmp and wtmp seem to exist, but not utmpx, or wtmpx.
- *
- * libpty Implementation Decisions:
- * --------------------------------
- *
- * We choose to use the pututxline() whenever possible, falling back
- * to pututline() and calling write() to write out struct utmp if
- * necessary. The code to handle pututxline() and pututline() is
- * rather similar, since the structure members are quite similar, and
- * we make the assumption that it will never be necessary to call
- * both. This allows us to avoid duplicating lots of code, by means
- * of some slightly demented macros.
- *
- * If neither pututxline() nor pututline() are available, we assume
- * BSD-style utmp files and behave accordingly, writing the structure
- * out to disk ourselves.
- *
- * On systems where updwtmpx() or updwtmp() are available, we use
- * those to update the wtmpx or wtmp file. When they're not
- * available, we write the utmpx or utmp structure out to disk
- * ourselves, though sometimes conversion from utmpx to utmp format is
- * needed.
- *
- * We assume that at logout the system is ok with with having an empty
- * username both in utmp and wtmp.
- */
-
-#include "com_err.h"
-#include "libpty.h"
-#include "pty-int.h"
-#include "k5-platform.h"
-
-#if !defined(UTMP_FILE) && defined(_PATH_UTMP)
-#define UTMP_FILE _PATH_UTMP
-#endif
-
-/* if it is *still* missing, assume SunOS */
-#ifndef UTMP_FILE
-#define UTMP_FILE "/etc/utmp"
-#endif
-
-/*
- * The following grossness exists to avoid duplicating lots of code
- * between the cases where we have an old-style sysV utmp and where we
- * have a modern (Unix98 or XPG4) utmpx, or the new (hp-ux 11.23) utmps.
- * See the above history rant for further explanation.
- */
-#if defined(HAVE_SETUTXENT) || defined(HAVE_SETUTENT) || defined(HAVE_SETUTSENT)
-#ifdef HAVE_SETUTSENT
-#include <utmps.h>
-#define PTY_STRUCT_UTMPX struct utmps
-#define PTY_SETUTXENT setutsent
-#define PTY_GETUTXENT GETUTSENT
-#define PTY_GETUTXLINE GETUTSLINE
-#define PTY_PUTUTXLINE PUTUTSLINE
-#define PTY_ENDUTXENT endutsent
-#else
-#ifdef HAVE_SETUTXENT
-#define PTY_STRUCT_UTMPX struct utmpx
-#define PTY_SETUTXENT setutxent
-#define PTY_GETUTXENT getutxent
-#define PTY_GETUTXLINE getutxline
-#define PTY_PUTUTXLINE pututxline
-#define PTY_ENDUTXENT endutxent
-#else
-#define PTY_STRUCT_UTMPX struct utmp
-#define PTY_SETUTXENT setutent
-#define PTY_GETUTXENT getutent
-#define PTY_GETUTXLINE getutline
-#define PTY_PUTUTXLINE pututline
-#define PTY_ENDUTXENT endutent
-#endif
-#endif
-static int better(const PTY_STRUCT_UTMPX *, const PTY_STRUCT_UTMPX *,
- const PTY_STRUCT_UTMPX *);
-static int match_pid(const PTY_STRUCT_UTMPX *,
- const PTY_STRUCT_UTMPX *);
-static PTY_STRUCT_UTMPX *best_utxent(const PTY_STRUCT_UTMPX *);
-
-/*
- * Utility function to determine whether A is a better match for
- * SEARCH than B. Should only be called by best_utxent().
- */
-static int
-better(const PTY_STRUCT_UTMPX *search,
- const PTY_STRUCT_UTMPX *a, const PTY_STRUCT_UTMPX *b)
-{
- if (strncmp(search->ut_id, b->ut_id, sizeof(b->ut_id))) {
- if (!strncmp(search->ut_id, a->ut_id, sizeof(a->ut_id))) {
- return 1;
- }
- }
-
- if (strncmp(a->ut_id, b->ut_id, sizeof(b->ut_id))) {
- /* Got different UT_IDs; find the right one. */
- if (!strncmp(search->ut_id, b->ut_id, sizeof(b->ut_id))) {
- /* Old entry already matches; use it. */
- return 0;
- }
- if (a->ut_type == LOGIN_PROCESS
- && b->ut_type != LOGIN_PROCESS) {
- /* Prefer LOGIN_PROCESS */
- return 1;
- }
- if (search->ut_type == DEAD_PROCESS
- && a->ut_type == USER_PROCESS
- && b->ut_type != USER_PROCESS) {
- /*
- * Try USER_PROCESS if we're entering a DEAD_PROCESS.
- */
- return 1;
- }
- return 0;
- } else {
- /*
- * Bad juju. We shouldn't get two entries with identical
- * ut_id fields for the same value of ut_line. pututxline()
- * will probably pick the first entry, in spite of the strange
- * state of utmpx, if we rewind with setutxent() first.
- *
- * For now, return 0, to force the earlier entry to be used.
- */
- return 0;
- }
-}
-
-static int
-match_pid(const PTY_STRUCT_UTMPX *search, const PTY_STRUCT_UTMPX *u)
-{
- if (u->ut_type != LOGIN_PROCESS && u->ut_type != USER_PROCESS)
- return 0;
- if (u->ut_pid == search->ut_pid) {
- /*
- * One of ut_line or ut_id should match, else some nastiness
- * may result. We can fall back to searching by ut_line if
- * need be. This should only really break if we're login.krb5
- * running out of getty, or we're cleaning up after the vendor
- * login, and either the vendor login or the getty has
- * different ideas than we do of what both ut_id and ut_line
- * should be. It should be rare, though. We may want to
- * remove this restriction later.
- */
- if (!strncmp(u->ut_line, search->ut_line, sizeof(u->ut_line)))
- return 1;
- if (!strncmp(u->ut_id, search->ut_id, sizeof(u->ut_id)))
- return 1;
- }
- return 0;
-}
-
-/*
- * This expects to be called with SEARCH pointing to a struct utmpx
- * with its ut_type equal to USER_PROCESS or DEAD_PROCESS, since if
- * we're making a LOGIN_PROCESS entry, we presumably don't care about
- * preserving existing state. At the very least, the ut_pid, ut_line,
- * ut_id, and ut_type fields must be filled in by the caller.
- */
-static PTY_STRUCT_UTMPX *
-best_utxent(const PTY_STRUCT_UTMPX *search)
-{
- PTY_STRUCT_UTMPX utxtmp, *utxp;
- int i, best;
-
- memset(&utxtmp, 0, sizeof(utxtmp));
-
- /*
- * First, search based on pid, but only if non-zero.
- */
- if (search->ut_pid) {
- i = 0;
- PTY_SETUTXENT();
- while ((utxp = PTY_GETUTXENT()) != NULL) {
- if (match_pid(search, utxp)) {
- return utxp;
- }
- i++;
- }
- }
- /*
- * Uh-oh, someone didn't enter our pid. Try valiantly to search
- * by terminal line.
- */
- i = 0;
- best = -1;
- PTY_SETUTXENT();
- while ((utxp = PTY_GETUTXLINE(search)) != NULL) {
- if (better(search, utxp, &utxtmp)) {
- utxtmp = *utxp;
- best = i;
- }
- memset(utxp, 0, sizeof(*utxp));
- i++;
- }
- if (best == -1)
- return NULL;
- PTY_SETUTXENT();
- for (i = 0; i <= best; i++) {
- if (utxp != NULL)
- memset(utxp, 0, sizeof(*utxp));
- utxp = PTY_GETUTXLINE(search);
- }
- return utxp;
-}
-
-/*
- * All calls to this function for a given login session must have the
- * pids be equal; various things will break if this is not the case,
- * since we do some searching based on the pid. Note that if a parent
- * process calls this via pty_cleanup(), it should still pass the
- * child's pid rather than its own.
- */
-long
-pty_update_utmp(int process_type, int pid, const char *username,
- const char *line, const char *host, int flags)
-{
- PTY_STRUCT_UTMPX utx, *utxtmp, utx2;
- const char *cp;
- size_t len;
- char utmp_id[5];
-
- /*
- * Zero things out in case there are fields we don't handle here.
- * They tend to be non-portable anyway.
- */
- memset(&utx, 0, sizeof(utx));
- utxtmp = NULL;
- cp = line;
- if (strncmp(cp, "/dev/", sizeof("/dev/") - 1) == 0)
- cp += sizeof("/dev/") - 1;
- strncpy(utx.ut_line, cp, sizeof(utx.ut_line));
- utx.ut_pid = pid;
- switch (process_type) {
- case PTY_LOGIN_PROCESS:
- utx.ut_type = LOGIN_PROCESS;
- break;
- case PTY_USER_PROCESS:
- utx.ut_type = USER_PROCESS;
- break;
- case PTY_DEAD_PROCESS:
- utx.ut_type = DEAD_PROCESS;
- break;
- default:
- return PTY_UPDATE_UTMP_PROCTYPE_INVALID;
- }
- len = strlen(line);
- if (len >= 2) {
- cp = line + len - 1;
- if (*(cp - 1) != '/')
- cp--; /* last two characters, unless it's a / */
- } else
- cp = line;
- /*
- * HP-UX has mostly 4-character inittab ids, while most other sysV
- * variants use only 2-charcter inittab ids, so to avoid
- * conflicts, we pick 2-character ut_ids for our own use. We may
- * want to feature-test for this, but it would be somewhat of a
- * pain, and would eit cross-compiling.
- */
-#ifdef __hpux
- strlcpy(utmp_id, cp, sizeof(utmp_id));
-#else
- if (len > 2 && *(cp - 1) != '/')
- snprintf(utmp_id, sizeof(utmp_id), "k%s", cp - 1);
- else
- snprintf(utmp_id, sizeof(utmp_id), "k0%s", cp);
-#endif
- strncpy(utx.ut_id, utmp_id, sizeof(utx.ut_id));
- /*
- * Get existing utmpx entry for PID or LINE, if any, so we can
- * copy some stuff from it. This is particularly important if we
- * are login.krb5 and are running out of getty, since getty will
- * have written the entry for the line with ut_type ==
- * LOGIN_PROCESS, and what it has recorded in ut_id may not be
- * what we come up with, since that's up to the whim of the
- * sysadmin who writes the inittab entry.
- *
- * Note that we may be screwed if we try to write a logout record
- * for a vendor's login program, since it may construct ut_line
- * and ut_id differently from us; even though we search on ut_pid,
- * we validate against ut_id or ut_line to sanity-check. We may
- * want to rethink whether to actually include this check, since
- * it should be highly unlikely that there will be a bogus entry
- * in utmpx matching our pid.
- */
- if (process_type != PTY_LOGIN_PROCESS)
- utxtmp = best_utxent(&utx);
-
-#ifdef HAVE_SETUTXENT
- if (gettimeofday(&utx.ut_tv, NULL))
- return errno;
-#else
- (void)time(&utx.ut_time);
-#endif
- /*
- * On what system is there not ut_host? Unix98 doesn't mandate
- * this field, but we have yet to see a system that supports utmpx
- * that doesn't have it. For what it's worth, some ancient utmp
- * headers on svr4 systems imply that there's no ut_host in struct
- * utmp...
- */
-#if (defined(HAVE_SETUTXENT) && defined(HAVE_STRUCT_UTMPX_UT_HOST)) \
- || (!defined(HAVE_SETUTXENT) && defined(HAVE_STRUCT_UTMP_UT_HOST))
- if (host != NULL) {
- strncpy(utx.ut_host, host, sizeof(utx.ut_host));
- /* Unlike other things in utmpx, ut_host is nul-terminated? */
- utx.ut_host[sizeof(utx.ut_host) - 1] = '\0';
- } else
- utx.ut_host[0] = '\0';
-#if (defined(HAVE_SETUTXENT) && defined(HAVE_STRUCT_UTMPX_UT_SYSLEN)) \
- || (!defined (HAVE_SETUTXENT) && defined(HAVE_STRUCT_UTMP_UT_SYSLEN))
- if (host != NULL)
- utx.ut_syslen = strlen(utx.ut_host) + 1;
- else
- utx.ut_syslen = 0;
-#endif
-#endif
-
- /* XXX deal with ut_addr? */
-
- if (utxtmp != NULL) {
- /*
- * For entries not of type LOGIN_PROCESS, override some stuff
- * with what was in the previous entry we found, if any.
- */
- strncpy(utx.ut_id, utxtmp->ut_id, sizeof(utx.ut_id));
- utx.ut_pid = utxtmp->ut_pid;
- }
-
- strncpy(utx.ut_user, username, sizeof(utx.ut_user));
-
- /*
- * Make a copy now and deal with copying relevant things out of
- * utxtmp in case setutxline() or pututxline() clobbers utxtmp.
- * (After all, the returned pointer from the getutx*() functions
- * is allowed to point to static storage that may get overwritten
- * by subsequent calls to related functions.)
- */
- utx2 = utx;
- if (process_type == PTY_DEAD_PROCESS && utxtmp != NULL) {
- /*
- * Use ut_line from old entry to avoid confusing last on
- * HP-UX.
- */
- strncpy(utx2.ut_line, utxtmp->ut_line, sizeof(utx2.ut_line));
- }
-
- PTY_SETUTXENT();
- PTY_PUTUTXLINE(&utx);
- PTY_ENDUTXENT();
-
- /* Don't record LOGIN_PROCESS entries. */
- if (process_type == PTY_LOGIN_PROCESS)
- return 0;
-
-#ifdef HAVE_SETUTXENT
- return ptyint_update_wtmpx(&utx2);
-#else
- return ptyint_update_wtmp(&utx2);
-#endif
-}
-
-#else /* !(HAVE_SETUTXENT || HAVE_SETUTENT) */
-
-long
-pty_update_utmp(int process_type, int pid, const char *username,
- const char *line, const char *host, int flags)
-{
- struct utmp ent, ut;
- const char *cp;
- int tty, lc, fd;
- off_t seekpos;
- ssize_t ret;
- struct stat statb;
-
- memset(&ent, 0, sizeof(ent));
-#ifdef HAVE_STRUCT_UTMP_UT_HOST
- if (host)
- strncpy(ent.ut_host, host, sizeof(ent.ut_host));
-#endif
- strncpy(ent.ut_name, username, sizeof(ent.ut_name));
- cp = line;
- if (strncmp(cp, "/dev/", sizeof("/dev/") - 1) == 0)
- cp += sizeof("/dev/") - 1;
- strncpy(ent.ut_line, cp, sizeof(ent.ut_line));
- (void)time(&ent.ut_time);
-
- if (flags & PTY_TTYSLOT_USABLE)
- tty = ttyslot();
- else {
- tty = -1;
- fd = open(UTMP_FILE, O_RDONLY);
- if (fd == -1)
- return errno;
- for (lc = 0; ; lc++) {
- seekpos = lseek(fd, (off_t)(lc * sizeof(struct utmp)), SEEK_SET);
- if (seekpos != (off_t)(lc * sizeof(struct utmp)))
- break;
- if (read(fd, (char *) &ut, sizeof(struct utmp))
- != sizeof(struct utmp))
- break;
- if (strncmp(ut.ut_line, ent.ut_line, sizeof(ut.ut_line)) == 0) {
- tty = lc;
- break;
- }
- }
- close(fd);
- }
- if (tty > 0) {
- fd = open(UTMP_FILE, O_WRONLY);
- if (fd == -1)
- return 0;
- if (fstat(fd, &statb)) {
- close(fd);
- return 0;
- }
- seekpos = lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET);
- if (seekpos != (off_t)(tty * sizeof(struct utmp))) {
- close(fd);
- return 0;
- }
- ret = write(fd, (char *)&ent, sizeof(struct utmp));
- if (ret != sizeof(struct utmp)) {
- ftruncate(fd, statb.st_size);
- }
- close(fd);
- }
- /* Don't record LOGIN_PROCESS entries. */
- if (process_type == PTY_LOGIN_PROCESS)
- return 0;
- else
- return ptyint_update_wtmp(&ent);
-}
-#endif