/*$Id: ezmlm-limit.c,v 1.2 1999/10/31 18:58:48 lindberg Exp $*/ /*$Name: ezmlm-idx-040 $*/ #include #include "stralloc.h" #include "substdio.h" #include "readwrite.h" #include "strerr.h" #include "sig.h" #include "lock.h" #include "getconf.h" #include "fmt.h" #include "now.h" #include "sgetopt.h" #include "error.h" #include "errtxt.h" #include "idx.h" #define FATAL "ezmlm-limit: fatal: " #define INFO "ezmlm-limit: info: " unsigned long deltasecs = LIMSECS; /* interval to test over (seconds) */ unsigned long deltanum = LIMMSG; /* max no messages in interval */ /* see idx.h. Usually 30 msg/3600 secs*/ int flagd = 0; /* =0 create modpost, =1 ignore */ /* excess, =2 defer excess */ int flagmod; /* list moderated */ int flagloop; char *fn = TXT_LOOPNUM; void die_usage() { strerr_die1x(100, "ezmlm-limit: usage: ezmlm-limit [-f file] [-dDF] [-n messages]" " [-t secs] dir"); } void die_nomem() { strerr_die2x(111,FATAL,ERR_NOMEM); } void die_new() { strerr_die4sys(111,FATAL,ERR_WRITE,fn,": "); } stralloc line = {0}; substdio ssnew; char newbuf[16]; char strnum[FMT_ULONG]; void main(argc,argv) int argc; char **argv; { char *dir; int opt; unsigned int pos; unsigned long num, loopnum, when; unsigned long loopwhen = 0L; unsigned long numwhen = 0L; int fd,fdlock; (void) umask(022); sig_pipeignore(); when = (unsigned long) now(); while ((opt = getopt(argc,argv,"dDf:Fn:t:")) != opteof) switch(opt) { case 'd': flagd = 1; break; case 'D': flagd = 0; break; case 'f': if (optarg && *optarg) fn = optarg; break; case 'F': fn = TXT_LOOPNUM; case 'n': if (optarg) scan_ulong(optarg,&deltanum); break; case 't': if (optarg) scan_ulong(optarg,&deltasecs); break; default: die_usage(); } dir = argv[optind++]; if (!dir) die_usage(); if (chdir(dir) == -1) strerr_die4sys(111,FATAL,ERR_SWITCH,dir,": "); if (argv[optind]) die_usage(); /* avoid common error of putting options after dir */ if ((flagmod = getconf_line(&line,"modpost",0,FATAL,dir))) _exit(0); /* already mod */ /* lock for num and for writing loopnum */ fdlock = open_append("lock"); if (fdlock == -1) strerr_die4sys(111,FATAL,ERR_OPEN,dir,"/lock: "); if (lock_ex(fdlock) == -1) strerr_die4sys(111,FATAL,ERR_OBTAIN,dir,"/lock: "); if (!getconf_line(&line,"num",0,FATAL,dir)) _exit(99); /* no msgs */ if(!stralloc_0(&line)) die_nomem(); pos = scan_ulong(line.s,&num); /* current msg */ if ((flagloop = getconf_line(&line,fn,0,FATAL,dir))) { if(!stralloc_0(&line)) die_nomem(); pos = scan_ulong(line.s,&loopnum); /* msg when written */ if (line.s[pos] == ':') scan_ulong(line.s+pos+1,&loopwhen); /* time written */ } if (!flagloop || loopwhen + deltasecs < when || loopwhen > when) { /* loopnum too old, bad or not there */ fd = open_trunc(fn); /* no need to write crash-proof */ if (fd == -1) die_new(); substdio_fdbuf(&ssnew,write,fd,newbuf,sizeof(newbuf)); if (substdio_put(&ssnew,strnum,fmt_ulong(strnum,num)) == -1) die_new(); if (substdio_puts(&ssnew,":") == -1) die_new(); if (substdio_put(&ssnew,strnum,fmt_ulong(strnum,when)) == -1) die_new(); if (substdio_puts(&ssnew,"\n") == -1) die_new(); if (substdio_flush(&ssnew) == -1) die_new(); close(fd); } else if (num >= loopnum + deltanum) { /* excess messages */ if (!flagd) { if ((fd = open_append("modpost")) == -1) /* create dir/modpost */ strerr_die3sys(111,FATAL,ERR_WRITE,"subpost:"); else { close(fd); unlink(fn); strerr_die2x(0,INFO,ERR_EXCESS_MOD); } } else strerr_die2x(111,FATAL,ERR_EXCESS_DEFER); } _exit(0); }