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