update pam config to use common-session
[debian/sudo] / boottime.c
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__)
63 int
64 get_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
91 int
92 get_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
109 int
110 get_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
127 int
128 get_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
145 int
146 get_boottime(tv)
147     struct timeval *tv;
148 {
149     return 0;
150 }
151 #endif