# include <stdlib.h>
# include <stdio.h>
# include <unistd.h>
# include <fcntl.h>
# include <signal.h>
# include <sac.h>
char Scratch[BUFSIZ]; /* scratch buffer */
char Tag[PMTAGSIZE + 1]; /* port monitor's tag */
FILE *Fp; /* file pointer for log file */
FILE *Tfp; /* file pointer for pid file */
char State; /* port monitor's current state*/
main(argc, argv)
int argc;
char *argv[];
{
char *istate;
strcpy(Tag, getenv("PMTAG"));
/*
* open up a log file in port monitor's private directory
*/
sprintf(Scratch, "/var/saf/%s/log", Tag);
Fp = fopen(Scratch, "a+");
if (Fp == (FILE *)NULL)
exit(1);
log(Fp, "starting");
/*
* retrieve initial state (either "enabled" or "disabled") and set
* State accordingly
*/
istate = getenv("ISTATE");
sprintf(Scratch, "ISTATE is %s", istate);
log(Fp, Scratch);
if (!strcmp(istate, "enabled"))
State = PM_ENABLED;
else if (!strcmp(istate, "disabled"))
State = PM_DISABLED;
else {
log(Fp, "invalid initial state");
exit(1);
}
sprintf(Scratch, "PMTAG is %s", Tag);
log(Fp, Scratch);
/*
* set up pid file and lock it to indicate that we are active
*/
Tfp = fopen("_pid", "w");
if (Tfp == (FILE *)NULL) {
log(Fp, "couldn't open pid file");
exit(1);
}
if (lockf(fileno(Tfp), F_TEST, 0) < 0) {
log(Fp, "pid file already locked");
exit(1);
}
fprintf(Tfp, "%d", getpid());
fflush(Tfp);
log(Fp, "locking file");
if (lockf(fileno(Tfp), F_LOCK, 0) < 0) {
log(Fp, "lock failed");
exit(1);
}
/*
* handle poll messages from the sac ... this function never
returns
*/
handlepoll();
pause();
fclose(Tfp);
fclose(Fp);
}
handlepoll()
{
int pfd; /* file descriptor for incoming pipe */
int sfd; /* file descriptor for outgoing pipe */
struct sacmsg sacmsg; /* incoming message */
struct pmmsg pmmsg; /* outgoing message */
/*
* open pipe for incoming messages from the sac
*/
pfd = open("_pmpipe", O_RDONLY|O_NONBLOCK);
if (pfd < 0) {
log(Fp, "_pmpipe open failed");
exit(1);
}
/*
* open pipe for outgoing messages to the sac
*/
sfd = open("../_sacpipe", O_WRONLY);
if (sfd < 0) {
log(Fp, "_sacpipe open failed");
exit(1);
}
/*
* start to build a return message; we only support class 1
messages
*/
strcpy(pmmsg.pm_tag, Tag);
pmmsg.pm_size = 0;
pmmsg.pm_maxclass = 1;
/*
* keep responding to messages from the sac
*/
for (;;) {
if (read(pfd, &sacmsg, sizeof(sacmsg)) != sizeof(sacmsg)) {
log(Fp, "_pmpipe read failed");
exit(1);
}
/*
* determine the message type and respond appropriately
*/
switch (sacmsg.sc_type) {
case SC_STATUS:
log(Fp, "Got SC_STATUS message");
pmmsg.pm_type = PM_STATUS;
pmmsg.pm_state = State;
break;
case SC_ENABLE:
/*note internal state change below*/
log(Fp, "Got SC_ENABLE message");
pmmsg.pm_type = PM_STATUS;
State = PM_ENABLED;
pmmsg.pm_state = State;
break;
case SC_DISABLE:
/*noteinternalstatechangebelow*/
log(Fp, "Got SC_DISABLE message");
pmmsg.pm_type = PM_STATUS;
State = PM_DISABLED;
pmmsg.pm_state = State;
break;
case SC_READDB:
/*
* if this were a fully functional port monitor it
* would read _pmtab here and take appropriate action
*/
log(Fp, "Got SC_READDB message");
pmmsg.pm_type = PM_STATUS;
pmmsg.pm_state = State;
break;
default:
sprintf(Scratch, "Got unknown message <%d>",
sacmsg.sc_type);
log(Fp, Scratch);
pmmsg.pm_type = PM_UNKNOWN;
pmmsg.pm_state = State;
break;
}
/*
* send back a response to the poll
* indicating current state
*/
if (write(sfd, &pmmsg, sizeof(pmmsg)) != sizeof(pmmsg))
log(Fp, "sanity response failed");
}
}
/*
* general logging function
*/
log(fp, msg)
FILE *fp;
char *msg;
{
fprintf(fp, "%d; %s\n", getpid(), msg);
fflush(fp);
}
|