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",": ");