# include # include # include # include "delivermail.h" /* ** ALIAS -- Compute aliases. ** ** Scans the file /usr/lib/mailaliases for a set of aliases. ** If found, it arranges to deliver to them by inserting the ** new names onto the SendQ queue. ** ** Parameters: ** none ** ** Returns: ** none ** ** Side Effects: ** Aliases found on SendQ are removed and put onto ** AliasQ; replacements are added to SendQ. This is ** done until no such replacement occurs. ** ** Defined Constants: ** MAXRCRSN -- the maximum recursion depth. ** ALIASFILE -- the pathname of the alias file. ** ** Requires: ** fopen (stdio) ** fgets (stdio) ** rewind (stdio) ** isspace (sys) ** printf (sys) ** deliver ** ** Called By: ** deliver ** ** Files: ** /usr/lib/mailaliases -- the mail aliases. ** ** Notes: ** If NoAlias (the "-n" flag) is set, no aliasing is ** done. ** ** Deficiencies: ** It should complain about names that are aliased to ** nothing. ** It is unsophisticated about line overflows. ** It should probably take either the ARPANET sndmsg ** format for aliases, or read Mail files and ** pick out 'alias' commands. ** ** History: ** 12/27/79 -- written. */ # define ALIASFILE "/usr/lib/mailaliases" # define MAXRCRSN 10 alias() { register addrq *q; FILE *af; char line[MAXLINE+1]; register char *p; register char *u; extern int errno; int didalias; int gotmatch; if (NoAlias) return (0); if (Debug) printf("--- alias ---\n"); /* open alias file if not already open */ if (Debug && (af = fopen("mailaliases", "r")) != NULL) printf(" [using local alias file]\n"); else if ((af = fopen(ALIASFILE, "r")) == NULL) { if (Debug) printf("Can't open %s\n", ALIASFILE); errno = 0; return; } /* ** Scan alias file. ** If we find any user that any line matches any user, we ** will send to the line rather than to the user. */ didalias = TRUE; while (didalias) { didalias = FALSE; gotmatch = FALSE; rewind(af); while (fgets(line, sizeof line, af) != NULL) { /* check for continuation lines */ if (isspace(line[0])) { if (gotmatch) { if (Debug) printf(" ... also aliased to %s", line); sendto(line); } continue; } gotmatch = FALSE; /* comments begin with `#' */ if (line[0] == '#') continue; p = NULL; for (q = &SendQ; (q = nxtinq(q)) != NULL; ) { if ((p = matchalias(valueq(q), line)) != NULL) break; } if (p != NULL) { /* ** Match on Alias. ** Deliver to the target list. ** Remove the alias from the send queue ** and put it on the Alias queue. */ if (Debug) printf("%s aliased to %s", valueq(q), p); tkoffq(q, &SendQ); putonq(q, &AliasQ); didalias++; gotmatch++; sendto(p); } } } fclose(af); } /* ** MATCHALIAS -- Match name against alias. ** ** The alias is a full alias line, in the format: ** pseudonym:name1,name2,name3,... ** This routine just matches against the pseudonym. ** ** Parameters: ** user -- the user to match against. ** line -- the alias line. ** ** Returns: ** A pointer to the first character after the colon on ** a match. ** NULL otherwise. ** ** Side Effects: ** none ** ** Requires: ** none ** ** Called By: ** alias ** ** History: ** 1/11/80 -- broken from alias */ matchalias(user, line) register char *user; register char *line; { for (; *user != '\0' && *line == *user; line++, user++) continue; while (isspace(*line)) line++; if (*user == '\0' && *line == ':') return (++line); return (NULL); } /* ** FORWARD -- Try to forward mail ** ** This is similar but not identical to aliasing. Local ** users may put a file ".userinfo" in their home directory ** saying what account(s) they would like their mail ** forwarded to. This file looks a lot like ARPANET ** mail headers, i.e., each line is ** field-name: value ** This routine is looking for the field "forward-to". ** ** Parameters: ** user -- the name of the user who's mail we ** would like to forward to. ** ** Returns: ** NULL -- we arranged to forward this somewhere, ** so don't send it yourself. ** else -- send it to whoever this returns. ** ** Side Effects: ** New names are added to SendQ. ** ** Requires: ** setpwent (sys) ** getpwname (sys) ** strcpy (sys) ** strcat (sys) ** fopen (sys) ** fgets (sys) ** matchhdr ** sendto ** fclose (sys) ** ** Called By: ** recipient ** ** History: ** 1/23/80 -- written. */ char * forward(user) char *user; { register struct passwd *pw; char buf[MAXLINE]; register char *p; register FILE *uf; extern struct passwd *getpwnam(); extern char *matchhdr(); /* ** Find and open the user's .userinfo file. */ setpwent(); if ((pw = getpwnam(user)) == NULL) return (user); strcpy(buf, pw->pw_dir); strcat(buf, "/.userinfo"); if ((uf = fopen(buf, "r")) == NULL) return (user); /* ** Look for forward-to: field. */ while (fgets(buf, sizeof buf, uf) != NULL) { if ((p = matchhdr(buf, "forward-to")) == NULL) continue; /* ** We have a foward entry. ** Send to the list */ fclose(uf); if (Debug) printf("--%s", buf); sendto(p); return (NULL); } /* ** No match -- send to the original user. */ fclose(uf); return (user); }