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