1 # include <stdio.h>
2 # include <ctype.h>
3 # include <pwd.h>
4 # include "dlvrmail.h"
5 
6 static char SccsId[] = "@(#)alias.c	1.2	07/25/80";
7 
8 /*
9 **  ALIAS -- Compute aliases.
10 **
11 **	Scans the file /usr/lib/mailaliases for a set of aliases.
12 **	If found, it arranges to deliver to them by inserting the
13 **	new names onto the SendQ queue.
14 **
15 **	Parameters:
16 **		none
17 **
18 **	Returns:
19 **		none
20 **
21 **	Side Effects:
22 **		Aliases found on SendQ are removed and put onto
23 **		AliasQ; replacements are added to SendQ.  This is
24 **		done until no such replacement occurs.
25 **
26 **	Defined Constants:
27 **		MAXRCRSN -- the maximum recursion depth.
28 **		ALIASFILE -- the pathname of the alias file.
29 **
30 **	Requires:
31 **		fopen (stdio)
32 **		fgets (stdio)
33 **		rewind (stdio)
34 **		isspace (sys)
35 **		printf (sys)
36 **		sendto
37 **		syserr
38 **		parse
39 **		nxtinq
40 **		sameaddr
41 **		tkoffq
42 **		putonq
43 **		fclose (sys)
44 **
45 **	Called By:
46 **		main
47 **
48 **	Files:
49 **		/usr/lib/mailaliases -- the mail aliases.
50 **
51 **	Notes:
52 **		If NoAlias (the "-n" flag) is set, no aliasing is
53 **			done.
54 **
55 **	Deficiencies:
56 **		It should complain about names that are aliased to
57 **			nothing.
58 **		It is unsophisticated about line overflows.
59 **
60 **	History:
61 **		3/5/80 -- extensive mods to change internal address
62 **			format.
63 **		12/27/79 -- written.
64 */
65 
66 
67 # define ALIASFILE	"/usr/lib/mailaliases"
68 # define MAXRCRSN	10
69 
70 
71 alias()
72 {
73 	register addrq *q;
74 	FILE *af;
75 	char line[MAXLINE+1];
76 	register char *p;
77 	extern int errno;
78 	bool didalias;
79 	bool gotmatch;
80 	auto addrq al;
81 	extern bool sameaddr();
82 	extern addrq *parse();
83 
84 	if (NoAlias)
85 		return;
86 # ifdef DEBUG
87 	if (Debug)
88 		printf("--- alias ---\n");
89 # endif
90 
91 	/* open alias file if not already open */
92 # ifdef DEBUG
93 	if (Debug && (af = fopen("mailaliases", "r")) != NULL)
94 		printf(" [using local alias file]\n");
95 	else
96 # endif
97 	if ((af = fopen(ALIASFILE, "r")) == NULL)
98 	{
99 # ifdef DEBUG
100 		if (Debug)
101 			printf("Can't open %s\n", ALIASFILE);
102 # endif
103 		errno = 0;
104 		return;
105 	}
106 
107 	/*
108 	**  Scan alias file.
109 	**	If we find any user that any line matches any user, we
110 	**	will send to the line rather than to the user.
111 	**
112 	**	We pass through the file several times.  Didalias tells
113 	**	us if we took some alias on this pass through the file;
114 	**	when it goes false at the top of the loop we don't have
115 	**	to scan any more.  Gotmatch tells the same thing, but
116 	**	on a line-by-line basis; it is used for processing
117 	**	continuation lines.
118 	*/
119 
120 	didalias = TRUE;
121 	while (didalias)
122 	{
123 		didalias = FALSE;
124 		gotmatch = FALSE;
125 		rewind(af);
126 		while (fgets(line, sizeof line, af) != NULL)
127 		{
128 			/* comments begin with `#' */
129 			if (line[0] == '#')
130 				continue;
131 
132 			/* check for continuation lines */
133 			if (isspace(line[0]))
134 			{
135 				if (gotmatch)
136 				{
137 # ifdef DEBUG
138 					if (Debug)
139 						printf("   ... also aliased to %s", line);
140 # endif
141 					sendto(line, 1);
142 				}
143 				continue;
144 			}
145 			gotmatch = FALSE;
146 
147 			/*
148 			**  Check to see if this pseudonym exists in SendQ.
149 			**	Turn the alias into canonical form.
150 			**	Then scan SendQ until you do (or do not)
151 			**	find that address.
152 			*/
153 
154 			/*  Get a canonical form for the alias. */
155 			for (p = line; *p != '\0' && *p != ':' && *p != '\n'; p++)
156 				continue;
157 			if (*p == '\0' || *p == '\n')
158 			{
159 			 syntaxerr:
160 				syserr("Bad alias line `%s'", line);
161 				continue;
162 			}
163 			*p++ = '\0';
164 			if (parse(line, &al, -1) == NULL)
165 			{
166 				*--p = ':';
167 				goto syntaxerr;
168 			}
169 
170 			/*  Scan SendQ for that canonical form. */
171 			for (q = &SendQ; (q = nxtinq(q)) != NULL; )
172 			{
173 				if (sameaddr(&al, q, TRUE))
174 					break;
175 			}
176 			if (q != NULL)
177 			{
178 				/*
179 				**  Match on Alias.
180 				**	Deliver to the target list.
181 				**	Remove the alias from the send queue
182 				**	  and put it on the Alias queue.
183 				*/
184 
185 # ifdef DEBUG
186 				if (Debug)
187 					printf("%s (%s, %s) aliased to %s (%s,%s,%s)\n",
188 					    q->q_paddr, q->q_host, q->q_user,
189 					    p, al.q_paddr, al.q_host, al.q_user);
190 # endif
191 				tkoffq(q, &SendQ);
192 				putonq(q, &AliasQ);
193 				didalias++;
194 				gotmatch++;
195 				sendto(p, 1);
196 			}
197 		}
198 	}
199 	fclose(af);
200 }
201 /*
202 **  FORWARD -- Try to forward mail
203 **
204 **	This is similar but not identical to aliasing.
205 **
206 **	Currently it is undefined, until the protocol for userinfo
207 **	databases is finalized.
208 **
209 **	Parameters:
210 **		user -- the name of the user who's mail we
211 **			would like to forward to.
212 **
213 **	Returns:
214 **		TRUE -- we have forwarded it somewhere.
215 **		FALSE -- not forwarded; go ahead & deliver.
216 **
217 **	Side Effects:
218 **		New names are added to SendQ.
219 **
220 **	Requires:
221 **		none
222 **
223 **	Called By:
224 **		recipient
225 **
226 **	History:
227 **		3/5/80 -- return value changed.
228 **		1/23/80 -- null version written.
229 */
230 
231 bool
232 forward(user)
233 	addrq *user;
234 {
235 	return (FALSE);
236 }
237