📄 alias.c
字号:
/* * Copyright (c) 1983 Eric P. Allman * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */# include "sendmail.h"# include <pwd.h>#ifndef lintstatic char sccsid[] = "@(#)alias.c 8.25 (Berkeley) 4/14/94";#endif /* not lint */MAP *AliasDB[MAXALIASDB + 1]; /* actual database list */int NAliasDBs; /* number of alias databases *//*** ALIAS -- Compute aliases.**** Scans the alias file for an alias for the given address.** If found, it arranges to deliver to the alias list instead.** Uses libdbm database if -DDBM.**** Parameters:** a -- address to alias.** sendq -- a pointer to the head of the send queue** to put the aliases in.** e -- the current envelope.**** Returns:** none**** Side Effects:** Aliases found are expanded.**** Deficiencies:** It should complain about names that are aliased to** nothing.*/alias(a, sendq, e) register ADDRESS *a; ADDRESS **sendq; register ENVELOPE *e;{ register char *p; int naliases; char *owner; char obuf[MAXNAME + 6]; extern char *aliaslookup(); if (tTd(27, 1)) printf("alias(%s)\n", a->q_paddr); /* don't realias already aliased names */ if (bitset(QDONTSEND|QBADADDR|QVERIFIED, a->q_flags)) return; if (NoAlias) return; e->e_to = a->q_paddr; /* ** Look up this name */ p = aliaslookup(a->q_user, e); if (p == NULL) return; /* ** Match on Alias. ** Deliver to the target list. */ if (tTd(27, 1)) printf("%s (%s, %s) aliased to %s\n", a->q_paddr, a->q_host, a->q_user, p); if (bitset(EF_VRFYONLY, e->e_flags)) { a->q_flags |= QVERIFIED; e->e_nrcpts++; return; } message("aliased to %s", p);#ifdef LOG if (LogLevel > 9) syslog(LOG_INFO, "%s: alias %s => %s", e->e_id == NULL ? "NOQUEUE" : e->e_id, a->q_paddr, p);#endif a->q_flags &= ~QSELFREF; AliasLevel++; naliases = sendtolist(p, a, sendq, e); AliasLevel--; if (!bitset(QSELFREF, a->q_flags)) { if (tTd(27, 5)) { printf("alias: QDONTSEND "); printaddr(a, FALSE); } a->q_flags |= QDONTSEND; } /* ** Look for owner of alias */ (void) strcpy(obuf, "owner-"); if (strncmp(a->q_user, "owner-", 6) == 0) (void) strcat(obuf, "owner"); else (void) strcat(obuf, a->q_user); if (!bitnset(M_USR_UPPER, a->q_mailer->m_flags)) makelower(obuf); owner = aliaslookup(obuf, e); if (owner == NULL) return; /* reflect owner into envelope sender */ if (strpbrk(owner, ",:/|\"") != NULL) owner = obuf; a->q_owner = newstr(owner); /* announce delivery to this alias; NORECEIPT bit set later */ if (e->e_xfp != NULL) { fprintf(e->e_xfp, "Message delivered to mailing list %s\n", a->q_paddr); e->e_flags |= EF_SENDRECEIPT; }}/*** ALIASLOOKUP -- look up a name in the alias file.**** Parameters:** name -- the name to look up.**** Returns:** the value of name.** NULL if unknown.**** Side Effects:** none.**** Warnings:** The return value will be trashed across calls.*/char *aliaslookup(name, e) char *name; ENVELOPE *e;{ register int dbno; register MAP *map; register char *p; for (dbno = 0; dbno < NAliasDBs; dbno++) { auto int stat; map = AliasDB[dbno]; if (!bitset(MF_OPEN, map->map_mflags)) continue; p = (*map->map_class->map_lookup)(map, name, NULL, &stat); if (p != NULL) return p; } return NULL;}/*** SETALIAS -- set up an alias map**** Called when reading configuration file.**** Parameters:** spec -- the alias specification**** Returns:** none.*/setalias(spec) char *spec;{ register char *p; register MAP *map; char *class; STAB *s; if (tTd(27, 8)) printf("setalias(%s)\n", spec); for (p = spec; p != NULL; ) { char aname[50]; while (isspace(*p)) p++; if (*p == '\0') break; spec = p; if (NAliasDBs >= MAXALIASDB) { syserr("Too many alias databases defined, %d max", MAXALIASDB); return; } (void) sprintf(aname, "Alias%d", NAliasDBs); s = stab(aname, ST_MAP, ST_ENTER); map = &s->s_map; AliasDB[NAliasDBs] = map; bzero(map, sizeof *map); p = strpbrk(p, " ,/:"); if (p != NULL && *p == ':') { /* map name */ *p++ = '\0'; class = spec; spec = p; } else { class = "implicit"; map->map_mflags = MF_OPTIONAL|MF_INCLNULL; } /* find end of spec */ if (p != NULL) p = strchr(p, ','); if (p != NULL) *p++ = '\0'; /* look up class */ s = stab(class, ST_MAPCLASS, ST_FIND); if (s == NULL) { if (tTd(27, 1)) printf("Unknown alias class %s\n", class); } else if (!bitset(MCF_ALIASOK, s->s_mapclass.map_cflags)) { syserr("setalias: map class %s can't handle aliases", class); } else { map->map_class = &s->s_mapclass; if (map->map_class->map_parse(map, spec)) { map->map_mflags |= MF_VALID|MF_ALIAS; NAliasDBs++; } } }}/*** ALIASWAIT -- wait for distinguished @:@ token to appear.**** This can decide to reopen or rebuild the alias file**** Parameters:** map -- a pointer to the map descriptor for this alias file.** ext -- the filename extension (e.g., ".db") for the** database file.** isopen -- if set, the database is already open, and we** should check for validity; otherwise, we are** just checking to see if it should be created.**** Returns:** TRUE -- if the database is open when we return.** FALSE -- if the database is closed when we return.*/boolaliaswait(map, ext, isopen) MAP *map; char *ext; int isopen;{ bool attimeout = FALSE; time_t mtime; struct stat stb; char buf[MAXNAME]; if (tTd(27, 3)) printf("aliaswait(%s:%s)\n", map->map_class->map_cname, map->map_file); if (bitset(MF_ALIASWAIT, map->map_mflags)) return isopen; map->map_mflags |= MF_ALIASWAIT; if (SafeAlias > 0) { auto int st; time_t toolong = curtime() + SafeAlias; unsigned int sleeptime = 2; while (isopen && map->map_class->map_lookup(map, "@", NULL, &st) == NULL) { if (curtime() > toolong) { /* we timed out */ attimeout = TRUE; break; } /* ** Close and re-open the alias database in case ** the one is mv'ed instead of cp'ed in. */ if (tTd(27, 2)) printf("aliaswait: sleeping for %d seconds\n", sleeptime); map->map_class->map_close(map); sleep(sleeptime); sleeptime *= 2; if (sleeptime > 60) sleeptime = 60; isopen = map->map_class->map_open(map, O_RDONLY); } } /* see if we need to go into auto-rebuild mode */ if (!bitset(MCF_REBUILDABLE, map->map_class->map_cflags)) { if (tTd(27, 3)) printf("aliaswait: not rebuildable\n"); map->map_mflags &= ~MF_ALIASWAIT; return isopen; } if (stat(map->map_file, &stb) < 0) { if (tTd(27, 3)) printf("aliaswait: no source file\n"); map->map_mflags &= ~MF_ALIASWAIT; return isopen; } mtime = stb.st_mtime; (void) strcpy(buf, map->map_file); if (ext != NULL) (void) strcat(buf, ext); if (stat(buf, &stb) < 0 || stb.st_mtime < mtime || attimeout) { /* database is out of date */ if (AutoRebuild && stb.st_ino != 0 && stb.st_uid == geteuid()) { message("auto-rebuilding alias database %s", buf); if (isopen) map->map_class->map_close(map); rebuildaliases(map, TRUE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -