/* 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); }