/*
Copyright (C) 1991, Marcus J. Ranum. All rights reserved.
*/
#ifndef lint
static char RCSid[] = "$Header: /usr/users/mjr/hacks/umud/RCS/cron.c,v 1.2 91/07/31 23:23:22 mjr Exp $";
#endif
/* configure all options BEFORE including system stuff. */
#include "config.h"
/*
#define CRON_DEBUG
*/
#ifdef NOSYSTYPES_H
#include <types.h>
#else
#include <sys/types.h>
#endif
#include "mud.h"
typedef struct kron {
int jobid;
time_t interv;
time_t last;
int runcnt;
char *who;
char *aswho;
char *cmd;
struct kron *nxt;
} Kron;
static Kron *crontab;
static int curjobid = 0;
cron_run(now)
time_t now;
{
Kron *k;
Kron *p;
k = p = crontab;
#ifdef CRON_DEBUG
printf("running cron - quantum is %d\n",cron_quantum);
#endif
while(k != (Kron *)0) {
if(now - k->last >= k->interv) {
#ifdef CRON_DEBUG
printf("trigger %s runs %s\n",k->who,k->cmd);
#endif
if(cache_check(k->who))
(void)run(k->who,k->aswho,k->cmd,0,0,1);
k->last = now;
if(k->runcnt != -1)
k->runcnt--;
}
if(k->runcnt == 0) {
if(k == crontab)
crontab = k->nxt;
else
p->nxt = k->nxt;
if(k->cmd != (char *)0)
free((mall_t)k->cmd);
if(k->aswho != (char *)0)
free((mall_t)k->aswho);
if(k->who != (char *)0)
free((mall_t)k->who);
p = k;
free((mall_t)k);
k = p->nxt;
continue;
}
p = k;
k = k->nxt;
}
return(0);
}
static int
cron_add(interv,runcnt,cmd,who,aswho)
time_t interv;
int runcnt;
char *cmd;
char *who;
char *aswho;
{
static char *allerr = "cannot allocate cron structure\n";
Kron *k;
if(cmd == (char *)0 || who == (char *)0 || aswho == (char *)0 ||
*cmd == '\0' || *who == '\0' || *aswho == '\0')
return(1);
if((k = (Kron *)malloc(sizeof(Kron))) == (Kron *)0) {
logf(allerr,(char *)0);
return(-1);
}
k->interv = interv;
time(&k->last);
k->runcnt = runcnt;
k->who = (char *)malloc((unsigned)(strlen(who) + 1));
if(k->who == (char *)0) {
logf(allerr,(char *)0);
return(-1);
}
strcpy(k->who,who);
k->aswho = (char *)malloc((unsigned)(strlen(aswho) + 1));
if(k->aswho == (char *)0) {
logf(allerr,(char *)0);
return(-1);
}
strcpy(k->aswho,aswho);
k->cmd = (char *)malloc((unsigned)(strlen(cmd) + 1));
if(k->cmd == (char *)0) {
logf(allerr,(char *)0);
return(-1);
}
strcpy(k->cmd,cmd);
k->nxt = crontab;
crontab = k;
k->jobid = curjobid++;
return(k->jobid);
}
static int
lowest_quant()
{
Kron *k;
int lowest = 3600;
for(k = crontab;k != (Kron *)0; k = k->nxt)
if(k->interv < lowest)
lowest = k->interv < CRONQUANT ? CRONQUANT : k->interv;
return(lowest);
}
static int
cron_del(jobid,who)
int jobid;
char *who;
{
Kron *k;
Kron *p;
k = p = crontab;
while(k != (Kron *)0) {
if(k->jobid == jobid) {
int squant;
squant = k->interv;
if(k == crontab)
crontab = k->nxt;
else
p->nxt = k->nxt;
if(k->cmd != (char *)0)
free((mall_t)k->cmd);
if(k->aswho != (char *)0)
free((mall_t)k->aswho);
if(k->who != (char *)0)
free((mall_t)k->who);
free((mall_t)k);
if(squant == cron_quantum) {
cron_quantum = lowest_quant();
#ifdef CRON_DEBUG
printf("new cron quantum %d\n",cron_quantum);
#endif
}
return(0);
}
p = k;
k = k->nxt;
}
return(1);
}
static void
cron_list(who)
char *who;
{
Kron *k;
char pbuf[80];
k = crontab;
while(k != (Kron *)0) {
sprintf(pbuf,"id# %d, every %d sec., ",k->jobid,k->interv);
say(who,pbuf,(char *)0);
if(k->runcnt != -1) {
sprintf(pbuf,"%d runs, ",k->runcnt);
say(who,pbuf,(char *)0);
}
sprintf(pbuf,"(%s/%s): %-30s\n",k->who,k->aswho,k->cmd);
say(who,pbuf,(char *)0);
k = k->nxt;
}
}
/* ARGSUSED */
cmd__cronconfig(ac,av,who,aswho)
int ac;
char *av[];
char *who;
char *aswho;
{
/* define an event */
if(!strcmp(av[1],"defevent")) {
int eid;
int iv;
int rc = -1; /* repeat forever */
char *twho;
char *taswho;
if(ac < 4) {
logf("usage: defevent interval macro [who] [aswho] [count]\n",(char *)0);
return(1);
}
if((iv = atoi(av[2])) < CRONQUANT) {
logf("event interval is too short\n",(char *)0);
iv = CRONQUANT;
}
if(iv < cron_quantum) {
cron_quantum = iv;
#ifdef CRON_DEBUG
printf("new cron quantum %d\n",cron_quantum);
#endif
}
twho = who;
if(ac > 4)
twho = av[4];
taswho = who;
if(ac > 5)
taswho = av[5];
if(ac > 6)
rc = atoi(av[6]);
eid = cron_add(iv,rc,av[3],twho,taswho);
if(eid < 0) {
logf("event not added\n",(char *)0);
return(1);
}
logf("added event: ",av[3],"\n",(char *)0);
return(0);
}
/* UNdefine an event */
if(!strcmp(av[1],"undefevent")) {
if(ac != 3) {
logf("usage: undefevent event-id\n",(char *)0);
return(1);
}
if(cron_del(atoi(av[2]),who)) {
logf("no such event: ",av[2],"\n",(char *)0);
return(1);
}
logf("undefined event ",av[2],"\n",(char *)0);
return(0);
}
if(!strcmp(av[1],"list")) {
cron_list(who);
return(0);
}
if(!strcmp(av[1],"help")) {
say(who,av[0]," undefevent event-id\n",(char *)0);
say(who,av[0]," defevent interval macro [who] [aswho] [count]\n",(char *)0);
say(who,av[0]," list\n",(char *)0);
return(0);
}
logf("_cronconfig: I don't understand ",av[1],"\n",(char *)0);
return(1);
}