ezmlmx 0.68
ezmlmx
Loading...
Searching...
No Matches
ezmlm-clean.c
Go to the documentation of this file.
1#include <sys/types.h>
2#include <sys/stat.h>
3#include <unistd.h>
4#include "error.h"
5#include "stralloc.h"
6#include "str.h"
7#include "env.h"
8#include "sig.h"
9#include "getconf.h"
10#include "byte.h"
11#include "getln.h"
12#include "case.h"
13#include "qmail.h"
14#include "buffer.h"
15#include "readwrite.h"
16#include "seek.h"
17#include "quote.h"
18#include "datetime.h"
19#include "now.h"
20#include "direntry.h"
21#include "cookie.h"
22#include "getoptb.h"
23#include "fmt.h"
24#include "errtxt.h"
25#include "ezcopy.h"
26#include "open.h"
27#include "scan.h"
28#include "lock.h"
29#include "hdr.h"
30#include "idx.h"
31#include "mime.h"
32#include "auto_version.h"
33#include "logmsg.h"
34#include "lockfile.h"
35#include "ezmlm.h"
36
37#define WHO "ezmlm-clean"
38
56
57int flagmime = MOD_MIME; /* default is message as attachment */
58int flagreturn = 1; /* default return timed-out messages */
59char flagcd = '\0'; /* default: no transferencoding */
60stralloc fnmsg = {0};
61
62/* The defines are in "idx.h" */
63
64static void die_read() { logmsg(WHO,111,FATAL,B(ERR_READ,fnmsg.s)); }
65static void die_usage() { logmsg(WHO,100,USAGE,"ezmlm-clean [-mMrRvV] dir"); }
66static void die_nomem() { logmsg(WHO,111,FATAL,ERR_NOMEM); }
67
69unsigned int older;
70
71char textbuf[1024];
72buffer bt;
73struct qmail qq;
74
75ssize_t qqwrite(int fd,char *buf, unsigned int len)
76{
78 return len;
79}
80char outbuf[256];
81buffer bq = BUFFER_INIT(qqwrite,-1,outbuf,sizeof(outbuf));
82
83char *dir;
84char strnum[FMT_ULONG];
87
88stralloc outhost = {0};
89stralloc outlocal = {0};
90stralloc quoted = {0};
91stralloc charset = {0};
92
93stralloc mailinglist = {0};
94stralloc listid = {0};
95stralloc line = {0};
96stralloc modtime = {0};
97stralloc to = {0};
98
100int fd;
102unsigned long msgnum = 0;
103 /* counter to make message-id unique, since we may */
104 /* send out several msgs. This is not bullet-proof.*/
105 /* Duplication occurs if we do x>1 msg && another */
106 /* ezmlm started within x seconds, and with the */
107 /* same pid. Very unlikely. */
108
109/* gets outlocal, outhost, etc. This is done only if there are any timed-out*/
110/* messages found, that merit a reply to the author. */
111
113{
114 getconf_line(&mailinglist,"mailinglist",1,dir);
115 getconf_line(&listid,"listid",0,dir);
116 getconf_line(&outhost,"outhost",1,dir);
117 getconf_line(&outlocal,"outlocal",1,dir);
118 set_cpouthost(&outlocal);
119 set_cpoutlocal(&outlocal);
120}
121
122/* sends file pointed to by d to the address in the return-path of the message. */
123
124void sendnotice(char *d)
125{
126 unsigned int x,y;
127 const char *err;
128
129 if (!flagconf) {
130 readconfigs();
131 }
132 if (qmail_open(&qq, (stralloc *) 0) == -1)
133 logmsg(WHO,111,FATAL,ERR_QMAIL_QUEUE);
134
135 fd = open_read(d);
136 if (fd == -1)
137 logmsg(WHO,111,FATAL,B(ERR_OPEN,d));
138 buffer_init(&bt,buffer_unixread,fd,textbuf,sizeof(textbuf));
139
140 if (getln(&bt,&line,&match,'\n') == -1) die_read();
141 if (!match) die_read();
142 if (!case_startb(line.s,line.len,"return-path:")) die_read();
143 x = 12 + byte_chr(line.s + 12,line.len-12,'<');
144 y = byte_rchr(line.s + x,line.len-x,'>');
145 if (x != line.len && x+y != line.len) {
146 if (!stralloc_copyb(&to,line.s+x+1, y-1)) die_nomem();
147 if (!stralloc_0(&to)) die_nomem();
148 } else
149 die_read();
150
151 hdr_add2("Mailing-List: ",mailinglist.s,mailinglist.len);
152 hdr_add2("List-ID: ",listid.s,listid.len);
154 hdr_from("-help");
156 hdr_add2s("To: ",to.s);
157 if (flagmime) {
158 if (getconf_line(&charset,"charset",0,dir)) {
159 if (charset.len >= 2 && charset.s[charset.len - 2] == ':') {
160 if (charset.s[charset.len - 1] == 'B' ||
161 charset.s[charset.len - 1] == 'Q') {
162 flagcd = charset.s[charset.len - 1];
163 charset.s[charset.len - 2] = '\0';
164 }
165 }
166 } else
167 if (!stralloc_copys(&charset,TXT_DEF_CHARSET)) die_nomem();
168
169 if (!stralloc_0(&charset)) die_nomem();
171 hdr_boundary(0);
174 } else
175 qmail_puts(&qq,"\n\n");
176
177 ezcopy(&qq,"text/top",flagcd);
178 ezcopy(&qq,"text/mod-timeout",flagcd);
179 if (flagcd == 'B') {
180 encode_b64("",0,&line,2);
181 qmail_put(&qq,line.s,line.len);
182 }
183
184 if (flagmime) {
185 hdr_boundary(0);
187 qmail_puts(&qq,"\n");
188 }
189
190 if (seek_begin(fd) == -1)
191 logmsg(WHO,111,FATAL,B(ERR_SEEK,d));
192
193 buffer_init(&bt,buffer_unixread,fd,textbuf,sizeof(textbuf));
194 if (buffer_copy(&bq,&bt) != 0) die_read();
195 close (fd);
196
197 if (flagmime) hdr_boundary(1);
198
199 if (!stralloc_copy(&line,&outlocal)) die_nomem();
200 if (!stralloc_cats(&line,"-return-@")) die_nomem();
201 if (!stralloc_cat(&line,&outhost)) die_nomem();
202 if (!stralloc_0(&line)) die_nomem();
203 qmail_from(&qq,line.s); /* sender */
204 qmail_to(&qq,to.s);
205
206 if (*(err = qmail_close(&qq)) != '\0')
207 logmsg(WHO,111,FATAL,B(ERR_TMP_QMAIL_QUEUE,err + 1));
208
209 strnum[fmt_ulong(strnum,qmail_qp(&qq))] = 0;
210 logmsg(WHO,0,INFO,B("qp ",strnum,0));
211}
212
236
237void dodir(char *dirname,int reply)
238{
239 DIR *moddir;
240 direntry *d;
241 unsigned long modtime;
242 struct stat st;
243
244 moddir = opendir(dirname);
245 if (!moddir)
246 logmsg(WHO,111,FATAL,B(ERR_OPEN,dir,"/",dirname));
247
248 while ((d = readdir(moddir))) {
249 if (d->d_name[0] == '.') continue;
250 scan_ulong(d->d_name,&modtime);
251 if (modtime < older) {
252 if (!stralloc_copys(&fnmsg,dirname)) die_nomem();
253 if (!stralloc_cats(&fnmsg,d->d_name)) die_nomem();
254 if (!stralloc_0(&fnmsg)) die_nomem();
255 if ((stat(fnmsg.s,&st) != -1) && (st.st_mode & 0200)) {
256 if (reply && (st.st_mode & 0100)) {
257 /* unlink unless there was a TEMPORARY */
258 /* not message-related error notifying */
259 /* poster and msg x bit set. Leave r/o*/
260 /* messages alone. Non-x bit msg are */
261 /* trash. Just unlink, don't notify */
262 sendnotice(fnmsg.s);
263 unlink(fnmsg.s);
264 } else
265 unlink(fnmsg.s);
266 }
267 }
268 }
269 closedir(moddir);
270}
271int main(int argc,char **argv)
272{
273 int fdlock;
274 unsigned long delay;
275 int opt;
276 umask(022);
277 sig_pipeignore();
278 when = now();
279
280 while ((opt = getoptb(argc,argv,"mMrRvV")) != opteof)
281 switch(opt) {
282 case 'm': flagmime = 1; break;
283 case 'M': flagmime = 0; break;
284 case 'r': flagreturn = 1; break;
285 case 'R': flagreturn = 0; break;
286 case 'v':
287 case 'V': logmsg(WHO,0,VERSION,auto_version);
288 default: die_usage();
289 }
290
291 dir = argv[optind];
292 if (!dir) die_usage();
293
294 if (chdir(dir) == -1)
295 logmsg(WHO,111,FATAL,B(ERR_SWITCH,dir));
296
297 getconf_line(&modtime,"modtime",0,dir);
298 if (!stralloc_0(&modtime)) die_nomem();
299 scan_ulong(modtime.s,&delay);
300 if (!delay) delay = DELAY_DEFAULT;
301 else if (delay < DELAY_MIN) delay = DELAY_MIN;
302 else if (delay > DELAY_MAX) delay = DELAY_MAX;
303 older = (unsigned long) when - 3600L * delay; /* delay is in hours */
304
305 fdlock = lockfile("mod/lock");
306
307 flagconf = 0;
308 dodir("mod/pending/",flagreturn);
309 dodir("mod/accepted/",0);
310 dodir("mod/rejected/",0);
311 dodir("mod/unconfirmed/",0);
312 _exit(0);
313
314 return 0;
315}
datetime_sec now(void)
Definition now.c:5
#define DELAY_DEFAULT
Definition idx.h:242
#define TXT_DEF_CHARSET
Definition idx.h:93
#define DELAY_MAX
Definition idx.h:243
#define DELAY_MIN
Definition idx.h:241
#define MOD_MIME
Definition idx.h:173
#define TXT_RETURNED_POST
Definition idx.h:109
const char auto_version[]
#define hdr_listsubject1(a)
Definition hdr.h:27
@ CTYPE_TEXT
Definition hdr.h:13
@ CTYPE_MULTIPART
Definition hdr.h:14
@ CTYPE_MESSAGE
Definition hdr.h:16
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_OPEN
Definition errtxt.h:30
#define ERR_SEEK
Definition errtxt.h:21
#define ERR_READ
Definition errtxt.h:18
#define ERR_QMAIL_QUEUE
Definition errtxt.h:53
#define ERR_SWITCH
Definition errtxt.h:42
#define ERR_TMP_QMAIL_QUEUE
Definition errtxt.h:54
int lockfile(const char *)
Definition lockfile.c:15
long datetime_sec
Definition datetime.h:15
const char * qmail_close(struct qmail *)
Definition qmail.c:120
void qmail_puts(struct qmail *, const char *)
Definition qmail.c:94
void qmail_put(struct qmail *, const char *, int)
Definition qmail.c:87
void qmail_from(struct qmail *, const char *)
Definition qmail.c:103
void qmail_to(struct qmail *, const char *)
Definition qmail.c:113
unsigned long qmail_qp(struct qmail *)
Definition qmail.c:77
int qmail_open(struct qmail *, const stralloc *)
Definition qmail.c:25
charset, outhost, outlocal and flagcd are shared
void die_nomem()
Definition getconf.c:17
int getconf_line(stralloc *sa, const char *fn, int flagrequired, const char *dir)
Definition getconf.c:53
void ezcopy(struct qmail *qqp, const char *fn, char q)
Definition ezcopy.c:128
void set_cpoutlocal(const stralloc *ln)
Definition ezcopy.c:67
void set_cpouthost(const stralloc *ln)
Definition ezcopy.c:73
#define WHO
Definition author.c:1
stralloc moddir
Definition ezmlm-get.c:71
void hdr_from(const char *append)
Definition hdr_from.c:23
char outbuf[1024]
char * dir
int main()
Definition ezmlm-weed.c:69
void hdr_boundary(int last)
void hdr_datemsgid(unsigned long when)
int opt
Definition ezmlm-cron.c:53
unsigned int len
Definition ezmlm-cron.c:68
int fdlock
Definition ezmlm-cron.c:71
char buf[256]
Definition install.c:113
int fd
Definition ezmlm-cgi.c:141
datetime_sec when
Definition ezmlm-cgi.c:173
const char * charset
Definition ezmlm-cgi.c:110
int match
Definition ezmlm-cgi.c:140
unsigned int flagmime
Definition ezmlm-cgi.c:145
#define HASHLEN
Definition idxthread.c:25
void die_read()
Definition ezmlm-warn.c:74
stralloc listid
Definition ezmlm-clean.c:94
unsigned long msgnum
stralloc quoted
Definition ezmlm-clean.c:90
unsigned int older
Definition ezmlm-clean.c:69
buffer bq
Definition ezmlm-clean.c:81
stralloc mailinglist
Definition ezmlm-clean.c:93
ssize_t qqwrite(int fd, char *buf, unsigned int len)
Definition ezmlm-clean.c:75
int flagreturn
Definition ezmlm-clean.c:58
void readconfigs()
char hboundary[HASHLEN]
Definition ezmlm-clean.c:86
stralloc fnmsg
Definition ezmlm-clean.c:60
void dodir(char *dirname, int reply)
parses file names in directory 'dirname'.
stralloc modtime
Definition ezmlm-clean.c:96
char flagcd
Definition ezmlm-clean.c:59
void sendnotice(char *d)
int flagconf
Definition ezmlm-clean.c:99
datetime_sec hashdate
Definition ezmlm-clean.c:85
stralloc to
Definition ezmlm-clean.c:97
struct qmail qq
Definition ezmlm-clean.c:73
void hdr_transferenc(void)
void hdr_add2(const char *start, const char *value, unsigned int len)
Definition hdr_add.c:25
void hdr_add2s(const char *start, const char *value)
Definition hdr_add.c:32
void encode_b64(const unsigned char *indata, unsigned int n, stralloc *outdata, int control)
Definition encode_b64.c:75
void hdr_ctype(enum ctype ctype)
Definition hdr_mime.c:24
void hdr_mime(enum ctype ctype)
Definition hdr_mime.c:43
Definition qmail.h:10
const char * logmsg(const char *dir, unsigned long num, unsigned long listno, unsigned long subs, int done)
Definition loginfo.c:32