Mercurial > hg > mlmmj
annotate src/mlmmj-bounce.c @ 756:f8f3f4525a2b
Cosmetic changes to help messages
author | Ben Schmidt |
---|---|
date | Fri, 08 Oct 2010 01:47:46 +1100 |
parents | b72bcb7e08a2 |
children | c3ee2bfaeb02 |
rev | line source |
---|---|
47 | 1 /* Copyright (C) 2004 Morten K. Poulsen <morten at afdelingp.dk> |
2 * | |
3 * $Id$ | |
4 * | |
225 | 5 * Permission is hereby granted, free of charge, to any person obtaining a copy |
6 * of this software and associated documentation files (the "Software"), to | |
7 * deal in the Software without restriction, including without limitation the | |
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | |
9 * sell copies of the Software, and to permit persons to whom the Software is | |
10 * furnished to do so, subject to the following conditions: | |
11 * | |
12 * The above copyright notice and this permission notice shall be included in | |
13 * all copies or substantial portions of the Software. | |
14 * | |
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | |
21 * IN THE SOFTWARE. | |
47 | 22 */ |
23 | |
24 #include <stdio.h> | |
25 #include <stdlib.h> | |
26 #include <unistd.h> | |
27 #include <errno.h> | |
28 #include <string.h> | |
29 #include <sys/types.h> | |
30 #include <sys/stat.h> | |
31 #include <fcntl.h> | |
32 #include <time.h> | |
108
51a1695e9d4b
Handle sub/unsub confirm mail bounces, and use subscribers.d/ not
mmj
parents:
102
diff
changeset
|
33 #include <dirent.h> |
193 | 34 #include <sys/mman.h> |
450
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
35 #include <string.h> |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
36 #include <ctype.h> |
47 | 37 |
192
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
38 #include "getlistaddr.h" |
520 | 39 #include "getlistdelim.h" |
47 | 40 #include "mlmmj.h" |
41 #include "strgen.h" | |
42 #include "wrappers.h" | |
43 #include "log_error.h" | |
49 | 44 #include "subscriberfuncs.h" |
186 | 45 #include "mygetline.h" |
193 | 46 #include "chomp.h" |
47 #include "prepstdreply.h" | |
245 | 48 #include "memory.h" |
450
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
49 #include "find_email_adr.h" |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
50 #include "gethdrline.h" |
186 | 51 |
192
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
52 char *fetchindexes(const char *bouncefile) |
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
53 { |
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
54 int fd; |
193 | 55 char *indexstr = NULL, *s, *start, *line, *cur, *colon, *next; |
56 size_t len; | |
192
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
57 struct stat st; |
672
dfc3ec149b60
Remove trailing whitespaces and not mmap 0 sized bounce index file
mmj
parents:
660
diff
changeset
|
58 |
192
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
59 fd = open(bouncefile, O_RDONLY); |
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
60 if(fd < 0) { |
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
61 log_error(LOG_ARGS, "Could not open bounceindexfile %s", |
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
62 bouncefile); |
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
63 return NULL; |
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
64 } |
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
65 |
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
66 if(fstat(fd, &st) < 0) { |
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
67 log_error(LOG_ARGS, "Could not open bounceindexfile %s", |
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
68 bouncefile); |
193 | 69 } |
192
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
70 |
672
dfc3ec149b60
Remove trailing whitespaces and not mmap 0 sized bounce index file
mmj
parents:
660
diff
changeset
|
71 if(st.st_size == 0) { |
dfc3ec149b60
Remove trailing whitespaces and not mmap 0 sized bounce index file
mmj
parents:
660
diff
changeset
|
72 log_error(LOG_ARGS, "Bounceindexfile %s is size 0", |
dfc3ec149b60
Remove trailing whitespaces and not mmap 0 sized bounce index file
mmj
parents:
660
diff
changeset
|
73 bouncefile); |
dfc3ec149b60
Remove trailing whitespaces and not mmap 0 sized bounce index file
mmj
parents:
660
diff
changeset
|
74 return NULL; |
dfc3ec149b60
Remove trailing whitespaces and not mmap 0 sized bounce index file
mmj
parents:
660
diff
changeset
|
75 } |
dfc3ec149b60
Remove trailing whitespaces and not mmap 0 sized bounce index file
mmj
parents:
660
diff
changeset
|
76 |
192
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
77 start = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0); |
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
78 if(start == MAP_FAILED) { |
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
79 log_error(LOG_ARGS, "Could not mmap bounceindexfile"); |
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
80 return NULL; |
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
81 } |
672
dfc3ec149b60
Remove trailing whitespaces and not mmap 0 sized bounce index file
mmj
parents:
660
diff
changeset
|
82 |
dfc3ec149b60
Remove trailing whitespaces and not mmap 0 sized bounce index file
mmj
parents:
660
diff
changeset
|
83 |
192
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
84 for(next = cur = start; next < start + st.st_size; next++) { |
193 | 85 if(*next == '\n') { |
86 len = next - cur; | |
245 | 87 line = mymalloc(len + 1); |
193 | 88 strncpy(line, cur, len); |
89 line[len] = '\0'; | |
90 cur = next + 1; | |
91 } else | |
92 continue; | |
192
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
93 |
193 | 94 colon = strchr(line, ':'); |
674 | 95 MY_ASSERT(colon); |
193 | 96 *colon = '\0'; |
97 s = indexstr; | |
98 indexstr = concatstr(4, s, " ", line, "\n"); | |
245 | 99 myfree(s); |
100 myfree(line); | |
193 | 101 } |
672
dfc3ec149b60
Remove trailing whitespaces and not mmap 0 sized bounce index file
mmj
parents:
660
diff
changeset
|
102 |
193 | 103 munmap(start, st.st_size); |
104 close(fd); | |
192
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
105 |
193 | 106 return indexstr; |
192
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
107 } |
812715644566
Sorry I broke CVS, I'll fix ASAP. It was a commit by mistake.
mmj
parents:
191
diff
changeset
|
108 |
186 | 109 void do_probe(const char *listdir, const char *mlmmjsend, const char *addr) |
110 { | |
359
ca217febcfbd
Rerwrite the way listtexts are handled and move Subject: out into the file
mmj
parents:
344
diff
changeset
|
111 char *myaddr, *from, *a, *indexstr, *queuefilename, *listaddr; |
520 | 112 char *listfqdn, *listname, *probefile, *listdelim=getlistdelim(listdir); |
363
000cf869301c
Further fixups to new prepstdreply. Seems to work now, needs more testing though
mmj
parents:
359
diff
changeset
|
113 char *maildata[] = { "bouncenumbers", NULL }; |
193 | 114 int fd; |
115 time_t t; | |
186 | 116 |
245 | 117 myaddr = mystrdup(addr); |
186 | 118 |
191 | 119 listaddr = getlistaddr(listdir); |
120 listname = genlistname(listaddr); | |
121 listfqdn = genlistfqdn(listaddr); | |
122 | |
520 | 123 from = concatstr(6, listname, listdelim, "bounces-probe-", myaddr, "@", |
124 listfqdn); | |
186 | 125 |
359
ca217febcfbd
Rerwrite the way listtexts are handled and move Subject: out into the file
mmj
parents:
344
diff
changeset
|
126 myfree(listaddr); |
520 | 127 myfree(listdelim); |
359
ca217febcfbd
Rerwrite the way listtexts are handled and move Subject: out into the file
mmj
parents:
344
diff
changeset
|
128 myfree(listfqdn); |
ca217febcfbd
Rerwrite the way listtexts are handled and move Subject: out into the file
mmj
parents:
344
diff
changeset
|
129 myfree(listname); |
ca217febcfbd
Rerwrite the way listtexts are handled and move Subject: out into the file
mmj
parents:
344
diff
changeset
|
130 |
344 | 131 a = strrchr(myaddr, '='); |
186 | 132 if (!a) { |
245 | 133 myfree(myaddr); |
134 myfree(from); | |
186 | 135 log_error(LOG_ARGS, "do_probe(): malformed address"); |
136 exit(EXIT_FAILURE); | |
359
ca217febcfbd
Rerwrite the way listtexts are handled and move Subject: out into the file
mmj
parents:
344
diff
changeset
|
137 |
186 | 138 } |
139 *a = '@'; | |
140 | |
193 | 141 indexstr = fetchindexes(addr); |
142 if(indexstr == NULL) { | |
143 log_error(LOG_ARGS, "Could not fetch bounceindexes"); | |
186 | 144 exit(EXIT_FAILURE); |
145 } | |
146 | |
359
ca217febcfbd
Rerwrite the way listtexts are handled and move Subject: out into the file
mmj
parents:
344
diff
changeset
|
147 maildata[1] = indexstr; |
ca217febcfbd
Rerwrite the way listtexts are handled and move Subject: out into the file
mmj
parents:
344
diff
changeset
|
148 queuefilename = prepstdreply(listdir, "bounce-probe", "$listowner$", |
741
b72bcb7e08a2
Arbitrary headers in listtexts, fix default Content-Transfer-Encoding: header,
Ben Schmidt
parents:
674
diff
changeset
|
149 myaddr, NULL, 1, maildata, NULL); |
193 | 150 MY_ASSERT(queuefilename); |
245 | 151 myfree(indexstr); |
186 | 152 |
193 | 153 probefile = concatstr(4, listdir, "/bounce/", addr, "-probe"); |
154 MY_ASSERT(probefile); | |
155 t = time(NULL); | |
245 | 156 a = mymalloc(32); |
193 | 157 snprintf(a, 31, "%ld", (long int)t); |
158 a[31] = '\0'; | |
159 unlink(probefile); | |
200 | 160 fd = open(probefile, O_WRONLY|O_TRUNC|O_CREAT, S_IRUSR|S_IWUSR); |
193 | 161 if(fd < 0) |
162 log_error(LOG_ARGS, "Could not open %s", probefile); | |
163 else | |
164 if(writen(fd, a, strlen(a)) < 0) | |
165 log_error(LOG_ARGS, "Could not write time in probe"); | |
166 | |
245 | 167 myfree(probefile); |
186 | 168 |
169 execlp(mlmmjsend, mlmmjsend, | |
264
d3ade2c1f058
Make mlmmj-send capable of handling bouncing bounce probes to a local user on
mmj
parents:
250
diff
changeset
|
170 "-l", "5", |
d3ade2c1f058
Make mlmmj-send capable of handling bouncing bounce probes to a local user on
mmj
parents:
250
diff
changeset
|
171 "-L", listdir, |
186 | 172 "-T", myaddr, |
173 "-F", from, | |
435 | 174 "-m", queuefilename, (char *)NULL); |
186 | 175 |
176 log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjsend); | |
177 | |
178 exit(EXIT_FAILURE); | |
179 } | |
180 | |
450
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
181 char *dsnparseaddr(const char *mailname) |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
182 { |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
183 int fd, indsn = 0, i; |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
184 char *line, *linedup, *search, *addr = NULL; |
453 | 185 struct email_container emails = { 0, NULL }; |
450
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
186 |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
187 fd = open(mailname, O_RDONLY); |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
188 if(fd < 0) { |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
189 log_error(LOG_ARGS, "Could not open bounceindexfile %s", |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
190 mailname); |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
191 return NULL; |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
192 } |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
193 |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
194 while((line = gethdrline(fd))) { |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
195 linedup = mystrdup(line); |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
196 for(i = 0; line[i]; i++) |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
197 linedup[i] = tolower(line[i]); |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
198 search = strstr(linedup, "message/delivery-status"); |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
199 myfree(linedup); |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
200 if(search) |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
201 indsn = 1; |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
202 if(indsn) { |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
203 i = strncasecmp(line, "Final-Recipient:", 16); |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
204 if(i == 0) { |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
205 find_email_adr(line, &emails); |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
206 if(emails.emailcount > 0) { |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
207 addr = mystrdup(emails.emaillist[0]); |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
208 for(i = 0; i < emails.emailcount; i++) |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
209 myfree(emails.emaillist[i]); |
672
dfc3ec149b60
Remove trailing whitespaces and not mmap 0 sized bounce index file
mmj
parents:
660
diff
changeset
|
210 myfree(emails.emaillist); |
450
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
211 } else { |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
212 addr = NULL; |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
213 } |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
214 myfree(line); |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
215 return addr; |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
216 } |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
217 } |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
218 myfree(line); |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
219 } |
672
dfc3ec149b60
Remove trailing whitespaces and not mmap 0 sized bounce index file
mmj
parents:
660
diff
changeset
|
220 |
450
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
221 return NULL; |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
222 } |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
223 |
47 | 224 static void print_help(const char *prg) |
225 { | |
756 | 226 printf("Usage: %s -L /path/to/list\n" |
227 " -a john=doe.org [-n num | -p]\n" | |
228 " -a: Address string that bounces\n" | |
229 " -h: This help\n" | |
230 " -L: Full path to list directory\n" | |
231 " -n: Message number in the archive\n" | |
232 " -p: Send out a probe\n" | |
233 " -V: Print version\n", prg); | |
102 | 234 |
47 | 235 exit(EXIT_SUCCESS); |
236 } | |
237 | |
238 int main(int argc, char **argv) | |
239 { | |
531 | 240 int opt, fd, dsnbounce = 0, i = 0; |
47 | 241 char *listdir = NULL, *address = NULL, *number = NULL; |
250 | 242 char *bindir, *mlmmjsend, *savename; |
531 | 243 char *mailname = NULL, *bfilename, *a, *buf, *lowcaseaddr; |
47 | 244 size_t len; |
245 time_t t; | |
186 | 246 int probe = 0; |
158 | 247 struct stat st; |
297 | 248 uid_t uid; |
47 | 249 |
250 log_set_name(argv[0]); | |
251 | |
208
688011dbc4b7
Add a macro to make sure mlmmj binaries are invoked with full path
mmj
parents:
205
diff
changeset
|
252 CHECKFULLPATH(argv[0]); |
688011dbc4b7
Add a macro to make sure mlmmj binaries are invoked with full path
mmj
parents:
205
diff
changeset
|
253 |
186 | 254 bindir = mydirname(argv[0]); |
255 mlmmjsend = concatstr(2, bindir, "/mlmmj-send"); | |
245 | 256 myfree(bindir); |
186 | 257 |
450
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
258 while ((opt = getopt(argc, argv, "hdVL:a:n:m:p")) != -1) { |
47 | 259 switch(opt) { |
260 case 'L': | |
261 listdir = optarg; | |
262 break; | |
263 case 'a': | |
264 address = optarg; | |
265 break; | |
450
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
266 case 'd': |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
267 dsnbounce = 1; |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
268 break; |
158 | 269 case 'm': |
270 mailname = optarg; | |
271 break; | |
47 | 272 case 'n': |
273 number = optarg; | |
274 break; | |
186 | 275 case 'p': |
276 probe = 1; | |
277 break; | |
47 | 278 case 'h': |
279 print_help(argv[0]); | |
280 break; | |
281 case 'V': | |
282 print_version(argv[0]); | |
283 exit(0); | |
284 } | |
285 } | |
297 | 286 |
450
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
287 if(listdir == NULL || (address == NULL && dsnbounce == 0) |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
288 || (number == NULL && probe == 0)) { |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
289 fprintf(stderr, |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
290 "You have to specify -L, -a or -d and -n or -p\n"); |
186 | 291 fprintf(stderr, "%s -h for help\n", argv[0]); |
292 exit(EXIT_FAILURE); | |
293 } | |
297 | 294 |
295 /* Lets make sure no random user tries to do bouncehandling */ | |
296 if(listdir) { | |
297 if(stat(listdir, &st) == 0) { | |
298 uid = getuid(); | |
299 if(uid && uid != st.st_uid) { | |
300 log_error(LOG_ARGS, | |
301 "Have to invoke either as root " | |
302 "or as the user owning listdir"); | |
303 writen(STDERR_FILENO, | |
304 "Have to invoke either as root " | |
305 "or as the user owning listdir\n", 60); | |
306 exit(EXIT_FAILURE); | |
307 } | |
308 } else { | |
309 log_error(LOG_ARGS, "Could not stat %s", listdir); | |
310 exit(EXIT_FAILURE); | |
311 } | |
312 } | |
450
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
313 |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
314 if(dsnbounce) { |
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
315 address = dsnparseaddr(mailname); |
481
3d3c60ef5667
Clean up after us when we have successfully parsed DSN mail
mmj
parents:
455
diff
changeset
|
316 |
3d3c60ef5667
Clean up after us when we have successfully parsed DSN mail
mmj
parents:
455
diff
changeset
|
317 /* Delete the mailfile, no need for it anymore */ |
3d3c60ef5667
Clean up after us when we have successfully parsed DSN mail
mmj
parents:
455
diff
changeset
|
318 if(mailname) |
3d3c60ef5667
Clean up after us when we have successfully parsed DSN mail
mmj
parents:
455
diff
changeset
|
319 unlink(mailname); |
3d3c60ef5667
Clean up after us when we have successfully parsed DSN mail
mmj
parents:
455
diff
changeset
|
320 |
3d3c60ef5667
Clean up after us when we have successfully parsed DSN mail
mmj
parents:
455
diff
changeset
|
321 if(address == NULL) |
450
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
322 exit(EXIT_SUCCESS); |
481
3d3c60ef5667
Clean up after us when we have successfully parsed DSN mail
mmj
parents:
455
diff
changeset
|
323 |
455 | 324 a = strrchr(address, '@'); |
674 | 325 MY_ASSERT(a); |
455 | 326 *a = '='; |
450
b57be6e2a98d
Make mlmmj-bounce able to extract addresses from DSN's as specified in RFC1891
mmj
parents:
436
diff
changeset
|
327 } |
531 | 328 |
329 /* Make the address lowercase */ | |
330 lowcaseaddr = mystrdup(address); | |
331 i = 0; | |
332 while(lowcaseaddr[i]) { | |
333 lowcaseaddr[i] = tolower(lowcaseaddr[i]); | |
334 i++; | |
335 } | |
336 address = lowcaseaddr; | |
672
dfc3ec149b60
Remove trailing whitespaces and not mmap 0 sized bounce index file
mmj
parents:
660
diff
changeset
|
337 |
186 | 338 if(number != NULL && probe != 0) { |
339 fprintf(stderr, "You can only specify one of -n or -p\n"); | |
47 | 340 fprintf(stderr, "%s -h for help\n", argv[0]); |
341 exit(EXIT_FAILURE); | |
342 } | |
343 | |
186 | 344 if (probe) { |
345 /* send out a probe */ | |
346 do_probe(listdir, mlmmjsend, address); | |
347 /* do_probe() will never return */ | |
348 exit(EXIT_FAILURE); | |
349 } | |
350 | |
436 | 351 #if 0 |
414
8e19d05d7a72
Fixup mlmmj-bounce to get the parameters correctly and everything.
mmj
parents:
363
diff
changeset
|
352 log_error(LOG_ARGS, "listdir = [%s] address = [%s] number = [%s]", listdir, address, number); |
60 | 353 #endif |
108
51a1695e9d4b
Handle sub/unsub confirm mail bounces, and use subscribers.d/ not
mmj
parents:
102
diff
changeset
|
354 |
51a1695e9d4b
Handle sub/unsub confirm mail bounces, and use subscribers.d/ not
mmj
parents:
102
diff
changeset
|
355 /* check if it's sub/unsub requests bouncing, and in that case |
51a1695e9d4b
Handle sub/unsub confirm mail bounces, and use subscribers.d/ not
mmj
parents:
102
diff
changeset
|
356 * simply remove the confirmation file. Variablenames address and |
51a1695e9d4b
Handle sub/unsub confirm mail bounces, and use subscribers.d/ not
mmj
parents:
102
diff
changeset
|
357 * number are a bit misleading in this case due to the different |
51a1695e9d4b
Handle sub/unsub confirm mail bounces, and use subscribers.d/ not
mmj
parents:
102
diff
changeset
|
358 * construction of the sub/unsub confirmation From header. |
51a1695e9d4b
Handle sub/unsub confirm mail bounces, and use subscribers.d/ not
mmj
parents:
102
diff
changeset
|
359 */ |
414
8e19d05d7a72
Fixup mlmmj-bounce to get the parameters correctly and everything.
mmj
parents:
363
diff
changeset
|
360 if(strcmp(number, "confsub") == 0) { |
8e19d05d7a72
Fixup mlmmj-bounce to get the parameters correctly and everything.
mmj
parents:
363
diff
changeset
|
361 a = concatstr(3, listdir, "/subconf/", address); |
108
51a1695e9d4b
Handle sub/unsub confirm mail bounces, and use subscribers.d/ not
mmj
parents:
102
diff
changeset
|
362 unlink(a); |
245 | 363 myfree(a); |
483 | 364 if(mailname) |
365 unlink(mailname); | |
108
51a1695e9d4b
Handle sub/unsub confirm mail bounces, and use subscribers.d/ not
mmj
parents:
102
diff
changeset
|
366 exit(EXIT_SUCCESS); |
51a1695e9d4b
Handle sub/unsub confirm mail bounces, and use subscribers.d/ not
mmj
parents:
102
diff
changeset
|
367 } |
414
8e19d05d7a72
Fixup mlmmj-bounce to get the parameters correctly and everything.
mmj
parents:
363
diff
changeset
|
368 if(strcmp(number, "confunsub") == 0) { |
8e19d05d7a72
Fixup mlmmj-bounce to get the parameters correctly and everything.
mmj
parents:
363
diff
changeset
|
369 a = concatstr(3, listdir, "/unsubconf/", address); |
108
51a1695e9d4b
Handle sub/unsub confirm mail bounces, and use subscribers.d/ not
mmj
parents:
102
diff
changeset
|
370 unlink(a); |
245 | 371 myfree(a); |
483 | 372 if(mailname) |
373 unlink(mailname); | |
108
51a1695e9d4b
Handle sub/unsub confirm mail bounces, and use subscribers.d/ not
mmj
parents:
102
diff
changeset
|
374 exit(EXIT_SUCCESS); |
51a1695e9d4b
Handle sub/unsub confirm mail bounces, and use subscribers.d/ not
mmj
parents:
102
diff
changeset
|
375 } |
199 | 376 /* Below checks for bounce probes bouncing. If they do, simply remove |
414
8e19d05d7a72
Fixup mlmmj-bounce to get the parameters correctly and everything.
mmj
parents:
363
diff
changeset
|
377 * the probe file and exit successfully. Yes, I know the variables |
8e19d05d7a72
Fixup mlmmj-bounce to get the parameters correctly and everything.
mmj
parents:
363
diff
changeset
|
378 * have horrible names, but please bear with me. |
199 | 379 */ |
414
8e19d05d7a72
Fixup mlmmj-bounce to get the parameters correctly and everything.
mmj
parents:
363
diff
changeset
|
380 if(strcmp(number, "probe") == 0) { |
199 | 381 a = concatstr(4, listdir, "/bounce/", address, "-probe"); |
382 unlink(a); | |
205
d4d6e5301970
Fix some directory leaks which could cause corruption, and dont leak the
mmj
parents:
200
diff
changeset
|
383 unlink(mailname); |
245 | 384 myfree(a); |
199 | 385 exit(EXIT_SUCCESS); |
386 } | |
672
dfc3ec149b60
Remove trailing whitespaces and not mmap 0 sized bounce index file
mmj
parents:
660
diff
changeset
|
387 |
55
bf3ca0ce00ff
fixed subscription check (convert '=' to '@' before check)
mortenp
parents:
49
diff
changeset
|
388 /* save the filename with '=' before replacing it with '@' */ |
bf3ca0ce00ff
fixed subscription check (convert '=' to '@' before check)
mortenp
parents:
49
diff
changeset
|
389 bfilename = concatstr(3, listdir, "/bounce/", address); |
bf3ca0ce00ff
fixed subscription check (convert '=' to '@' before check)
mortenp
parents:
49
diff
changeset
|
390 |
344 | 391 a = strrchr(address, '='); |
486 | 392 if (!a) { |
393 if(mailname) | |
394 unlink(mailname); | |
108
51a1695e9d4b
Handle sub/unsub confirm mail bounces, and use subscribers.d/ not
mmj
parents:
102
diff
changeset
|
395 exit(EXIT_SUCCESS); /* ignore malformed address */ |
486 | 396 } |
55
bf3ca0ce00ff
fixed subscription check (convert '=' to '@' before check)
mortenp
parents:
49
diff
changeset
|
397 *a = '@'; |
bf3ca0ce00ff
fixed subscription check (convert '=' to '@' before check)
mortenp
parents:
49
diff
changeset
|
398 |
bf3ca0ce00ff
fixed subscription check (convert '=' to '@' before check)
mortenp
parents:
49
diff
changeset
|
399 /* make sure it's a subscribed address */ |
108
51a1695e9d4b
Handle sub/unsub confirm mail bounces, and use subscribers.d/ not
mmj
parents:
102
diff
changeset
|
400 if(is_subbed(listdir, address)) { |
486 | 401 log_error(LOG_ARGS, "%s is bouncing but not subscribed?", |
402 address); | |
403 if(mailname) | |
404 unlink(mailname); | |
245 | 405 myfree(bfilename); |
49 | 406 exit(EXIT_SUCCESS); /* Not subbed, so exit silently */ |
56 | 407 } |
408 | |
158 | 409 if(lstat(bfilename, &st) == 0) { |
410 if((st.st_mode & S_IFLNK) == S_IFLNK) { | |
411 log_error(LOG_ARGS, "%s is a symbolic link", | |
412 bfilename); | |
413 exit(EXIT_FAILURE); | |
414 } | |
415 } | |
416 | |
55
bf3ca0ce00ff
fixed subscription check (convert '=' to '@' before check)
mortenp
parents:
49
diff
changeset
|
417 if ((fd = open(bfilename, O_WRONLY|O_APPEND|O_CREAT, |
47 | 418 S_IRUSR|S_IWUSR)) < 0) { |
55
bf3ca0ce00ff
fixed subscription check (convert '=' to '@' before check)
mortenp
parents:
49
diff
changeset
|
419 log_error(LOG_ARGS, "Could not open '%s'", bfilename); |
245 | 420 myfree(bfilename); |
47 | 421 exit(EXIT_FAILURE); |
422 } | |
423 | |
424 /* TODO check that the message is not already bounced */ | |
425 | |
426 /* XXX How long can the string representation of an integer be? | |
427 * It is not a security issue (we use snprintf()), but it would be | |
428 * bad mojo to cut the timestamp field -- mortenp 20040427 */ | |
429 | |
430 /* int + ":" + int + " # Wed Jun 30 21:49:08 1993\n" + NUL */ | |
431 len = 20 + 1 + 20 + 28 + 1; | |
432 | |
245 | 433 buf = mymalloc(len); |
47 | 434 if (!buf) exit(EXIT_FAILURE); |
435 | |
436 t = time(NULL); | |
193 | 437 snprintf(buf, len-26, "%s:%ld # ", number, (long int)t); |
47 | 438 ctime_r(&t, buf+strlen(buf)); |
439 writen(fd, buf, strlen(buf)); | |
440 close(fd); | |
441 | |
249 | 442 if(mailname) { |
443 savename = concatstr(2, bfilename, ".lastmsg"); | |
444 rename(mailname, savename); | |
250 | 445 myfree(savename); |
249 | 446 } |
672
dfc3ec149b60
Remove trailing whitespaces and not mmap 0 sized bounce index file
mmj
parents:
660
diff
changeset
|
447 |
245 | 448 myfree(bfilename); |
453 | 449 if(dsnbounce && address) |
450 myfree(address); | |
158 | 451 |
452 return EXIT_SUCCESS; | |
47 | 453 } |