/
ezmlm-limit.c
107 lines (95 loc) · 3.03 KB
/
ezmlm-limit.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#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 "getconfopt.h"
#include "error.h"
#include "scan.h"
#include "open.h"
#include "messages.h"
#include "die.h"
#include "config.h"
#include "idx.h"
const char FATAL[] = "ezmlm-limit: fatal: ";
const char INFO[] = "ezmlm-limit: info: ";
const char USAGE[] =
"ezmlm-limit: usage: ezmlm-limit [-f file] [-dDF] [-n messages] [-t secs] dir";
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 flagloop;
const char *fn = TXT_LOOPNUM;
static struct option options[] = {
OPT_FLAG(flagd,'d',1,0),
OPT_FLAG(flagd,'D',0,0),
OPT_CSTR(fn,'f',0),
OPT_CSTR_FLAG(fn,'F',TXT_LOOPNUM,0),
OPT_ULONG(deltanum,'n',0),
OPT_ULONG(deltasecs,'t',0),
OPT_END
};
void die_new(void) { strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fn)); }
stralloc line = {0};
substdio ssnew;
char newbuf[16];
char strnum[FMT_ULONG];
int main(int argc,char **argv)
{
int opt;
unsigned int pos;
unsigned long num, loopnum, when;
unsigned long loopwhen = 0L;
int fd,fdlock;
(void) umask(022);
sig_pipeignore();
when = (unsigned long) now();
opt = getconfopt(argc,argv,options,1,0);
if (argv[opt])
die_usage(); /* avoid common error of putting options after dir */
if (getconf_isset("modpost"))
_exit(0); /* already mod */
/* lock for num and for writing loopnum */
fdlock = lockfile("lock");
if (!getconf_ulong(&num,"num",1))
_exit(99); /* no msgs */
if ((flagloop = getconf_line(&line,fn,0))) {
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_die2sys(111,FATAL,MSG1(ERR_WRITE,"modpost"));
else {
close(fd);
unlink(fn);
strerr_die2x(0,INFO,MSG(ERR_EXCESS_MOD));
}
} else
strerr_die2x(111,FATAL,MSG(ERR_EXCESS_DEFER));
}
_exit(0);
}