1/* 2 * Copyright (c) 2009-2010 Todd C. Miller <Todd.Miller@courtesan.com> 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17#include <config.h> 18 19#include <sys/param.h> 20#include <sys/types.h> 21#include <sys/time.h> 22 23#include <stdio.h> 24#ifdef STDC_HEADERS 25# include <stdlib.h> 26# include <stddef.h> 27#else 28# ifdef HAVE_STDLIB_H 29# include <stdlib.h> 30# endif 31#endif /* STDC_HEADERS */ 32#ifdef HAVE_STRING_H 33# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS) 34# include <memory.h> 35# endif 36# include <string.h> 37#endif /* HAVE_STRING_H */ 38#ifdef HAVE_STRINGS_H 39# include <strings.h> 40#endif /* HAVE_STRINGS_H */ 41#include <limits.h> 42#if TIME_WITH_SYS_TIME 43# include <time.h> 44#endif 45#ifdef HAVE_GETUTXID 46# include <utmpx.h> 47#endif 48#ifdef HAVE_GETUTID 49# include <utmp.h> 50#endif 51#ifdef HAVE_SYSCTL 52# include <sys/sysctl.h> 53#endif 54 55#include "missing.h" 56 57/* 58 * Fill in a struct timeval with the time the system booted. 59 * Returns 1 on success and 0 on failure. 60 */ 61 62#if defined(__linux__) 63int 64get_boottime(tv) 65 struct timeval *tv; 66{ 67 char *line = NULL; 68 size_t linesize = 0; 69 ssize_t len; 70 FILE * fp; 71 72 /* read btime from /proc/stat */ 73 fp = fopen("/proc/stat", "r"); 74 if (fp != NULL) { 75 while ((len = getline(&line, &linesize, fp)) != -1) { 76 if (strncmp(line, "btime ", 6) == 0) { 77 tv->tv_sec = atoi(line + 6); 78 tv->tv_usec = 0; 79 return 1; 80 } 81 } 82 fclose(fp); 83 free(line); 84 } 85 86 return 0; 87} 88 89#elif defined(HAVE_SYSCTL) && defined(KERN_BOOTTIME) 90 91int 92get_boottime(tv) 93 struct timeval *tv; 94{ 95 size_t size; 96 int mib[2]; 97 98 mib[0] = CTL_KERN; 99 mib[1] = KERN_BOOTTIME; 100 size = sizeof(*tv); 101 if (sysctl(mib, 2, tv, &size, NULL, 0) != -1) 102 return 1; 103 104 return 0; 105} 106 107#elif defined(HAVE_GETUTXID) 108 109int 110get_boottime(tv) 111 struct timeval *tv; 112{ 113 struct utmpx *ut, key; 114 115 memset(&key, 0, sizeof(key)); 116 key.ut_type = BOOT_TIME; 117 if ((ut = getutxid(&key)) != NULL) { 118 tv->tv_sec = ut->ut_tv.tv_sec; 119 tv->tv_usec = ut->ut_tv.tv_usec; 120 endutxent(); 121 } 122 return ut != NULL; 123} 124 125#elif defined(HAVE_GETUTID) 126 127int 128get_boottime(tv) 129 struct timeval *tv; 130{ 131 struct utmp *ut, key; 132 133 memset(&key, 0, sizeof(key)); 134 key.ut_type = BOOT_TIME; 135 if ((ut = getutid(&key)) != NULL) { 136 tv->tv_sec = ut->ut_time; 137 tv->tv_usec = 0; 138 endutent(); 139 } 140 return ut != NULL; 141} 142 143#else 144 145int 146get_boottime(tv) 147 struct timeval *tv; 148{ 149 return 0; 150} 151#endif 152