📄 parseaddr.c
字号:
} (void) strcat(tokbuf, *avp++); s = stab(tokbuf, ST_CLASS, ST_FIND); } while (s == NULL || !bitnset(rp[1], s->s_class)); /* found an extension */ mlp[-1].last = avp-1; rvp++; break; } cantextend: if (*rp == MATCHANY || *rp == MATCHZANY) { /* extend binding and continue */ avp = ++mlp[-1].last; avp++; rvp++; break; } avp--; if (*rp == MATCHONE || *rp == MATCHNCLASS || *rp == MATCHYELLOW || *rp == MATCHNYELLOW) { /* back out binding */ mlp--; } } if (rvp < rwr->r_lhs) { /* total failure to match */ break; } } /* ** See if we successfully matched */ if (rvp < rwr->r_lhs || *rvp != NULL) {# ifdef DEBUG if (tTd(21, 10)) printf("----- rule fails\n");# endif DEBUG rwr = rwr->r_next; continue; } 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]) { goto toolong; } *avp++ = *pp++; } } else { /* vanilla replacement */ if (avp >= &npvp[MAXATOM]) { toolong: syserr("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 any NIS replacements */ 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]; char *mapname; extern char *DelimChar; extern char *macvalue(); if (**rvp != YELLOWBEGIN) continue; if (*++rvp == NULL) continue; mapname = macvalue(**rvp,CurEnv); /* ** Got a NIS replacement. ** ** This could be optimized fairly easily. */ hbrvp = rvp; /* extract the match part */ while (*++rvp != NULL && **rvp != YELLOWEND) 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 + 1, buf, sizeof buf); mapusername(mapname, buf, sizeof buf); /* scan the new host name */ olddelimchar = DelimChar; xpvp = prescan(buf, '\0', pvpbuf); DelimChar = olddelimchar; if (xpvp == NULL) { syserr("cannot prescan NIS result: %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 ADDRESS NullAddress; if (a == NULL) a = (ADDRESS *) xalloc(sizeof *a); *a = NullAddress; /* figure out what net/mailer to use */ if (**tv != CANONNET) { syserr("buildaddr: no mailer"); return (NULL); } tv++; if (!strcasecmp(*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("%s", buf); return (NULL); } for (mp = Mailer; (m = *mp++) != NULL; ) { if (!strcasecmp(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==NULL || **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==NULL || **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); /* 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 (CurEnv->e_fromdomain != NULL) { /* 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; /* * WARNING: this is necessary because we want to * get uucp domain names too, which means * we have to do this before the from address * gets defocused by ruleset 4. */ while (*qxq != NULL && **qxq != '>') *pxp++ = *qxq++; *pxp = NULL; 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);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -