ezmlmx 0.68
ezmlmx
Loading...
Searching...
No Matches
ezmlm-tstdig.c
Go to the documentation of this file.
1#include <sys/types.h>
2#include <sys/stat.h>
3#include <stdio.h>
4#include <unistd.h>
5#include "stralloc.h"
6#include "buffer.h"
7#include "readwrite.h"
8#include "sig.h"
9#include "getconf.h"
10#include "env.h"
11#include "fmt.h"
12#include "now.h"
13#include "lock.h"
14#include "getoptb.h"
15#include "errtxt.h"
16#include "scan.h"
17#include "case.h"
18#include "str.h"
19#include "open.h"
20#include "idx.h"
21#include "auto_version.h"
22#include "logmsg.h"
23#include "lockfile.h"
24
25#define WHO "ezmlm-tstdig"
26
32
33
34static void die_usage() { logmsg(WHO,100,USAGE,"ezmlm-tstdig [-k kbytes] [-m messages] [-t hours] dir"); }
35static void die_nomem() { logmsg(WHO,111,FATAL,ERR_NOMEM); }
36
37stralloc line = {0};
38
39buffer bn;
40char numbuf[16];
41
42char strnum[FMT_ULONG];
43
44int flaglocal = 0;
45
46int main(int argc,char **argv)
47{
48 char *dir;
49 char *local;
50 char *def;
51 int opt;
52 unsigned int pos;
53 unsigned long num, digsize, dignum;
54 unsigned long cumsize = 0L;
55 unsigned long deltanum = 0L;
56 unsigned long deltawhen = 0L;
57 unsigned long deltasize = 0L;
58 unsigned long when, tsttime, digwhen;
59 int fd, fdlock;
60
61 umask(022);
62 sig_pipeignore();
63 when = (unsigned long) now();
64
65 while ((opt = getoptb(argc,argv,"k:t:m:vV")) != opteof)
66 switch(opt) {
67 case 'k': if (optarg)
68 scan_ulong(optarg,&deltasize);
69 break;
70 case 't': if (optarg) /* hours */
71 scan_ulong(optarg,&deltawhen);
72 break;
73 case 'm': if (optarg)
74 scan_ulong(optarg,&deltanum);
75 break;
76 case 'v':
77 case 'V': logmsg(WHO,0,VERSION,auto_version);
78 default: die_usage();
79 }
80
81
82 dir = argv[optind++];
83 if (!dir) die_usage();
84
85 if (chdir(dir) == -1)
86 logmsg(WHO,111,FATAL,B(ERR_SWITCH,dir));
87
88 if (argv[optind])
89 die_usage(); /* avoid common error of putting options after dir */
90 if (!getconf_line(&line,"num",0,dir))
91 _exit(99); /* no msgs no shirt -> no digest */
92 if(!stralloc_0(&line)) die_nomem();
93 pos = scan_ulong(line.s,&num);
94 if (line.s[pos] == ':')
95 scan_ulong(line.s+pos+1,&cumsize);
96
97 if (getconf_line(&line,"dignum",0,dir)) {
98 if(!stralloc_0(&line)) die_nomem();
99 pos = scan_ulong(line.s,&dignum);
100 if (line.s[pos] == ':')
101 pos += 1 + scan_ulong(line.s + pos + 1,&digsize);
102 if (line.s[pos] == ':')
103 scan_ulong(line.s +pos + 1,&digwhen);
104 } else {
105 dignum = 0L; /* no file, not done any digest */
106 digsize = 0L; /* nothing digested */
107 digwhen = 0L; /* will force a digest, but the last one was eons ago. */
108 /* ezmlm-get sends it out only if there are messages. */
109 /* This is as it should for new lists. */
110 }
111 local = env_get("LOCAL");
112 if (local && *local) { /* in editor or manager */
113 def = env_get("DEFAULT");
114 if (def && *def) { /* in manager */
115 if (!case_starts(def,"dig") || case_starts(def,"digest-"))
116 _exit(0);
117 } else { /* in editor */
118 flaglocal = 1;
119 }
120 }
121
122 if (!deltawhen && !deltasize && !deltanum) _exit(0);
123 if ((deltawhen && ((digwhen + deltawhen * 3600L) <= when)) ||
124 (deltasize && ((digsize + (deltasize << 2)) <= cumsize)) ||
125 (deltanum && ((dignum + deltanum) <= num))) { /* digest! */
126 if (flaglocal) { /* avoid multiple digests. Of course, ezmlm-tstdig*/
127 /* belongs in ezmlm-digest, but it's too late ....*/
128 fdlock = lockfile("lock");
129 getconf_line(&line,"tstdig",0,dir);
130 if (!stralloc_0(&line)) die_nomem();
131 scan_ulong(line.s,&tsttime); /* give digest 1 h to complete */
132 /* nobody does digests more often */
133 if ((tsttime + 3600L < when) || (tsttime <= digwhen)) {
134 fd = open_trunc("tstdign");
135 if (fd == -1)
136 logmsg(WHO,111,FATAL,B(ERR_CREATE,dir,"/","tstdign"));
137 buffer_init(&bn,buffer_unixwrite,fd,numbuf,sizeof(numbuf));
138 if (buffer_put(&bn,strnum,fmt_ulong(strnum,when)) == -1)
139 logmsg(WHO,111,FATAL,B(ERR_WRITE,dir,"/","tstdign"));
140 if (buffer_puts(&bn,"\n") == -1)
141 logmsg(WHO,111,FATAL,B(ERR_WRITE,dir,"/","tstdign"));
142 if (buffer_flush(&bn) == -1)
143 logmsg(WHO,111,FATAL,B(ERR_FLUSH,dir,"/","tstdign"));
144 if (fsync(fd) == -1)
145 logmsg(WHO,111,FATAL,B(ERR_SYNC,dir,"/","tstdign"));
146 if (close(fd) == -1)
147 logmsg(WHO,111,FATAL,B(ERR_CLOSE,dir,"/","tstdign"));
148 if (rename("tstdign","tstdig") == -1)
149 logmsg(WHO,111,FATAL,B(ERR_MOVE,"tstdign"));
150 _exit(0);
151 }
152 } else
153 _exit(0);
154 }
155 _exit(99);
156
157 return 0;
158}
datetime_sec now(void)
Definition now.c:5
const char auto_version[]
Error messages. If you translate these, I would urge you to keep the English version as well....
#define ERR_FLUSH
Definition errtxt.h:20
#define ERR_NOMEM
Definition errtxt.h:14
#define ERR_SYNC
Definition errtxt.h:22
#define ERR_MOVE
Definition errtxt.h:29
#define ERR_CREATE
Definition errtxt.h:28
#define ERR_SWITCH
Definition errtxt.h:42
#define ERR_WRITE
Definition errtxt.h:17
#define ERR_CLOSE
Definition errtxt.h:16
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
unsigned long cumsize
Definition ezmlm-get.c:81
datetime_sec digwhen
Definition ezmlm-get.c:85
unsigned long dignum()
Definition ezmlm-get.c:251
buffer bn
stralloc num
char numbuf[16]
char * dir
int main()
Definition ezmlm-weed.c:69
int opt
Definition ezmlm-cron.c:53
int fdlock
Definition ezmlm-cron.c:71
char * local
Definition ezmlm-cgi.c:106
int fd
Definition ezmlm-cgi.c:141
datetime_sec when
Definition ezmlm-cgi.c:173
int flaglocal
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