1292Seric # include <stdio.h>
2292Seric # include <ctype.h>
3292Seric # include <pwd.h>
4292Seric # include "dlvrmail.h"
5292Seric 
6*402Seric static char SccsId[] = "@(#)alias.c	1.2	07/25/80";
7*402Seric 
8292Seric /*
9292Seric **  ALIAS -- Compute aliases.
10292Seric **
11292Seric **	Scans the file /usr/lib/mailaliases for a set of aliases.
12292Seric **	If found, it arranges to deliver to them by inserting the
13292Seric **	new names onto the SendQ queue.
14292Seric **
15292Seric **	Parameters:
16292Seric **		none
17292Seric **
18292Seric **	Returns:
19292Seric **		none
20292Seric **
21292Seric **	Side Effects:
22292Seric **		Aliases found on SendQ are removed and put onto
23292Seric **		AliasQ; replacements are added to SendQ.  This is
24292Seric **		done until no such replacement occurs.
25292Seric **
26292Seric **	Defined Constants:
27292Seric **		MAXRCRSN -- the maximum recursion depth.
28292Seric **		ALIASFILE -- the pathname of the alias file.
29292Seric **
30292Seric **	Requires:
31292Seric **		fopen (stdio)
32292Seric **		fgets (stdio)
33292Seric **		rewind (stdio)
34292Seric **		isspace (sys)
35292Seric **		printf (sys)
36292Seric **		sendto
37292Seric **		syserr
38292Seric **		parse
39292Seric **		nxtinq
40292Seric **		sameaddr
41292Seric **		tkoffq
42292Seric **		putonq
43292Seric **		fclose (sys)
44292Seric **
45292Seric **	Called By:
46292Seric **		main
47292Seric **
48292Seric **	Files:
49292Seric **		/usr/lib/mailaliases -- the mail aliases.
50292Seric **
51292Seric **	Notes:
52292Seric **		If NoAlias (the "-n" flag) is set, no aliasing is
53292Seric **			done.
54292Seric **
55292Seric **	Deficiencies:
56292Seric **		It should complain about names that are aliased to
57292Seric **			nothing.
58292Seric **		It is unsophisticated about line overflows.
59292Seric **
60292Seric **	History:
61292Seric **		3/5/80 -- extensive mods to change internal address
62292Seric **			format.
63292Seric **		12/27/79 -- written.
64292Seric */
65292Seric 
66292Seric 
67292Seric # define ALIASFILE	"/usr/lib/mailaliases"
68292Seric # define MAXRCRSN	10
69292Seric 
70292Seric 
71292Seric alias()
72292Seric {
73292Seric 	register addrq *q;
74292Seric 	FILE *af;
75292Seric 	char line[MAXLINE+1];
76292Seric 	register char *p;
77292Seric 	extern int errno;
78292Seric 	bool didalias;
79292Seric 	bool gotmatch;
80292Seric 	auto addrq al;
81292Seric 	extern bool sameaddr();
82292Seric 	extern addrq *parse();
83292Seric 
84292Seric 	if (NoAlias)
85292Seric 		return;
86292Seric # ifdef DEBUG
87292Seric 	if (Debug)
88292Seric 		printf("--- alias ---\n");
89292Seric # endif
90292Seric 
91292Seric 	/* open alias file if not already open */
92292Seric # ifdef DEBUG
93292Seric 	if (Debug && (af = fopen("mailaliases", "r")) != NULL)
94292Seric 		printf(" [using local alias file]\n");
95292Seric 	else
96292Seric # endif
97292Seric 	if ((af = fopen(ALIASFILE, "r")) == NULL)
98292Seric 	{
99292Seric # ifdef DEBUG
100292Seric 		if (Debug)
101292Seric 			printf("Can't open %s\n", ALIASFILE);
102292Seric # endif
103292Seric 		errno = 0;
104292Seric 		return;
105292Seric 	}
106292Seric 
107292Seric 	/*
108292Seric 	**  Scan alias file.
109292Seric 	**	If we find any user that any line matches any user, we
110292Seric 	**	will send to the line rather than to the user.
111292Seric 	**
112292Seric 	**	We pass through the file several times.  Didalias tells
113292Seric 	**	us if we took some alias on this pass through the file;
114292Seric 	**	when it goes false at the top of the loop we don't have
115292Seric 	**	to scan any more.  Gotmatch tells the same thing, but
116292Seric 	**	on a line-by-line basis; it is used for processing
117292Seric 	**	continuation lines.
118292Seric 	*/
119292Seric 
120292Seric 	didalias = TRUE;
121292Seric 	while (didalias)
122292Seric 	{
123292Seric 		didalias = FALSE;
124292Seric 		gotmatch = FALSE;
125292Seric 		rewind(af);
126292Seric 		while (fgets(line, sizeof line, af) != NULL)
127292Seric 		{
128292Seric 			/* comments begin with `#' */
129292Seric 			if (line[0] == '#')
130292Seric 				continue;
131292Seric 
132292Seric 			/* check for continuation lines */
133292Seric 			if (isspace(line[0]))
134292Seric 			{
135292Seric 				if (gotmatch)
136292Seric 				{
137292Seric # ifdef DEBUG
138292Seric 					if (Debug)
139292Seric 						printf("   ... also aliased to %s", line);
140292Seric # endif
141292Seric 					sendto(line, 1);
142292Seric 				}
143292Seric 				continue;
144292Seric 			}
145292Seric 			gotmatch = FALSE;
146292Seric 
147292Seric 			/*
148292Seric 			**  Check to see if this pseudonym exists in SendQ.
149292Seric 			**	Turn the alias into canonical form.
150292Seric 			**	Then scan SendQ until you do (or do not)
151292Seric 			**	find that address.
152292Seric 			*/
153292Seric 
154292Seric 			/*  Get a canonical form for the alias. */
155292Seric 			for (p = line; *p != '\0' && *p != ':' && *p != '\n'; p++)
156292Seric 				continue;
157292Seric 			if (*p == '\0' || *p == '\n')
158292Seric 			{
159292Seric 			 syntaxerr:
160292Seric 				syserr("Bad alias line `%s'", line);
161292Seric 				continue;
162292Seric 			}
163292Seric 			*p++ = '\0';
164292Seric 			if (parse(line, &al, -1) == NULL)
165292Seric 			{
166292Seric 				*--p = ':';
167292Seric 				goto syntaxerr;
168292Seric 			}
169292Seric 
170292Seric 			/*  Scan SendQ for that canonical form. */
171292Seric 			for (q = &SendQ; (q = nxtinq(q)) != NULL; )
172292Seric 			{
173292Seric 				if (sameaddr(&al, q, TRUE))
174292Seric 					break;
175292Seric 			}
176292Seric 			if (q != NULL)
177292Seric 			{
178292Seric 				/*
179292Seric 				**  Match on Alias.
180292Seric 				**	Deliver to the target list.
181292Seric 				**	Remove the alias from the send queue
182292Seric 				**	  and put it on the Alias queue.
183292Seric 				*/
184292Seric 
185292Seric # ifdef DEBUG
186292Seric 				if (Debug)
187292Seric 					printf("%s (%s, %s) aliased to %s (%s,%s,%s)\n",
188292Seric 					    q->q_paddr, q->q_host, q->q_user,
189292Seric 					    p, al.q_paddr, al.q_host, al.q_user);
190292Seric # endif
191292Seric 				tkoffq(q, &SendQ);
192292Seric 				putonq(q, &AliasQ);
193292Seric 				didalias++;
194292Seric 				gotmatch++;
195292Seric 				sendto(p, 1);
196292Seric 			}
197292Seric 		}
198292Seric 	}
199292Seric 	fclose(af);
200292Seric }
201292Seric /*
202292Seric **  FORWARD -- Try to forward mail
203292Seric **
204292Seric **	This is similar but not identical to aliasing.
205292Seric **
206292Seric **	Currently it is undefined, until the protocol for userinfo
207292Seric **	databases is finalized.
208292Seric **
209292Seric **	Parameters:
210292Seric **		user -- the name of the user who's mail we
211292Seric **			would like to forward to.
212292Seric **
213292Seric **	Returns:
214292Seric **		TRUE -- we have forwarded it somewhere.
215292Seric **		FALSE -- not forwarded; go ahead & deliver.
216292Seric **
217292Seric **	Side Effects:
218292Seric **		New names are added to SendQ.
219292Seric **
220292Seric **	Requires:
221292Seric **		none
222292Seric **
223292Seric **	Called By:
224292Seric **		recipient
225292Seric **
226292Seric **	History:
227292Seric **		3/5/80 -- return value changed.
228292Seric **		1/23/80 -- null version written.
229292Seric */
230292Seric 
231292Seric bool
232292Seric forward(user)
233292Seric 	addrq *user;
234292Seric {
235292Seric 	return (FALSE);
236292Seric }
237