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