headers.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 863 行 · 第 1/2 页
C
863 行
#ifndef lintstatic char *sccsid = "@(#)headers.c 4.1 (ULTRIX) 7/2/90";#endif lint/************************************************************************ * * * Copyright (c) 1987 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************/# include <errno.h># include "sendmail.h"/*** CHOMPHEADER -- process and save a header line.**** Called by collect and by readcf to deal with header lines.**** Parameters:** line -- header as a text line.** def -- if set, this is a default value.**** Returns:** flags for this header.**** Side Effects:** The header is saved on the header list.** Contents of 'line' are destroyed.*/chompheader(line, def) char *line; bool def;{ register char *p; register HDR *h; HDR **hp; char *fname; char *fvalue; struct hdrinfo *hi; bool cond = FALSE; BITMAP mopts; extern char *crackaddr();# ifdef DEBUG if (tTd(31, 6)) printf("chompheader: %s\n", line);# endif DEBUG /* strip off options */ clrbitmap(mopts); p = line; if (*p == '?') { /* have some */ register char *q = index(p + 1, *p); if (q != NULL) { *q++ = '\0'; while (*++p != '\0') setbitn(*p, mopts); p = q; } else syserr("chompheader: syntax error, line \"%s\"", line); cond = TRUE; } /* find canonical name */ fname = p; p = index(p, ':'); if (p == NULL) { syserr("chompheader: syntax error, line \"%s\"", line); return (0); } fvalue = &p[1]; while (isspace(*--p)) continue; *++p = '\0'; makelower(fname); /* strip field value on front */ if (*fvalue == ' ') fvalue++; /* see if it is a known type */ for (hi = HdrInfo; hi->hi_field != NULL; hi++) { if (strcmp(hi->hi_field, fname) == 0) break; } /* see if this is a resent message */ if (!def && bitset(H_RESENT, hi->hi_flags)) CurEnv->e_flags |= EF_RESENT; /* if this means "end of header" quit now */ if (bitset(H_EOH, hi->hi_flags)) return (hi->hi_flags); /* drop explicit From: if same as what we would generate -- for MH */ p = "resent-from"; if (!bitset(EF_RESENT, CurEnv->e_flags)) p += 7; if (!def && !QueueRun && strcmp(fname, p) == 0) { if (CurEnv->e_from.q_paddr != NULL && strcmp(fvalue, CurEnv->e_from.q_paddr) == 0) return (hi->hi_flags); } /* delete default value for this header */ for (hp = &CurEnv->e_header; (h = *hp) != NULL; hp = &h->h_link) { if (strcmp(fname, h->h_field) == 0 && bitset(H_DEFAULT, h->h_flags) && !bitset(H_FORCE, h->h_flags)) h->h_value = NULL; } /* create a new node */ h = (HDR *) xalloc(sizeof *h); h->h_field = newstr(fname); h->h_value = NULL; h->h_link = NULL; bcopy((char *) mopts, (char *) h->h_mflags, sizeof mopts); *hp = h; h->h_flags = hi->hi_flags; if (def) h->h_flags |= H_DEFAULT; if (cond) h->h_flags |= H_CHECK; if (h->h_value != NULL) free((char *) h->h_value); h->h_value = newstr(fvalue); /* hack to see if this is a new format message */ if (!def && bitset(H_RCPT|H_FROM, h->h_flags) && (index(fvalue, ',') != NULL || index(fvalue, '(') != NULL || index(fvalue, '<') != NULL || index(fvalue, ';') != NULL)) { CurEnv->e_flags &= ~EF_OLDSTYLE; } return (h->h_flags);}/*** ADDHEADER -- add a header entry to the end of the queue.**** This bypasses the special checking of chompheader.**** Parameters:** field -- the name of the header field.** value -- the value of the field. It must be lower-cased.** e -- the envelope to add them to.**** Returns:** none.**** Side Effects:** adds the field on the list of headers for this envelope.*/addheader(field, value, e) char *field; char *value; ENVELOPE *e;{ register HDR *h; register struct hdrinfo *hi; HDR **hp; /* find info struct */ for (hi = HdrInfo; hi->hi_field != NULL; hi++) { if (strcmp(field, hi->hi_field) == 0) break; } /* find current place in list -- keep back pointer? */ for (hp = &e->e_header; (h = *hp) != NULL; hp = &h->h_link) { if (strcmp(field, h->h_field) == 0) break; } /* allocate space for new header */ h = (HDR *) xalloc(sizeof *h); h->h_field = field; h->h_value = newstr(value); h->h_link = *hp; h->h_flags = hi->hi_flags | H_DEFAULT; clrbitmap(h->h_mflags); *hp = h;}/*** HVALUE -- return value of a header.**** Only "real" fields (i.e., ones that have not been supplied** as a default) are used.**** Parameters:** field -- the field name.**** Returns:** pointer to the value part.** NULL if not found.**** Side Effects:** none.*/char *hvalue(field) char *field;{ register HDR *h; for (h = CurEnv->e_header; h != NULL; h = h->h_link) { if (!bitset(H_DEFAULT, h->h_flags) && strcmp(h->h_field, field) == 0) return (h->h_value); } return (NULL);}/*** ISHEADER -- predicate telling if argument is a header.**** A line is a header if it has a single word followed by** optional white space followed by a colon.**** Parameters:** s -- string to check for possible headerness.**** Returns:** TRUE if s is a header.** FALSE otherwise.**** Side Effects:** none.*/boolisheader(s) register char *s;{ while (*s > ' ' && *s != ':' && *s != '\0') s++; /* following technically violates RFC822 */ while (isspace(*s)) s++; return (*s == ':');}/*** EATHEADER -- run through the stored header and extract info.**** Parameters:** e -- the envelope to process.**** Returns:** none.**** Side Effects:** Sets a bunch of global variables from information** in the collected header.** Aborts the message if the hop count is exceeded.*/eatheader(e) register ENVELOPE *e;{ register HDR *h; register char *p; int hopcnt = 0;#ifdef DEBUG if (tTd(32, 1)) printf("----- collected header -----\n");#endif DEBUG for (h = e->e_header; h != NULL; h = h->h_link) {#ifdef DEBUG extern char *capitalize(); if (tTd(32, 1)) printf("%s: %s\n", capitalize(h->h_field), h->h_value);#endif DEBUG /* count the number of times it has been processed */ if (bitset(H_TRACE, h->h_flags)) hopcnt++; /* send to this person if we so desire */ if (GrabTo && bitset(H_RCPT, h->h_flags) && !bitset(H_DEFAULT, h->h_flags) && (!bitset(EF_RESENT, CurEnv->e_flags) || bitset(H_RESENT, h->h_flags))) { sendtolist(h->h_value, (ADDRESS *) NULL, &CurEnv->e_sendqueue); } /* log the message-id */#ifdef LOG if (!QueueRun && LogLevel > 8 && h->h_value != NULL && strcmp(h->h_field, "message-id") == 0) { char buf[MAXNAME]; p = h->h_value; if (bitset(H_DEFAULT, h->h_flags)) { expand(p, buf, &buf[sizeof buf], e); p = buf; } syslog(LOG_INFO, "%s: message-id=%s", e->e_id, p); }#endif LOG }#ifdef DEBUG if (tTd(32, 1)) printf("----------------------------\n");#endif DEBUG /* store hop count */ if (hopcnt > e->e_hopcount) e->e_hopcount = hopcnt; /* message priority */ p = hvalue("precedence"); if (p != NULL) e->e_class = priencode(p); if (!QueueRun) e->e_msgpriority = e->e_msgsize - e->e_class * WkClassFact + e->e_nrcpts * WkRecipFact; /* return receipt to */ p = hvalue("return-receipt-to"); if (p != NULL) e->e_receiptto = p; /* errors to */ p = hvalue("errors-to"); if (p != NULL) sendtolist(p, (ADDRESS *) NULL, &e->e_errorqueue); /* from person */ if (OpMode == MD_ARPAFTP) { register struct hdrinfo *hi = HdrInfo; for (p = NULL; p == NULL && hi->hi_field != NULL; hi++) { if (bitset(H_FROM, hi->hi_flags)) p = hvalue(hi->hi_field); } if (p != NULL) setsender(p); } /* full name of from person */ p = hvalue("full-name"); if (p != NULL) define('x', p, e); /* date message originated */ p = hvalue("posted-date"); if (p == NULL) p = hvalue("date"); if (p != NULL) { define('a', p, e); /* we don't have a good way to do canonical conversion .... define('d', newstr(arpatounix(p)), e); .... so we will ignore the problem for the time being */ } /* ** Log collection information. */# ifdef LOG if (!QueueRun && LogLevel > 1) { syslog(LOG_INFO, "%s: from=%s, size=%ld, class=%d\n", CurEnv->e_id, CurEnv->e_from.q_paddr, CurEnv->e_msgsize, CurEnv->e_class); }# endif LOG}/*** PRIENCODE -- encode external priority names into internal values.**** Parameters:** p -- priority in ascii.**** Returns:** priority as a numeric level.**** Side Effects:** none.*/priencode(p) char *p;{ register int i; extern bool sameword();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?