|
|
1.1 root 1: # include <stdio.h>
2: # include <ctype.h>
3: # include <pwd.h>
4: # include "delivermail.h"
5:
6: /*
7: ** ALIAS -- Compute aliases.
8: **
9: ** Scans the file /usr/lib/mailaliases for a set of aliases.
10: ** If found, it arranges to deliver to them by inserting the
11: ** new names onto the SendQ queue.
12: **
13: ** Parameters:
14: ** none
15: **
16: ** Returns:
17: ** none
18: **
19: ** Side Effects:
20: ** Aliases found on SendQ are removed and put onto
21: ** AliasQ; replacements are added to SendQ. This is
22: ** done until no such replacement occurs.
23: **
24: ** Defined Constants:
25: ** MAXRCRSN -- the maximum recursion depth.
26: ** ALIASFILE -- the pathname of the alias file.
27: **
28: ** Requires:
29: ** fopen (stdio)
30: ** fgets (stdio)
31: ** rewind (stdio)
32: ** isspace (sys)
33: ** printf (sys)
34: ** deliver
35: **
36: ** Called By:
37: ** deliver
38: **
39: ** Files:
40: ** /usr/lib/mailaliases -- the mail aliases.
41: **
42: ** Notes:
43: ** If NoAlias (the "-n" flag) is set, no aliasing is
44: ** done.
45: **
46: ** Deficiencies:
47: ** It should complain about names that are aliased to
48: ** nothing.
49: ** It is unsophisticated about line overflows.
50: ** It should probably take either the ARPANET sndmsg
51: ** format for aliases, or read Mail files and
52: ** pick out 'alias' commands.
53: **
54: ** History:
55: ** 12/27/79 -- written.
56: */
57:
58:
59: # define ALIASFILE "/usr/lib/mailaliases"
60: # define MAXRCRSN 10
61:
62:
63: alias()
64: {
65: register addrq *q;
66: FILE *af;
67: char line[MAXLINE+1];
68: register char *p;
69: register char *u;
70: extern int errno;
71: int didalias;
72: int gotmatch;
73:
74: if (NoAlias)
75: return (0);
76: if (Debug)
77: printf("--- alias ---\n");
78:
79: /* open alias file if not already open */
80: if (Debug && (af = fopen("mailaliases", "r")) != NULL)
81: printf(" [using local alias file]\n");
82: else if ((af = fopen(ALIASFILE, "r")) == NULL)
83: {
84: if (Debug)
85: printf("Can't open %s\n", ALIASFILE);
86: errno = 0;
87: return;
88: }
89:
90: /*
91: ** Scan alias file.
92: ** If we find any user that any line matches any user, we
93: ** will send to the line rather than to the user.
94: */
95:
96: didalias = TRUE;
97: while (didalias)
98: {
99: didalias = FALSE;
100: gotmatch = FALSE;
101: rewind(af);
102: while (fgets(line, sizeof line, af) != NULL)
103: {
104: /* check for continuation lines */
105: if (isspace(line[0]))
106: {
107: if (gotmatch)
108: {
109: if (Debug)
110: printf(" ... also aliased to %s", line);
111: sendto(line);
112: }
113: continue;
114: }
115: gotmatch = FALSE;
116: /* comments begin with `#' */
117: if (line[0] == '#')
118: continue;
119: p = NULL;
120: for (q = &SendQ; (q = nxtinq(q)) != NULL; )
121: {
122: if ((p = matchalias(valueq(q), line)) != NULL)
123: break;
124: }
125:
126: if (p != NULL)
127: {
128: /*
129: ** Match on Alias.
130: ** Deliver to the target list.
131: ** Remove the alias from the send queue
132: ** and put it on the Alias queue.
133: */
134:
135: if (Debug)
136: printf("%s aliased to %s", valueq(q), p);
137: tkoffq(q, &SendQ);
138: putonq(q, &AliasQ);
139: didalias++;
140: gotmatch++;
141: sendto(p);
142: }
143: }
144: }
145: fclose(af);
146: }
147: /*
148: ** MATCHALIAS -- Match name against alias.
149: **
150: ** The alias is a full alias line, in the format:
151: ** pseudonym:name1,name2,name3,...
152: ** This routine just matches against the pseudonym.
153: **
154: ** Parameters:
155: ** user -- the user to match against.
156: ** line -- the alias line.
157: **
158: ** Returns:
159: ** A pointer to the first character after the colon on
160: ** a match.
161: ** NULL otherwise.
162: **
163: ** Side Effects:
164: ** none
165: **
166: ** Requires:
167: ** none
168: **
169: ** Called By:
170: ** alias
171: **
172: ** History:
173: ** 1/11/80 -- broken from alias
174: */
175:
176: matchalias(user, line)
177: register char *user;
178: register char *line;
179: {
180: for (; *user != '\0' && *line == *user; line++, user++)
181: continue;
182: while (isspace(*line))
183: line++;
184: if (*user == '\0' && *line == ':')
185: return (++line);
186: return (NULL);
187: }
188: /*
189: ** FORWARD -- Try to forward mail
190: **
191: ** This is similar but not identical to aliasing. Local
192: ** users may put a file ".userinfo" in their home directory
193: ** saying what account(s) they would like their mail
194: ** forwarded to. This file looks a lot like ARPANET
195: ** mail headers, i.e., each line is
196: ** field-name: value
197: ** This routine is looking for the field "forward-to".
198: **
199: ** Parameters:
200: ** user -- the name of the user who's mail we
201: ** would like to forward to.
202: **
203: ** Returns:
204: ** NULL -- we arranged to forward this somewhere,
205: ** so don't send it yourself.
206: ** else -- send it to whoever this returns.
207: **
208: ** Side Effects:
209: ** New names are added to SendQ.
210: **
211: ** Requires:
212: ** setpwent (sys)
213: ** getpwname (sys)
214: ** strcpy (sys)
215: ** strcat (sys)
216: ** fopen (sys)
217: ** fgets (sys)
218: ** matchhdr
219: ** sendto
220: ** fclose (sys)
221: **
222: ** Called By:
223: ** recipient
224: **
225: ** History:
226: ** 1/23/80 -- written.
227: */
228:
229: char *
230: forward(user)
231: char *user;
232: {
233: register struct passwd *pw;
234: char buf[MAXLINE];
235: register char *p;
236: register FILE *uf;
237: extern struct passwd *getpwnam();
238: extern char *matchhdr();
239:
240: /*
241: ** Find and open the user's .userinfo file.
242: */
243:
244: setpwent();
245: if ((pw = getpwnam(user)) == NULL)
246: return (user);
247: strcpy(buf, pw->pw_dir);
248: strcat(buf, "/.userinfo");
249: if ((uf = fopen(buf, "r")) == NULL)
250: return (user);
251:
252: /*
253: ** Look for forward-to: field.
254: */
255:
256: while (fgets(buf, sizeof buf, uf) != NULL)
257: {
258: if ((p = matchhdr(buf, "forward-to")) == NULL)
259: continue;
260:
261: /*
262: ** We have a foward entry.
263: ** Send to the list
264: */
265:
266: fclose(uf);
267: if (Debug)
268: printf("--%s", buf);
269: sendto(p);
270: return (NULL);
271: }
272:
273: /*
274: ** No match -- send to the original user.
275: */
276:
277: fclose(uf);
278: return (user);
279: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.