#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include "misc.h"
#include "msgs.h"
#include <sac.h>
#include "structs.h"
#include <sys/types.h>
#include <unistd.h>
#include "extern.h"
void
read_table(startflag)
int startflag;
{
FILE *fp;
int ret;
struct sactab *sp;
# ifdef DEBUG
debug("in read_table");
# endif
Nentries = 0;
if ((ret = check_version(VERSION, SACTAB)) == 1)
error(E_BADVER, EXIT);
else if (ret == 2)
error(E_SACOPEN, EXIT);
else if (ret == 3)
error(E_BADFILE, EXIT);
fp = fopen(SACTAB, "r");
if (fp == NULL)
error(E_SACOPEN, EXIT);
for (sp = Sactab; sp; sp = sp->sc_next)
sp->sc_valid = 0;
while (sp = read_entry(fp))
insert(sp, startflag);
purge();
(void) fclose(fp);
}
struct sactab *
read_entry(fp)
FILE *fp;
{
register struct sactab *sp;
register char *p;
char buf[SIZE];
do {
if (fgets(buf, SIZE, fp) == NULL)
return(NULL);
p = trim(buf);
} while (*p == '\0');
sp = (struct sactab *) calloc(1, sizeof(struct sactab));
if (sp == NULL)
error(E_MALLOC, EXIT);
sp->sc_sstate = sp->sc_lstate = sp->sc_pstate = NOTRUNNING;
(void) memset(sp->sc_utid, '\0', IDLEN);
parse(p, sp);
return(sp);
}
void
insert(sp, startflag)
register struct sactab *sp;
int startflag;
{
register struct sactab *tsp, *savtsp;
int ret;
# ifdef DEBUG
debug("in insert");
# endif
savtsp = tsp = Sactab;
while (tsp) {
ret = strcmp(sp->sc_tag, tsp->sc_tag);
# ifdef DEBUG
(void) sprintf(Scratch, "sp->sc_tag <%s> tsp->sc_tag <%s>, ret is %d", sp->sc_tag, tsp->sc_tag, ret);
debug(Scratch);
# endif
if (ret > 0) {
savtsp = tsp;
tsp = tsp->sc_next;
continue;
}
else if (ret == 0) {
if (tsp->sc_valid) {
(void) sprintf(Scratch, "Ignoring duplicate entry for <%s>", tsp->sc_tag);
log(Scratch);
}
else {
tsp->sc_rsmax = sp->sc_rsmax;
tsp->sc_flags = sp->sc_flags;
# ifdef DEBUG
(void) sprintf(Scratch, "replacing <%s>", sp->sc_tag);
debug(Scratch);
# endif
tsp->sc_valid = 1;
Nentries++;
}
free(sp->sc_cmd);
free(sp);
return;
}
else {
if (tsp == Sactab) {
sp->sc_next = Sactab;
Sactab = sp;
}
else {
sp->sc_next = savtsp->sc_next;
savtsp->sc_next = sp;
}
# ifdef DEBUG
(void) sprintf(Scratch, "adding <%s>", sp->sc_tag);
debug(Scratch);
# endif
Nentries++;
sp->sc_valid = 1;
if (startflag && !(sp->sc_flags & X_FLAG))
(void) startpm(sp);
return;
}
}
sp->sc_next = NULL;
if (Sactab == NULL)
Sactab = sp;
else
savtsp->sc_next = sp;
# ifdef DEBUG
(void) sprintf(Scratch, "adding <%s>", sp->sc_tag);
debug(Scratch);
# endif
++Nentries;
sp->sc_valid = 1;
if (startflag && !(sp->sc_flags & X_FLAG))
(void) startpm(sp);
}
void
purge()
{
register struct sactab *sp;
register struct sactab *savesp, *tsp;
sigset_t cset;
sigset_t tset;
# ifdef DEBUG
debug("in purge");
# endif
(void) sigprocmask(SIG_SETMASK, NULL, &cset);
sp = savesp = Sactab;
while (sp) {
if (sp->sc_valid) {
savesp = sp;
sp = sp->sc_next;
continue;
}
switch (sp->sc_sstate) {
case UNKNOWN:
case ENABLED:
case DISABLED:
case STARTING:
tset = cset;
(void) sigaddset(&tset, SIGALRM);
(void) sigaddset(&tset, SIGCLD);
(void) sigprocmask(SIG_SETMASK, &tset, NULL);
if (sendsig(sp, SIGTERM))
(void) sprintf(Scratch, "could not send SIGTERM to <%s>", sp->sc_tag);
else
(void) sprintf(Scratch, "terminating <%s>", sp->sc_tag);
log(Scratch);
(void) sigdelset(&tset, SIGALRM);
(void) sigprocmask(SIG_SETMASK, &tset, NULL);
case STOPPING:
(void) close(sp->sc_fd);
case NOTRUNNING:
case FAILED:
cleanutx(sp);
tsp = sp;
if (tsp == Sactab) {
Sactab = sp->sc_next;
savesp = Sactab;
}
else
savesp->sc_next = sp->sc_next;
# ifdef DEBUG
(void) sprintf(Scratch, "purging <%s>", sp->sc_tag);
debug(Scratch);
# endif
sp = sp->sc_next;
free(tsp->sc_cmd);
free(tsp->sc_comment);
free(tsp);
(void) sigprocmask(SIG_SETMASK, &cset, NULL);
break;
}
}
}
char **
dump_table()
{
register struct sactab *sp;
register char *p;
register int size;
char **info, **savinfo;
# ifdef DEBUG
(void) sprintf(Scratch, "about to 'info' malloc %d entries", Nentries);
debug(Scratch);
# endif
if (Nentries == 0)
return(NULL);
if ((info = (char **) malloc(Nentries * sizeof(char *))) == NULL) {
error(E_MALLOC, CONT);
return(NULL);
}
savinfo = info;
for (sp = Sactab; sp; sp = sp->sc_next) {
size = strlen(sp->sc_tag) + strlen(sp->sc_type) + strlen(sp->sc_cmd) + strlen(sp->sc_comment) + SLOP;
if ((p = malloc((unsigned) size)) == NULL) {
error(E_MALLOC, CONT);
return(NULL);
}
(void) sprintf(p, "%s:%s:%d:%d:%d:%s:%s\n", sp->sc_tag, sp->sc_type,
sp->sc_flags, sp->sc_rsmax, sp->sc_pstate, sp->sc_cmd, sp->sc_comment);
*info++ = p;
# ifdef DEBUG
debug(*(info - 1));
# endif
}
return(savinfo);
}