1 
2 /*
3  * Licensed Materials - Property of IBM
4  *
5  * trousers - An open source TCG Software Stack
6  *
7  * (C) Copyright International Business Machines Corp. 2004, 2005
8  *
9  */
10 
11 
12 #if defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__NetBSD__) || defined (__APPLE__)
13 #include <sys/param.h>
14 #include <sys/sysctl.h>
15 #include <err.h>
16 #elif (defined (__linux) || defined (linux) || defined(__GLIBC__))
17 #include <utmp.h>
18 #elif (defined (SOLARIS))
19 #include <utmpx.h>
20 #endif
21 
22 #include <sys/time.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 
27 #include "trousers/tss.h"
28 #include "trousers_types.h"
29 #include "tcs_tsp.h"
30 #include "tcs_int_literals.h"
31 #include "capabilities.h"
32 #include "tcsps.h"
33 #include "tcslog.h"
34 
35 
36 #if (defined (__linux) || defined (linux) || defined(__GLIBC__))
37 MUTEX_DECLARE_INIT(utmp_lock);
38 
39 char
platform_get_runlevel()40 platform_get_runlevel()
41 {
42           char runlevel;
43           struct utmp ut, save, *next = NULL;
44           struct timeval tv;
45           int flag = 0, counter = 0;
46 
47           MUTEX_LOCK(utmp_lock);
48 
49           memset(&ut, 0, sizeof(struct utmp));
50           memset(&save, 0, sizeof(struct utmp));
51           memset(&tv, 0, sizeof(struct timeval));
52 
53           ut.ut_type = RUN_LVL;
54 
55           setutent();
56           next = getutid(&ut);
57 
58           while (next != NULL) {
59                     if (next->ut_tv.tv_sec > tv.tv_sec) {
60                               memcpy(&save, next, sizeof(*next));
61                               flag = 1;
62                     } else if (next->ut_tv.tv_sec == tv.tv_sec) {
63                               if (next->ut_tv.tv_usec > tv.tv_usec) {
64                                         memcpy(&save, next, sizeof(*next));
65                                         flag = 1;
66                               }
67                     }
68 
69                     counter++;
70                     next = getutid(&ut);
71           }
72 
73           if (flag) {
74                     //printf("prev_runlevel=%c, runlevel=%c\n", save.ut_pid / 256, save.ut_pid % 256);
75                     runlevel = save.ut_pid % 256;
76           } else {
77                     //printf("unknown\n");
78                     runlevel = 'u';
79           }
80 
81           MUTEX_UNLOCK(utmp_lock);
82 
83           return runlevel;
84 }
85 #elif defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__NetBSD__) || defined (__APPLE__)
86 
87 char
platform_get_runlevel()88 platform_get_runlevel()
89 {
90           int mib[2], rlevel = -1;
91           size_t len;
92 
93           mib[0] = CTL_KERN;
94           mib[1] = KERN_SECURELVL;
95 
96           len = sizeof(rlevel);
97           if (sysctl(mib,2,&rlevel,&len, NULL,0) == -1) {
98                     err(1,"Could not get runlevel");
99                     return 'u';
100           }
101 #if defined (__OpenBSD__)
102           if (rlevel == 0)
103 #else
104           if (rlevel == -1)
105 #endif
106                     return 's';
107 
108           return rlevel + '0';
109 }
110 #elif (defined (SOLARIS))
111 
112 MUTEX_DECLARE_INIT(utmp_lock);
113 char
platform_get_runlevel()114 platform_get_runlevel()
115 {
116           char runlevel = 'u';          /* unknown run level */
117           struct utmpx ut, *utp = NULL;
118 
119           MUTEX_LOCK(utmp_lock);
120 
121           memset(&ut, 0, sizeof(ut));
122           ut.ut_type = RUN_LVL;
123 
124           setutxent();
125           utp = getutxid(&ut);
126           if (utp->ut_type == RUN_LVL &&
127               sscanf(utp->ut_line, "run-level %c", &runlevel) != 1)
128                               runlevel = 'u';
129           endutxent();
130 
131           MUTEX_UNLOCK(utmp_lock);
132 
133           return runlevel;
134 }
135 #endif
136