1 /*$Id: ezmlm-tstdig.c,v 1.17 1999/03/20 16:43:42 lindberg Exp $*/
2 /*$Name: ezmlm-idx-040 $*/
19 #define FATAL "ezmlm-tstdig: fatal: "
23 strerr_die1x(100,"ezmlm-tstdig: usage: ezmlm-tstdig [-k kbytes] [-m messages] [-t hours] dir");
26 void die_nomem() { strerr_die2x(111,FATAL
,ERR_NOMEM
); }
33 char strnum
[FMT_ULONG
];
46 unsigned long num
, digsize
, dignum
;
47 unsigned long cumsize
= 0L;
48 unsigned long deltanum
= 0L;
49 unsigned long deltawhen
= 0L;
50 unsigned long deltasize
= 0L;
51 unsigned long when
, tsttime
, digwhen
;
56 when
= (unsigned long) now();
58 while ((opt
= getopt(argc
,argv
,"k:t:m:vV")) != opteof
)
62 scan_ulong(optarg
,&deltasize
);
65 if (optarg
) /* hours */
66 scan_ulong(optarg
,&deltawhen
);
70 scan_ulong(optarg
,&deltanum
);
73 case 'V': strerr_die2x(0,"ezmlm-tstdig version: ",EZIDX_VERSION
);
80 if (!dir
) die_usage();
83 strerr_die4sys(111,FATAL
,ERR_SWITCH
,dir
,": ");
86 die_usage(); /* avoid common error of putting options after dir */
87 if (!getconf_line(&line
,"num",0,FATAL
,dir
))
88 _exit(99); /* no msgs no shirt -> no digest */
89 if(!stralloc_0(&line
)) die_nomem();
90 pos
= scan_ulong(line
.s
,&num
);
91 if (line
.s
[pos
] == ':')
92 scan_ulong(line
.s
+pos
+1,&cumsize
);
94 if (getconf_line(&line
,"dignum",0,FATAL
,dir
)) {
95 if(!stralloc_0(&line
)) die_nomem();
96 pos
= scan_ulong(line
.s
,&dignum
);
97 if (line
.s
[pos
] == ':')
98 pos
+= 1 + scan_ulong(line
.s
+pos
+1,&digsize
);
99 if (line
.s
[pos
] == ':')
100 scan_ulong(line
.s
+pos
+1,&digwhen
);
102 dignum
= 0L; /* no file, not done any digest */
103 digsize
= 0L; /* nothing digested */
104 digwhen
= 0L; /* will force a digest, but the last one was eons */
105 /* ago. ezmlm-get sends it out only if there are */
106 /* messages. This is as it should for new lists. */
108 local
= env_get("LOCAL");
109 if (local
&& *local
) { /* in editor or manager */
110 def
= env_get("DEFAULT");
111 if (def
&& *def
) { /* qmail>=1.02 and manager */
112 if (!case_starts(def
,"dig") || case_starts(def
,"digest-"))
114 } else { /* older qmail versions or editor */
115 if (!getconf_line(&line
,"inlocal",0,FATAL
,dir
)) {
118 pos
= str_len(local
);
119 if (pos
<= line
.len
) { /* maybe qmail>=1.02 and editor */
120 flaglocal
= 1; /* editor and qmail>=1.02. No harm */
122 } else { /* older qmail */
123 if (case_diffb(local
,line
.len
,line
.s
)) /* local */
124 flaglocal
= 1; /* minimal harm */
125 else if (pos
< line
.len
+4 || /* in manager and non-digest */
126 !case_starts(local
+line
.len
,"-dig"))
128 else if (case_starts(local
+line
.len
,"-digest-"))
135 if (!deltawhen
&& !deltasize
&& !deltanum
) _exit(0);
136 if ((deltawhen
&& ((digwhen
+ deltawhen
* 3600L) <= when
)) ||
137 (deltasize
&& ((digsize
+ (deltasize
<< 2)) <= cumsize
)) ||
138 (deltanum
&& ((dignum
+ deltanum
) <= num
))) { /* digest! */
139 if (flaglocal
) { /* avoid multiple digests. Of course, ezmlm-tstdig*/
140 /* belongs in ezmlm-digest, but it's too late ....*/
141 fdlock
= open_append("lock");
143 strerr_die2sys(111,FATAL
,ERR_OPEN_LOCK
);
144 if (lock_ex(fdlock
) == -1) {
146 strerr_die2sys(111,FATAL
,ERR_OBTAIN_LOCK
);
148 getconf_line(&line
,"tstdig",0,dir
,FATAL
);
149 if (!stralloc_0(&line
)) die_nomem();
150 scan_ulong(line
.s
,&tsttime
); /* give digest 1 h to complete */
151 /* nobody does digests more often */
152 if ((tsttime
+ 3600L < when
) || (tsttime
<= digwhen
)) {
153 fd
= open_trunc("tstdign");
155 strerr_die6sys(111,FATAL
,ERR_CREATE
,dir
,"/","tstdign",": ");
156 substdio_fdbuf(&ssnum
,write
,fd
,numbuf
,sizeof(numbuf
));
157 if (substdio_put(&ssnum
,strnum
,fmt_ulong(strnum
,when
)) == -1)
158 strerr_die6sys(111,FATAL
,ERR_WRITE
,dir
,"/","tstdign",": ");
159 if (substdio_puts(&ssnum
,"\n") == -1)
160 strerr_die6sys(111,FATAL
,ERR_WRITE
,dir
,"/","tstdign",": ");
161 if (substdio_flush(&ssnum
) == -1)
162 strerr_die6sys(111,FATAL
,ERR_FLUSH
,dir
,"/","tstdign",": ");
164 strerr_die6sys(111,FATAL
,ERR_SYNC
,dir
,"/","tstdign",": ");
166 strerr_die6sys(111,FATAL
,ERR_CLOSE
,dir
,"/","tstdign",": ");
167 if (rename("tstdign","tstdig") == -1)
168 strerr_die4sys(111,FATAL
,ERR_MOVE
,"tstdign",": ");