1 # include <stdio.h> 2 # include <ctype.h> 3 # include <pwd.h> 4 # include "sendmail.h" 5 6 static char SccsId[] = "@(#)alias.c 3.9 08/10/81"; 7 8 /* 9 ** ALIAS -- Compute aliases. 10 ** 11 ** Scans the file AliasFile for a set of aliases. 12 ** If found, it arranges to deliver to them. Uses libdbm 13 ** database if -DDBM. 14 ** 15 ** Parameters: 16 ** a -- address to alias. 17 ** 18 ** Returns: 19 ** none 20 ** 21 ** Side Effects: 22 ** Aliases found are expanded. 23 ** 24 ** Defined Constants: 25 ** MAXRCRSN -- the maximum recursion depth. 26 ** 27 ** Files: 28 ** AliasFile -- the mail aliases. The format is 29 ** a series of lines of the form: 30 ** alias:name1,name2,name3,... 31 ** where 'alias' expands to all of 32 ** 'name[i]'. Continuations begin with 33 ** space or tab. 34 ** AliasFile.pag, AliasFile.dir: libdbm version 35 ** of alias file. Keys are aliases, datums 36 ** (data?) are name1,name2, ... 37 ** 38 ** Notes: 39 ** If NoAlias (the "-n" flag) is set, no aliasing is 40 ** done. 41 ** 42 ** Deficiencies: 43 ** It should complain about names that are aliased to 44 ** nothing. 45 ** It is unsophisticated about line overflows. 46 */ 47 48 49 # define MAXRCRSN 10 50 51 #ifdef DBM 52 typedef struct 53 { 54 char *dptr; 55 int dsize; 56 } datum; 57 datum lhs, rhs; 58 extern datum fetch(); 59 #endif DBM 60 61 alias(a) 62 register ADDRESS *a; 63 { 64 register ADDRESS *q; 65 register char *p; 66 extern char *AliasFile; 67 # ifndef DBM 68 FILE *af; 69 char line[MAXLINE+1]; 70 bool didalias; 71 bool gotmatch; 72 auto ADDRESS al; 73 # endif DBM 74 75 if (NoAlias) 76 return; 77 # ifdef DEBUG 78 if (Debug) 79 printf("--- alias ---\n"); 80 # endif 81 82 # ifdef DBM 83 dbminit(AliasFile); 84 # endif DBM 85 86 /* 87 ** Scan send queue for local mailer. 88 ** We only have to do this once, since anything we alias 89 ** to is being put at the end of the queue we are 90 ** scanning or another queue. This is because we only 91 ** scan the local mailer queue. 92 */ 93 94 for (q = Mailer[M_LOCAL]->m_sendq; q != NULL; q = q->q_next) 95 { 96 To = q->q_paddr; 97 98 /* don't realias already aliased names */ 99 if (bitset(QDONTSEND, q->q_flags)) 100 continue; 101 102 # ifdef DBM 103 /* create a key for fetch */ 104 lhs.dptr = q->q_user; 105 lhs.dsize = strlen(q->q_user) + 1; 106 rhs = fetch(lhs); 107 108 /* find this alias? */ 109 p = rhs.dptr; 110 if (p == NULL) 111 continue; 112 # else DBM 113 s = stab(q->q_user, ST_ALIAS, ST_FIND); 114 if (s == NULL) 115 continue; 116 p = s->s_alias; 117 # endif DBM 118 119 /* 120 ** Match on Alias. 121 ** Deliver to the target list. 122 ** Remove the alias from the send queue 123 ** and put it on the Alias queue. 124 */ 125 126 # ifdef DEBUG 127 if (Debug) 128 printf("%s (%s, %s) aliased to %s\n", 129 q->q_paddr, q->q_host, q->q_user, p); 130 # endif 131 if (Verbose) 132 message("050", "aliased to %s", p); 133 q->q_flags |= QDONTSEND; 134 sendto(p, 1); 135 } 136 } 137 /* 138 ** FORWARD -- Try to forward mail 139 ** 140 ** This is similar but not identical to aliasing. 141 ** 142 ** Currently it is undefined, until the protocol for userinfo 143 ** databases is finalized. 144 ** 145 ** Parameters: 146 ** user -- the name of the user who's mail we 147 ** would like to forward to. 148 ** 149 ** Returns: 150 ** TRUE -- we have forwarded it somewhere. 151 ** FALSE -- not forwarded; go ahead & deliver. 152 ** 153 ** Side Effects: 154 ** New names are added to send queues. 155 */ 156 157 bool 158 forward(user) 159 ADDRESS *user; 160 { 161 char buf[60]; 162 register FILE *fp; 163 register char *p; 164 165 if (user->q_mailer != M_LOCAL || bitset(QBADADDR, user->q_flags)) 166 return (FALSE); 167 168 /* good address -- look for .forward file in home */ 169 (void) expand("$z/.forward", buf, &buf[sizeof buf - 1]); 170 fp = fopen(buf, "r"); 171 if (fp == NULL) 172 return (FALSE); 173 174 /* we do have an address to forward to -- do it */ 175 (void) fgets(buf, sizeof buf, fp); 176 if ((p = index(buf, '\n')) != NULL) 177 *p = '\0'; 178 (void) fclose(fp); 179 if (buf[0] == '\0') 180 return (FALSE); 181 if (Verbose) 182 message("050", "forwarded to %s", buf); 183 sendto(buf, 1); 184 return (TRUE); 185 } 186