1292Seric # include <stdio.h> 2292Seric # include <ctype.h> 3292Seric # include <pwd.h> 43309Seric # include "sendmail.h" 5292Seric 6*4104Seric static char SccsId[] = "@(#)alias.c 3.11 08/10/81"; 7402Seric 8292Seric /* 9292Seric ** ALIAS -- Compute aliases. 10292Seric ** 114098Seric ** Scans the file /usr/lib/aliases for a set of aliases. 123185Seric ** If found, it arranges to deliver to them. Uses libdbm 133185Seric ** database if -DDBM. 14292Seric ** 15292Seric ** Parameters: 164097Seric ** a -- address to alias. 17292Seric ** 18292Seric ** Returns: 19292Seric ** none 20292Seric ** 21292Seric ** Side Effects: 223185Seric ** Aliases found are expanded. 23292Seric ** 24292Seric ** Files: 254098Seric ** /usr/lib/aliases -- the mail aliases. The format is 26569Seric ** a series of lines of the form: 27569Seric ** alias:name1,name2,name3,... 28569Seric ** where 'alias' expands to all of 29569Seric ** 'name[i]'. Continuations begin with 30569Seric ** space or tab. 314098Seric ** /usr/lib/aliases.pag, /usr/lib/aliases.dir: libdbm version 321503Smark ** of alias file. Keys are aliases, datums 331503Smark ** (data?) are name1,name2, ... 34292Seric ** 35292Seric ** Notes: 36292Seric ** If NoAlias (the "-n" flag) is set, no aliasing is 37292Seric ** done. 38292Seric ** 39292Seric ** Deficiencies: 40292Seric ** It should complain about names that are aliased to 41292Seric ** nothing. 42292Seric ** It is unsophisticated about line overflows. 43292Seric */ 44292Seric 45292Seric 461503Smark #ifdef DBM 472966Seric typedef struct 482966Seric { 492966Seric char *dptr; 502966Seric int dsize; 512966Seric } datum; 521503Smark datum lhs, rhs; 531515Seric extern datum fetch(); 541503Smark #endif DBM 55292Seric 564097Seric alias(a) 574097Seric register ADDRESS *a; 58292Seric { 594081Seric register char *p; 604081Seric # ifndef DBM 614098Seric register STAB *s; 624081Seric # endif DBM 63292Seric 64292Seric if (NoAlias) 65292Seric return; 66292Seric # ifdef DEBUG 67292Seric if (Debug) 684098Seric printf("alias(%s)\n", a->q_paddr); 69292Seric # endif 70292Seric 714098Seric /* don't realias already aliased names */ 724098Seric if (bitset(QDONTSEND, a->q_flags)) 734098Seric return; 744098Seric 754098Seric To = a->q_paddr; 764098Seric 774097Seric # ifdef DBM 784098Seric /* create a key for fetch */ 794098Seric lhs.dptr = a->q_user; 804098Seric lhs.dsize = strlen(a->q_user) + 1; 814098Seric rhs = fetch(lhs); 824098Seric 834098Seric /* find this alias? */ 844098Seric p = rhs.dptr; 854098Seric if (p == NULL) 864098Seric return; 874098Seric # else DBM 884098Seric s = stab(a->q_user, ST_ALIAS, ST_FIND); 894098Seric if (s == NULL) 904098Seric return; 914098Seric p = s->s_alias; 924097Seric # endif DBM 93292Seric 94292Seric /* 954098Seric ** Match on Alias. 964098Seric ** Deliver to the target list. 971515Seric */ 981515Seric 994098Seric # ifdef DEBUG 1004098Seric if (Debug) 1014098Seric printf("%s (%s, %s) aliased to %s\n", 1024098Seric a->q_paddr, a->q_host, a->q_user, p); 1034098Seric # endif 1044098Seric if (Verbose) 1054098Seric message("050", "aliased to %s", p); 1064098Seric a->q_flags |= QDONTSEND; 1074098Seric AliasLevel++; 1084098Seric sendto(p, 1); 1094098Seric AliasLevel--; 1104098Seric } 1114098Seric /* 1124098Seric ** INITALIASES -- initialize for aliasing 1134098Seric ** 1144098Seric ** Very different depending on whether we are running DBM or not. 1154098Seric ** 1164098Seric ** Parameters: 1174098Seric ** aliasfile -- location of aliases. 1184098Seric ** 1194098Seric ** Returns: 1204098Seric ** none. 1214098Seric ** 1224098Seric ** Side Effects: 1234098Seric ** initializes aliases: 1244098Seric ** if DBM: opens the database. 1254098Seric ** if ~DBM: reads the aliases into the symbol table. 1264098Seric */ 1274098Seric 1284098Seric initaliases(aliasfile) 1294098Seric char *aliasfile; 1304098Seric { 1314098Seric # ifdef DBM 1324098Seric dbminit(aliasfile); 1334098Seric # else DBM 1344098Seric char line[BUFSIZ]; 1354098Seric register char *p; 1364098Seric char *p2; 1374098Seric char *rhs; 1384098Seric bool skipping; 1394098Seric ADDRESS al, bl; 1404098Seric extern char *prescan(); 1414098Seric bool contin; 1424098Seric 1434098Seric if ((af = fopen(aliasfile, "r")) == NULL) 1441515Seric { 1454098Seric # ifdef DEBUG 1464098Seric if (Debug) 1474098Seric printf("Can't open %s\n", AliasFile); 1484098Seric # endif 1494098Seric errno = 0; 1504098Seric NoAlias++; 1514098Seric return; 1524098Seric } 1534098Seric /* read and interpret lines */ 1544098Seric lineno = 0; 1554098Seric skipping = FALSE; 1564098Seric while (fgets(line, sizeof (line), af) != NULL) 1574098Seric { 1584098Seric lineno++; 1594098Seric switch (line[0]) 1604098Seric { 1614098Seric case '#': 1624098Seric case '\n': 1634098Seric case '\0': 1644098Seric skipping = FALSE; 1654098Seric continue; 1664065Seric 1674098Seric case ' ': 1684098Seric case '\t': 1694098Seric if (!skipping) 1704098Seric syserr("aliases: %d: Non-continuation line starts with space", lineno); 1714098Seric skipping = TRUE; 1724097Seric continue; 1734098Seric } 1744098Seric skipping = FALSE; 1751874Seric 1764098Seric /* process the LHS */ 1774098Seric for (p = line; *p != '\0' && *p != ':' && *p != '\n'; p++) 1784097Seric continue; 1794098Seric if (*p == '\0' || *p == '\n') 1804098Seric { 1814098Seric syntaxerr: 1824098Seric syserr("aliases: %d: missing colon", lineno); 1834097Seric continue; 1844098Seric } 1854098Seric *p++ = '\0'; 1864098Seric if (parse(line, &al, 1) == NULL) 1874098Seric { 1884098Seric *--p = ':'; 1894098Seric goto syntaxerr; 1904098Seric } 1914098Seric rhs = p; 1924098Seric contin = FALSE; 1934098Seric for (;;) 1944098Seric { 1954098Seric register char c; 1961515Seric 1974098Seric /* do parsing & compression of addresses */ 1984098Seric c = *p; 1994098Seric while (c != '\0') 2004098Seric { 2014098Seric p2 = p; 2024098Seric while (*p != '\n' && *p != ',' && *p != '\0') 2034098Seric p++; 2044098Seric c = *p; 2054098Seric *p++ = '\0'; 2064098Seric if (*p2 == '\0') 2074098Seric { 2084098Seric p[-1] = c; 2094098Seric continue; 2104098Seric } 2114098Seric parse(p2, &bl, -1); 2124098Seric contin = (c == ','); 2134098Seric p[-1] = c; 2144098Seric while (isspace(*p)) 2154098Seric p++; 2164098Seric } 2171515Seric 2184098Seric /* see if there should be a continuation line */ 2194098Seric if (!contin) 2204098Seric break; 2214098Seric 2224098Seric /* read continuation line */ 2234098Seric p--; 2244098Seric if (fgets(p, sizeof line - (p - line), af) == NULL) 2254098Seric break; 2264098Seric lineno++; 2274098Seric 2284098Seric if (!isspace(*p)) 2294098Seric syserr("aliases: %d: continuation line missing", lineno); 2304098Seric } 2314098Seric if (al.q_mailer != M_LOCAL) 2324098Seric { 2334098Seric syserr("aliases: %d: cannot alias non-local names", lineno); 2344098Seric continue; 2354098Seric } 2364098Seric s = stab(al.q_user, ST_ALIAS, rhs); 2371515Seric } 2384098Seric (void) fclose(af); 2394098Seric # endif DBM 240292Seric } 241292Seric /* 242292Seric ** FORWARD -- Try to forward mail 243292Seric ** 244292Seric ** This is similar but not identical to aliasing. 245292Seric ** 246292Seric ** Parameters: 247292Seric ** user -- the name of the user who's mail we 248292Seric ** would like to forward to. 249292Seric ** 250292Seric ** Returns: 2514098Seric ** none. 252292Seric ** 253292Seric ** Side Effects: 2543185Seric ** New names are added to send queues. 2554098Seric ** Sets the QDONTSEND bit in addresses that are forwarded. 256292Seric */ 257292Seric 258292Seric forward(user) 2592966Seric ADDRESS *user; 260292Seric { 2614078Seric char buf[60]; 2624069Seric register FILE *fp; 2634069Seric register char *p; 2644069Seric 2654098Seric # ifdef DEBUG 2664098Seric if (Debug) 2674098Seric printf("forward(%s)\n", user->q_paddr); 2684098Seric # endif DEBUG 2694098Seric 2704078Seric if (user->q_mailer != M_LOCAL || bitset(QBADADDR, user->q_flags)) 2714098Seric return; 2724069Seric 2734069Seric /* good address -- look for .forward file in home */ 274*4104Seric define('z', user->q_home); 2754081Seric (void) expand("$z/.forward", buf, &buf[sizeof buf - 1]); 2764069Seric fp = fopen(buf, "r"); 2774069Seric if (fp == NULL) 2784098Seric return; 2794069Seric 2804069Seric /* we do have an address to forward to -- do it */ 2814098Seric user->q_flags |= QDONTSEND; 2824081Seric (void) fgets(buf, sizeof buf, fp); 2834069Seric if ((p = index(buf, '\n')) != NULL) 2844069Seric *p = '\0'; 2854081Seric (void) fclose(fp); 2864069Seric if (buf[0] == '\0') 2874098Seric return; 2884069Seric if (Verbose) 2894069Seric message("050", "forwarded to %s", buf); 2904098Seric AliasLevel++; 2914069Seric sendto(buf, 1); 2924098Seric AliasLevel--; 2934098Seric return; 294292Seric } 295