1 # include <stdio.h>
2 # include <ctype.h>
3 # include <pwd.h>
4 # include "sendmail.h"
5 
6 static char SccsId[] = "@(#)alias.c	3.9	08/10/81";
7 
8 /*
9 **  ALIAS -- Compute aliases.
10 **
11 **	Scans the file AliasFile for a set of aliases.
12 **	If found, it arranges to deliver to them.  Uses libdbm
13 **	database if -DDBM.
14 **
15 **	Parameters:
16 **		a -- address to alias.
17 **
18 **	Returns:
19 **		none
20 **
21 **	Side Effects:
22 **		Aliases found are expanded.
23 **
24 **	Defined Constants:
25 **		MAXRCRSN -- the maximum recursion depth.
26 **
27 **	Files:
28 **		AliasFile -- the mail aliases.  The format is
29 **			a series of lines of the form:
30 **				alias:name1,name2,name3,...
31 **			where 'alias' expands to all of
32 **			'name[i]'.  Continuations begin with
33 **			space or tab.
34 **		AliasFile.pag, AliasFile.dir: libdbm version
35 **			of alias file.  Keys are aliases, datums
36 **			(data?) are name1,name2, ...
37 **
38 **	Notes:
39 **		If NoAlias (the "-n" flag) is set, no aliasing is
40 **			done.
41 **
42 **	Deficiencies:
43 **		It should complain about names that are aliased to
44 **			nothing.
45 **		It is unsophisticated about line overflows.
46 */
47 
48 
49 # define MAXRCRSN	10
50 
51 #ifdef DBM
52 typedef struct
53 {
54 	char	*dptr;
55 	int dsize;
56 } datum;
57 datum lhs, rhs;
58 extern datum fetch();
59 #endif DBM
60 
61 alias(a)
62 	register ADDRESS *a;
63 {
64 	register ADDRESS *q;
65 	register char *p;
66 	extern char *AliasFile;
67 # ifndef DBM
68 	FILE *af;
69 	char line[MAXLINE+1];
70 	bool didalias;
71 	bool gotmatch;
72 	auto ADDRESS al;
73 # endif DBM
74 
75 	if (NoAlias)
76 		return;
77 # ifdef DEBUG
78 	if (Debug)
79 		printf("--- alias ---\n");
80 # endif
81 
82 # ifdef DBM
83 	dbminit(AliasFile);
84 # endif DBM
85 
86 	/*
87 	**  Scan send queue for local mailer.
88 	**	We only have to do this once, since anything we alias
89 	**	to is being put at the end of the queue we are
90 	**	scanning or another queue.  This is because we only
91 	**	scan the local mailer queue.
92 	*/
93 
94 	for (q = Mailer[M_LOCAL]->m_sendq; q != NULL; q = q->q_next)
95 	{
96 		To = q->q_paddr;
97 
98 		/* don't realias already aliased names */
99 		if (bitset(QDONTSEND, q->q_flags))
100 			continue;
101 
102 # ifdef DBM
103 		/* create a key for fetch */
104 		lhs.dptr = q->q_user;
105 		lhs.dsize = strlen(q->q_user) + 1;
106 		rhs = fetch(lhs);
107 
108 		/* find this alias? */
109 		p = rhs.dptr;
110 		if (p == NULL)
111 			continue;
112 # else DBM
113 		s = stab(q->q_user, ST_ALIAS, ST_FIND);
114 		if (s == NULL)
115 			continue;
116 		p = s->s_alias;
117 # endif DBM
118 
119 		/*
120 		**  Match on Alias.
121 		**	Deliver to the target list.
122 		**	Remove the alias from the send queue
123 		**	  and put it on the Alias queue.
124 		*/
125 
126 # ifdef DEBUG
127 		if (Debug)
128 			printf("%s (%s, %s) aliased to %s\n",
129 			    q->q_paddr, q->q_host, q->q_user, p);
130 # endif
131 		if (Verbose)
132 			message("050", "aliased to %s", p);
133 		q->q_flags |= QDONTSEND;
134 		sendto(p, 1);
135 	}
136 }
137 /*
138 **  FORWARD -- Try to forward mail
139 **
140 **	This is similar but not identical to aliasing.
141 **
142 **	Currently it is undefined, until the protocol for userinfo
143 **	databases is finalized.
144 **
145 **	Parameters:
146 **		user -- the name of the user who's mail we
147 **			would like to forward to.
148 **
149 **	Returns:
150 **		TRUE -- we have forwarded it somewhere.
151 **		FALSE -- not forwarded; go ahead & deliver.
152 **
153 **	Side Effects:
154 **		New names are added to send queues.
155 */
156 
157 bool
158 forward(user)
159 	ADDRESS *user;
160 {
161 	char buf[60];
162 	register FILE *fp;
163 	register char *p;
164 
165 	if (user->q_mailer != M_LOCAL || bitset(QBADADDR, user->q_flags))
166 		return (FALSE);
167 
168 	/* good address -- look for .forward file in home */
169 	(void) expand("$z/.forward", buf, &buf[sizeof buf - 1]);
170 	fp = fopen(buf, "r");
171 	if (fp == NULL)
172 		return (FALSE);
173 
174 	/* we do have an address to forward to -- do it */
175 	(void) fgets(buf, sizeof buf, fp);
176 	if ((p = index(buf, '\n')) != NULL)
177 		*p = '\0';
178 	(void) fclose(fp);
179 	if (buf[0] == '\0')
180 		return (FALSE);
181 	if (Verbose)
182 		message("050", "forwarded to %s", buf);
183 	sendto(buf, 1);
184 	return (TRUE);
185 }
186