📄 alias.c
字号:
/* * Copyright (c) 1988 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that this notice is preserved and that due credit is given * to the University of California at Berkeley. The name of the University * may not be used to endorse or promote products derived from this * software without specific prior written permission. This software * is provided ``as is'' without express or implied warranty. * * Sendmail * Copyright (c) 1983 Eric P. Allman * Berkeley, California */# include <pwd.h># include <sys/types.h># include <sys/stat.h># include <signal.h># include <errno.h># include "sendmail.h"# include <sys/file.h>SCCSID(@(#)alias.c 1.1 92/07/30 SMI); /* from UCB 5.15 4/1/88 *//*** 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.**** Returns:** none**** Side Effects:** Aliases found are expanded.**** Notes:** If NoAlias (the "-n" flag) is set, no aliasing is** done.**** Deficiencies:** It should complain about names that are aliased to** nothing.*/#ifdef DBMtypedef struct{ char *dptr; int dsize;} DATUM;extern DATUM fetch();#endif DBMalias(a, sendq) register ADDRESS *a; ADDRESS **sendq;{ register char *p; extern char *aliaslookup(), *yellowlookup();# ifdef DEBUG if (tTd(27, 1)) printf("alias(%s)\n", a->q_paddr);# endif /* don't realias already aliased names */ if (bitset(QDONTSEND, a->q_flags)) return; CurEnv->e_to = a->q_paddr; /* ** Look up this name */ if (NoAlias) p = NULL; else { p = aliaslookup(a->q_user); if (p == NULL) p = yellowlookup(a); } if (p == NULL) return; /* ** Match on Alias. ** Deliver to the target list. */# ifdef DEBUG if (tTd(27, 1)) printf("%s (%s, %s) aliased to %s\n", a->q_paddr, a->q_host, a->q_user, p);# endif message(Arpa_Info, "aliased to %s", p); AliasLevel++; sendtolist(p, a, sendq); AliasLevel--;}/*** 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) char *name;{# ifdef DBM DATUM rhs, lhs; /* create a key for fetch */ lhs.dptr = name; lhs.dsize = strlen(name) + 1; rhs = fetch(lhs); return (rhs.dptr);# else DBM register STAB *s; s = stab(name, ST_ALIAS, ST_FIND); if (s == NULL) return (NULL); return (s->s_alias);# endif DBM}char *ypDomain = NULL;/*** YELLOWMATCH -- look up any token in the Network Information Services.**** Parameters:** string - string to look up** mac - macro to use as name of map**** Returns:** True if the value was found in the database**** Side Effects:** If token is found, enter into cache.** Note the careful copying of the string, converting it** to lower case before doing the NIS lookup, and then converting** it back to original case in the symbol table.**** Warnings:** Will hang forever if no NIS server responds*/yellowmatch(string,mac) char *string; char mac; { int insize, outsize; register STAB *s; char *mapname, *result, *lowered, *macvalue(); if (mac == 'y') { /* * handle the special host name mapping macro. */ struct hostinfo *h, *lookuphost(); h = lookuphost(string); errno = 0; return(h->h_exists && (h->h_down == 0 || h->h_errno != ENAMESER)); } mapname = macvalue(mac,CurEnv); if (mapname==NULL) return(FALSE); lowered = newstr(string); makelower(lowered); s = stab(lowered, ST_YP, ST_FIND); if (s != NULL) { if (bitnset(mac, s->s_value.sv_bitmap2.positive)) { free(lowered); return(TRUE); } if (bitnset(mac, s->s_value.sv_bitmap2.negative)) { free(lowered); return(FALSE); } } else s = stab(lowered, ST_YP, ST_ENTER); insize = strlen(lowered); if (ypDomain==NULL) { yp_get_default_domain(&ypDomain); if (ypDomain==NULL) return(FALSE); }# ifdef DEBUG if (tTd(27, 1)) printf("NIS lookup of %s in map %s\n",lowered, mapname);# endif DEBUG if (yp_match(ypDomain,mapname,lowered, insize, &result, &outsize) && yp_match(ypDomain,mapname,lowered, insize+1, &result, &outsize)) { setbitn(mac, s->s_value.sv_bitmap2.negative); errno = 0; return(FALSE); }# ifdef DEBUG if (tTd(27, 1)) printf("NIS found %s as value for %s\n",result,lowered);# endif DEBUG setbitn(mac, s->s_value.sv_bitmap2.positive); free(result); return(TRUE); }/*** MAPUSERNAME -- look up a string in the NIS with replacement**** Parameters:** map -- name of the NIS map to use** buf -- input buffer** bufsize -- size of input buffer**** Side Effects:** changes buffer to be its value in the map*/mapusername(map, buf, bufsize) char *map, *buf; int bufsize; { int insize, outsize; char *result, *lowered; if (ypDomain==NULL) { yp_get_default_domain(&ypDomain); if (ypDomain==NULL) return; } lowered = newstr(buf); makelower(lowered); insize = strlen(lowered); if (yp_match(ypDomain, map, lowered, insize, &result, &outsize) && yp_match(ypDomain, map, lowered, insize+1, &result, &outsize)) { errno = 0; free(lowered); return; }# ifdef DEBUG if (tTd(27, 1)) printf("NIS found %s as value for %s\n",result,buf);# endif DEBUG free(lowered); if (outsize >= bufsize) outsize = bufsize - 1; strncpy(buf, result, outsize); buf[outsize] = '\0'; }/*** YELLOWLOOKUP -- look up a name in the NIS.**** Parameters:** a -- the address to look up.**** Returns:** the value of name.** NULL if unknown.**** Side Effects:** sets **** Warnings:** The return value will be trashed across calls.*/char *yellowlookup(a) register ADDRESS *a; { char *result; int insize, outsize; extern char *AliasMap; /* * if we did not find a local alias, then * try a remote alias through NIS. */ if (AliasMap==NULL || *AliasMap=='\0') return(NULL); if (ypDomain==NULL) { yp_get_default_domain(&ypDomain); if (ypDomain == NULL) return(NULL);# ifdef DEBUG if (tTd(27, 1)) printf("NIS domain is %s\n",ypDomain);# endif DEBUG } if (bitset(QWASLOCAL,a->q_flags)) return(NULL); insize = strlen(a->q_user); if (yp_match(ypDomain,AliasMap,a->q_user, insize, &result, &outsize) && yp_match(ypDomain,AliasMap,a->q_user, insize+1, &result, &outsize)) { errno = 0; return(NULL); } # ifdef DEBUG if (tTd(27, 1)) printf("%s maps to %s\n",a->q_user, result );# endif DEBUG a->q_flags |= QDOMAIN; return(result); }/*** INITALIASES -- initialize for aliasing**** Very different depending on whether we are running DBM or not.**** Parameters:** aliasfile -- location of aliases.** init -- if set and if DBM, initialize the DBM files.**** Returns:** none.**** Side Effects:** initializes aliases:** if DBM: opens the database.** if ~DBM: reads the aliases into the symbol table.*/# define DBMMODE 0666initaliases(aliasfile, init) char *aliasfile; bool init;{#ifdef DBM int atcnt; bool automatic = FALSE; char buf[MAXNAME];#endif DBM time_t modtime; struct stat stb; static bool initialized = FALSE; if (initialized) return; initialized = TRUE; if (aliasfile == NULL || stat(aliasfile, &stb) < 0) { if (aliasfile != NULL && init) syserr("Cannot open %s", aliasfile); NoAlias = TRUE; errno = 0; return; }# ifdef DBM /* ** Check to see that the alias file is complete. ** If not, we will assume that someone died, and it is up ** to us to rebuild it. */ if (!init) dbminit(aliasfile); atcnt = SafeAlias * 2; if (atcnt > 0) { while (!init && atcnt-- >= 0 && aliaslookup("@") == NULL) { /* ** Reinitialize alias file in case the new ** one is mv'ed in instead of cp'ed in. ** ** Only works with new DBM -- old one will ** just consume file descriptors forever. ** If you have a dbmclose() it can be ** added before the sleep(30). */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -