1*292Seric # include <stdio.h> 2*292Seric # include <ctype.h> 3*292Seric # include <pwd.h> 4*292Seric # include "dlvrmail.h" 5*292Seric 6*292Seric /* 7*292Seric ** ALIAS -- Compute aliases. 8*292Seric ** 9*292Seric ** Scans the file /usr/lib/mailaliases for a set of aliases. 10*292Seric ** If found, it arranges to deliver to them by inserting the 11*292Seric ** new names onto the SendQ queue. 12*292Seric ** 13*292Seric ** Parameters: 14*292Seric ** none 15*292Seric ** 16*292Seric ** Returns: 17*292Seric ** none 18*292Seric ** 19*292Seric ** Side Effects: 20*292Seric ** Aliases found on SendQ are removed and put onto 21*292Seric ** AliasQ; replacements are added to SendQ. This is 22*292Seric ** done until no such replacement occurs. 23*292Seric ** 24*292Seric ** Defined Constants: 25*292Seric ** MAXRCRSN -- the maximum recursion depth. 26*292Seric ** ALIASFILE -- the pathname of the alias file. 27*292Seric ** 28*292Seric ** Requires: 29*292Seric ** fopen (stdio) 30*292Seric ** fgets (stdio) 31*292Seric ** rewind (stdio) 32*292Seric ** isspace (sys) 33*292Seric ** printf (sys) 34*292Seric ** sendto 35*292Seric ** syserr 36*292Seric ** parse 37*292Seric ** nxtinq 38*292Seric ** sameaddr 39*292Seric ** tkoffq 40*292Seric ** putonq 41*292Seric ** fclose (sys) 42*292Seric ** 43*292Seric ** Called By: 44*292Seric ** main 45*292Seric ** 46*292Seric ** Files: 47*292Seric ** /usr/lib/mailaliases -- the mail aliases. 48*292Seric ** 49*292Seric ** Notes: 50*292Seric ** If NoAlias (the "-n" flag) is set, no aliasing is 51*292Seric ** done. 52*292Seric ** 53*292Seric ** Deficiencies: 54*292Seric ** It should complain about names that are aliased to 55*292Seric ** nothing. 56*292Seric ** It is unsophisticated about line overflows. 57*292Seric ** 58*292Seric ** History: 59*292Seric ** 3/5/80 -- extensive mods to change internal address 60*292Seric ** format. 61*292Seric ** 12/27/79 -- written. 62*292Seric */ 63*292Seric 64*292Seric 65*292Seric # define ALIASFILE "/usr/lib/mailaliases" 66*292Seric # define MAXRCRSN 10 67*292Seric 68*292Seric 69*292Seric alias() 70*292Seric { 71*292Seric register addrq *q; 72*292Seric FILE *af; 73*292Seric char line[MAXLINE+1]; 74*292Seric register char *p; 75*292Seric extern int errno; 76*292Seric bool didalias; 77*292Seric bool gotmatch; 78*292Seric auto addrq al; 79*292Seric extern bool sameaddr(); 80*292Seric extern addrq *parse(); 81*292Seric 82*292Seric if (NoAlias) 83*292Seric return; 84*292Seric # ifdef DEBUG 85*292Seric if (Debug) 86*292Seric printf("--- alias ---\n"); 87*292Seric # endif 88*292Seric 89*292Seric /* open alias file if not already open */ 90*292Seric # ifdef DEBUG 91*292Seric if (Debug && (af = fopen("mailaliases", "r")) != NULL) 92*292Seric printf(" [using local alias file]\n"); 93*292Seric else 94*292Seric # endif 95*292Seric if ((af = fopen(ALIASFILE, "r")) == NULL) 96*292Seric { 97*292Seric # ifdef DEBUG 98*292Seric if (Debug) 99*292Seric printf("Can't open %s\n", ALIASFILE); 100*292Seric # endif 101*292Seric errno = 0; 102*292Seric return; 103*292Seric } 104*292Seric 105*292Seric /* 106*292Seric ** Scan alias file. 107*292Seric ** If we find any user that any line matches any user, we 108*292Seric ** will send to the line rather than to the user. 109*292Seric ** 110*292Seric ** We pass through the file several times. Didalias tells 111*292Seric ** us if we took some alias on this pass through the file; 112*292Seric ** when it goes false at the top of the loop we don't have 113*292Seric ** to scan any more. Gotmatch tells the same thing, but 114*292Seric ** on a line-by-line basis; it is used for processing 115*292Seric ** continuation lines. 116*292Seric */ 117*292Seric 118*292Seric didalias = TRUE; 119*292Seric while (didalias) 120*292Seric { 121*292Seric didalias = FALSE; 122*292Seric gotmatch = FALSE; 123*292Seric rewind(af); 124*292Seric while (fgets(line, sizeof line, af) != NULL) 125*292Seric { 126*292Seric /* comments begin with `#' */ 127*292Seric if (line[0] == '#') 128*292Seric continue; 129*292Seric 130*292Seric /* check for continuation lines */ 131*292Seric if (isspace(line[0])) 132*292Seric { 133*292Seric if (gotmatch) 134*292Seric { 135*292Seric # ifdef DEBUG 136*292Seric if (Debug) 137*292Seric printf(" ... also aliased to %s", line); 138*292Seric # endif 139*292Seric sendto(line, 1); 140*292Seric } 141*292Seric continue; 142*292Seric } 143*292Seric gotmatch = FALSE; 144*292Seric 145*292Seric /* 146*292Seric ** Check to see if this pseudonym exists in SendQ. 147*292Seric ** Turn the alias into canonical form. 148*292Seric ** Then scan SendQ until you do (or do not) 149*292Seric ** find that address. 150*292Seric */ 151*292Seric 152*292Seric /* Get a canonical form for the alias. */ 153*292Seric for (p = line; *p != '\0' && *p != ':' && *p != '\n'; p++) 154*292Seric continue; 155*292Seric if (*p == '\0' || *p == '\n') 156*292Seric { 157*292Seric syntaxerr: 158*292Seric syserr("Bad alias line `%s'", line); 159*292Seric continue; 160*292Seric } 161*292Seric *p++ = '\0'; 162*292Seric if (parse(line, &al, -1) == NULL) 163*292Seric { 164*292Seric *--p = ':'; 165*292Seric goto syntaxerr; 166*292Seric } 167*292Seric 168*292Seric /* Scan SendQ for that canonical form. */ 169*292Seric for (q = &SendQ; (q = nxtinq(q)) != NULL; ) 170*292Seric { 171*292Seric if (sameaddr(&al, q, TRUE)) 172*292Seric break; 173*292Seric } 174*292Seric if (q != NULL) 175*292Seric { 176*292Seric /* 177*292Seric ** Match on Alias. 178*292Seric ** Deliver to the target list. 179*292Seric ** Remove the alias from the send queue 180*292Seric ** and put it on the Alias queue. 181*292Seric */ 182*292Seric 183*292Seric # ifdef DEBUG 184*292Seric if (Debug) 185*292Seric printf("%s (%s, %s) aliased to %s (%s,%s,%s)\n", 186*292Seric q->q_paddr, q->q_host, q->q_user, 187*292Seric p, al.q_paddr, al.q_host, al.q_user); 188*292Seric # endif 189*292Seric tkoffq(q, &SendQ); 190*292Seric putonq(q, &AliasQ); 191*292Seric didalias++; 192*292Seric gotmatch++; 193*292Seric sendto(p, 1); 194*292Seric } 195*292Seric } 196*292Seric } 197*292Seric fclose(af); 198*292Seric } 199*292Seric /* 200*292Seric ** FORWARD -- Try to forward mail 201*292Seric ** 202*292Seric ** This is similar but not identical to aliasing. 203*292Seric ** 204*292Seric ** Currently it is undefined, until the protocol for userinfo 205*292Seric ** databases is finalized. 206*292Seric ** 207*292Seric ** Parameters: 208*292Seric ** user -- the name of the user who's mail we 209*292Seric ** would like to forward to. 210*292Seric ** 211*292Seric ** Returns: 212*292Seric ** TRUE -- we have forwarded it somewhere. 213*292Seric ** FALSE -- not forwarded; go ahead & deliver. 214*292Seric ** 215*292Seric ** Side Effects: 216*292Seric ** New names are added to SendQ. 217*292Seric ** 218*292Seric ** Requires: 219*292Seric ** none 220*292Seric ** 221*292Seric ** Called By: 222*292Seric ** recipient 223*292Seric ** 224*292Seric ** History: 225*292Seric ** 3/5/80 -- return value changed. 226*292Seric ** 1/23/80 -- null version written. 227*292Seric */ 228*292Seric 229*292Seric bool 230*292Seric forward(user) 231*292Seric addrq *user; 232*292Seric { 233*292Seric return (FALSE); 234*292Seric } 235