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 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
/*
* utmp.c Routines to read/write the utmp and wtmp files.
* Basically just wrappers around the library routines.
*
* Version: @(#)utmp.c 1.22 22-Jan-1998 miquels@cistron.nl
*
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <time.h>
#include <fcntl.h>
#include <string.h>
#include <utmp.h>
#include "init.h"
#include "initreq.h"
#include "paths.h"
#if defined(__GLIBC__)
# if (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 0) && defined(__powerpc__)
# define HAVE_UPDWTMP 0
# else
# define HAVE_UPDWTMP 1
# endif
#else
# define HAVE_UPDWTMP 0
#endif
/*
* Log an event ONLY in the wtmp file (reboot, runlevel)
*/
void write_wtmp(
char *user, /* name of user */
char *id, /* inittab ID */
int pid, /* PID of process */
int type, /* TYPE of entry */
char *line) /* Which line is this */
{
int fd;
struct utmp utmp;
/*
* Try to open the wtmp file. Note that we even try
* this if we have updwtmp() so we can see if the
* wtmp file is accessible.
*/
if ((fd = open(WTMP_FILE, O_WRONLY|O_APPEND)) < 0) return;
#ifdef INIT_MAIN
/*
* Note if we are going to write a boot record.
*/
if (type == BOOT_TIME) wrote_reboot++;
/*
* See if we need to write a reboot record. The reason that
* we are being so paranoid is that when we first tried to
* write the reboot record, /var was possibly not mounted
* yet. As soon as we can open WTMP we write a delayed boot record.
*/
if (wrote_reboot == 0 && type != BOOT_TIME)
write_wtmp("reboot", "~~", 0, BOOT_TIME, "~");
#endif
/*
* Zero the fields and enter new fields.
*/
memset(&utmp, 0, sizeof(utmp));
#if defined(__GLIBC__)
gettimeofday(&utmp.ut_tv, NULL);
#else
time(&utmp.ut_time);
#endif
utmp.ut_pid = pid;
utmp.ut_type = type;
strncpy(utmp.ut_name, user, sizeof(utmp.ut_name));
strncpy(utmp.ut_id , id , sizeof(utmp.ut_id ));
strncpy(utmp.ut_line, line, sizeof(utmp.ut_line));
#if HAVE_UPDWTMP
updwtmp(WTMP_FILE, &utmp);
#else
write(fd, (char *)&utmp, sizeof(utmp));
#endif
close(fd);
}
/*
* Proper implementation of utmp handling. This part uses the
* library functions for utmp stuff, and doesn't worry about
* cleaning up if other programs mess up utmp.
*/
void write_utmp_wtmp(
char *user, /* name of user */
char *id, /* inittab ID */
int pid, /* PID of process */
int type, /* TYPE of entry */
char *line) /* LINE if used. */
{
struct utmp utmp;
struct utmp tmp;
struct utmp *utmptr;
int fd;
/*
* For backwards compatibility we just return
* if user == NULL (means : clean up utmp file).
*/
if (user == NULL)
return;
/*
* Fill out an utmp struct.
*/
memset(&utmp, 0, sizeof(utmp));
utmp.ut_type = type;
utmp.ut_pid = pid;
strncpy(utmp.ut_id, id, sizeof(utmp.ut_id));
#if defined(__GLIBC__)
gettimeofday(&utmp.ut_tv, NULL);
#else
time(&utmp.ut_time);
#endif
strncpy(utmp.ut_user, user, UT_NAMESIZE);
if (line) strncpy(utmp.ut_line, line, UT_LINESIZE);
/*
* We might need to find the existing entry first, to
* find the tty of the process (for wtmp accounting).
*/
if (type == DEAD_PROCESS) {
/*
* Find existing entry for the tty line.
*/
setutent();
tmp = utmp;
if ((utmptr = getutid(&tmp)) != NULL)
strncpy(utmp.ut_line, utmptr->ut_line, UT_LINESIZE);
}
/*
* Update existing utmp file.
*/
setutent();
pututline(&utmp);
endutent();
/*
* Write the wtmp record if we can open the wtmp file.
*/
if ((fd = open(WTMP_FILE, O_WRONLY|O_APPEND)) >= 0) {
#ifdef INIT_MAIN
/* See if we need to write a boot record */
if (wrote_reboot == 0 && type != BOOT_TIME) {
write_wtmp("reboot", "~~", 0, BOOT_TIME, "~");
wrote_reboot++;
}
#endif
#if HAVE_UPDWTMP
updwtmp(WTMP_FILE, &utmp);
#else
(void) write(fd, (char *) &utmp, sizeof(struct utmp));
#endif
(void) close(fd);
}
}
|