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