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  | /***************************************************************************/