/*
 * This file has been modified from the original OpenBSD version 
 */

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

#include "config.h"
#ifndef HAVE_LOGIN

#include <errno.h>

#if defined(LIBC_SCCS) && !defined(lint)
/* from: static char sccsid[] = "@(#)login.c	8.1 (Berkeley) 6/4/93"; */
static char *rcsid = "$OpenBSD: login.c,v 1.5 1998/07/13 02:11:12 millert Exp $";
#endif /* LIBC_SCCS and not lint */

#include <sys/types.h>

#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
# include <utmpx.h>
#endif
#ifdef HAVE_UTMP_H
# include <utmp.h>
#endif
#include <stdio.h>
#include <string.h>

#ifdef USER_PROCESS
/*
 * find first matching slot in utmp, or "-1" for none
 *
 * algorithm: for USER_PROCESS, check tty name
 *            for DEAD_PROCESS, check PID and tty name
 *
 */
int find_tty_slot( utp )
struct utmp * utp;
{
	int t = 0;
	struct utmp * u;

#if defined(HAVE_TYPE_IN_UTMP) || defined(HAVE_TYPE_IN_UTMPX)
	setutent();

	while((u = getutent()) != NULL) {
		if (utp->ut_type == USER_PROCESS &&
		    (strncmp(utp->ut_line, u->ut_line, sizeof(utp->ut_line)) == 0)) {
			endutent();
			return(t);
		}

		if ((utp->ut_type == DEAD_PROCESS) && (utp->ut_pid == u->ut_pid) &&
		    (strncmp(utp->ut_line, u->ut_line, sizeof(utp->ut_line)) == 0 )) {
			endutent();
			return(t);
		}
		t++;
	}

	endutent();
#endif
	return(-1);
}
#else
int find_tty_slot( utp )
struct utmp * utp;
{
	return(ttyslot());
}
#endif

#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
void
login(utp,utx)
	struct utmp *utp;
	struct utmpx *utx;
#else /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
void
login(utp)
	struct utmp *utp;
#endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
{
#if defined(HAVE_HOST_IN_UTMP)
	struct utmp old_ut;
#endif
#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
	struct utmpx *old_utx;
#endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
	register int fd;
	int tty;

	/* can't use ttyslot here, as that will not work for logout
	 * (record_logout() is called from the master sshd, which does
	 * not have the correct tty on stdin/out, so ttyslot will return
	 * "-1" or (worse) a wrong number
	 */
	tty = find_tty_slot(utp);

#ifdef USE_UTMPX
	fd = open(_PATH_UTMPX, O_RDWR|O_CREAT, 0644);
	if (fd == -1) {
		log("Couldn't open %s: %s", _PATH_UTMPX, strerror(errno));
#else /* USE_UTMPX */
	fd = open(_PATH_UTMP, O_RDWR|O_CREAT, 0644);
	if (fd == -1) {
		log("Couldn't open %s: %s", _PATH_UTMP, strerror(errno));
#endif /* USE_UTMPX */
	} else {
		/* If no tty was found... */
		if (tty == -1) {
			/* ... append it to utmp on login */
#if defined(HAVE_TYPE_IN_UTMP) || defined(HAVE_TYPE_IN_UTMPX)
			if (utp->ut_type == USER_PROCESS) {
#ifdef USE_UTMPX
				if ((fd = open(_PATH_UTMPX, O_WRONLY|O_APPEND, 0)) >= 0) {
#else /* USE_UTMPX */
				if ((fd = open(_PATH_UTMP, O_WRONLY|O_APPEND, 0)) >= 0) {
#endif /* USE_UTMPX */
					(void)write(fd, utp, sizeof(struct utmp));
					(void)close(fd);
				}
			} else {
				/* Shouldn't get to here unless somthing happened to utmp */
				/* Between login and logout */
				log("No tty slot found at logout");
			}
#endif
		} else {
			/* Otherwise, tty was found - update at its location */
#if defined(HAVE_HOST_IN_UTMP)
# ifndef UT_LINESIZE
#  define UT_LINESIZE (sizeof(old_ut.ut_line))
#  define UT_NAMESIZE (sizeof(old_ut.ut_name))
#  define UT_HOSTSIZE (sizeof(old_ut.ut_host))
# endif
			(void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET);
			/*
			 * Prevent luser from zero'ing out ut_host.
			 * If the new ut_line is empty but the old one is not
			 * and ut_line and ut_name match, preserve the old ut_line.
			 */
			if (read(fd, &old_ut, sizeof(struct utmp)) ==
		   	 sizeof(struct utmp) && utp->ut_host[0] == '\0' &&
		   	 old_ut.ut_host[0] != '\0' &&
		   	 strncmp(old_ut.ut_line, utp->ut_line, UT_LINESIZE) == 0 &&
		   	 strncmp(old_ut.ut_name, utp->ut_name, UT_NAMESIZE) == 0)
				(void)memcpy(utp->ut_host, old_ut.ut_host, UT_HOSTSIZE);
#endif /* defined(HAVE_HOST_IN_UTMP) */
			(void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET);
			(void)write(fd, utp, sizeof(struct utmp));
			(void)close(fd);
		}
	}

	if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) >= 0) {
		(void)write(fd, utp, sizeof(struct utmp));
		(void)close(fd);
	}
#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
	old_utx = pututxline(utx);
# ifdef HAVE_UPDWTMPX
	updwtmpx(_PATH_WTMPX, utx);
# endif /* HAVE_UPDWTMPX */
	endutxent();
#endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
}

#endif /* HAVE_LOGIN */
