1 | /*
2 | ** $Log: ml_getaddr.c,v $
3 | ** Revision 1.3 2002/08/27 22:27:54 millis
4 | ** Updated for automake/autoconf functionality
5 | **
6 | ** Revision 1.2 2000/11/14 14:27:37 miller
7 | ** Small correction
8 | **
9 | ** Revision 1.1 1998/02/28 17:49:42 david
10 | ** Initial revision
11 | **
12 | ** Revision 1.1 1996/10/20 12:29:45 rpaar
13 | ** Morrolan v9.0
14 | **
15 | */
16 |
17 | /* mail_getaddr.c -- process an email return address
18 | **
19 | ** Copyright 1987, Lowe.
20 | **
21 | ** Diplomacy is a trademark of the Avalon Hill Game Company, Baltimore,
22 | ** Maryland, all rights reserved; used with permission.
23 | **
24 | ** Redistribution and use in source and binary forms are permitted
25 | ** provided that it is for non-profit purposes, that this and the
26 | ** above notices are preserved and that due credit is given to Mr.
27 | ** Lowe.
28 | **
29 | */
30 |
31 | #include "config.h"
32 | #include "dip.h"
33 | #include "mail.h"
34 | #include "functions.h"
35 |
36 | #include <string.h>
37 |
38 | /***************************************************************************/
39 |
40 | int mail_getaddr(char *s, char *addr)
41 | {
42 |
43 | /*
44 | * Extract a mailing address off of the input line. The address can be
45 | * in either of the following formats:
46 | *
47 | * name <id@domain> -or- id@domain (name)
48 | *
49 | * In either case, the name is ignored.
50 | */
51 |
52 | char c, *t, buf[100], line[150];
53 | char *percent, *at, *bang;
54 | int period, period1, quote;
55 |
56 |
57 | period1 = period = quote = 0;
58 | at = bang = percent = NULL;
59 | t = buf;
60 | while (*s && *s != '\n') {
61 |
62 | if (t >= buf + sizeof(buf))
63 | return E_WARN;
64 |
65 | switch (c = *s++) {
66 | case ' ':
67 | case ';':
68 | case '*':
69 | case '?':
70 | break;
71 |
72 | case '"': /* Ignore garbage between quote marks */
73 | if (quote)
74 | quote = 0;
75 | else {
76 | char *r;
77 | for (r = s; *s && *s != '"'; s++) {
78 | if (*s == '!')
79 | quote = 1; /* "host!user (name)"@domain */
80 | }
81 | if (*s != '"' || (*++s == '@' && quote))
82 | s = r;
83 | else
84 | quote = 0;
85 | }
86 | break;
87 |
88 | case '<': /* name <id@domain> */
89 | at = bang = percent = 0;
90 | t = buf;
91 | break;
92 |
93 | case '>': /* name <id@domain> */
94 | *t++ = '\0';
95 | break;
96 |
97 | case '(': /* id@domain (name) */
98 | c = 1;
99 | while (*s && c) {
100 | if (*s == ')')
101 | c--;
102 | else if (*s == '(')
103 | c++;
104 | s++;
105 | }
106 | break;
107 |
108 | default:
109 | if (c == '@') {
110 | at = t;
111 | period = period1;
112 | period1 = 0;
113 | } else if (c == '%') {
114 | percent = t;
115 | period1 = 0;
116 | } else if (c == '!') { /* UUCP host!user */
117 | bang = t;
118 | } else if (!*addr && c == ':') { /* DECNET host::user */
119 | bang = t;
120 | }
121 | if (c == '.')
122 | period1++;
123 | *t++ = c;
124 | }
125 | *t = '\0';
126 | }
127 |
128 | /*
129 | * Validate the address. It must have nonzero length and it can't be to
130 | * ourselves or any of the other known mailers. If we've already got an
131 | * address that contains an '@' or a '!' and this one doesn't, we use the
132 | * previous one.
133 | */
134 |
135 | if (t == buf || (!at && !bang && *addr)) {
136 | moreaddr++;
137 | return E_WARN;
138 | }
139 | t = bang ? bang + 1 : buf;
140 | if (!strncasecmp(t, "mailer", 6) ||
141 | !strncasecmp(t, "mail-daemon", 11) ||
142 | !strncasecmp(t, "root", 4) ||
143 | !strncasecmp(t, "uucp", 4) ||
144 | !strncasecmp(t, "mmdf", 4) ||
145 | !strncasecmp(t, "smtp", 4) ||
146 | !strncasecmp(t, "postma", 6) ||
147 | !strncasecmp(t, "portal_mail", 11) ||
148 | !strncasecmp(t, "tnc_mailer", 10) ||
149 | !strncasecmp(t, "udb@cs.utex", 11) ||
150 | !strncasecmp(t, "-MaiSer-", 8) ||
151 | !strncasecmp(t, OURSELVES, strlen(OURSELVES))) {
152 |
153 | *addr = '*'; /* Ensure that we don't reply */
154 |
155 | fprintf(log_fp, "Ignoring mail from funny address.\n");
156 |
157 | bang = 0;
158 | while (fgets(line, sizeof(line), inp)) {
159 | fputs(line, log_fp);
160 | fputs(line, ifp);
161 | if (!strcmp(line, "Subject: Returned mail: Return receipt\n"))
162 | bang++;
163 | }
164 |
165 | if (!bang) {
166 | if ((tfp = fopen("dip.ignore", "a"))) {
167 | fflush(ifp);
168 | rewind(ifp);
169 | while (fgets(line, sizeof(line), ifp))
170 | fputs(line, tfp);
171 | fputs("\n", tfp);
172 | } else {
173 | perror("dip.ignore");
174 | fprintf(log_fp, "Unable to open ignore file.\n");
175 | bailout(1);
176 | }
177 | }
178 | return E_WARN;
179 |
180 | }
181 | /*
182 | * Pretty up the address a bit. We can get to everywhere that our
183 | * BITNET gateway can get to, so remove the extra garbage that it
184 | * throws on to the end of addresses.
185 | */
186 |
187 | if (percent && at && (!strcmp(at, BITNET_GATEWAY1) ||
188 | !strcmp(at, BITNET_GATEWAY2) ||
189 | !strncasecmp(at - 7, ".bitnet", 7))) {
190 | *percent = '@';
191 | if (!period)
192 | strcpy(at, ".BITNET");
193 | else
194 | *at = '\0';
195 | at = percent;
196 | }
197 | #if 0
198 | /*
199 | * If there are no periods in the address there's a pretty good chance
200 | * that this is a bitnet address and needs a little help. This assumes
201 | * that all the local hosts fully qualify their addresses in the headers.
202 | */
203 |
204 | for (t = at; t && *t; t++)
205 | if (*t == '.' || *t == '!')
206 | break;
207 |
208 | if (t && !*t) {
209 | strcpy(t, ".BITNET");
210 | }
211 | #endif
212 |
213 | /*
214 | * Fix up those British people who drive on the wrong side of the road.
215 | */
216 |
217 | if (at && !strncasecmp(at, "@uk.ac", 6)) {
218 | *at++ = '\0';
219 | strcpy(addr, buf);
220 | strcat(addr, "@");
221 | while ((t = strrchr(at, '.'))) {
222 | strcat(addr, t + 1);
223 | strcat(addr, ".");
224 | *t = '\0';
225 | }
226 | strcat(addr, at);
227 | }
228 | /*
229 | * Fix up those French people who can't keep their mailers operational.
230 | */
231 |
232 | else if (at && (t = strchr(at, '.')) && !strncasecmp(t, ".greco-prog.fr", 14)) {
233 | *at = '\0';
234 | sprintf(addr, "%s@geocub.greco-prog.fr", buf);
235 | }
236 | /*
237 | * Otherwise we simply copy the address across.
238 | */
239 |
240 | else {
241 | strcpy(addr, buf);
242 | }
243 | return 0;
244 |
245 | }
246 |
247 |
248 | /***************************************************************************/