--- /dev/null
+/*$Id: ezmlm-tstdig.c,v 1.17 1999/03/20 16:43:42 lindberg Exp $*/
+/*$Name: ezmlm-idx-040 $*/
+
+#include <sys/types.h>
+#include "stralloc.h"
+#include "substdio.h"
+#include "readwrite.h"
+#include "strerr.h"
+#include "sig.h"
+#include "getconf.h"
+#include "env.h"
+#include "fmt.h"
+#include "now.h"
+#include "lock.h"
+#include "sgetopt.h"
+#include "errtxt.h"
+#include "idx.h"
+
+#define FATAL "ezmlm-tstdig: fatal: "
+
+void die_usage()
+{
+ strerr_die1x(100,"ezmlm-tstdig: usage: ezmlm-tstdig [-k kbytes] [-m messages] [-t hours] dir");
+}
+
+void die_nomem() { strerr_die2x(111,FATAL,ERR_NOMEM); }
+
+stralloc line = {0};
+
+substdio ssnum;
+char numbuf[16];
+
+char strnum[FMT_ULONG];
+
+int flaglocal = 0;
+
+void main(argc,argv)
+int argc;
+char **argv;
+{
+ char *dir;
+ char *local;
+ char *def;
+ int opt;
+ unsigned int pos;
+ unsigned long num, digsize, dignum;
+ unsigned long cumsize = 0L;
+ unsigned long deltanum = 0L;
+ unsigned long deltawhen = 0L;
+ unsigned long deltasize = 0L;
+ unsigned long when, tsttime, digwhen;
+ int fd,fdlock;
+
+ (void) umask(022);
+ sig_pipeignore();
+ when = (unsigned long) now();
+
+ while ((opt = getopt(argc,argv,"k:t:m:vV")) != opteof)
+ switch(opt) {
+ case 'k':
+ if (optarg)
+ scan_ulong(optarg,&deltasize);
+ break;
+ case 't':
+ if (optarg) /* hours */
+ scan_ulong(optarg,&deltawhen);
+ break;
+ case 'm':
+ if (optarg)
+ scan_ulong(optarg,&deltanum);
+ break;
+ case 'v':
+ case 'V': strerr_die2x(0,"ezmlm-tstdig version: ",EZIDX_VERSION);
+ default:
+ die_usage();
+ }
+
+
+ dir = argv[optind++];
+ if (!dir) die_usage();
+
+ if (chdir(dir) == -1)
+ strerr_die4sys(111,FATAL,ERR_SWITCH,dir,": ");
+
+ if (argv[optind])
+ die_usage(); /* avoid common error of putting options after dir */
+ if (!getconf_line(&line,"num",0,FATAL,dir))
+ _exit(99); /* no msgs no shirt -> no digest */
+ if(!stralloc_0(&line)) die_nomem();
+ pos = scan_ulong(line.s,&num);
+ if (line.s[pos] == ':')
+ scan_ulong(line.s+pos+1,&cumsize);
+
+ if (getconf_line(&line,"dignum",0,FATAL,dir)) {
+ if(!stralloc_0(&line)) die_nomem();
+ pos = scan_ulong(line.s,&dignum);
+ if (line.s[pos] == ':')
+ pos += 1 + scan_ulong(line.s+pos+1,&digsize);
+ if (line.s[pos] == ':')
+ scan_ulong(line.s+pos+1,&digwhen);
+ } else {
+ dignum = 0L; /* no file, not done any digest */
+ digsize = 0L; /* nothing digested */
+ digwhen = 0L; /* will force a digest, but the last one was eons */
+ /* ago. ezmlm-get sends it out only if there are */
+ /* messages. This is as it should for new lists. */
+ }
+ local = env_get("LOCAL");
+ if (local && *local) { /* in editor or manager */
+ def = env_get("DEFAULT");
+ if (def && *def) { /* qmail>=1.02 and manager */
+ if (!case_starts(def,"dig") || case_starts(def,"digest-"))
+ _exit(0);
+ } else { /* older qmail versions or editor */
+ if (!getconf_line(&line,"inlocal",0,FATAL,dir)) {
+ flaglocal = 1;
+ } else {
+ pos = str_len(local);
+ if (pos <= line.len) { /* maybe qmail>=1.02 and editor */
+ flaglocal = 1; /* editor and qmail>=1.02. No harm */
+ /* if we're wrong */
+ } else { /* older qmail */
+ if (case_diffb(local,line.len,line.s)) /* local */
+ flaglocal = 1; /* minimal harm */
+ else if (pos < line.len +4 || /* in manager and non-digest */
+ !case_starts(local+line.len,"-dig"))
+ _exit(0);
+ else if (case_starts(local+line.len,"-digest-"))
+ _exit(0);
+ }
+ }
+ }
+ }
+
+ if (!deltawhen && !deltasize && !deltanum) _exit(0);
+ if ((deltawhen && ((digwhen + deltawhen * 3600L) <= when)) ||
+ (deltasize && ((digsize + (deltasize << 2)) <= cumsize)) ||
+ (deltanum && ((dignum + deltanum) <= num))) { /* digest! */
+ if (flaglocal) { /* avoid multiple digests. Of course, ezmlm-tstdig*/
+ /* belongs in ezmlm-digest, but it's too late ....*/
+ fdlock = open_append("lock");
+ if (fdlock == -1)
+ strerr_die2sys(111,FATAL,ERR_OPEN_LOCK);
+ if (lock_ex(fdlock) == -1) {
+ close(fdlock);
+ strerr_die2sys(111,FATAL,ERR_OBTAIN_LOCK);
+ }
+ getconf_line(&line,"tstdig",0,dir,FATAL);
+ if (!stralloc_0(&line)) die_nomem();
+ scan_ulong(line.s,&tsttime); /* give digest 1 h to complete */
+ /* nobody does digests more often */
+ if ((tsttime + 3600L < when) || (tsttime <= digwhen)) {
+ fd = open_trunc("tstdign");
+ if (fd == -1)
+ strerr_die6sys(111,FATAL,ERR_CREATE,dir,"/","tstdign",": ");
+ substdio_fdbuf(&ssnum,write,fd,numbuf,sizeof(numbuf));
+ if (substdio_put(&ssnum,strnum,fmt_ulong(strnum,when)) == -1)
+ strerr_die6sys(111,FATAL,ERR_WRITE,dir,"/","tstdign",": ");
+ if (substdio_puts(&ssnum,"\n") == -1)
+ strerr_die6sys(111,FATAL,ERR_WRITE,dir,"/","tstdign",": ");
+ if (substdio_flush(&ssnum) == -1)
+ strerr_die6sys(111,FATAL,ERR_FLUSH,dir,"/","tstdign",": ");
+ if (fsync(fd) == -1)
+ strerr_die6sys(111,FATAL,ERR_SYNC,dir,"/","tstdign",": ");
+ if (close(fd) == -1)
+ strerr_die6sys(111,FATAL,ERR_CLOSE,dir,"/","tstdign",": ");
+ if (rename("tstdign","tstdig") == -1)
+ strerr_die4sys(111,FATAL,ERR_MOVE,"tstdign",": ");
+ _exit(0);
+ }
+ } else
+ _exit(0);
+ }
+ _exit(99);
+}
+