|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T r
Length: 20666 (0x50ba) Types: TextFile Names: »rd_rfchdr.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z« └─⟦e5a54fb17⟧ └─⟦this⟧ »pp-5.0/Src/submit/rd_rfchdr.c«
/* rd_rfchdr.c: parse 822 headers */ # ifndef lint static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Src/submit/RCS/rd_rfchdr.c,v 5.0 90/09/20 16:23:08 pp Exp Locker: pp $"; # endif /* * $Header: /cs/research/pp/hubris/pp-beta/Src/submit/RCS/rd_rfchdr.c,v 5.0 90/09/20 16:23:08 pp Exp Locker: pp $ * * $Log: rd_rfchdr.c,v $ * Revision 5.0 90/09/20 16:23:08 pp * rcsforce : 5.0 public release * */ #include "head.h" #include <isode/cmd_srch.h> #include "q.h" #include "tb_q.h" #include "or.h" #include "ap.h" extern void err_abrt(); static int hdr_parse (); static int hdr_type (), fillin_DomId(); static void hdr_rcv (); static void hdr_via (); static void hdr_check (); static void hdr_subject (); static void hdr_date (); static void hdr_msgid (); static void hdr_remcomm (); static void hdr_trace (); static int getline (); static int ua_id_set_by_subject = FALSE; static void hdr_x400_content_id(), hdr_priority(), hdr_x400_mts_id(), hdr_dl_history(), hdr_conversion(), hdr_convert_with_loss(), hdr_x400_received(), hdr_def_deliv(), hdr_latest_time(), hdr_orig_eit (); #define ub_content_id_length 16 /* -- basic states for the state machine -- */ #define HDV_EOH 0 #define HDV_NEW 1 #define HDV_MORE 2 /* -- munge the header lines of the message -- */ #define HDR_FROM 1 #define HDR_SENDER 2 #define HDR_REPLYTO 3 #define HDR_RECEIVED 4 #define HDR_VIA 5 #define HDR_DATE 6 #define HDR_MESSAGEID 7 #define HDR_SUBJECT 8 /* rfc 1138 fields */ /* mts */ #define HDR_X400_MTS_ID 9 #define HDR_ORIG_EIT 10 #define HDR_CONTENT_IDENTIFIER 11 #define HDR_PRIORITY 12 #define HDR_DL_HISTORY 13 #define HDR_CONVERSION 18 #define HDR_CONVERT_WITH_LOSS 14 /* mta */ #define HDR_X400_RECEIVED 15 #define HDR_DEF_DELIV 16 #define HDR_LAST_DELIV 17 static CMD_TABLE htbl_rfc [] = { "from", HDR_FROM, "sender", HDR_SENDER, "reply-to", HDR_REPLYTO, "received", HDR_RECEIVED, "via", HDR_VIA, "date", HDR_DATE, "message-id", HDR_MESSAGEID, "subject", HDR_SUBJECT, /* rfc 1138 */ "x400-mts-identifier", HDR_X400_MTS_ID, "original-encoded-information-types", HDR_ORIG_EIT, "content-identifier", HDR_CONTENT_IDENTIFIER, "priority", HDR_PRIORITY, "dl-expansion-history", HDR_DL_HISTORY, "conversion", HDR_CONVERSION, "conversion-with-loss", HDR_CONVERT_WITH_LOSS, "x400-received", HDR_X400_RECEIVED, "deferred-delivery", HDR_DEF_DELIV, "latest-delivery-time", HDR_LAST_DELIV, 0, 0 }; /* -- statics -- */ static FILE *hdr_fp; static time_t read_time(); static int from_count, trace_count, date_count, hdr_prefix, redistributed_mail, sender_count; static Trace *gettrace (); /* -- externals -- */ extern Q_struct Qstruct; extern CHAN *ch_inbound; extern char *loc_dom_mta; /* --------------------- Begin Routines -------------------------------- */ void rd_rfchdr (file) /* -- basic processing of incoming header lines -- */ char *file; { char *bp, *name = NULLCP, /* hdr content location */ *contents = NULLCP; int retval = NOTOK, type; PP_DBG (("submit/rd_rfchdr (%s)", file)); sender_count = 0; from_count = 0; trace_count = 0; date_count = 0; redistributed_mail = FALSE; ua_id_set_by_subject = FALSE; if ((hdr_fp = fopen (file, "r")) == NULL) err_abrt (RP_FIO, "submit/rd_rfchdr/Unable to open '%s'", file); while (getline (&bp, hdr_fp) == OK) { hdr_prefix = FALSE; switch (retval = hdr_parse (bp, &name, &contents)) { case HDV_MORE: continue; case HDV_NEW: if ((type = hdr_type (name)) > 0) hdr_check (type, contents); continue; case HDV_EOH: break; case NOTOK: err_abrt(RP_USER, "submit/rd_rfchdr: Unable to parse '%s' as key:field", bp); break; } break; } (void) fclose (hdr_fp); if (retval != HDV_EOH) PP_DBG (("submit/rd_rfchdr/retval (%d) != hdr_eoh", retval)); if (ch_inbound -> ch_access == CH_MTS && sender_count == 0 && from_count == 0) err_abrt (RP_USER, "submit/rd_rfchdr/No sender given"); if (date_count == 0) err_abrt (RP_USER, "submit/rd_rfchdr/No date field given"); } /* --------------------- Static Routines ------------------------------- */ static int hdr_parse (txt, name, contents) /* -- parse one header line -- */ register char *txt; /* -- a line of header text -- */ char **name; /* -- location of field's name -- */ char **contents; /* -- location of field's contents -- */ { extern char *compress(); char linetype; PP_DBG (("submit/hdr_parse (%s)", txt)); if (isspace (*txt)) { /* -- continuation text -- */ if (*txt == '\n' || *txt == '\0') return (HDV_EOH); linetype = HDV_MORE; } else { linetype = HDV_NEW; *name = txt; while (*txt && *txt != ':') txt ++; if (*txt == '\0' || *txt == '\n') return NOTOK; *txt ++ = '\0'; (void) compress (*name, *name); } *contents = txt; compress (*contents, *contents); return (linetype); } static int hdr_type (name) /* -- return the type of the component -- */ char *name; { PP_DBG (("submit/hdr_type (%s)",name)); if (prefix ("Resent-", name)) { name += 7; goto doremail; } if (prefix ("Remailed-", name)) { name += 9; goto doremail; } if (prefix ("Redistributed-", name)) { name += 14; doremail: hdr_prefix = TRUE; if (!redistributed_mail) { sender_count = from_count = 0; redistributed_mail = TRUE; } } return (cmd_srch (name, htbl_rfc)); } static void hdr_check (type, body) char *body; int type; { AP_ptr ap; PP_DBG (("submit/hdr_check (%d,%s)", type, body)); if (type <= 0) return; /* -- for all unknown types -- */ switch (type) { case HDR_SENDER: if (redistributed_mail && !hdr_prefix) break; if ((ap = ap_s2t (body)) == NULLAP) err_abrt (RP_USER, "submit/rd_rfchdr syntactically invalid address for sender '%s'", body); else ap_free(ap); sender_count++; break; case HDR_FROM: if (redistributed_mail && !hdr_prefix) break; if ((ap = ap_s2t (body)) == NULLAP) err_abrt (RP_USER, "submit/rd_rfchdr syntactically invalid address for from field '%s'", body); else ap_free(ap); from_count++; break; case HDR_REPLYTO: if (redistributed_mail && !hdr_prefix) break; break; case HDR_VIA: hdr_via (body); break; case HDR_RECEIVED: hdr_rcv (body); break; case HDR_MESSAGEID: hdr_msgid (body); break; case HDR_DATE: hdr_date (body); date_count++; break; case HDR_SUBJECT: hdr_subject (body); break; case HDR_X400_MTS_ID: hdr_x400_mts_id (body); break; case HDR_ORIG_EIT: hdr_orig_eit (body); break; case HDR_CONTENT_IDENTIFIER: hdr_x400_content_id (body); break; case HDR_PRIORITY: hdr_priority(body); break; case HDR_DL_HISTORY: hdr_dl_history(body); break; case HDR_CONVERSION: hdr_conversion(body); break; case HDR_CONVERT_WITH_LOSS: hdr_convert_with_loss(body); break; case HDR_X400_RECEIVED: hdr_x400_received (body); break; case HDR_DEF_DELIV: hdr_def_deliv (body); break; case HDR_LAST_DELIV: hdr_latest_time (body); break; default: break; } /* -- switch -- */ } static void hdr_subject (str) char *str; { char buf[BUFSIZ]; if (Qstruct.ua_id != NULLCP) return; bzero (buf, sizeof buf); if (strlen(str) >= ub_content_id_length) { (void) strncat (buf, str, (ub_content_id_length-strlen("..."))); (void) strcat (buf, "..."); } else (void) strcat (buf, str); Qstruct.ua_id = strdup (buf); ua_id_set_by_subject = TRUE; } static void hdr_x400_content_id (str) char *str; { char buf[BUFSIZ]; if (Qstruct.ua_id != NULLCP) free(Qstruct.ua_id); bzero (buf, sizeof buf); if (strlen(str) >= ub_content_id_length) { (void) strncat (buf, str, (ub_content_id_length-strlen("..."))); (void) strcat (buf, "..."); } else (void) strncat (buf, str, strlen(str)); Qstruct.ua_id = strdup (buf); } static void hdr_priority (str) char *str; { compress(str, str); if (lexequ(str, "normal") == 0) Qstruct.priority = PRIO_NORMAL; else if (lexequ(str, "urgent") == 0) Qstruct.priority = PRIO_URGENT; else if (lexequ(str, "non-urgent") == 0 || lexequ(str, "nonurgent") == 0) Qstruct.priority = PRIO_NONURGENT; } static void hdr_dl_history (str) char *str; { register DLHistory *dlp; char *start, *end, *tmp; tmp = strdup (str); start = tmp; compress(start, start); while (start != NULLCP && *start != '\0') { dlp = (DLHistory *) smalloc (sizeof(DLHistory)); bzero ((char *)dlp, sizeof(*dlp)); end = start; while (!isspace(*end)) end++; *end++ = '\0'; dlp -> dlh_addr = strdup(start); while (isspace(*end)) end++; start = end; if (*start = '(') { start++; if ((end = index(start, ')')) == NULLCP) return; *end++ = '\0'; if (rfc2UTC(start, &dlp -> dlh_time) != OK) return; start = end; } dlp -> dlh_next = Qstruct.dl_expansion_history; Qstruct.dl_expansion_history = dlp; } free(tmp); } static void hdr_conversion (str) char *str; { compress (str, str); if (lexequ (str, "prohibited") == 0) Qstruct.implicit_conversion = 1; } static void hdr_convert_with_loss (str) char *str; { compress (str, str); if (lexequ (str, "prohibited") == 0) Qstruct.conversion_with_loss_prohibited = 1; } static void hdr_x400_received (str) char *str; { Trace *trace; PP_DBG (("submit/hdr_x400_received (%s)", str)); trace = (Trace *) smalloc (sizeof(Trace)); bzero ((char *) trace, sizeof(*trace)); if (rfc2x400trace (trace, str) == OK) { PP_DBG (("rfc2x400trace OK")); trace -> trace_next = Qstruct.trace; Qstruct.trace = trace; } else free((char *) trace); } static void hdr_def_deliv (str) char *str; { if (Qstruct.defertime != 0) /* don't override */ return; if (rfc2UTC (str, &Qstruct.defertime) != OK) /* ignore */ Qstruct.defertime = 0; } static void hdr_latest_time (str) char *str; { if (Qstruct.latest_time != 0) /* don't override */ return; if (rfc2UTC (str, &Qstruct.latest_time) != OK) Qstruct.latest_time = 0; else /* assume if present then critical */ Qstruct.latest_time_crit = Q_LATESTTIME; } static void hdr_date (str) char *str; { Trace *tp; char *adr = NULL; OR_ptr or; tp = (Trace *) smalloc (sizeof (Trace)); bzero ((char *)tp, sizeof(*tp)); if (rfc2UTC (str, &(tp -> trace_DomSinfo.dsi_time)) != OK) { PP_LOG(LLOG_EXCEPTIONS, ("submit/hdr_date unable to convert time to UTC '%s'", str)); free((char *) tp); return; } tp->trace_DomSinfo.dsi_action = ACTION_RELAYED; if (Qstruct.Oaddress->ad_r400adr != NULL) { adr = strdup(Qstruct.Oaddress->ad_r400adr); if ((or = or_std2or(adr)) == NULLOR) { PP_LOG(LLOG_EXCEPTIONS, ("submit/hdr_date unable to get OR tree for orig '%s'", Qstruct.Oaddress->ad_r400adr)); free((char *)adr); } } if (or == NULL && Qstruct.Oaddress->ad_r822adr != NULL) { adr = strdup(Qstruct.Oaddress->ad_r822adr); if (or_rfc2or_aux (adr, &or, CH_UK_PREF) == NOTOK) { PP_LOG(LLOG_EXCEPTIONS, ("submit/hdr_date unable to get OR tree for orig '%s'", Qstruct.Oaddress->ad_r822adr)); free ((char *) adr); } } if (or == NULL || fillin_DomId (&tp -> trace_DomId, or, adr) == NOTOK) { PP_LOG(LLOG_EXCEPTIONS, ("submit/hdr_date unable to create gld for orig")); free ((char *) tp); } or_free(or); free(adr); tp -> trace_next = Qstruct.trace; Qstruct.trace = tp; } static void hdr_date_987 (str) char *str; { Trace *tp; UTC *utc; UTC nutc; tp = gettrace (); utc = &tp -> trace_DomSinfo.dsi_time; if (rfc2UTC (str, &nutc) == OK) { if (*utc) free ((char *)*utc); *utc = nutc; } else if (*utc == NULLUTC) *utc = utcnow (); } static void hdr_x400_mts_id (str) char *str; { if (Qstruct.msgid.mpduid_string != NULL) MPDUid_free(&Qstruct.msgid); rfc2msgid(&Qstruct.msgid, str); } static void hdr_orig_eit (str) char *str; { if (Qstruct.orig_encodedinfo.eit_types != NULL) /* override */ encodedinfo_free (&Qstruct.orig_encodedinfo); rfc2encinfo (&Qstruct.orig_encodedinfo, str); } static void hdr_msgid (str) char *str; { MPDUid *mp; if (Qstruct.msgid.mpduid_string == NULL) MPDUid_new (&Qstruct.msgid); mp = &Qstruct.msgid; if (mp -> mpduid_string != NULLCP) free (mp -> mpduid_string); compress (str, str); mp -> mpduid_string = strdup (str); } static Trace *gettrace () { Trace *tp; if (Qstruct.trace == (Trace *)NULL) trace_add (&Qstruct.trace, trace_new()); tp = Qstruct.trace; return tp; } static void hdr_via_987 (contents) char *contents; { char *argv [25]; char *datestart; char extraspace [LINESIZE]; UTC utc; PP_DBG (("submit/hdr_via (%s)", contents)); trace_count ++; if (ch_inbound -> ch_access == CH_MTS) err_abrt (RP_MECH, "No trace information allowed for local submission"); if (trace_count == 1) return;/* we've added the first trace! */ if ((datestart = index (contents, ';')) != NULL) *datestart++ = '\0'; /* -- rip out the comments -- */ *extraspace = '\0'; hdr_remcomm (contents, extraspace); if (datestart) hdr_remcomm (datestart, extraspace); (void) sstr2arg (contents, 25, argv, ",\t "); if (datestart == NULLCP || rfc2UTC (datestart, &utc) == NOTOK) utc = utcnow (); hdr_trace ((char *)NULL, argv [0], utc, extraspace); } /* -- take comments from 'from' & add to 'to' leaving 'from' without any -- */ static void hdr_remcomm (from, to) char *from; char *to; { char *start = from, *r = to, *s, *p, *q; if (start) { /* -- in case of NULL start ie missing date -- */ PP_DBG (("submit/hdr_remcomm (%s,%s)", from, to)); /* -- get to end -- */ while (*r != '\0') r++; for (p = start ; (p = index (p, '(')) ;) { if ((q = index (p, ')')) == NULLCP) { *p = '\0'; break; } if (*to != '\0') *r++ = ' '; for (s = p; s <= q; *r++ = *s++); (void) strcpy (p, q+1); } /* -- for -- */ *r = '\0'; (void) compress (from, from); } /* -- if -- */ else PP_DBG (("submit/hdr_remcomm (NULL, %s)",to)); } static void hdr_via (contents) char *contents; { register Trace *tp; char *datestart = NULLCP, *argv[25], *domain, extraspace[LINESIZE]; OR_ptr or; PP_DBG (("submit/hdr_via (%s)", contents)); trace_count++; if (ch_inbound -> ch_access == CH_MTS) err_abrt (RP_MECH, "No trace information allowed for local submission"); if (trace_count == 1) return;/* we've added the first trace! */ /* -- rip out the comments -- */ *extraspace = '\0'; hdr_remcomm (contents, extraspace); if ((datestart = index (contents, ';')) != NULLCP) *datestart++ = '\0'; if (sstr2arg (contents, 25, argv, ",\t ") < 1 || argv[0] == NULLCP) return; domain = strdup(argv[0]); if (or_rbits2or ("pp", domain, &or) == NOTOK) { PP_TRACE(("unable to parse domain '%s' to OR tree", argv[0])); return; } tp = (Trace *) smalloc (sizeof (Trace)); bzero ((char *)tp, sizeof(*tp)); if (fillin_DomId (&tp -> trace_DomId, or, argv[0]) == NOTOK){ free ((char *) tp); return; } or_free(or); free(domain); tp -> trace_mta = strdup(argv[0]); if (datestart == NULLCP || rfc2UTC(datestart,&(tp->trace_DomSinfo.dsi_time)) == NOTOK) tp -> trace_DomSinfo.dsi_time = utcnow(); tp->trace_DomSinfo.dsi_action = ACTION_RELAYED; tp -> trace_next = Qstruct.trace; Qstruct.trace = tp; } static void hdr_rcv (contents) char *contents; { register Trace *tp; char *bystart = NULLCP, *datestart = NULLCP, *argv[25], *domain, extraspace[LINESIZE]; int argc, i; OR_ptr or; PP_DBG (("submit/hdr_rcv (%s)", contents)); trace_count++; if (ch_inbound -> ch_access == CH_MTS) err_abrt (RP_MECH, "No trace information allowed for local submission"); if (trace_count == 1) return;/* we've added the first trace! */ /* -- rip out the comments -- */ *extraspace = '\0'; hdr_remcomm (contents, extraspace); if ((datestart = index (contents, ';')) != NULLCP) *datestart++ = '\0'; argc = sstr2arg (contents, 25, argv, ",\t "); for (i = 0; i < argc; i++) { if (lexequ (argv [i], "by") == 0) { if (bystart == NULLCP && i < argc -1) { bystart = argv [++i]; continue; } } } if (bystart == NULLCP) return; domain = strdup(bystart); if (or_rbits2or ("pp", domain, &or) == NOTOK) { PP_TRACE(("unable to parse domain '%s' to OR tree", bystart)); return; } tp = (Trace *) smalloc (sizeof (Trace)); bzero ((char *)tp, sizeof(*tp)); if (fillin_DomId (&tp -> trace_DomId, or, bystart) == NOTOK){ free ((char *) tp); return; } or_free(or); free(domain); tp -> trace_mta = strdup(bystart); if (datestart == NULLCP || rfc2UTC(datestart,&(tp->trace_DomSinfo.dsi_time)) == NOTOK) tp -> trace_DomSinfo.dsi_time = utcnow(); tp->trace_DomSinfo.dsi_action = ACTION_RELAYED; tp -> trace_next = Qstruct.trace; Qstruct.trace = tp; } static void hdr_rcv_987 (contents) char *contents; { char *cur_host = NULLCP, *prev_host = NULLCP, *argv [25], *datestart, extraspace [LINESIZE]; int argc, ind; UTC utc; PP_DBG (("submit/hdr_rcv (%s)", contents)); trace_count ++; if (ch_inbound -> ch_access == CH_MTS) err_abrt (RP_MECH, "No trace information allowed for local submission"); if ((datestart = index (contents, ';')) != NULLCP) *datestart++ = '\0'; /* -- rip out the comments -- */ *extraspace = '\0'; hdr_remcomm (contents, extraspace); argc = sstr2arg (contents, 25, argv, ",\t "); for (ind = 0 ; ind < argc ; ind++) { if (lexequ ("from", argv [ind]) == 0) { if (prev_host == NULLCP && ind < argc - 1) { prev_host = argv [++ind]; continue; } } else if (lexequ (argv [ind], "by") == 0) { if (cur_host == NULLCP && ind < argc -1) { cur_host = argv [++ind]; continue; } } if (*extraspace) (void) strcat (extraspace, " "); (void) strcat (extraspace, argv [ind]); } /* -- for completed -- */ if (datestart) hdr_remcomm (datestart, extraspace); if (datestart == NULLCP || rfc2UTC (datestart, &utc) == NOTOK) utc = utcnow (); hdr_trace (cur_host, prev_host, utc, extraspace); } /* -- put the trace info into a trace structure -- */ static void hdr_trace (cur_host, prev_host, prev_time, extra) char *cur_host, *prev_host; UTC prev_time; char *extra; { register Trace *tp; char tbuf [LINESIZE]; PP_DBG (("submit/hdr_trace (%s, %s, %s)", cur_host, prev_host, extra)); if (cur_host == NULLCP && prev_host == NULLCP) return; tp = (Trace*) smalloc (sizeof (Trace)); bzero ((char *)tp, sizeof (*tp)); tp -> trace_DomId.global_Country = strdup (""); if (cur_host != NULLCP) tp->trace_DomId.global_Admin = strdup (cur_host); (void) compress (extra, extra); if (prev_host != NULLCP || *extra) { if (*extra && prev_host) (void) sprintf (tbuf, "%s %s", prev_host, extra); else if (*extra) (void) strcpy (tbuf, extra); else (void) strcpy (tbuf, prev_host); tp->trace_DomSinfo.dsi_attempted_md.global_Admin = strdup (tbuf); } tp->trace_DomSinfo.dsi_time = prev_time; tp->trace_DomSinfo.dsi_action = ACTION_RELAYED; tp -> trace_next = Qstruct.trace; Qstruct.trace = tp; /* trace_add (&Qstruct.trace, tp);*/ } static int getline (bp, fp) char **bp; FILE *fp; { static char *buf; static int bufsiz = 0; int count; char *cp; int c; if (buf == NULLCP) buf = smalloc (bufsiz = BUFSIZ); for (cp = buf, count = 0; ; count ++) { if (count >= bufsiz - 5) { int curlen = cp - buf; buf = realloc (buf, (unsigned) (bufsiz += BUFSIZ)); if (buf == NULL) err_abrt (RP_LIO, "Out of memeory"); cp = buf + curlen; } switch (c = getc (fp)) { case '\n': *cp ++ = ' '; if ((c = getc(fp)) == ' ' || c == '\t') continue; ungetc (c, fp); break; case EOF: if (cp == buf) return NOTOK; break; default: *cp ++ = c; continue; } break; } *cp = '\0'; *bp = buf; return OK; } static int fillin_DomId (domId, or, str) GlobalDomId *domId; OR_ptr or; char *str; { OR_ptr tmp_or; if ((tmp_or = or_find (or, OR_C, NULLCP)) == NULLOR) { PP_LOG(LLOG_EXCEPTIONS, ("submit/fillin_DomId: no country in '%s'", str)); return NOTOK; } domId->global_Country = strdup(tmp_or -> or_value); if ((tmp_or = or_find (or, OR_ADMD, NULLCP)) == NULLOR) { PP_LOG(LLOG_EXCEPTIONS, ("submit/fillin_DomId: no ADMD in '%s'", str)); free ((char *) domId -> global_Country); return NOTOK; } domId->global_Admin = strdup(tmp_or -> or_value); if ((tmp_or = or_find (or, OR_PRMD, NULLCP)) != NULLOR) domId->global_Private = strdup(tmp_or -> or_value); return OK; }