/*
* Licensed Materials - Property of IBM
*
* trousers - An open source TCG Software Stack
*
* (C) Copyright International Business Machines Corp. 2004, 2005
*
*/
#if defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__NetBSD__) || defined (__APPLE__)
#include <sys/param.h>
#include <sys/sysctl.h>
#include <err.h>
#elif (defined (__linux) || defined (linux) || defined(__GLIBC__))
#include <utmp.h>
#elif (defined (SOLARIS))
#include <utmpx.h>
#endif
#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "trousers/tss.h"
#include "trousers_types.h"
#include "tcs_tsp.h"
#include "tcs_int_literals.h"
#include "capabilities.h"
#include "tcsps.h"
#include "tcslog.h"
#if (defined (__linux) || defined (linux) || defined(__GLIBC__))
MUTEX_DECLARE_INIT(utmp_lock);
char
platform_get_runlevel()
{
char runlevel;
struct utmp ut, save, *next = NULL;
struct timeval tv;
int flag = 0, counter = 0;
MUTEX_LOCK(utmp_lock);
memset(&ut, 0, sizeof(struct utmp));
memset(&save, 0, sizeof(struct utmp));
memset(&tv, 0, sizeof(struct timeval));
ut.ut_type = RUN_LVL;
setutent();
next = getutid(&ut);
while (next != NULL) {
if (next->ut_tv.tv_sec > tv.tv_sec) {
memcpy(&save, next, sizeof(*next));
flag = 1;
} else if (next->ut_tv.tv_sec == tv.tv_sec) {
if (next->ut_tv.tv_usec > tv.tv_usec) {
memcpy(&save, next, sizeof(*next));
flag = 1;
}
}
counter++;
next = getutid(&ut);
}
if (flag) {
//printf("prev_runlevel=%c, runlevel=%c\n", save.ut_pid / 256, save.ut_pid % 256);
runlevel = save.ut_pid % 256;
} else {
//printf("unknown\n");
runlevel = 'u';
}
MUTEX_UNLOCK(utmp_lock);
return runlevel;
}
#elif defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__NetBSD__) || defined (__APPLE__)
char
platform_get_runlevel()
{
int mib[2], rlevel = -1;
size_t len;
mib[0] = CTL_KERN;
mib[1] = KERN_SECURELVL;
len = sizeof(rlevel);
if (sysctl(mib,2,&rlevel,&len, NULL,0) == -1) {
err(1,"Could not get runlevel");
return 'u';
}
#if defined (__OpenBSD__)
if (rlevel == 0)
#else
if (rlevel == -1)
#endif
return 's';
return rlevel + '0';
}
#elif (defined (SOLARIS))
MUTEX_DECLARE_INIT(utmp_lock);
char
platform_get_runlevel()
{
char runlevel = 'u'; /* unknown run level */
struct utmpx ut, *utp = NULL;
MUTEX_LOCK(utmp_lock);
memset(&ut, 0, sizeof(ut));
ut.ut_type = RUN_LVL;
setutxent();
utp = getutxid(&ut);
if (utp->ut_type == RUN_LVL &&
sscanf(utp->ut_line, "run-level %c", &runlevel) != 1)
runlevel = 'u';
endutxent();
MUTEX_UNLOCK(utmp_lock);
return runlevel;
}
#endif