Commit | Line | Data |
---|---|---|
b3cbe40f EA |
1 | # include <stdio.h> |
2 | # include <ctype.h> | |
3 | # include <pwd.h> | |
4 | # include "dlvrmail.h" | |
5 | ||
f895a45d | 6 | static char SccsId[] = "@(#)alias.c 1.3 %G%"; |
916b3375 | 7 | |
b3cbe40f EA |
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 | ** | |
b3cbe40f EA |
30 | ** Called By: |
31 | ** main | |
32 | ** | |
33 | ** Files: | |
f895a45d EA |
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. | |
b3cbe40f EA |
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. | |
b3cbe40f EA |
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 | \f/* | |
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 | ** | |
b3cbe40f EA |
205 | ** Called By: |
206 | ** recipient | |
b3cbe40f EA |
207 | */ |
208 | ||
209 | bool | |
210 | forward(user) | |
211 | addrq *user; | |
212 | { | |
213 | return (FALSE); | |
214 | } |