Import ezmlm-idx 0.40
[ezmlm] / ezmlm-limit.c
CommitLineData
f8beb284
MW
1/*$Id: ezmlm-limit.c,v 1.2 1999/10/31 18:58:48 lindberg Exp $*/
2/*$Name: ezmlm-idx-040 $*/
3
4#include <sys/types.h>
5#include "stralloc.h"
6#include "substdio.h"
7#include "readwrite.h"
8#include "strerr.h"
9#include "sig.h"
10#include "lock.h"
11#include "getconf.h"
12#include "fmt.h"
13#include "now.h"
14#include "sgetopt.h"
15#include "error.h"
16#include "errtxt.h"
17#include "idx.h"
18
19#define FATAL "ezmlm-limit: fatal: "
20#define INFO "ezmlm-limit: info: "
21
22unsigned long deltasecs = LIMSECS; /* interval to test over (seconds) */
23unsigned long deltanum = LIMMSG; /* max no messages in interval */
24 /* see idx.h. Usually 30 msg/3600 secs*/
25int flagd = 0; /* =0 create modpost, =1 ignore */
26 /* excess, =2 defer excess */
27int flagmod; /* list moderated */
28int flagloop;
29char *fn = TXT_LOOPNUM;
30
31void die_usage()
32{
33 strerr_die1x(100,
34 "ezmlm-limit: usage: ezmlm-limit [-f file] [-dDF] [-n messages]"
35 " [-t secs] dir");
36}
37
38void die_nomem() { strerr_die2x(111,FATAL,ERR_NOMEM); }
39
40void die_new() { strerr_die4sys(111,FATAL,ERR_WRITE,fn,": "); }
41
42stralloc line = {0};
43
44substdio ssnew;
45char newbuf[16];
46
47char strnum[FMT_ULONG];
48
49void main(argc,argv)
50int argc;
51char **argv;
52{
53 char *dir;
54 int opt;
55 unsigned int pos;
56 unsigned long num, loopnum, when;
57 unsigned long loopwhen = 0L;
58 unsigned long numwhen = 0L;
59 int fd,fdlock;
60
61 (void) umask(022);
62 sig_pipeignore();
63 when = (unsigned long) now();
64
65 while ((opt = getopt(argc,argv,"dDf:Fn:t:")) != opteof)
66 switch(opt) {
67 case 'd': flagd = 1; break;
68 case 'D': flagd = 0; break;
69 case 'f': if (optarg && *optarg) fn = optarg; break;
70 case 'F': fn = TXT_LOOPNUM;
71 case 'n':
72 if (optarg)
73 scan_ulong(optarg,&deltanum);
74 break;
75 case 't':
76 if (optarg)
77 scan_ulong(optarg,&deltasecs);
78 break;
79 default:
80 die_usage();
81 }
82
83 dir = argv[optind++];
84 if (!dir) die_usage();
85
86 if (chdir(dir) == -1)
87 strerr_die4sys(111,FATAL,ERR_SWITCH,dir,": ");
88
89 if (argv[optind])
90 die_usage(); /* avoid common error of putting options after dir */
91 if ((flagmod = getconf_line(&line,"modpost",0,FATAL,dir)))
92 _exit(0); /* already mod */
93 /* lock for num and for writing loopnum */
94 fdlock = open_append("lock");
95 if (fdlock == -1)
96 strerr_die4sys(111,FATAL,ERR_OPEN,dir,"/lock: ");
97 if (lock_ex(fdlock) == -1)
98 strerr_die4sys(111,FATAL,ERR_OBTAIN,dir,"/lock: ");
99
100 if (!getconf_line(&line,"num",0,FATAL,dir))
101 _exit(99); /* no msgs */
102 if(!stralloc_0(&line)) die_nomem();
103 pos = scan_ulong(line.s,&num); /* current msg */
104 if ((flagloop = getconf_line(&line,fn,0,FATAL,dir))) {
105 if(!stralloc_0(&line)) die_nomem();
106 pos = scan_ulong(line.s,&loopnum); /* msg when written */
107 if (line.s[pos] == ':')
108 scan_ulong(line.s+pos+1,&loopwhen); /* time written */
109 }
110 if (!flagloop || loopwhen + deltasecs < when || loopwhen > when) {
111 /* loopnum too old, bad or not there */
112 fd = open_trunc(fn); /* no need to write crash-proof */
113 if (fd == -1) die_new();
114 substdio_fdbuf(&ssnew,write,fd,newbuf,sizeof(newbuf));
115 if (substdio_put(&ssnew,strnum,fmt_ulong(strnum,num)) == -1) die_new();
116 if (substdio_puts(&ssnew,":") == -1) die_new();
117 if (substdio_put(&ssnew,strnum,fmt_ulong(strnum,when)) == -1) die_new();
118 if (substdio_puts(&ssnew,"\n") == -1) die_new();
119 if (substdio_flush(&ssnew) == -1) die_new();
120 close(fd);
121 } else if (num >= loopnum + deltanum) { /* excess messages */
122 if (!flagd) {
123 if ((fd = open_append("modpost")) == -1) /* create dir/modpost */
124 strerr_die3sys(111,FATAL,ERR_WRITE,"subpost:");
125 else {
126 close(fd);
127 unlink(fn);
128 strerr_die2x(0,INFO,ERR_EXCESS_MOD);
129 }
130 } else
131 strerr_die2x(111,FATAL,ERR_EXCESS_DEFER);
132 }
133 _exit(0);
134}