#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include "ttymon.h"
#include "tmextern.h"
#include "sac.h"
void
openpid(void)
{
char lockbuf[16];
(void) close(0);
if ((Lckfd = open(PIDFILE, O_RDONLY)) != -1) {
if (lockf(Lckfd, F_TEST, 0L) == -1)
fatal("pid file is locked. ttymon may already be "
"running!");
(void) close(Lckfd);
}
if ((Lckfd = open(PIDFILE, O_WRONLY|O_CREAT|O_TRUNC, 0644)) != 0)
fatal("open pid file failed: %s", strerror(errno));
if (lockf(Lckfd, F_LOCK, 0L) == -1)
fatal("lock pid file failed: %s", strerror(errno));
(void) snprintf(lockbuf, sizeof (lockbuf), "%ld", getpid());
(void) write(Lckfd, lockbuf, strlen(lockbuf) + 1);
#ifdef DEBUG
log("fd(pid)\t = %d", Lckfd);
#endif
}
void
openpipes(void)
{
Sfd = open(SACPIPE, O_WRONLY);
if (Sfd < 0)
fatal("open sacpipe failed: %s", strerror(errno));
Pfd = open(PMPIPE, O_RDWR|O_NONBLOCK);
if (Pfd < 0)
fatal("open pmpipe failed: %s", strerror(errno));
#ifdef DEBUG
log("fd(sacpipe)\t = %d", Sfd);
log("fd(pmpipe)\t = %d", Pfd);
#endif
}
static void
remove_env(char *env)
{
char **p;
char **rp = NULL;
p = environ;
if (p == NULL)
return;
while (*p) {
if (strncmp(*p, env, strlen(env)) == 0)
rp = p;
p++;
}
if (rp) {
*rp = *--p;
*p = NULL;
}
}
void
get_environ(void)
{
if ((Tag = getenv("PMTAG")) == NULL)
fatal("PMTAG is missing");
if ((Istate = getenv("ISTATE")) == NULL)
fatal("ISTATE is missing");
State = (strcmp(Istate, "enabled") == 0) ? PM_ENABLED : PM_DISABLED;
remove_env("ISTATE");
remove_env("PMTAG");
}
void
sacpoll(void)
{
int ret;
char oldState;
struct sacmsg sacmsg;
struct pmmsg pmmsg;
sigset_t cset;
sigset_t tset;
#ifdef DEBUG
debug("in sacpoll");
#endif
(void) sigprocmask(SIG_SETMASK, NULL, &cset);
tset = cset;
(void) sigaddset(&tset, SIGCLD);
(void) sigprocmask(SIG_SETMASK, &tset, NULL);
for (;;) {
ret = read(Pfd, &sacmsg, sizeof (sacmsg));
if (ret < 0) {
switch (errno) {
case EAGAIN:
(void) sigprocmask(SIG_SETMASK, &cset, NULL);
return;
case EINTR:
break;
default:
fatal("pmpipe read failed: %s",
strerror(errno));
break;
}
} else if (ret == 0) {
(void) sigprocmask(SIG_SETMASK, &cset, NULL);
return;
} else {
pmmsg.pm_size = 0;
(void) strcpy(pmmsg.pm_tag, Tag);
pmmsg.pm_maxclass = TM_MAXCLASS;
pmmsg.pm_type = PM_STATUS;
switch (sacmsg.sc_type) {
case SC_STATUS:
break;
case SC_ENABLE:
log("Got SC_ENABLE message");
oldState = State;
State = PM_ENABLED;
if (State != oldState) {
#ifdef DEBUG
debug("state changed to ENABLED");
#endif
state_change();
}
break;
case SC_DISABLE:
log("Got SC_DISABLE message");
oldState = State;
State = PM_DISABLED;
if (State != oldState) {
#ifdef DEBUG
debug("state changed to DISABLED");
#endif
state_change();
}
break;
case SC_READDB:
log("Got SC_READDB message");
Reread_flag = 1;
break;
default:
log("Got unknown message %d", sacmsg.sc_type);
pmmsg.pm_type = PM_UNKNOWN;
break;
}
pmmsg.pm_state = State;
while (write(Sfd, &pmmsg, sizeof (pmmsg)) !=
sizeof (pmmsg)) {
if (errno == EINTR)
continue;
log("sanity response to SAC failed: %s",
strerror(errno));
break;
}
}
}
}