1292Seric # include <stdio.h> 2292Seric # include <ctype.h> 3292Seric # include <pwd.h> 4292Seric # include "dlvrmail.h" 5292Seric 6*402Seric static char SccsId[] = "@(#)alias.c 1.2 07/25/80"; 7*402Seric 8292Seric /* 9292Seric ** ALIAS -- Compute aliases. 10292Seric ** 11292Seric ** Scans the file /usr/lib/mailaliases for a set of aliases. 12292Seric ** If found, it arranges to deliver to them by inserting the 13292Seric ** new names onto the SendQ queue. 14292Seric ** 15292Seric ** Parameters: 16292Seric ** none 17292Seric ** 18292Seric ** Returns: 19292Seric ** none 20292Seric ** 21292Seric ** Side Effects: 22292Seric ** Aliases found on SendQ are removed and put onto 23292Seric ** AliasQ; replacements are added to SendQ. This is 24292Seric ** done until no such replacement occurs. 25292Seric ** 26292Seric ** Defined Constants: 27292Seric ** MAXRCRSN -- the maximum recursion depth. 28292Seric ** ALIASFILE -- the pathname of the alias file. 29292Seric ** 30292Seric ** Requires: 31292Seric ** fopen (stdio) 32292Seric ** fgets (stdio) 33292Seric ** rewind (stdio) 34292Seric ** isspace (sys) 35292Seric ** printf (sys) 36292Seric ** sendto 37292Seric ** syserr 38292Seric ** parse 39292Seric ** nxtinq 40292Seric ** sameaddr 41292Seric ** tkoffq 42292Seric ** putonq 43292Seric ** fclose (sys) 44292Seric ** 45292Seric ** Called By: 46292Seric ** main 47292Seric ** 48292Seric ** Files: 49292Seric ** /usr/lib/mailaliases -- the mail aliases. 50292Seric ** 51292Seric ** Notes: 52292Seric ** If NoAlias (the "-n" flag) is set, no aliasing is 53292Seric ** done. 54292Seric ** 55292Seric ** Deficiencies: 56292Seric ** It should complain about names that are aliased to 57292Seric ** nothing. 58292Seric ** It is unsophisticated about line overflows. 59292Seric ** 60292Seric ** History: 61292Seric ** 3/5/80 -- extensive mods to change internal address 62292Seric ** format. 63292Seric ** 12/27/79 -- written. 64292Seric */ 65292Seric 66292Seric 67292Seric # define ALIASFILE "/usr/lib/mailaliases" 68292Seric # define MAXRCRSN 10 69292Seric 70292Seric 71292Seric alias() 72292Seric { 73292Seric register addrq *q; 74292Seric FILE *af; 75292Seric char line[MAXLINE+1]; 76292Seric register char *p; 77292Seric extern int errno; 78292Seric bool didalias; 79292Seric bool gotmatch; 80292Seric auto addrq al; 81292Seric extern bool sameaddr(); 82292Seric extern addrq *parse(); 83292Seric 84292Seric if (NoAlias) 85292Seric return; 86292Seric # ifdef DEBUG 87292Seric if (Debug) 88292Seric printf("--- alias ---\n"); 89292Seric # endif 90292Seric 91292Seric /* open alias file if not already open */ 92292Seric # ifdef DEBUG 93292Seric if (Debug && (af = fopen("mailaliases", "r")) != NULL) 94292Seric printf(" [using local alias file]\n"); 95292Seric else 96292Seric # endif 97292Seric if ((af = fopen(ALIASFILE, "r")) == NULL) 98292Seric { 99292Seric # ifdef DEBUG 100292Seric if (Debug) 101292Seric printf("Can't open %s\n", ALIASFILE); 102292Seric # endif 103292Seric errno = 0; 104292Seric return; 105292Seric } 106292Seric 107292Seric /* 108292Seric ** Scan alias file. 109292Seric ** If we find any user that any line matches any user, we 110292Seric ** will send to the line rather than to the user. 111292Seric ** 112292Seric ** We pass through the file several times. Didalias tells 113292Seric ** us if we took some alias on this pass through the file; 114292Seric ** when it goes false at the top of the loop we don't have 115292Seric ** to scan any more. Gotmatch tells the same thing, but 116292Seric ** on a line-by-line basis; it is used for processing 117292Seric ** continuation lines. 118292Seric */ 119292Seric 120292Seric didalias = TRUE; 121292Seric while (didalias) 122292Seric { 123292Seric didalias = FALSE; 124292Seric gotmatch = FALSE; 125292Seric rewind(af); 126292Seric while (fgets(line, sizeof line, af) != NULL) 127292Seric { 128292Seric /* comments begin with `#' */ 129292Seric if (line[0] == '#') 130292Seric continue; 131292Seric 132292Seric /* check for continuation lines */ 133292Seric if (isspace(line[0])) 134292Seric { 135292Seric if (gotmatch) 136292Seric { 137292Seric # ifdef DEBUG 138292Seric if (Debug) 139292Seric printf(" ... also aliased to %s", line); 140292Seric # endif 141292Seric sendto(line, 1); 142292Seric } 143292Seric continue; 144292Seric } 145292Seric gotmatch = FALSE; 146292Seric 147292Seric /* 148292Seric ** Check to see if this pseudonym exists in SendQ. 149292Seric ** Turn the alias into canonical form. 150292Seric ** Then scan SendQ until you do (or do not) 151292Seric ** find that address. 152292Seric */ 153292Seric 154292Seric /* Get a canonical form for the alias. */ 155292Seric for (p = line; *p != '\0' && *p != ':' && *p != '\n'; p++) 156292Seric continue; 157292Seric if (*p == '\0' || *p == '\n') 158292Seric { 159292Seric syntaxerr: 160292Seric syserr("Bad alias line `%s'", line); 161292Seric continue; 162292Seric } 163292Seric *p++ = '\0'; 164292Seric if (parse(line, &al, -1) == NULL) 165292Seric { 166292Seric *--p = ':'; 167292Seric goto syntaxerr; 168292Seric } 169292Seric 170292Seric /* Scan SendQ for that canonical form. */ 171292Seric for (q = &SendQ; (q = nxtinq(q)) != NULL; ) 172292Seric { 173292Seric if (sameaddr(&al, q, TRUE)) 174292Seric break; 175292Seric } 176292Seric if (q != NULL) 177292Seric { 178292Seric /* 179292Seric ** Match on Alias. 180292Seric ** Deliver to the target list. 181292Seric ** Remove the alias from the send queue 182292Seric ** and put it on the Alias queue. 183292Seric */ 184292Seric 185292Seric # ifdef DEBUG 186292Seric if (Debug) 187292Seric printf("%s (%s, %s) aliased to %s (%s,%s,%s)\n", 188292Seric q->q_paddr, q->q_host, q->q_user, 189292Seric p, al.q_paddr, al.q_host, al.q_user); 190292Seric # endif 191292Seric tkoffq(q, &SendQ); 192292Seric putonq(q, &AliasQ); 193292Seric didalias++; 194292Seric gotmatch++; 195292Seric sendto(p, 1); 196292Seric } 197292Seric } 198292Seric } 199292Seric fclose(af); 200292Seric } 201292Seric /* 202292Seric ** FORWARD -- Try to forward mail 203292Seric ** 204292Seric ** This is similar but not identical to aliasing. 205292Seric ** 206292Seric ** Currently it is undefined, until the protocol for userinfo 207292Seric ** databases is finalized. 208292Seric ** 209292Seric ** Parameters: 210292Seric ** user -- the name of the user who's mail we 211292Seric ** would like to forward to. 212292Seric ** 213292Seric ** Returns: 214292Seric ** TRUE -- we have forwarded it somewhere. 215292Seric ** FALSE -- not forwarded; go ahead & deliver. 216292Seric ** 217292Seric ** Side Effects: 218292Seric ** New names are added to SendQ. 219292Seric ** 220292Seric ** Requires: 221292Seric ** none 222292Seric ** 223292Seric ** Called By: 224292Seric ** recipient 225292Seric ** 226292Seric ** History: 227292Seric ** 3/5/80 -- return value changed. 228292Seric ** 1/23/80 -- null version written. 229292Seric */ 230292Seric 231292Seric bool 232292Seric forward(user) 233292Seric addrq *user; 234292Seric { 235292Seric return (FALSE); 236292Seric } 237