#include "compat.h"
#include "missing.h"
+/*
+ * Fill in a struct timeval with the time the system booted.
+ * Returns TRUE on success and FALSE on failure.
+ */
+
#if defined(__linux__)
-time_t
-get_boottime()
+int
+get_boottime(struct timeval *tv)
{
- time_t boottime = 0;
char *line = NULL;
size_t linesize = 0;
ssize_t len;
if (fp != NULL) {
while ((len = getline(&line, &linesize, fp)) != -1) {
if (strncmp(line, "btime ", 6) == 0) {
- boottime = atoi(line + 6);
- break;
+ tv->tv_sec = atoi(line + 6);
+ tv->tv_usec = 0;
+ return TRUE;
}
}
fclose(fp);
free(line);
}
- return(boottime);
+ return FALSE;
}
#elif defined(HAVE_SYSCTL) && defined(KERN_BOOTTIME)
-time_t
-get_boottime()
+int
+get_boottime(struct timeval *tv)
{
- struct timeval tv;
- time_t boottime = 0;
size_t size;
int mib[2];
mib[0] = CTL_KERN;
mib[1] = KERN_BOOTTIME;
- size = sizeof(tv);
- if (sysctl(mib, 2, &tv, &size, NULL, 0) != -1)
- boottime = tv.tv_sec;
+ size = sizeof(*tv);
+ if (sysctl(mib, 2, tv, &size, NULL, 0) != -1)
+ return TRUE;
- return(boottime);
+ return FALSE;
}
#elif defined(HAVE_GETUTXID)
#include <utmpx.h>
-time_t
-get_boottime()
+int
+get_boottime(struct timeval *tv)
{
- time_t boottime = 0;
struct utmpx *ut, key;
zero_bytes(&key, sizeof(key));
- key.ut_type = BOOT_TIME;
+ key.ut_type = BOOT_TIME;
if ((ut = getutxid(&key)) != NULL) {
- boottime = ut->ut_tv.tv_sec;
+ tv->tv_sec = ut->ut_tv.tv_sec;
+ tv->tv_usec = ut->ut_tv.tv_usec;
endutxent();
}
- return(boottime);
+ return ut != NULL;
}
#elif defined(HAVE_GETUTID)
#include <utmp.h>
-time_t
-get_boottime()
+int
+get_boottime(struct timeval *tv)
{
- time_t boottime = 0;
struct utmp *ut, key;
zero_bytes(&key, sizeof(key));
- key.ut_type = BOOT_TIME;
+ key.ut_type = BOOT_TIME;
if ((ut = getutid(&key)) != NULL) {
- boottime = ut->ut_time;
+ tv->tv_sec = ut->ut_time;
+ tv->tv_usec = 0;
endutent();
}
- return(boottime);
+ return ut != NULL;
}
#else
time_t
get_boottime()
{
- return(0);
+ return FALSE;
}
#endif
int flags;
{
struct stat sb;
- time_t boottime, now;
+ struct timeval boottime, mtime;
+ time_t now;
char *dirparent = def_timestampdir;
int status = TS_ERROR; /* assume the worst */
* If the file/dir exists and we are not removing it, check its mtime.
*/
if (status == TS_OLD && !ISSET(flags, TS_REMOVE)) {
+ mtim_get(&sb, &mtime);
/* Negative timeouts only expire manually (sudo -k). */
- if (def_timestamp_timeout < 0 && sb.st_mtime != 0)
+ if (def_timestamp_timeout < 0 && mtime.tv_sec != 0)
status = TS_CURRENT;
else {
- /* XXX - should use timeval here */
now = time(NULL);
- boottime = get_boottime();
if (def_timestamp_timeout &&
- now - sb.st_mtime < 60 * def_timestamp_timeout) {
+ now - mtime.tv_sec < 60 * def_timestamp_timeout) {
/*
* Check for bogus time on the stampfile. The clock may
* have been set back or someone could be trying to spoof us.
*/
- if (sb.st_mtime > now + 60 * def_timestamp_timeout * 2) {
+ if (mtime.tv_sec > now + 60 * def_timestamp_timeout * 2) {
log_error(NO_EXIT,
"timestamp too far in the future: %20.20s",
- 4 + ctime(&sb.st_mtime));
+ 4 + ctime(&mtime.tv_sec));
if (timestampfile)
(void) unlink(timestampfile);
else
(void) rmdir(timestampdir);
status = TS_MISSING;
- } else if (sb.st_mtime < boottime) {
+ } else if (get_boottime(&boottime) && timercmp(&mtime, &boottime, <)) {
status = TS_OLD;
} else {
status = TS_CURRENT;
int term_raw(int, int, int);
int term_restore(int, int);
char *get_timestr(time_t, int);
-time_t get_boottime(void);
int user_in_group(struct passwd *, const char *);
YY_DECL;
/* atobool.c */
int atobool(const char *str);
+/* boottime.c */
+int get_boottime(struct timeval *);
+
/* iolog.c */
int sudoers_io_open(unsigned int version, sudo_conv_t conversation,
char * const settings[], char * const user_info[], char * const user_env[]);