parseaddr.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,432 行 · 第 1/2 页
C
1,432 行
rvp = rwr->r_rhs;# ifdef DEBUG if (tTd(21, 12)) { printf("-----rule matches:"); printav(rvp); }# endif DEBUG rp = *rvp; if (*rp == CANONUSER) { rvp++; rwr = rwr->r_next; } else if (*rp == CANONHOST) { rvp++; rwr = NULL; } else if (*rp == CANONNET) rwr = NULL; /* substitute */ for (avp = npvp; *rvp != NULL; rvp++) { register struct match *m; register char **pp; rp = *rvp; if (*rp == MATCHREPL) { /* substitute from LHS */ m = &mlist[rp[1] - '1']; if (m >= mlp) { syserr("rewrite: ruleset %d: replacement out of bounds", ruleset); return; }# ifdef DEBUG if (tTd(21, 15)) { printf("$%c:", rp[1]); pp = m->first; while (pp <= m->last) { printf(" %x=\"", *pp); (void) fflush(stdout); printf("%s\"", *pp++); } printf("\n"); }# endif DEBUG pp = m->first; while (pp <= m->last) { if (avp >= &npvp[MAXATOM]) { syserr("rewrite: expansion too long"); return; } *avp++ = *pp++; } } else { /* vanilla replacement */ if (avp >= &npvp[MAXATOM]) { toolong: syserr("rewrite: expansion too long"); return; } *avp++ = rp; } } *avp++ = NULL; /* ** Check for any hostname lookups. */ for (rvp = npvp; *rvp != NULL; rvp++) { char **hbrvp; char **xpvp; int trsize; char *olddelimchar; char buf[MAXNAME + 1]; char *pvpb1[MAXATOM + 1]; char pvpbuf[PSBUFSIZE]; extern char *DelimChar; if (**rvp != HOSTBEGIN) continue; /* ** Got a hostname lookup. ** ** This could be optimized fairly easily. */ hbrvp = rvp; /* extract the match part */ while (*++rvp != NULL && **rvp != HOSTEND) continue; if (*rvp != NULL) *rvp++ = NULL; /* save the remainder of the input string */ trsize = (int) (avp - rvp + 1) * sizeof *rvp; bcopy((char *) rvp, (char *) pvpb1, trsize); /* look it up */ cataddr(++hbrvp, buf, sizeof buf); maphostname(buf, sizeof buf); /* scan the new host name */ olddelimchar = DelimChar; xpvp = prescan(buf, '\0', pvpbuf); DelimChar = olddelimchar; if (xpvp == NULL) { syserr("rewrite: cannot prescan canonical hostname: %s", buf); return; } /* append it to the token list */ for (avp = --hbrvp; *xpvp != NULL; xpvp++) { *avp++ = newstr(*xpvp); if (avp >= &npvp[MAXATOM]) goto toolong; } /* restore the old trailing information */ for (xpvp = pvpb1; (*avp++ = *xpvp++) != NULL; ) if (avp >= &npvp[MAXATOM]) goto toolong; break; } /* ** Check for subroutine calls. */ if (*npvp != NULL && **npvp == CALLSUBR) { bcopy((char *) &npvp[2], (char *) pvp, (int) (avp - npvp - 2) * sizeof *avp);# ifdef DEBUG if (tTd(21, 3)) printf("-----callsubr %s\n", npvp[1]);# endif DEBUG rewrite(pvp, atoi(npvp[1])); } else { bcopy((char *) npvp, (char *) pvp, (int) (avp - npvp) * sizeof *avp); }# ifdef DEBUG if (tTd(21, 4)) { printf("rewritten as:"); printav(pvp); }# endif DEBUG } if (OpMode == MD_TEST || tTd(21, 2)) { printf("rewrite: ruleset %2d returns:", ruleset); printav(pvp); }}/*** BUILDADDR -- build address from token vector.**** Parameters:** tv -- token vector.** a -- pointer to address descriptor to fill.** If NULL, one will be allocated.**** Returns:** NULL if there was an error.** 'a' otherwise.**** Side Effects:** fills in 'a'*/ADDRESS *buildaddr(tv, a) register char **tv; register ADDRESS *a;{ static char buf[MAXNAME]; struct mailer **mp; register struct mailer *m; extern bool sameword(); if (a == NULL) a = (ADDRESS *) xalloc(sizeof *a); bzero((char *) a, sizeof *a); /* figure out what net/mailer to use */ if (**tv != CANONNET) { syserr("buildaddr: no net"); return (NULL); } tv++; if (sameword(*tv, "error")) { if (**++tv == CANONHOST) { setstat(atoi(*++tv)); tv++; } if (**tv != CANONUSER) syserr("buildaddr: error: no user"); buf[0] = '\0'; while (*++tv != NULL) { if (buf[0] != '\0') (void) strcat(buf, " "); (void) strcat(buf, *tv); } usrerr(buf); return (NULL); } for (mp = Mailer; (m = *mp++) != NULL; ) { if (sameword(m->m_name, *tv)) break; } if (m == NULL) { syserr("buildaddr: unknown mailer %s", *tv); return (NULL); } a->q_mailer = m; /* figure out what host (if any) */ tv++; if (!bitnset(M_LOCAL, m->m_flags)) { if (**tv++ != CANONHOST) { syserr("buildaddr: no host"); return (NULL); } buf[0] = '\0'; while (*tv != NULL && **tv != CANONUSER) (void) strcat(buf, *tv++); a->q_host = newstr(buf); } else a->q_host = NULL; /* figure out the user */ if (**tv != CANONUSER) { syserr("buildaddr: no user"); return (NULL); } /* rewrite according recipient mailer rewriting rules */ rewrite(++tv, 2); if (m->m_r_rwset > 0) rewrite(tv, m->m_r_rwset); rewrite(tv, 4); /* save the result for the command line/RCPT argument */ cataddr(tv, buf, sizeof buf); a->q_user = buf; return (a);}/*** CATADDR -- concatenate pieces of addresses (putting in <LWSP> subs)**** Parameters:** pvp -- parameter vector to rebuild.** buf -- buffer to build the string into.** sz -- size of buf.**** Returns:** none.**** Side Effects:** Destroys buf.*/cataddr(pvp, buf, sz) char **pvp; char *buf; register int sz;{ bool oatomtok = FALSE; bool natomtok = FALSE; register int i; register char *p; if (pvp == NULL) { (void) strcpy(buf, ""); return; } p = buf; sz -= 2; while (*pvp != NULL && (i = strlen(*pvp)) < sz) { natomtok = (toktype(**pvp) == ATM); if (oatomtok && natomtok) *p++ = SpaceSub; (void) strcpy(p, *pvp); oatomtok = natomtok; p += i; sz -= i + 1; pvp++; } *p = '\0';}/*** SAMEADDR -- Determine if two addresses are the same**** This is not just a straight comparison -- if the mailer doesn't** care about the host we just ignore it, etc.**** Parameters:** a, b -- pointers to the internal forms to compare.**** Returns:** TRUE -- they represent the same mailbox.** FALSE -- they don't.**** Side Effects:** none.*/boolsameaddr(a, b) register ADDRESS *a; register ADDRESS *b;{ /* if they don't have the same mailer, forget it */ if (a->q_mailer != b->q_mailer) return (FALSE); /* if the user isn't the same, we can drop out */ if (strcmp(a->q_user, b->q_user) != 0) return (FALSE); /** ** For Reading mail+ support.. (mailplus) ** ** If the mailer is 'prog' AND the addressess from which we are ** aliased are owned by different UIDs, then return false. ** Different programs are picked up later. The paranoia checks ** are probably not needed. Quote: JCH :Enquote **/ if (a->q_mailer == ProgMailer && a->q_alias != NULL && b->q_alias != NULL && a->q_alias->q_flags|QGOODUID && b->q_alias->q_flags|QGOODUID && a->q_alias->q_uid != b->q_alias->q_uid) return FALSE; /* if the mailer ignores hosts, we have succeeded! */ if (bitnset(M_LOCAL, a->q_mailer->m_flags)) return (TRUE); /* otherwise compare hosts (but be careful for NULL ptrs) */ if (a->q_host == NULL || b->q_host == NULL) return (FALSE); if (strcmp(a->q_host, b->q_host) != 0) return (FALSE); return (TRUE);}/*** PRINTADDR -- print address (for debugging)**** Parameters:** a -- the address to print** follow -- follow the q_next chain.**** Returns:** none.**** Side Effects:** none.*/# ifdef DEBUGprintaddr(a, follow) register ADDRESS *a; bool follow;{ bool first = TRUE; while (a != NULL) { first = FALSE; printf("%x=", a); (void) fflush(stdout); printf("%s: mailer %d (%s), host `%s', user `%s', ruser `%s'\n", a->q_paddr, a->q_mailer->m_mno, a->q_mailer->m_name, a->q_host, a->q_user, a->q_ruser ? a->q_ruser : "<null>"); printf("\tnext=%x, flags=%o, alias %x\n", a->q_next, a->q_flags, a->q_alias); printf("\thome=\"%s\", fullname=\"%s\"\n", a->q_home, a->q_fullname); if (!follow) return; a = a->q_next; } if (first) printf("[NULL]\n");}# endif DEBUG/*** REMOTENAME -- return the name relative to the current mailer**** Parameters:** name -- the name to translate.** m -- the mailer that we want to do rewriting relative** to.** senderaddress -- if set, uses the sender rewriting rules** rather than the recipient rewriting rules.** canonical -- if set, strip out any comment information,** etc.**** Returns:** the text string representing this address relative to** the receiving mailer.**** Side Effects:** none.**** Warnings:** The text string returned is tucked away locally;** copy it if you intend to save it.*/char *remotename(name, m, senderaddress, canonical) char *name; struct mailer *m; bool senderaddress; bool canonical;{ register char **pvp; char *fancy; extern char *macvalue(); char *oldg = macvalue('g', CurEnv); static char buf[MAXNAME]; char lbuf[MAXNAME]; char pvpbuf[PSBUFSIZE]; extern char **prescan(); extern char *crackaddr();# ifdef DEBUG if (tTd(12, 1)) printf("remotename(%s)\n", name);# endif DEBUG /* don't do anything if we are tagging it as special */ if ((senderaddress ? m->m_s_rwset : m->m_r_rwset) < 0) return (name); /* ** Do a heuristic crack of this name to extract any comment info. ** This will leave the name as a comment and a $g macro. */ if (canonical) fancy = "\001g"; else fancy = crackaddr(name); /* ** Turn the name into canonical form. ** Normally this will be RFC 822 style, i.e., "user@domain". ** If this only resolves to "user", and the "C" flag is ** specified in the sending mailer, then the sender's ** domain will be appended. */ pvp = prescan(name, '\0', pvpbuf); if (pvp == NULL) return (name); rewrite(pvp, 3); if( ! canonical && CurEnv->e_fromdomain != NULL ) /* 001 */ { /* append from domain to this address */ register char **pxp = pvp; /* see if there is an "@domain" in the current name */ while (*pxp != NULL && strcmp(*pxp, "@") != 0) pxp++; if (*pxp == NULL) { /* no.... append the "@domain" from the sender */ register char **qxq = CurEnv->e_fromdomain; while ((*pxp++ = *qxq++) != NULL) continue; rewrite(pvp, 3); } } /* ** Do more specific rewriting. ** Rewrite using ruleset 1 or 2 depending on whether this is ** a sender address or not. ** Then run it through any receiving-mailer-specific rulesets. */ if (senderaddress) { rewrite(pvp, 1); if (m->m_s_rwset > 0) rewrite(pvp, m->m_s_rwset); } else { rewrite(pvp, 2); if (m->m_r_rwset > 0) rewrite(pvp, m->m_r_rwset); } /* ** Do any final sanitation the address may require. ** This will normally be used to turn internal forms ** (e.g., user@host.LOCAL) into external form. This ** may be used as a default to the above rules. */ rewrite(pvp, 4); /* ** Now restore the comment information we had at the beginning. */ cataddr(pvp, lbuf, sizeof lbuf); define('g', lbuf, CurEnv); expand(fancy, buf, &buf[sizeof buf - 1], CurEnv); define('g', oldg, CurEnv);# ifdef DEBUG if (tTd(12, 1)) printf("remotename => `%s'\n", buf);# endif DEBUG return (buf);}/***** IN_PASSWD_MAP -- See if something is in a passwd map**** Parameters:** rvp -- rewrite rule vector pointer** ap -- argument vector** rather than the recipient rewriting rules.**** Returns:** NULL -- if not found in the map** else** TRUE -- if found in the map**** Side Effects:** none.**** Warnings:*/struct svcinfo *svcinfo;struct passwd *nopasswd_local();struct passwd *getpwnam_yp();struct passwd *getpwnam_bind();struct passwd * (*getpasswdnames []) ()={ nopasswd_local, getpwnam_yp, getpwnam_bind};struct passwd *getpasswdname(name) char *name;{ struct passwd *p=NULL; register i; struct passwd *call; if ((svcinfo = getsvc()) != NULL) for (i=0; (svc_lastlookup = svcinfo->svcpath[SVC_PASSWD][i]) != SVC_LAST; i++) if (p = ((*(getpasswdnames [svcinfo->svcpath[SVC_PASSWD][i]])) (name) )) break; return(p);}struct passwd *nopasswd_local(name){ return(NULL);}in_passwd_map(rvp,ap) char **rvp; char **ap;{ int err; if ((getpasswdname(ap)) == NULL) { /* * Assume not in the map. */# ifdef DEBUG if (tTd(21,1)) printf("Map entry NOT found for %s\n",ap);# endif DEBUG rvp--; return(NULL); }# ifdef DEBUG if (tTd(21,1)) printf("Map entry found\n");# endif DEBUG return(TRUE);}/***** IN_ALIAS_MAP -- See if something is in an aliases map**** Parameters:** rvp -- rewrite rule vector pointer** ap -- argument vector** rather than the recipient rewriting rules.**** Returns:** NULL -- if not found in the map** else** TRUE -- if found in the map**** Side Effects:** none.**** Warnings:*/char *noalias_local();char *aliaslookup_yp();char *aliaslookup_bind();char * (*getaliasnames []) ()={ noalias_local, aliaslookup_yp, aliaslookup_bind};char *noalias_local(name){ return(NULL);}char *getaliasname(name) char *name;{ char *p=NULL; register i; char *call; if ((svcinfo = getsvc()) != NULL) for (i=0; (svc_lastlookup = svcinfo->svcpath[SVC_ALIASES][i]) != SVC_LAST; i++) if (p = ((*(getaliasnames [svcinfo->svcpath[SVC_ALIASES][i]])) (name) )) break; return(p);}in_alias_map(rvp,ap) char **rvp; char **ap;{ int err; if ((getaliasname(ap)) == NULL) { /* * Assume not in the map. */# ifdef DEBUG if (tTd(21,1)) printf("Map entry NOT found for %s\n",ap);# endif DEBUG rvp--; return(NULL); }# ifdef DEBUG if (tTd(21,1)) printf("Map entry found\n");# endif DEBUG return(TRUE);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?