Just ignore the timestamps given to pututxline().
I've noticed many applications do a bad job at timekeeping, for several reasons: - Applications like screen(1) don't update time records when restoring the old user login record. - Many applications only set ut_tv.tv_sec, not ut_tv.tv_usec. This causes many problems for tools such as ac(8), which require the timestamps to be properly ordered. This is why I've decided to let the utmpx code obtain valid timestamps itself.
This commit is contained in:
parent
e066c90bb2
commit
a7607816bf
@ -311,13 +311,9 @@ will only be written to
|
||||
Entries of type
|
||||
.Dv USER_PROCESS
|
||||
will also be written to
|
||||
.Pa /var/run/utx.active .
|
||||
It will only be written to
|
||||
.Pa /var/log/utx.lastlogin
|
||||
if
|
||||
.Fa ut_tv
|
||||
for that user has a greater value than the existing entry or when no
|
||||
entry for the user has been found.
|
||||
.Pa /var/run/utx.active
|
||||
and
|
||||
.Pa /var/log/utx.lastlogin .
|
||||
.Pp
|
||||
Entries of type
|
||||
.Dv DEAD_PROCESS
|
||||
@ -345,6 +341,8 @@ to be discarded.
|
||||
All entries whose type has not been mentioned previously, are discarded
|
||||
by this implementation of
|
||||
.Fn pututxline .
|
||||
This implementation also ignores the value of
|
||||
.Fa ut_tv .
|
||||
.Sh RETURN VALUES
|
||||
The
|
||||
.Fn getutxent ,
|
||||
|
@ -132,13 +132,6 @@ utx_active_remove(struct futx *fu)
|
||||
if (memcmp(fu->fu_id, fe.fu_id, sizeof fe.fu_id) != 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Prevent login sessions from having a negative
|
||||
* timespan.
|
||||
*/
|
||||
if (be64toh(fu->fu_tv) < be64toh(fe.fu_tv))
|
||||
fu->fu_tv = fe.fu_tv;
|
||||
|
||||
/* Terminate session. */
|
||||
fseeko(fp, -(off_t)sizeof fe, SEEK_CUR);
|
||||
fwrite(fu, sizeof *fu, 1, fp);
|
||||
@ -175,17 +168,12 @@ utx_lastlogin_add(const struct futx *fu)
|
||||
while (fread(&fe, sizeof fe, 1, fp) == 1) {
|
||||
if (strncmp(fu->fu_user, fe.fu_user, sizeof fe.fu_user) != 0)
|
||||
continue;
|
||||
|
||||
/* Prevent lowering the time value. */
|
||||
if (be64toh(fu->fu_tv) <= be64toh(fe.fu_tv))
|
||||
goto done;
|
||||
|
||||
/* Found a previous lastlogin entry for this user. */
|
||||
fseeko(fp, -(off_t)sizeof fe, SEEK_CUR);
|
||||
break;
|
||||
}
|
||||
fwrite(fu, sizeof *fu, 1, fp);
|
||||
done:
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include "namespace.h"
|
||||
#include <sys/endian.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <utmpx.h>
|
||||
@ -50,9 +51,11 @@ __FBSDID("$FreeBSD$");
|
||||
#define UTOF_TYPE(ut, fu) do { \
|
||||
(fu)->fu_type = (ut)->ut_type; \
|
||||
} while (0)
|
||||
#define UTOF_TV(ut, fu) do { \
|
||||
(fu)->fu_tv = htobe64((uint64_t)(ut)->ut_tv.tv_sec * 1000000 + \
|
||||
(uint64_t)(ut)->ut_tv.tv_usec); \
|
||||
#define UTOF_TV(fu) do { \
|
||||
struct timeval tv; \
|
||||
gettimeofday(&tv, NULL); \
|
||||
(fu)->fu_tv = htobe64((uint64_t)tv.tv_sec * 1000000 + \
|
||||
(uint64_t)tv.tv_usec); \
|
||||
} while (0)
|
||||
|
||||
void
|
||||
@ -96,7 +99,7 @@ utx_to_futx(const struct utmpx *ut, struct futx *fu)
|
||||
}
|
||||
|
||||
UTOF_TYPE(ut, fu);
|
||||
UTOF_TV(ut, fu);
|
||||
UTOF_TV(fu);
|
||||
}
|
||||
|
||||
#define FTOU_STRING(fu, ut, field) do { \
|
||||
|
Loading…
Reference in New Issue
Block a user