ezmlmx 0.68
ezmlmx
Loading...
Searching...
No Matches
ezmlm-limit.c
Go to the documentation of this file.
1#include <sys/types.h>
2#include <sys/stat.h>
3#include <unistd.h>
4#include "stralloc.h"
5#include "buffer.h"
6#include "readwrite.h"
7#include "sig.h"
8#include "lock.h"
9#include "getconf.h"
10#include "fmt.h"
11#include "now.h"
12#include "getoptb.h"
13#include "error.h"
14#include "scan.h"
15#include "open.h"
16#include "errtxt.h"
17#include "idx.h"
18#include "logmsg.h"
19#include "lockfile.h"
20
21#define WHO "ezmlm-limit"
22
28
29unsigned long deltasecs = LIMSECS; /* interval to test over (seconds) */
30unsigned long deltanum = LIMMSG; /* max no messages in interval */
31 /* see idx.h. Usually 30 msg/3600 secs*/
32int flagd = 0; /* =0 create modpost, =1 ignore, excess, =2 defer excess */
33int flagmod; /* list moderated */
35const char *fn = TXT_LOOPNUM;
36
37static void die_usage() { logmsg(WHO,100,USAGE,"ezmlm-limit [-f file] [-dDF] [-n messages]" " [-t secs] dir"); }
38static void die_nomem() { logmsg(WHO,111,FATAL,ERR_NOMEM); }
39static void die_new() { logmsg(WHO,111,FATAL,B(ERR_WRITE,"fn")); }
40
41stralloc line = {0};
42
43buffer bn;
44char newbuf[16];
45
46char strnum[FMT_ULONG];
47
48int main(int argc,char **argv)
49{
50 char *dir;
51 int opt;
52 unsigned int pos;
53 unsigned long num, loopnum, when;
54 unsigned long loopwhen = 0L;
55 int fd, fdlock;
56
57 umask(022);
58 sig_pipeignore();
59 when = (unsigned long) now();
60
61 while ((opt = getoptb(argc,argv,"dDf:Fn:t:")) != opteof)
62 switch(opt) {
63 case 'd': flagd = 1; break;
64 case 'D': flagd = 0; break;
65 case 'f': if (optarg && *optarg) fn = optarg; break;
66 case 'F': fn = TXT_LOOPNUM;
67 case 'n': if (optarg) scan_ulong(optarg,&deltanum); break;
68 case 't': if (optarg) scan_ulong(optarg,&deltasecs); break;
69 default: die_usage();
70 }
71
72 dir = argv[optind++];
73 if (!dir) die_usage();
74
75 if (chdir(dir) == -1)
76 logmsg(WHO,111,FATAL,B(ERR_SWITCH,dir));
77
78 if (argv[optind])
79 die_usage(); /* avoid common error of putting options after dir */
80 if ((flagmod = getconf_line(&line,"modpost",0,dir)))
81 _exit(0); /* already mod */
82
83 fdlock = lockfile("lock"); /* lock for num and for writing loopnum */
84
85 if (!getconf_line(&line,"num",0,dir))
86 _exit(99); /* no msgs */
87
88 if (!stralloc_0(&line)) die_nomem();
89 pos = scan_ulong(line.s,&num); /* current msg */
90 if ((flagloop = getconf_line(&line,fn,0,dir))) {
91 if (!stralloc_0(&line)) die_nomem();
92 pos = scan_ulong(line.s,&loopnum); /* msg when written */
93 if (line.s[pos] == ':')
94 scan_ulong(line.s+pos+1,&loopwhen);/* time written */
95 }
96 if (!flagloop || loopwhen + deltasecs < when || loopwhen > when) { /* loopnum too old, bad or not there */
97 fd = open_trunc(fn); /* no need to write crash-proof */
98 if (fd == -1) die_new();
99 buffer_init(&bn,buffer_unixwrite,fd,newbuf,sizeof(newbuf));
100 if (buffer_put(&bn,strnum,fmt_ulong(strnum,num)) == -1) die_new();
101 if (buffer_puts(&bn,":") == -1) die_new();
102 if (buffer_put(&bn,strnum,fmt_ulong(strnum,when)) == -1) die_new();
103 if (buffer_puts(&bn,"\n") == -1) die_new();
104 if (buffer_flush(&bn) == -1) die_new();
105 close(fd);
106 } else if (num >= loopnum + deltanum) { /* excess messages */
107 if (!flagd) {
108 if ((fd = open_append("modpost")) == -1) /* create dir/modpost */
109 logmsg(WHO,111,FATAL,B(ERR_WRITE,"subpost"));
110 else {
111 close(fd);
112 unlink(fn);
113 logmsg(WHO,0,INFO,ERR_EXCESS_MOD);
114 }
115 } else
116 logmsg(WHO,111,FATAL,ERR_EXCESS_DEFER);
117 }
118 _exit(0);
119
120 return 0;
121}
datetime_sec now(void)
Definition now.c:5
#define TXT_LOOPNUM
Definition idx.h:266
#define LIMSECS
Definition idx.h:38
#define LIMMSG
Definition idx.h:37
Error messages. If you translate these, I would urge you to keep the English version as well....
#define ERR_NOMEM
Definition errtxt.h:14
#define ERR_EXCESS_DEFER
Definition errtxt.h:125
#define ERR_EXCESS_MOD
Definition errtxt.h:124
#define ERR_SWITCH
Definition errtxt.h:42
#define ERR_WRITE
Definition errtxt.h:17
int lockfile(const char *)
Definition lockfile.c:15
void die_nomem()
Definition getconf.c:17
int getconf_line(stralloc *sa, const char *fn, int flagrequired, const char *dir)
Definition getconf.c:53
#define WHO
Definition author.c:1
stralloc fn
buffer bn
stralloc num
char * dir
int main()
Definition ezmlm-weed.c:69
int opt
Definition ezmlm-cron.c:53
int fdlock
Definition ezmlm-cron.c:71
int fd
Definition ezmlm-cgi.c:141
datetime_sec when
Definition ezmlm-cgi.c:173
unsigned long deltasecs
Definition ezmlm-limit.c:29
char newbuf[16]
Definition ezmlm-limit.c:44
int flagmod
Definition ezmlm-limit.c:33
int flagloop
Definition ezmlm-limit.c:34
int flagd
Definition ezmlm-limit.c:32
unsigned long deltanum
Definition ezmlm-limit.c:30
const char * logmsg(const char *dir, unsigned long num, unsigned long listno, unsigned long subs, int done)
Definition loginfo.c:32