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