|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T c
Length: 28919 (0x70f7)
Types: TextFile
Names: »config.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦f1ce22008⟧ »EurOpenD3/news/newsxd2.5.0.tar.Z«
└─⟦caa165e81⟧
└─⟦this⟧ »config.c«
/*
* #include <legal/bs.h>
>
> Copyright (c) 1989 Washington University in Saint Louis, Missouri and
> Chris Myers. All rights reserved.
>
> Permission is hereby granted to copy, reproduce, redistribute or
> otherwise use this software as long as: (1) there is no monetary
> profit gained specifically from the use or reproduction of this
> software, (2) it is not sold, rented, traded, or otherwise marketed,
> (3) the above copyright notice and this paragraph is included
> prominently in any copy made, and (4) that the name of the University
> is not used to endorse or promote products derived from this software
> without the specific prior written permission of the University.
> THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
> IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
> WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
>
*/
#include "defs.h"
/*************************************************************************/
/* FUNCTION : getclass */
/* PURPOSE : Return a pointer to the class structure given the name of */
/* a class */
/* ARGUMENTS : The name of a class */
/*************************************************************************/
struct class *
getclass(classname)
char *classname;
{
struct class *classptr;
if (strlen(classname) > MAXCLASSNAMELEN - 1) {
Dprintf("(getclass): classname %s is too long, no match\n", classname);
return((struct class *) NULL);
}
foreach (classptr, classlist) {
Dprintf("(getclass): now checking class %s\n", classptr->classname);
if (strcmp(classname, classptr->classname) == 0) break;
}
return(classptr);
}
/*************************************************************************/
/* FUNCTION : addclass */
/* PURPOSE : Add a class to or modify a class in the class list */
/* ARGUMENTS : All the information needed to define a class... */
/*************************************************************************/
void
addclass(classname,maxxmits,interval,startint,maxload,ttl,ttlpenalty,nice,flags)
char *classname;
int maxxmits, interval, startint, maxload, ttl, ttlpenalty, nice, flags;
{
struct class *classptr = classlist;
int loop,
newclass = 0;
if (strlen(classname) > MAXCLASSNAMELEN - 1) {
logerr("(addclass) Class name %s too long, max %d - ignoring\n",
classname, MAXCLASSNAMELEN - 1);
return;
}
if ((classptr = getclass(classname)) == NULL) {
Dprintf("(addclass): CALLOCing new class structure\n");
classptr = (struct class *) calloc(1, sizeof(struct class));
if (classptr == NULL) {
logerr("(addclass) Can't calloc struct class for class %s\n",
classname);
return;
}
for (loop = 0; loop < MAXCLASSXMITTERS; loop++)
classptr->slots[loop] = '.';
newclass++;
} else if (classptr->valid == 1) {
logerr("(addclass) Duplicated class %s\n", classname);
return;
}
/*
* Build class structure for this class and insert at the head of the
* class list
*/
(void) strcpy(classptr->classname, classname);
classptr->maxxmits = maxxmits;
classptr->options.maxload = maxload;
classptr->options.interval = interval;
classptr->options.startint = startint;
classptr->options.ttl = ttl;
classptr->options.deltanice = nice;
classptr->options.ttlpenalty = ttlpenalty;
classptr->valid = 1;
classptr->xmitsernum = 0;
classptr->members = 0;
/*
* Set all of the class flags. flag is a bitmap.
*/
for (loop = 0; loop < MAXCLASSFLAGS; loop++) {
if (flags & (1 << loop))
classptr->flags[loop] = 1;
else
classptr->flags[loop] = 0;
Dprintf("(addclass): flags[%d] = %d\n", loop,
classptr->flags[loop]);
}
/*
* Check to see if we are just overwriting a class description, if so don't
* wipe the pointer to the next entry in the list.
*/
if (newclass) {
classptr->next = classlist;
classlist = classptr;
}
Dprintf("(addclass): classlist = %d\n", classlist);
}
/*************************************************************************/
/* FUNCTION : addhost */
/* PURPOSE : Add a host to the list of hosts to transmit to */
/* ARGUMENTS : Name of the host, class name, start and stop times */
/*************************************************************************/
void
addhost(hostname, classname, times, deltanice, maxload, interval, startint,
ttl, ttlpenalty, flags)
char *hostname, *classname, *times, *flags;
int deltanice, maxload, interval, startint, ttl, ttlpenalty;
{
struct host *hostptr,
*loopptr,
*lastptr = NULL;
struct class *classptr;
int loop;
char *flagbuf;
if (strlen(hostname) > MAXHOSTNAMELEN - 1) {
logerr("(addhost) Host name %s too long, max %d - ignoring\n",
classname, MAXHOSTNAMELEN - 1);
return;
}
if (strlen(times) > MAXTIMENAMELEN - 1) {
logerr("(addhost) Host time %s too long, max %d - ignoring\n",
classname, MAXTIMENAMELEN - 1);
return;
}
if ((classptr = getclass(classname)) == NULL) {
logerr("(addhost) Host's (%s) class %s doesn't exist - ignoring host\n",
hostname, classname);
return;
}
if (classptr->valid == 0) {
logerr("(addhost) Host's (%s) class %s is invalid - ignoring host\n",
hostname, classname);
return;
}
if (strcmp(classname, "DEFAULT") == 0) {
logerr("(addhost) Host (%s) can't be a member of class DEFAULT\n",
hostname);
return;
}
lastptr = NULL;
foreach (hostptr, hostlist) {
Dprintf("(addhost): now checking host %s\n", hostptr->hostname);
if (strcmp(hostname, hostptr->hostname) == 0) break;
lastptr = hostptr;
}
if (hostptr != NULL) {
if (hostptr->valid == 1) {
logerr("(addhost) Duplicated host %s\n", hostname);
return;
}
if (lastptr != NULL) {
lastptr->next = hostptr->next;
Dprintf("(addhost) host %s next was %s, now %s\n", lastptr->hostname,
hostptr->hostname, hostptr->next ? hostptr->next->hostname : NULL);
} else
hostlist = hostptr->next;
} else {
Dprintf("(addhost): CALLOCing new host structure\n");
hostptr = (struct host *) calloc(1, sizeof(struct host));
if (hostptr == NULL) {
logerr("(addhost) Can't calloc struct host for host %s\n",
hostname);
return;
}
}
(void) strcpy(hostptr->hostname, hostname);
(void) strcpy(hostptr->class, classname);
(void) strcpy(hostptr->times, times);
hostptr->valid = 1;
hostptr->options.deltanice = deltanice;
hostptr->options.maxload = maxload;
hostptr->options.interval = interval;
hostptr->options.startint = startint;
hostptr->options.ttl = ttl;
hostptr->options.ttlpenalty = ttlpenalty;
hostptr->xmitsernum = 0;
hostptr->xargc = 0;
classptr->members++;
if (strlen(flags) > 0) {
if ((flagbuf = (char *) calloc(1, strlen(flags) + 1)) != NULL) {
(void) strcpy(flagbuf, flags);
while (1) {
hostptr->xargv[hostptr->xargc++] = flagbuf;
if ((flagbuf = STRCHR(flagbuf, '|')) == (char *) NULL) break;
*flagbuf++ = '\0';
}
}
}
for (loop = 0; loop < hostptr->xargc; loop++)
Dprintf("host %s: flag[%d] = %s\n", hostname, loop, hostptr->xargv[loop]);
/*
* If this is a new host, do a two-key insertion sort based on the
* hostname and name of the transmission class. Makes things look nice
* in the status display...
*/
lastptr = NULL;
if (hostlist == NULL) {
Dprintf("(addhost): %s IS hostlist now\n", hostname);
hostlist = hostptr;
} else {
foreach (loopptr, hostlist) {
if (((strcmp(hostptr->hostname, loopptr->hostname) < 0) &
(strcmp(hostptr->class, loopptr->class) == 0)) |
(strcmp(hostptr->class, loopptr->class) < 0)) {
Dprintf("(addhost): Inserting %s before %s\n", hostname,
loopptr->hostname);
hostptr->next = loopptr;
if (lastptr != NULL) lastptr->next = hostptr;
if (loopptr == hostlist) hostlist = hostptr;
break;
}
lastptr = loopptr;
}
if (loopptr == NULL) {
Dprintf("(addhost): appending host %s to hostlist\n", hostname);
lastptr->next = hostptr; /* append to current host list */
hostptr->next = NULL;
}
}
Dprintf("(addhost): hostlist = %d\n", hostlist);
}
/*************************************************************************/
/* FUNCTION : make_invalid */
/* PURPOSE : Mark all hosts and classes as invalid */
/* ARGUMENTS : none */
/*************************************************************************/
void
make_invalid()
{
struct class *classptr,
*nextclass;
struct host *hostptr,
*nexthost;
dprintf("(make_invalid) marking all classes as invalid\n");
for (classptr = classlist; classptr != NULL; classptr = nextclass) {
Dprintf("(make_invalid) marking class %s as invalid\n",
classptr->classname);
classptr->valid = 0;
classptr->members = 0;
nextclass = classptr->next;
}
dprintf("(make_invalid) marking all hosts as invalid\n");
for (hostptr = hostlist; hostptr != NULL; hostptr = nexthost) {
Dprintf("(make_invalid) marking host %s as invalid\n", hostptr->hostname);
hostptr->valid = 0;
nexthost = hostptr->next;
}
}
/*************************************************************************/
/* FUNCTION : clear_invalid */
/* PURPOSE : Remove all hosts and classes which are not valid anymore */
/* ARGUMENTS : none */
/*************************************************************************/
void
clear_invalid()
{
struct class *lastclass = NULL,
*classptr,
*nextclass;
struct host *lasthost = NULL,
*hostptr,
*nexthost;
int loop;
dprintf("(clear_invalid) clearing all invalid hosts\n");
for (hostptr = hostlist; hostptr != NULL; hostptr = nexthost) {
nexthost = hostptr->next;
if (hostptr->valid == 0) {
if (hostptr->pid > 0) {
dprintf("(clear_invalid): killing transmitter for host %s\n",
hostptr->hostname);
if (kill(hostptr->pid, SIGTERM) != 0) xmit_done(-hostptr->pid);
}
Dprintf("(clear_invalid): clearing host %s\n", hostptr->hostname);
(void) free(hostptr);
if (hostlist == hostptr) hostlist = nexthost;
if (lasthost) lasthost->next = nexthost;
} else {
lasthost = hostptr;
}
}
dprintf("(clear_invalid) clearing all invalid classes\n");
for (classptr = classlist; classptr != NULL; classptr = nextclass) {
nextclass = classptr->next;
if (classptr->valid == 0) {
Dprintf("(clear_invalid): clearing class %s\n", classptr->classname);
for (loop = 0; loop < classptr->xargc; loop++) {
Dprintf("(clear_invalid): clearing class %s argv %d\n",
classptr->classname, loop);
free(classptr->xargv[loop]);
}
free(classptr);
if (classlist == classptr) classlist = nextclass;
if (lastclass) lastclass->next = nextclass;
} else {
lastclass = classptr;
}
}
}
/*************************************************************************/
/* FUNCTION : read_config */
/* PURPOSE : Read the newsxd configuration file */
/* ARGUMENTS : none */
/*************************************************************************/
void
read_config(sig)
int sig;
{
FILE *config;
char line[MAXPATHLEN], /* buffer used for inputting lines */
buf[9][MAXPATHLEN], /* buffers for various command parameters */
*comment; /* used to trim comments from input lines */
int loop,
deltanice, /* Amount to change proc's nice for xmit */
optioncnt, /* number of parameters found by sscanf */
maxxmits, /* number of allowed simul. transmitters */
interval, /* interval between xmits to a single host */
startint, /* interval between starting xmits 4 a class */
maxload, /* max allowed load for starting new xmits */
ttl, /* maximum time-to-live for a transmitter */
ttlpenalty, /* time penalty for exceeding ttl */
flags; /* option flags for this transmission class */
struct class *classptr; /* used to traverse the class list */
struct stat statbuf;
if (!(config = fopen(configfile, "r"))) {
logerr("Couldn't open config file (%s) - aborting\n", configfile);
(void) exit(1);
}
/*
* Mark all hosts and classes as undefined, but don't delete 'em yet
*/
if (sig) log(LOG_INFO, "reinitializing\n");
make_invalid();
CONFIGCHANGED = 1;
#ifdef FAKESYSLOG
CONFIGCHANGEDFILE = 1;
#endif
daemon_idle = 0; /* Allow newsxd to begin running the queue again */
/*
* Reset all of the various data files to their default location
*/
(void) strcpy(batchfile, default_batchfile);
(void) strcpy(workfile, default_workfile);
(void) strcpy(xmitlogs, default_xmitlogs);
locking = 0; /* locking defaults to OFF */
tallying = 0; /* use of the tally file defaults to OFF */
queueinterval = 60; /* default queue run interval of 1 minute */
/*
* Add the DEFAULT pseudo-class so that a default xmitter can be specified
*/
addclass("DEFAULT", 0, 0, 0, 0, 0, 0, 0, 0);
while (fgets(line, 255, config) != NULL) {
if ((comment = index(line, '#')) != NULL)
(void) strcpy(comment, "\n");
Dprintf("> %s", line);
if (sscanf(line, "tallyfile %s\n", tallyfile) > 0) {
dprintf("tallyfile is %s\n", tallyfile);
tallying = 1;
}
/*
if (sscanf(line, "perhostlock %s\n", perhostlock) > 0) {
dprintf("perhostlock is %s\n", perhostlock);
locking = 1;
}
*/
if (sscanf(line, "batchfile %s\n", batchfile) > 0)
dprintf("batchfile is %s\n", batchfile);
if (sscanf(line, "xmitlogs %s\n", xmitlogs) > 0) {
dprintf("xmitlogs is %s\n", xmitlogs); continue; }
if (sscanf(line, "workfile %s\n", workfile) > 0)
dprintf("workfile is %s\n", workfile);
if (sscanf(line, "queueinterval %d\n", &queueinterval) > 0)
dprintf("queueinterval is %d\n", queueinterval);
if ((optioncnt = sscanf(line, "class %s %s %s %s %s %s %s %s", buf[0],
buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8])) > 0) {
maxxmits = 1;
interval = 60;
startint = 0;
maxload = 99;
ttl = 999999;
ttlpenalty = 0;
flags = 0;
deltanice = 0;
Dprintf("optioncnt = %d\n", optioncnt);
for (loop = 1; loop < optioncnt; loop++) {
(void) sscanf(buf[loop], "maxxmits=%d", &maxxmits);
(void) sscanf(buf[loop], "maxload=%d", &maxload);
(void) sscanf(buf[loop], "nice=%d", &deltanice);
(void) sscanf(buf[loop], "interval=%d/%d", &interval, &startint);
(void) sscanf(buf[loop], "ttl=%d/%d", &ttl, &ttlpenalty);
if (strcmp(buf[loop], "noworkfile") == 0) flags |= (1<<C_NOWORK);
if (strcmp(buf[loop], "nobatchfile") == 0) flags |= (1<<C_NOBATCH);
}
dprintf("class %s, maxxmits %d, intvl %d/%d, maxload %d, ttl %d/%d, nice %d, flags=%d\n",
buf[0], maxxmits, interval, startint, maxload, ttl, ttlpenalty,
deltanice, flags);
addclass(buf[0], maxxmits, interval, startint, maxload, ttl,
ttlpenalty, deltanice, flags);
}
if ((optioncnt = sscanf(line, "xmit %s %s %s %s %s %s %s %s %s", buf[0],
buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8])) > 0) {
classptr = getclass(buf[0]);
if (!classptr | (classptr->valid == 0)) {
logerr("(read_config) xmit class for invalid class %s ignored\n",
buf[0]);
}
if (stat(buf[1], &statbuf) != 0) {
logerr("(read_config) xmit program %s for class %s unavailable\n",
buf[1], buf[0]);
logerr("(read_config) no xmit for class %s, invalidating class\n",
buf[0]);
classptr->valid = 0;
continue;
}
(void) strcpy(classptr->xpath, buf[1]);
for (loop = 2; loop < optioncnt; loop++) {
Dprintf("class %s: setting xmit parm %d = %s\n",
classptr->classname, loop - 2, buf[loop]);
classptr->xargv[loop-2] = (char *) malloc(strlen(buf[loop])+1);
(void) strcpy(classptr->xargv[loop-2], buf[loop]);
}
classptr->xargv[optioncnt - 2] = NULL;
classptr->xargc = optioncnt - 2;
}
if ((optioncnt = sscanf(line, "host %s %s %s %s %s %s %s %s", buf[0],
buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7])) > 0) {
Dprintf("optioncnt = %d\n", optioncnt);
interval = 0;
startint = 0;
maxload = 0;
ttl = 0;
ttlpenalty = 0;
deltanice = 0;
*buf[9] = '\0';
for (loop = 3; loop < optioncnt; loop++) {
(void) sscanf(buf[loop], "maxload=%d", &maxload);
(void) sscanf(buf[loop], "interval=%d/%d", &interval, &startint);
(void) sscanf(buf[loop], "ttl=%d/%d", &ttl, &ttlpenalty);
(void) sscanf(buf[loop], "nice=%d", &deltanice);
(void) sscanf(buf[loop], "flags=%s", buf[9]);
}
dprintf("host %s, class %s, times %s, deltanice %d, maxload %d, intvl %d/%d, ttl %d/%d, flags=\"%s\"\n",
buf[0], buf[1], buf[2], deltanice, maxload, interval, startint,
ttl, ttlpenalty, buf[9]);
addhost(buf[0], buf[1], buf[2], deltanice, maxload, interval, startint,
ttl, ttlpenalty, buf[9]);
}
}
/*
* Remove any hosts or classes not defined anymore
*/
clear_invalid();
}
/*************************************************************************/
/* FUNCTION : dump_config */
/* PURPOSE : Write the current configuration and status of newsxd to */
/* a file */
/* ARGUMENTS : none */
/*************************************************************************/
void
dump_config()
{
struct host *hostptr;
struct class *classptr;
char lastxmittime[30], /* bunches of buffers for ctime */
buf1[30],
buf2[30],
pid[30]; /* holds (pid) or "none" */
FILE *status;
int curtime;
if ((debug <= 0) || (DEBUG <= 0)) {
status = fopen(statusfile, "w");
if (status == NULL) {
logerr("Can't open statusfile (%s, \"w\")\n", statusfile);
return;
}
} else
status = stderr;
curtime = time((long *) NULL);
(void) fprintf(status, "%s", ctime(&curtime));
if (daemon_idle) (void) fprintf(status, "Newsxd is idled\n");
if (classlist == NULL) {
(void) fprintf(status, "No valid classes defined!\n");
return;
}
(void) fputc('\n', status);
foreach (classptr, classlist) {
if (strcmp(classptr->classname, "DEFAULT") == 0) continue;
(void) fprintf(status, "Class %-7.7s : %2d active transmitters (%2d max)",
classptr->classname, classptr->curxmits, classptr->maxxmits);
if (getla() > classptr->options.maxload)
(void) fprintf(status, " [no new xmits, load %d > %d max]",
getla(), classptr->options.maxload);
(void) fputc('\n', status);
}
(void) fputc('\n', status);
(void) fprintf(status, " Service Valid Start Last XMIT Xmitter Why Not\n");
(void) fprintf(status, "Hostname Class Times Started pid Running\n");
(void) fprintf(status, "----------------------- ------- ------------- --------- ------- ----------\n");
if (hostlist == NULL) {
(void) fprintf(status, "No valid hosts defined!\n");
}
foreach (hostptr, hostlist) {
if (hostptr->lasttime == NULL)
(void) strcpy(lastxmittime, "* NEVER *");
else {
(void) sscanf(ctime(&hostptr->lasttime), "%s %*s %*s %s", buf1, buf2);
(void) sprintf(lastxmittime, "%s %5.5s", buf1, buf2);
}
(void) sprintf(pid, (hostptr->pid) ? "%d" : "none", hostptr->pid);
(void) fprintf(status, "%-23.23s %-7s %-13.13s %9s %5s ",
hostptr->hostname, hostptr->class, hostptr->times, lastxmittime, pid);
switch (hostptr->whynot) {
case WN_PENALTYTIME:
(void) fputs("TTL Penlty", status);
break;
case WN_TTL:
(void) fputs("TTL Kill", status);
break;
case WN_CLASSSTARTINT:
(void) fputs("Class Intv", status);
break;
case WN_HOSTSTARTINT:
(void) fputs("Host Intvl", status);
break;
case WN_LOAD:
(void) fputs("High Load", status);
break;
case WN_BADTIME:
(void) fputs("Wrong Time", status);
break;
case WN_MAXXMITS:
(void) fputs("Max Xmits", status);
break;
case WN_RUNNING:
(void) fputs("RUNNING", status);
break;
case WN_NOWORK:
(void) fputs("No Work", status);
break;
case WN_RENAMEFAILED:
(void) fputs("Bad Rename", status);
break;
case WN_NOTMYTURN:
(void) fputs("NotMyTurn", status);
break;
case WN_NOSLOT:
(void) fputs("No Slot!", status);
break;
}
(void) fputc('\n', status);
}
if ((debug <= 0) || (DEBUG <= 0)) (void) fclose(status);
}
/*************************************************************************/
/* FUNCTION : dump_info */
/* PURPOSE : Dump newsxd's data structures to a file. */
/* ARGUMENTS : none */
/*************************************************************************/
void
dump_info()
{
struct host *hostptr;
struct class *classptr;
long curtime;
int loop, which;
FILE *status;
char outfile[MAXPATHLEN];
if ((debug <= 0) || (DEBUG <= 0)) {
(void) sprintf(outfile, "%s.dump", statusfile);
status = fopen(outfile, "w");
if (status == NULL) {
logerr("Can't open statusfile (%s, \"w\")\n", statusfile);
return;
}
} else
status = stderr;
curtime = time((long *) NULL);
(void) fprintf(status, "Newsxd data structures at %s\n", ctime(&curtime));
(void) fprintf(status, "debug is %s, DEBUG is %s, newsxdebug is %s\n",
debug ? "On" : "Off", DEBUG ? "On" : "Off", newsxdebug ? "On" : "Off");
(void) fprintf(status, "Queue runs occur every %d seconds, newsxd %s idled\n\n",
queueinterval, daemon_idle ? "is" : "is not");
(void) fprintf(status, "Active transmitter PID mappings:\n");
which = 0;
for (loop = 0; loop < MAXXMITTERS; loop++) {
if (pidlist[loop] != 0) {
if (!which) (void) fputc('\n', status);
(void) fprintf(status, "pid %5d --> host %-20.20s ", pidlist[loop],
pidmap[loop]->hostname);
which = !which;
}
}
(void) fputs("\n\n", status);
(void) fprintf(status, "batchfile is %s\n", batchfile);
(void) fprintf(status, "workfile is %s\n", workfile);
(void) fprintf(status, "xmitlogs is %s\n", xmitlogs);
(void) fprintf(status, "newsxd status written to %s\n", statusfile);
(void) fprintf(status, "newsxd pid written to %s\n", pidfile);
(void) fprintf(status, "newsxd config file is %s\n", configfile);
(void) fprintf(status, "\n");
if (classlist == NULL) (void) fprintf(status, "NO DEFINED CLASSES\n");
foreach (classptr, classlist) {
(void) fprintf(status, "CLASS %s (%02d members)\n\n", classptr->classname,
classptr->members);
(void) fprintf(status, " xmit prog %s", classptr->xpath);
for (loop = 0; loop < classptr->xargc; loop++)
(void) fprintf(status, " %s", classptr->xargv[loop]);
(void) fprintf(status, "\n");
(void) fprintf(status, " xmitters %02d running, %02d max\n",
classptr->curxmits, classptr->maxxmits);
(void) fprintf(status, " last xmit %s", ctime(&classptr->laststart));
(void) fprintf(status, " sernum %d\n", classptr->xmitsernum);
(void) fprintf(status, " options ");
if (classptr->options.deltanice)
(void) fprintf(status, " nice=%d", classptr->options.deltanice);
if (classptr->options.interval)
(void) fprintf(status, " interval=%d", classptr->options.interval);
if (classptr->options.startint)
(void) fprintf(status, " startint=%d", classptr->options.startint);
if (classptr->options.ttl)
(void) fprintf(status, " ttl=%d", classptr->options.ttl);
if (classptr->options.ttlpenalty)
(void) fprintf(status, " ttlpenalty=%d", classptr->options.ttlpenalty);
if (classptr->options.maxload)
(void) fprintf(status, " maxload=%d", classptr->options.maxload);
(void) fputc('\n', status);
(void) fprintf(status, " slots ");
for (loop = 0; loop < MAXCLASSXMITTERS; loop++) {
if ((loop > 0) & ((loop % 50) == 0))
(void) fputs("\n ", status);
(void) fputc(classptr->slots[loop], status);
}
(void) fputs("\n\n", status);
}
if (hostlist == NULL) (void) fprintf(status, "NO DEFINED HOSTS\n");
foreach (hostptr, hostlist) {
(void) fprintf(status, "HOST %s\n", hostptr->hostname);
(void) fprintf(status, " class %s\n", hostptr->class);
(void) fprintf(status, " xmit times %s\n", hostptr->times);
(void) fprintf(status, " xmit pid %d\n", hostptr->pid);
(void) fprintf(status, " last xmit %s", hostptr->lasttime ?
ctime(&hostptr->lasttime) : "NEVER\n");
(void) fprintf(status, " penalty to %s", hostptr->penaltytime ?
ctime(&hostptr->penaltytime) : "NONE\n");
(void) fprintf(status, " xmitsernum %d\n", hostptr->xmitsernum);
(void) fprintf(status, " whynot %d\n", hostptr->whynot);
(void) fprintf(status, " xmit slot %d\n", hostptr->classslot);
(void) fprintf(status, " xmit flags");
for (loop = 0; loop < hostptr->xargc; loop++)
(void) fprintf(status, " %s", hostptr->xargv[loop]);
(void) fputc('\n', status);
(void) fprintf(status, " options ");
if (hostptr->options.deltanice)
(void) fprintf(status, " nice=%d", hostptr->options.deltanice);
if (hostptr->options.interval)
(void) fprintf(status, " interval=%d", hostptr->options.interval);
if (hostptr->options.startint)
(void) fprintf(status, " startint=%d", hostptr->options.startint);
if (hostptr->options.ttl)
(void) fprintf(status, " ttl=%d", hostptr->options.ttl);
if (hostptr->options.ttlpenalty)
(void) fprintf(status, " ttlpenalty=%d", hostptr->options.ttlpenalty);
if (hostptr->options.maxload)
(void) fprintf(status, " maxload=%d", hostptr->options.maxload);
(void) fputs("\n\n", status);
}
if ((debug <= 0) || (DEBUG <= 0)) (void) fclose(status);
}