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