📄 headers.c
字号:
** 6. comment <address (comment)> ==> comment <$g (comment)>** 7. .... etc ....**** Parameters:** addr -- the address to be cracked.**** Returns:** a pointer to the new version.**** Side Effects:** none.**** Warning:** The return value is saved in local storage and should** be copied if it is to be reused.*/char *crackaddr(addr) register char *addr;{ register char *p; register int i; static char buf[MAXNAME]; char *rhs; bool gotaddr; register char *bp;# ifdef DEBUG if (tTd(33, 1)) printf("crackaddr(%s)\n", addr);# endif DEBUG (void) strcpy(buf, ""); rhs = NULL; /* strip leading spaces */ while (*addr != '\0' && isspace(*addr)) addr++; /* ** See if we have anything in angle brackets. If so, that is ** the address part, and the rest is the comment. */ p = index(addr, '<'); if (p != NULL) { /* copy the beginning of the addr field to the buffer */ *p = '\0'; (void) strcpy(buf, addr); (void) strcat(buf, "<"); *p++ = '<'; /* skip spaces */ while (isspace(*p)) p++; /* find the matching right angle bracket */ addr = p; for (i = 0; *p != '\0'; p++) { switch (*p) { case '<': i++; break; case '>': i--; break; } if (i < 0) break; } /* p now points to the closing quote (or a null byte) */ if (*p != '\0') { /* make rhs point to the extra stuff at the end */ rhs = p; *p++ = '\0'; } } /* ** Now parse the real address part. "addr" points to the (null ** terminated) version of what we are inerested in; rhs points ** to the extra stuff at the end of the line, if any. */ p = addr; /* now strip out comments */ bp = &buf[strlen(buf)]; gotaddr = FALSE; for (; *p != '\0'; p++) { if (*p == '(') { /* copy to matching close paren */ *bp++ = *p++; for (i = 0; *p != '\0'; p++) { *bp++ = *p; switch (*p) { case '(': i++; break; case ')': i--; break; } if (i < 0) break; } continue; } /* ** If this is the first "real" character we have seen, ** then we put the "$g" in the buffer now. */ if (isspace(*p)) *bp++ = *p; else if (!gotaddr) { (void) strcpy(bp, "\001g"); bp += 2; gotaddr = TRUE; } } /* hack, hack.... strip trailing blanks */ do { *bp-- = '\0'; } while (isspace(*bp)); bp++; /* put any right hand side back on */ if (rhs != NULL) { *rhs = '>'; (void) strcpy(bp, rhs); }# ifdef DEBUG if (tTd(33, 1)) printf("crackaddr=>`%s'\n", buf);# endif DEBUG return (buf);}/*** PUTHEADER -- put the header part of a message from the in-core copy**** Parameters:** fp -- file to put it on.** m -- mailer to use.** e -- envelope to use.**** Returns:** none.**** Side Effects:** none.*/putheader(fp, m, e) register FILE *fp; register MAILER *m; register ENVELOPE *e;{ char buf[BUFSIZ]; register HDR *h; extern char *arpadate(); extern char *capitalize(); char obuf[MAXLINE]; for (h = e->e_header; h != NULL; h = h->h_link) { register char *p; extern bool bitintersect(); if (bitset(H_CHECK|H_ACHECK, h->h_flags) && !bitintersect(h->h_mflags, m->m_flags)) continue; /* handle Resent-... headers specially */ if (bitset(H_RESENT, h->h_flags) && !bitset(EF_RESENT, e->e_flags)) continue; p = h->h_value; if (bitset(H_DEFAULT, h->h_flags)) { if (bitset(H_ERRSTO, h->h_flags)) { errors_to(h, e); if (h->h_value && h->h_value[0]) commaize(h, h->h_value, fp, FALSE, m); continue; } /* macro expand value if generated internally */ expand(p, buf, &buf[sizeof buf], e); p = buf; if (p == NULL || *p == '\0') continue; } if (bitset(H_FROM|H_RCPT, h->h_flags)) { /* address field */ bool oldstyle = bitset(EF_OLDSTYLE, e->e_flags); if (bitset(H_FROM, h->h_flags)) oldstyle = FALSE; commaize(h, p, fp, oldstyle, m); } else { /* vanilla header line */ register char *nlp; (void) sprintf(obuf, "%s: ", capitalize(h->h_field)); while ((nlp = index(p, '\n')) != NULL) { *nlp = '\0'; (void) strcat(obuf, p); *nlp = '\n'; putline(obuf, fp, m); p = ++nlp; obuf[0] = '\0'; } (void) strcat(obuf, p); putline(obuf, fp, m); } }}/*** COMMAIZE -- output a header field, making a comma-translated list.**** Parameters:** h -- the header field to output.** p -- the value to put in it.** fp -- file to put it to.** oldstyle -- TRUE if this is an old style header.** m -- a pointer to the mailer descriptor. If NULL,** don't transform the name at all.**** Returns:** none.**** Side Effects:** outputs "p" to file "fp".*/commaize(h, p, fp, oldstyle, m) register HDR *h; register char *p; FILE *fp; bool oldstyle; register MAILER *m;{ register char *obp; int opos; bool firstone = TRUE; char obuf[MAXLINE + 3]; /* ** Output the address list translated by the ** mailer and with commas. */# ifdef DEBUG if (tTd(14, 2)) printf("commaize(%s: %s)\n", h->h_field, p);# endif DEBUG obp = obuf; (void) sprintf(obp, "%s: ", capitalize(h->h_field)); opos = strlen(h->h_field) + 2; obp += opos; /* ** Run through the list of values. */ while (*p != '\0') { register char *name; char savechar; extern char *remotename(); extern char *DelimChar; /* defined in prescan */ /* ** Find the end of the name. New style names ** end with a comma, old style names end with ** a space character. However, spaces do not ** necessarily delimit an old-style name -- at ** signs mean keep going. */ /* find end of name */ while (isspace(*p) || *p == ',') p++; name = p; for (;;) { char *oldp; char pvpbuf[PSBUFSIZE]; extern bool isatword(); extern char **prescan(); (void) prescan(p, oldstyle ? ' ' : ',', pvpbuf); p = DelimChar; /* look to see if we have an at sign */ oldp = p; while (*p != '\0' && isspace(*p)) p++; if (*p != '@' && !isatword(p)) { p = oldp; break; } p += *p == '@' ? 1 : 2; while (*p != '\0' && isspace(*p)) p++; } /* at the end of one complete name */ /* strip off trailing white space */ while (p >= name && (isspace(*p) || *p == ',' || *p == '\0')) p--; if (++p == name) continue; savechar = *p; *p = '\0'; /* translate the name to be relative */ name = remotename(name, m, bitset(H_FROM, h->h_flags), FALSE); if (*name == '\0') { *p = savechar; continue; } /* output the name with nice formatting */ opos += qstrlen(name); if (!firstone) opos += 2; if (opos > 78 && !firstone) { (void) strcpy(obp, ",\n"); putline(obuf, fp, m); obp = obuf; (void) sprintf(obp, " "); opos = strlen(obp); obp += opos; opos += qstrlen(name); } else if (!firstone) { (void) sprintf(obp, ", "); obp += 2; } /* strip off quote bits as we output */ while (*name != '\0' && obp < &obuf[MAXLINE]) { if (bitset(0200, *name)) *obp++ = '\\'; *obp++ = *name++ & ~0200; } firstone = FALSE; *p = savechar; } (void) strcpy(obp, "\n"); putline(obuf, fp, m);}/*** ISATWORD -- tell if the word we are pointing to is "at".**** Parameters:** p -- word to check.**** Returns:** TRUE -- if p is the word at.** FALSE -- otherwise.**** Side Effects:** none.*/boolisatword(p) register char *p;{ extern char lower(); if (lower(p[0]) == 'a' && lower(p[1]) == 't' && p[2] != '\0' && isspace(p[2])) return (TRUE); return (FALSE);}/* * create a default Errors-to: line if there is none yet * But we DO have something in the error queue (e.g. a list owner) */errors_to(h, e) register HDR *h; register ENVELOPE *e;{ char buf[1024]; ADDRESS *q; register char *p; bool another = FALSE; if (bitset(EF_ERRSTOFROM, e->e_flags) || e->e_errorqueue == NULL) return; if (h->h_value && h->h_value[0]) return; p = buf; p[0] = '\0'; for (q = e->e_errorqueue;q;q = q->q_next) { if (bitset(QDONTSEND|QBADADDR, q->q_flags)) continue; if (another) (void) strcat(p, ", "); (void) strcat(p, q->q_paddr); another = TRUE; } h->h_value = newstr(p);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -