1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
/* logwtmp.c - A version of BSDs `logwtmp' that should be widely portable
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016,
2017, 2018, 2019, 2020, 2021 Free Software Foundation, Inc.
This file is part of GNU Inetutils.
GNU Inetutils is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at
your option) any later version.
GNU Inetutils is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see `http://www.gnu.org/licenses/'. */
/* Written by Miles Bader. */
/* If `KEEP_OPEN' is defined, then a special version of logwtmp is compiled,
called logwtmp_keep_open, which keeps the wtmp file descriptor open
between calls, and doesn't attempt to open the file after the first call. */
#include <config.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <time.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <errno.h>
#ifdef HAVE_UTMPX_H
# ifndef __USE_GNU
# define __USE_GNU 1
# endif
# include <utmpx.h>
# define OUR_WTMP PATH_WTMPX
#elif defined HAVE_UTMP_H
# include <utmp.h>
# define OUR_WTMP PATH_WTMP
#endif
#include <string.h>
#if !HAVE_DECL_ERRNO
extern int errno;
#endif
#ifdef HAVE_UTMPX_H
static void
_logwtmp (struct utmpx *ut)
#else /* !HAVE_UTMPX_H */
static void
_logwtmp (struct utmp *ut)
#endif /* !HAVE_UTMP_H */
{
#ifdef KEEP_OPEN
static int fd = -1;
if (fd < 0)
fd = open (OUR_WTMP, O_WRONLY | O_APPEND, 0);
#else
int fd = open (OUR_WTMP, O_WRONLY | O_APPEND, 0);
#endif
if (fd >= 0)
{
struct stat st;
#ifdef HAVE_FLOCK
if (flock (fd, LOCK_EX | LOCK_NB) < 0 && errno != ENOSYS)
{
sleep (1);
flock (fd, LOCK_EX | LOCK_NB); /* ignore error */
}
#endif
#ifdef HAVE_FTRUNCATE
if (fstat (fd, &st) == 0
&& write (fd, (char *) ut, sizeof *ut) != sizeof *ut)
ftruncate (fd, st.st_size);
#else
write (fd, (char *) ut, sizeof *ut);
#endif
#ifdef HAVE_FLOCK
flock (fd, LOCK_UN);
#endif
#ifndef KEEP_OPEN
close (fd);
#endif
}
}
void
#ifdef KEEP_OPEN
logwtmp_keep_open (char *line, char *name, char *host)
#else
logwtmp (char *line, char *name, char *host)
#endif
{
#ifdef HAVE_UTMPX_H
struct utmpx ut;
struct timeval tv;
#else /* !HAVE_UTMPX_H */
struct utmp ut;
# ifdef HAVE_STRUCT_UTMP_UT_TV
struct timeval tv;
# endif
#endif
/* Set information in new entry. */
memset (&ut, 0, sizeof (ut));
#if defined HAVE_STRUCT_UTMP_UT_TYPE || defined HAVE_STRUCT_UTMPX_UT_TYPE
if (name && *name)
ut.ut_type = USER_PROCESS;
else
ut.ut_type = DEAD_PROCESS;
#endif /* UT_TYPE */
#if defined HAVE_STRUCT_UTMP_UT_PID || defined HAVE_STRUCT_UTMPX_UT_PID
ut.ut_pid = getpid ();
#endif /* UT_PID */
strncpy (ut.ut_line, line, sizeof ut.ut_line);
#if defined HAVE_STRUCT_UTMP_UT_USER || defined HAVE_STRUCT_UTMPX_UT_USER
strncpy (ut.ut_user, name, sizeof ut.ut_user);
#elif defined HAVE_STRUCT_UTMP_UT_NAME || defined HAVE_STRUCT_UTMPX_UT_NAME
strncpy (ut.ut_name, name, sizeof ut.ut_name);
#endif
#if defined HAVE_STRUCT_UTMP_UT_HOST || defined HAVE_STRUCT_UTMPX_UT_HOST
strncpy (ut.ut_host, host, sizeof ut.ut_host);
# ifdef HAVE_STRUCT_UTMPX_UT_SYSLEN /* Only utmpx. */
if (strlen (host) < sizeof (ut.ut_host))
ut.ut_syslen = strlen (host) + 1; /* Including NUL. */
else
{
ut.ut_host[sizeof (ut.ut_host) - 1] = '\0';
ut.ut_syslen = sizeof (ut.ut_host);
}
# endif /* UT_SYSLEN */
#endif /* UT_HOST */
#if defined HAVE_STRUCT_UTMP_UT_TV || defined HAVE_STRUCT_UTMPX_UT_TV
gettimeofday (&tv, NULL);
ut.ut_tv.tv_sec = tv.tv_sec;
ut.ut_tv.tv_usec = tv.tv_usec;
#else
time (&ut.ut_time);
#endif
_logwtmp (&ut);
}
|