1292Seric # include <stdio.h> 2292Seric # include <ctype.h> 3292Seric # include <pwd.h> 43309Seric # include "sendmail.h" 5292Seric 6*4097Seric static char SccsId[] = "@(#)alias.c 3.9 08/10/81"; 7402Seric 8292Seric /* 9292Seric ** ALIAS -- Compute aliases. 10292Seric ** 11*4097Seric ** Scans the file AliasFile for a set of aliases. 123185Seric ** If found, it arranges to deliver to them. Uses libdbm 133185Seric ** database if -DDBM. 14292Seric ** 15292Seric ** Parameters: 16*4097Seric ** a -- address to alias. 17292Seric ** 18292Seric ** Returns: 19292Seric ** none 20292Seric ** 21292Seric ** Side Effects: 223185Seric ** Aliases found are expanded. 23292Seric ** 24292Seric ** Defined Constants: 25292Seric ** MAXRCRSN -- the maximum recursion depth. 26292Seric ** 27292Seric ** Files: 28*4097Seric ** AliasFile -- the mail aliases. The format is 29569Seric ** a series of lines of the form: 30569Seric ** alias:name1,name2,name3,... 31569Seric ** where 'alias' expands to all of 32569Seric ** 'name[i]'. Continuations begin with 33569Seric ** space or tab. 34*4097Seric ** AliasFile.pag, AliasFile.dir: libdbm version 351503Smark ** of alias file. Keys are aliases, datums 361503Smark ** (data?) are name1,name2, ... 37292Seric ** 38292Seric ** Notes: 39292Seric ** If NoAlias (the "-n" flag) is set, no aliasing is 40292Seric ** done. 41292Seric ** 42292Seric ** Deficiencies: 43292Seric ** It should complain about names that are aliased to 44292Seric ** nothing. 45292Seric ** It is unsophisticated about line overflows. 46292Seric */ 47292Seric 48292Seric 49292Seric # define MAXRCRSN 10 50292Seric 511503Smark #ifdef DBM 522966Seric typedef struct 532966Seric { 542966Seric char *dptr; 552966Seric int dsize; 562966Seric } datum; 571503Smark datum lhs, rhs; 581515Seric extern datum fetch(); 591503Smark #endif DBM 60292Seric 61*4097Seric alias(a) 62*4097Seric register ADDRESS *a; 63292Seric { 642966Seric register ADDRESS *q; 654081Seric register char *p; 66*4097Seric extern char *AliasFile; 674081Seric # ifndef DBM 68292Seric FILE *af; 69292Seric char line[MAXLINE+1]; 70292Seric bool didalias; 71292Seric bool gotmatch; 722966Seric auto ADDRESS al; 734081Seric # endif DBM 74292Seric 75292Seric if (NoAlias) 76292Seric return; 77292Seric # ifdef DEBUG 78292Seric if (Debug) 79292Seric printf("--- alias ---\n"); 80292Seric # endif 81292Seric 82*4097Seric # ifdef DBM 83*4097Seric dbminit(AliasFile); 84*4097Seric # endif DBM 85292Seric 86292Seric /* 87*4097Seric ** Scan send queue for local mailer. 881515Seric ** We only have to do this once, since anything we alias 891874Seric ** to is being put at the end of the queue we are 90*4097Seric ** scanning or another queue. This is because we only 91*4097Seric ** scan the local mailer queue. 921515Seric */ 931515Seric 94*4097Seric for (q = Mailer[M_LOCAL]->m_sendq; q != NULL; q = q->q_next) 951515Seric { 96*4097Seric To = q->q_paddr; 974065Seric 98*4097Seric /* don't realias already aliased names */ 99*4097Seric if (bitset(QDONTSEND, q->q_flags)) 100*4097Seric continue; 1011874Seric 102*4097Seric # ifdef DBM 103*4097Seric /* create a key for fetch */ 104*4097Seric lhs.dptr = q->q_user; 105*4097Seric lhs.dsize = strlen(q->q_user) + 1; 106*4097Seric rhs = fetch(lhs); 1071622Seric 108*4097Seric /* find this alias? */ 109*4097Seric p = rhs.dptr; 110*4097Seric if (p == NULL) 111*4097Seric continue; 112*4097Seric # else DBM 113*4097Seric s = stab(q->q_user, ST_ALIAS, ST_FIND); 114*4097Seric if (s == NULL) 115*4097Seric continue; 116*4097Seric p = s->s_alias; 117*4097Seric # endif DBM 1181515Seric 119*4097Seric /* 120*4097Seric ** Match on Alias. 121*4097Seric ** Deliver to the target list. 122*4097Seric ** Remove the alias from the send queue 123*4097Seric ** and put it on the Alias queue. 124*4097Seric */ 1251515Seric 1261515Seric # ifdef DEBUG 127*4097Seric if (Debug) 128*4097Seric printf("%s (%s, %s) aliased to %s\n", 129*4097Seric q->q_paddr, q->q_host, q->q_user, p); 1301515Seric # endif 131*4097Seric if (Verbose) 132*4097Seric message("050", "aliased to %s", p); 133*4097Seric q->q_flags |= QDONTSEND; 134*4097Seric sendto(p, 1); 1351515Seric } 136292Seric } 137292Seric /* 138292Seric ** FORWARD -- Try to forward mail 139292Seric ** 140292Seric ** This is similar but not identical to aliasing. 141292Seric ** 142292Seric ** Currently it is undefined, until the protocol for userinfo 143292Seric ** databases is finalized. 144292Seric ** 145292Seric ** Parameters: 146292Seric ** user -- the name of the user who's mail we 147292Seric ** would like to forward to. 148292Seric ** 149292Seric ** Returns: 150292Seric ** TRUE -- we have forwarded it somewhere. 151292Seric ** FALSE -- not forwarded; go ahead & deliver. 152292Seric ** 153292Seric ** Side Effects: 1543185Seric ** New names are added to send queues. 155292Seric */ 156292Seric 157292Seric bool 158292Seric forward(user) 1592966Seric ADDRESS *user; 160292Seric { 1614078Seric char buf[60]; 1624069Seric register FILE *fp; 1634069Seric register char *p; 1644069Seric 1654078Seric if (user->q_mailer != M_LOCAL || bitset(QBADADDR, user->q_flags)) 1664069Seric return (FALSE); 1674069Seric 1684069Seric /* good address -- look for .forward file in home */ 1694081Seric (void) expand("$z/.forward", buf, &buf[sizeof buf - 1]); 1704069Seric fp = fopen(buf, "r"); 1714069Seric if (fp == NULL) 1724069Seric return (FALSE); 1734069Seric 1744069Seric /* we do have an address to forward to -- do it */ 1754081Seric (void) fgets(buf, sizeof buf, fp); 1764069Seric if ((p = index(buf, '\n')) != NULL) 1774069Seric *p = '\0'; 1784081Seric (void) fclose(fp); 1794069Seric if (buf[0] == '\0') 1804069Seric return (FALSE); 1814069Seric if (Verbose) 1824069Seric message("050", "forwarded to %s", buf); 1834069Seric sendto(buf, 1); 1844069Seric return (TRUE); 185292Seric } 186