|
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 w
Length: 43147 (0xa88b) Types: TextFile Names: »write_report.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z« └─⟦e5a54fb17⟧ └─⟦this⟧ »pp-5.0/Chans/dr2rfc/write_report.c«
/* write_report.c - Writes the DR struct as a Message -- */ # ifndef lint static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Chans/dr2rfc/RCS/write_report.c,v 5.0 90/09/20 15:47:12 pp Exp Locker: pp $"; # endif /* * $Header: /cs/research/pp/hubris/pp-beta/Chans/dr2rfc/RCS/write_report.c,v 5.0 90/09/20 15:47:12 pp Exp Locker: pp $ * * $Log: write_report.c,v $ * Revision 5.0 90/09/20 15:47:12 pp * rcsforce : 5.0 public release * */ /* --- *** --- * These routines create 2 text files containing body part info: * The files are called "hdr.822.uk" and "1.ia5". These files are * placed by submit into the $Q/msg directory * --- *** --- */ #include "head.h" #include "q.h" #include "or.h" #include "dr.h" #include "tb_bpt84.h" #include <isode/cmd_srch.h> #include <isode/usr.dirent.h> #include <sys/file.h> extern CHAN *mychan; extern CMD_TABLE bptbl_body_parts84 [/* body part types */]; extern char *this_msg, *loc_or, *loc_dom, *loc_dom_mta, *loc_dom_site, *mquedir, *postmaster, *hdr_822_bp, *ia5_bp, *recip_err, *cont_822, error[]; extern Q_struct *PPQuePtr; extern int order_pref; extern void msgid2rfc(), reprecip2rfc(), rfctxtfold(), globalid2rfc(), encinfo2rfc(); extern UTC utclocalise(); static int wr_hdr_rest (); static void new_printablestr (); static int rrinfo2str (); static int get_DR (); static int end_admin_info(), start_admin_info(); static int wr_hdr_end (); static int wr_body (); static int copy (); static int DR_print (); static int DR_write (); static DRmpdu DRstruct; static char *getSubject(); static int write_start(), write_cont(), write_end(); static ADDR *to; static int linecopy(); static int do_subject_intermediate_trace(); static int get822Mailbox(), getMailbox(), allSameType(), allSameMta(); static char message[BUFSIZ*2]; /* -- holds the Recip info -- */ extern CMD_TABLE rr_rcode[], rr_dcode[], rr_tcode[]; static CMD_TABLE rr_dcode_eng [] = { /* -- diagnostic-codes -- */ "Bad Address", DRD_UNRECOGNISED_OR, "Ambiguous Address", DRD_AMBIGUOUS_OR, "Message rejected due to congestion", DRD_MTA_CONGESTION, "Message looping detected (please contact local administrator)", DRD_LOOP_DETECTED, "Recipient's Mailbox unavailable", DRD_UA_UNAVAILABLE, "Message timed out", DRD_MAX_TIME_EXPIRED, "Some of your message could not be displayed by the recipient's system", DRD_ENCINFOTYPES_NOTSUPPORTED, "The message is too big for delivery", DRD_CONTENT_TOO_LONG, "Unable to perform the conversion required for delivery", DRD_CONVERSION_IMPRACTICAL, "Not allowed to perform the conversion required for delivery", DRD_CONVERSION_PROHIBITED, "Don't know how to convert for delivery", DRD_IMPLICITCONV_NOTREGISTERED, "One or more of the message parameters is invalid", DRD_INVALID_PARAMETERS, "A syntax error was detected in the header of the message", DRD_CONTENT_SYNTAX_ERROR, "X.400 protocol error - constraint violation (please contact local administrator)", DRD_SIZE_CONSTRAINT_VIOLATION, "X.400 protocol error - missing argument (please contact local administrator)", DRD_PROTOCOL_VIOLATION, "The recipient site could not handle the content type of the message", DRD_CONTENT_TYPE_NOT_SUPPORTED, "The message specified too many recipients for the system to cope with", DRD_TOO_MANY_RECIPIENTS, "Incompatibility between two sites on the route of the message (please contact local administrator)", DRD_NO_BILATERAL_AGREEMENT, "A critical function required for the transfer or delivery of the message is not supported by the originating site of this report", DRD_UNSUPPORTED_CRITICAL_FUNCTION, "Not allowed to perform the conversion required for delivery as it would result in loss of information", DRD_CONVERSION_WITH_LOSS_PROHIBITED, "Some lines of the message were too long to be delivered", DRD_LINE_TOO_LONG, "Some pages of the message were too long to be delivered", DRD_PAGE_SPLIT, "Some pictorial symbols would have been lost if the message was delivered", DRD_PICTORIAL_SYMBOL_LOSS, "Some punctuation symbols would have been lost if the message was delivered", DRD_PUNCTUATION_SYMBOL_LOSS, "Some alphabetic characters would have been lost if the message was delivered", DRD_ALPHABETIC_CHARACTER_LOSS, "Some information would have been lost if the message was delivered", DRD_MULTIPLE_INFORMATION_LOSS, "The message could not be delivered because the originator of the message prohibited redirection", DRD_RECIPIENT_REASSIGNMENT_PROHIBITED, "The message could not be redirected to an alternate recipient because that recipient had previously redirected the message (redirection loop)", DRD_REDIRECTION_LOOP_DETECTED, "The message could not be delivered because the originator of the message prohibited the expansion of distribution lists", DRD_DL_EXPANSION_PROHIBITED, "The originator of the message does not have permission to submit messages to the recipient distribution list", DRD_NO_DL_SUBMIT_PERMISSION, "The expansion of a distribution list could not be completed", DRD_DL_EXPANSION_FAILURE, "The postal access unit does not support the physical format required", DRD_PHYSICAL_RENDITION_ATTRIBUTES_NOT_SUPPORTED, "The message was undeliverable because the specified recipient postal address was incorrect", DRD_UNDLIV_PD_ADDRESS_INCORRECT, "The message was undeliverable because the physical delivery office identified by the specified postal address was incorrect or invalid", DRD_UNDLIV_PD_OFFICE_INCORRECT_OR_INVALID, "The message was undeliverable because the specified recipient postal address was incompletely specified", DRD_UNDLIV_PD_ADDRESS_INCOMPLETE, "The message was undeliverable because the recipient specified in the postal address was not known at that address", DRD_UNDLIV_RECIPIENT_UNKNOWN, "The message was undeliverable because the recipient specified in the postal address is deceased", DRD_UNDLIV_RECIPIENT_DECEASED, "The message was undeliverable because the recipient organization specified in the postal address is no longer registered", DRD_UNDLIV_ORGANIZATION_EXPIRED, "The message was undeliverable because the recipient specified in the postal address refused to accept it", DRD_UNDLIV_RECIPIENT_REFUSED_TO_ACCEPT, "The message was undeliverable because the recipient specified in the postal address did not collect the mail", DRD_UNDLIV_RECIPIENT_DID_NOT_CLAIM, "The message was undeliverable because the recipient specified in the postal address had changed address permanently ('moved') and forwarding was not applicable", DRD_UNDLIV_RECIPIENT_CHANGED_ADDRESS_PERMANENTLY, "The message was undeliverable because the recipient specified in the postal address had changed address temporarily ('on holiday') and forwarding was not applicable", DRD_UNDLIV_RECIPIENT_CHANGED_ADDRESS_TEMPORARILY, "The message was undeliverable because the recipient specified in the postal address had changed temporary address ('departed') and forwarding was not applicable", DRD_UNDLIV_RECIPIENT_CHANGED_TEMPORARY_ADDRESS, "The message was undeliverable because the recipient has moved and the recipient's new address is unknown", DRD_UNDLIV_NEW_ADDRESS_UNKNOWN, "The message was undeliverable because delivery would have required physical forwarding which the recipient did not want", DRD_UNDLIV_RECIPIENT_DID_NOT_WANT_FORWARDING, "The physical forwarding required for the message to be delivered has been prohibited by the originator of the message", DRD_UNDLIV_ORIGINATOR_PROHIBITED_FORWARDING, "The message could not be progressed because it would violate the security policy in force", DRD_SECURE_MESSAGING_ERROR, "The downgrading of the message's content required for delivery could not be performed", DRD_UNABLE_TO_DOWNGRADE, 0, -1 }; int dirlen; /* --------------------- Begin Routines -------------------------------- */ write_report (ap, DRno, recip) ADDR *ap; int DRno; ADDR *recip; { int retval = RP_BAD; PP_TRACE (("write_report: %s (%d) (%s)", ap->ad_value, DRno, this_msg)); if (ap == NULLADDR) return retval; else to = ap; /* -- initialise -- */ bzero (message, sizeof (message)); dr_init (&DRstruct); if (rp_isbad (get_DR (DRno))) goto write_report_end; if (rp_isbad (wr_hdr_start())) goto write_report_end; if (rp_isbad (wr_hdr_rest())) goto write_report_end; if (rp_isbad (wr_hdr_end())) goto write_report_end; if (rp_isbad (wr_body(ap, recip))) goto write_report_end; retval = RP_OK; write_report_end: ; dr_free (&DRstruct); if (recip_err) { free(recip_err); recip_err = NULLCP; } return retval; } /* -------------------- Static Routines ------------------------------- */ static int write_p1_trace (trace) Trace *trace; { char abuf[BUFSIZ]; if (trace == NULL) return RP_OK; if (rp_isbad(write_p1_trace (trace -> trace_next))) return RP_BAD; x400trace2rfc (trace, abuf); if (rp_isbad(DR_write("X400-Received: ",abuf))) return RP_BAD; return RP_OK; } wr_postmaster_hdr() { char buf[BUFSIZ], temp[BUFSIZ], part[BUFSIZ]; RP_Buf rps, *rp = &rps; UTC now, localnow; PP_TRACE(("dr2rfc/wr_postmaster_hdr()")); if (rp_isbad (io_tpart (hdr_822_bp, FALSE, rp))) { PP_LOG (LLOG_EXCEPTIONS, ("dr2rfc/wr_hdr/io_tpart blows %s", rp -> rp_line)); stop_io(); (void) sprintf (error, "io_tpart error [%s]", rp -> rp_line); return RP_BAD; } if (rp_isbad (DR_write ("From: ", postmaster))) return RP_BAD; /* -- To -- */ if (rp_isbad (DR_write ("To: ", postmaster))) return RP_BAD; /* -- Subject -- */ if (adr2rfc (to, temp, order_pref) == RP_BAD) return RP_BAD; (void) sprintf (buf, "Unable to send delivery report to %s", temp); if (rp_isbad (DR_write ("Subject: ", buf))) return RP_BAD; now = utcnow(); localnow = utclocalise(now); UTC2rfc(localnow, buf); if (now) free((char *) now); if (localnow) free((char *) localnow); if (rp_isbad (DR_write ("Date: ", buf))) return RP_BAD; if (rp_isbad (io_tdend (rp))) { PP_LOG (LLOG_EXCEPTIONS, ("dr2rfc/wr_hdr_end/tdend blows %s", rp -> rp_line)); (void) sprintf (error, "io_tdend error [%s]", rp -> rp_line); stop_io(); return RP_BAD; } (void) sprintf(part, "1.%s", ia5_bp); if (rp_isbad (io_tpart (part, FALSE, rp))) { PP_TRACE (("dr2rfc/wr_body/tpart blows %s", rp -> rp_line)); (void) sprintf (error, "io_tpart error [%s]", rp -> rp_line); stop_io(); return RP_BAD; } (void) sprintf(buf, "%s was unable to construct a delivery report\n\taddressed to '%s'.\nThe reason given was '%s'.\n\nThe delivery report follows:\n\n", mychan->ch_name, temp, recip_err); if (rp_isbad(io_tdata (buf, strlen(buf)))) { PP_LOG (LLOG_EXCEPTIONS, ("Error writing message")); (void) sprintf(error, "io_tdata error [%s]", rp -> rp_line); stop_io(); return RP_BAD; } if (rp_isbad (io_tdend (rp))) { PP_LOG (LLOG_EXCEPTIONS, ("dr2rfc/wr_body/io_tdend fails")); (void) sprintf (error, "io_tdend error"); stop_io(); return RP_BAD; } return RP_OK; } wr_hdr_start () { RP_Buf rps, *rp = &rps; char buffer[BUFSIZ], part[BUFSIZ], *pmailbox; UTC now, localnow; Rrinfo *ix; if (rp_isbad (io_tinit (rp))) { PP_LOG (LLOG_EXCEPTIONS, ("dr2rfc/wr_hdr/tinit blows %s", rp -> rp_line)); (void) sprintf (error, "io_tinit error [%s]", rp -> rp_line); stop_io(); return RP_BAD; } if (recip_err != NULLCP) { if (rp_isbad(wr_postmaster_hdr())) return RP_BAD; (void) sprintf(part, "2.ipm/%s", hdr_822_bp); } else (void) sprintf(part, "%s", hdr_822_bp); if (rp_isbad (io_tpart (part, FALSE, rp))) { PP_LOG (LLOG_EXCEPTIONS, ("dr2rfc/wr_hdr/io_tpart blows %s", rp -> rp_line)); (void) sprintf (error, "io_tpart error [%s]", rp -> rp_line); stop_io(); return RP_BAD; } if (DRstruct.dr_trace != NULL && DRstruct.dr_trace -> trace_next != NULL) /* not local (x400 ?) */ if (rp_isbad(write_p1_trace(DRstruct.dr_trace))) return RP_BAD; /* -- From -- */ if (rp_isbad (DR_write ("From: ", postmaster))) return RP_BAD; /* -- To -- */ if (adr2rfc (to, buffer, order_pref) == RP_BAD) return RP_BAD; if (rp_isbad (DR_write ("To: ", buffer))) return RP_BAD; /* -- Subject -- */ (void) sprintf (buffer, "Delivery Report"); ix = DRstruct.dr_recip_list; if (allSameType(ix, DR_REP_SUCCESS) == TRUE) sprintf (buffer, "%s (success)", buffer); else if (allSameType(ix, DR_REP_FAILURE) == TRUE) sprintf (buffer, "%s (failure)", buffer); if (ix && ix->rr_next == NULL && !rp_isbad(get822Mailbox(ix, &pmailbox))) { sprintf (buffer, "%s for %s", buffer, pmailbox); free(pmailbox); } else if (allSameMta(ix, &pmailbox) == TRUE) { sprintf (buffer, "%s for MTA %s", buffer, pmailbox); free(pmailbox); } if (rp_isbad (DR_write ("Subject: ", buffer))) return RP_BAD; if (rp_isbad(DR_write("Message-Type: ", "Delivery Report"))) return RP_BAD; now = utcnow(); localnow = utclocalise(now); UTC2rfc(localnow, buffer); if (now) free((char *) now); if (localnow) free((char *) localnow); if (rp_isbad (DR_write ("Date: ", buffer))) return RP_BAD; return RP_OK; } static int wr_hdr_rest () { char buffer [BUFSIZ], fbuf [BUFSIZ]; PP_TRACE (("dr2rfc/wr_hdr_rest ()")); /* -- P1-Message-ID -- */ if (DRstruct.dr_mpduid && DRstruct.dr_mpduid->mpduid_string) { (void) sprintf (fbuf, "Message-ID: "); (void) sprintf (buffer, "<\"%s\"@%s>", DRstruct.dr_mpduid->mpduid_string, loc_dom_site); if (rp_isbad (DR_write (fbuf, buffer))) return RP_BAD; } /* -- UAContentId (optional) -- */ if (PPQuePtr -> ua_id) { (void) sprintf (fbuf, "Content-Identifier: "); if (rp_isbad (DR_write (fbuf, PPQuePtr -> ua_id))) return RP_BAD; } return RP_OK; } static void new_printablestr (buffer) char *buffer; { time_t t, time(); struct tm *tp; PP_TRACE (("dr2rfc/new_printablestr()")); t = time((time_t *)0); tp = gmtime(&t); (void) sprintf(buffer, "%d:%02d.%02d.%02d.%02d.%02d.%02d", getpid(), tp->tm_mday, tp->tm_mon, tp->tm_year+70, tp->tm_hour, tp->tm_min, tp->tm_sec); } static rrinfo2str (key, rp) char *key; Rrinfo *rp; { ADDR *ad; PP_TRACE (("rrinfo2str (%s %d)", key, rp->rr_recip)); for (ad = PPQuePtr -> Raddress; ad; ad = ad->ad_next) if (ad -> ad_no == rp -> rr_recip) break; if (ad == NULLADDR) return NOTOK; /* -- write message -- */ (void) strcat (message, "Recipient: "); (void) strcat (message, ad -> ad_r400adr); (void) strcat (message, " - "); if (rp->rr_report.rep_type == DR_REP_SUCCESS) (void) strcat (message, "Successfully Delivered"); else (void) strcat (message, "Not Delivered"); (void) strcat (message, "\n"); return OK; } static int get_DR (DRno) int DRno; { int retval; PP_TRACE (("get_DR for %s (%d)", this_msg, DRno)); retval = get_dr (DRno, this_msg, &DRstruct); if (rp_isbad(retval) && retval != RP_EOF) goto get_DR_free; return (RP_OK); get_DR_free: ; return RP_BAD; } static wr_hdr_end() { RP_Buf rps, *rp = &rps; PP_TRACE (("dr2rfc/wr_hdr_end()")); if (rp_isbad (io_tdend (rp))) { PP_LOG (LLOG_EXCEPTIONS, ("dr2rfc/wr_hdr_end/tdend blows %s", rp -> rp_line)); (void) sprintf (error, "io_tdend error [%s]", rp -> rp_line); stop_io(); return RP_BAD; } return RP_OK; } #define DEFAULT_MAX_INCLUDE 5000 #define DEFAULT_NUM_INCLUDE_LINES 10 static long max_include_msg = DEFAULT_MAX_INCLUDE; static int num_include_lines = DEFAULT_NUM_INCLUDE_LINES; static wr_body (ap, recip) ADDR *ap; ADDR *recip; { RP_Buf rps, *rp = &rps; char *dir = NULLCP; char filename[FILNSIZE], *pmailbox, *cix, buffer[BUFSIZ], buffer2[BUFSIZ], part[BUFSIZ], temp[BUFSIZ]; int retval, avail, correlator, Thisreport, nosubject = FALSE; Rrinfo *ix; ADDR *ad; UTC now; UTC localtime; if (recip_err != NULLCP) (void) sprintf(part, "2.ipm/1.%s", ia5_bp); else (void) sprintf(part, "1.%s", ia5_bp); if (rp_isbad (io_tpart (part, FALSE, rp))) { PP_LOG(LLOG_EXCEPTIONS, ("dr2rfc/wr_body/tpart blows %s", rp -> rp_line)); (void) sprintf (error, "io_tpart error [%s]", rp -> rp_line); stop_io(); return RP_BAD; } /* dr-summary */ if (PPQuePtr -> pp_content_correlator == NULL && PPQuePtr -> ua_id == NULL) correlator = FALSE; else correlator = TRUE; if (correlator == TRUE) { if (rp_isbad(write_start("This report relates to your message:", ""))) return RP_BAD; /* content correlator */ if (pretty_output((PPQuePtr -> pp_content_correlator) ? PPQuePtr -> pp_content_correlator : PPQuePtr -> ua_id) == RP_BAD) return RP_BAD; } else { char *subject; if ((subject = getSubject(this_msg, recip)) != NULLCP) { if (rp_isbad(write_start("This report relates to your message with subject:", subject))) return RP_BAD; free(subject); } else if (rp_isbad(write_start("This report relates to your message", ""))) { nosubject = TRUE; return RP_BAD; } } if (DRstruct.dr_subject_intermediate_trace != NULL) { Trace *tix = DRstruct.dr_subject_intermediate_trace; while (tix->trace_next != NULL) tix = tix->trace_next; localtime = utclocalise(tix->trace_DomSinfo.dsi_time); UTC2rfc(localtime, temp); if (localtime) free((char *) localtime); (void) sprintf(buffer, "of %s\n",temp); if (rp_isbad(write_cont(buffer, FALSE))) return RP_BAD; } if (nosubject == TRUE && rp_isbad(write_cont("(no subject)", FALSE))) return RP_BAD; if (rp_isbad(write_end())) return RP_BAD; /* dr-recipients */ ix = DRstruct.dr_recip_list; while (ix != NULL) { if (rp_isbad(get822Mailbox(ix, &pmailbox))) return RP_BAD; if (ix -> rr_report.rep_type == DR_REP_SUCCESS) { if (rp_isbad(write_start("Your message was successfully delivered to", ""))) return RP_BAD; if (rp_isbad(write_cont(pmailbox))) return RP_BAD; if (rp_isbad(write_end())) return RP_BAD; } else { char *diag; if (rp_isbad(write_start("Your message was not delivered to ", ""))) return RP_BAD; if (rp_isbad(write_cont(pmailbox))) return RP_BAD; if (rp_isbad(write_cont("for the following reason:", FALSE))) return RP_BAD; if ((diag = rcmd_srch(ix -> rr_report.rep.rep_ndinfo.nd_dcode, rr_dcode_eng)) != NULL) (void) sprintf(buffer, "%s", diag); else (void) sprintf(buffer, "%s", rcmd_srch(ix -> rr_report.rep.rep_ndinfo.nd_rcode, rr_rcode)); if (rp_isbad(write_cont(buffer, TRUE))) return RP_BAD; if (ix-> rr_supplementary) { (void) sprintf (buffer, "%s", ix -> rr_supplementary); if (rp_isbad(write_cont(ix -> rr_supplementary, TRUE))) return RP_BAD; } if (rp_isbad(write_cont("\n", FALSE)) || rp_isbad(write_end())) return RP_BAD; } if (pmailbox != NULLCP) { free(pmailbox); pmailbox = NULLCP; } ix = ix -> rr_next; } start_admin_info(); Thisreport = FALSE; if (DRstruct.dr_trace != NULL) { Trace *tix = DRstruct.dr_trace; /* while (tix->trace_next != NULL) tix = ix->trace_next;*/ if (tix -> trace_mta != NULL) { (void) sprintf(buffer, "by mta %s", tix -> trace_mta); if (rp_isbad(write_start("DR generated",buffer))) return RP_BAD; Thisreport = TRUE; globalid2rfc(&(tix -> trace_DomId), temp); (void) sprintf(buffer, "in %s", temp); if (rp_isbad(write_cont(buffer, TRUE))) return RP_BAD; } else { globalid2rfc(&(tix -> trace_DomId), temp); (void) sprintf(buffer, "in %s", temp); if (rp_isbad(write_start("DR generated",buffer))) return RP_BAD; Thisreport = TRUE; } localtime = utclocalise (tix -> trace_DomSinfo.dsi_time); UTC2rfc(localtime, temp); if (localtime) free((char *) localtime); (void) sprintf(buffer,"at %s\n*",temp); if (rp_isbad(write_cont(buffer, FALSE)) || rp_isbad(write_end())) return RP_BAD; } now = utcnow(); localtime = utclocalise(now); UTC2rfc(localtime, temp); if (now) free((char *) now); if (localtime) free((char *) localtime); (void) sprintf(buffer, "at %s", loc_dom_mta); if (Thisreport == FALSE) { if (rp_isbad(write_start("Converted to RFC 822", buffer))) return RP_BAD; } else if (rp_isbad(write_start("Converted to RFC 822", buffer))) return RP_BAD; (void) sprintf(buffer, "at %s\n*", temp); if (rp_isbad(write_cont(buffer, FALSE)) || rp_isbad(write_end())) return RP_BAD; /* dr-extra-information */ (void) sprintf(buffer, "* Delivery Report Contents:\n*\n"); if (rp_isbad(io_tdata (buffer, strlen(buffer)))) { PP_LOG (LLOG_EXCEPTIONS, ("Error writing message")); (void) sprintf (error, "io_tdata error"); stop_io(); return RP_BAD; } /* drc-field-list */ globalid2rfc(&(PPQuePtr->msgid.mpduid_DomId), buffer2); if (PPQuePtr->msgid.mpduid_string != NULL) (void) sprintf(buffer, "[%s;%s]", buffer2, PPQuePtr->msgid.mpduid_string); else (void) sprintf(buffer, "[%s]", buffer2); if (rp_isbad (DR_write("Subject-Submission-Identifier: ", buffer))) return RP_BAD; if (PPQuePtr -> ua_id != NULL && rp_isbad (DR_print("Content-Identifier: ", PPQuePtr -> ua_id))) return RP_BAD; if (PPQuePtr -> cont_type != NULL && strcmp(PPQuePtr -> cont_type, cont_822) != 0 && rp_isbad (DR_print("Content-Type: ", PPQuePtr -> cont_type))) return RP_BAD; if (PPQuePtr -> orig_encodedinfo.eit_types != 0) { encinfo2rfc (&PPQuePtr -> orig_encodedinfo, &buffer[0]); if (buffer[0] != '\0') if (rp_isbad (DR_print("Original-Encoded-Information-Types: ", buffer))) return RP_BAD; } if (DRstruct.dr_subject_intermediate_trace != NULL) { if (rp_isbad(do_subject_intermediate_trace(DRstruct.dr_subject_intermediate_trace))) return RP_BAD; } if (DRstruct.dr_dl_history != NULL) { DLHistory *dlix = DRstruct.dr_dl_history; buffer[0] = '\0'; if (rp_isbad(write_start("Originator-and-DL-Expansion-History: ", ""))) return RP_BAD; while (dlix != NULL) { if (dlix->dlh_next != NULL) { (void) sprintf(buffer, "%s,", dlix -> dlh_addr); if (rp_isbad(write_cont(buffer, FALSE))) return RP_BAD; } else if (rp_isbad(write_cont(dlix -> dlh_addr, FALSE))) return RP_BAD; dlix = dlix -> dlh_next; } if (rp_isbad(write_end())) return RP_BAD; } if (DRstruct.dr_reporting_dl_name != NULL && DRstruct.dr_reporting_dl_name -> fn_addr != NULL && rp_isbad(DR_print("Reporting-DL-Name: ", DRstruct.dr_reporting_dl_name -> fn_addr))) return RP_BAD; if (PPQuePtr -> pp_content_correlator != NULL && rp_isbad(DR_print("Content-Correlator: ", PPQuePtr -> pp_content_correlator))) return RP_BAD; ix = DRstruct.dr_recip_list; while (ix != NULL) { char *str = NULLCP; for (ad = PPQuePtr -> Raddress; ad; ad = ad->ad_next) if (ad -> ad_no == ix -> rr_recip) break; if (ad == NULL) { PP_LOG(LLOG_EXCEPTIONS, ("unable to find recip '%d'", ix -> rr_recip)); return RP_BAD; } ap_s2s(ad -> ad_r822adr, &str, order_pref); if (str != NULLCP) { (void) sprintf(buffer, "%s,", str); free(str); } else (void) sprintf(buffer, "%s,", ad -> ad_r822adr); if (rp_isbad(write_start("Recipient-Info:", buffer))) return RP_BAD; (void) sprintf(buffer, "%s;", ad -> ad_r400adr); if (rp_isbad(write_cont(buffer, FALSE))) return RP_BAD; if (ix -> rr_report.rep_type == DR_REP_SUCCESS) { char delivered[BUFSIZ], *type; localtime = utclocalise (ix -> rr_report.rep.rep_dinfo.del_time); UTC2rfc(localtime, delivered); if (localtime) free ((char *) localtime); (void) sprintf(buffer, "SUCCESS delivered at %s;", delivered); if (rp_isbad(write_cont(buffer, FALSE))) return RP_BAD; if (ix -> rr_report.rep.rep_dinfo.del_type != 0 && (type = rcmd_srch(ix -> rr_report.rep.rep_dinfo.del_type, rr_tcode)) != NULL) { (void) sprintf(buffer, "type of MTS user %s (%d);", type, ix -> rr_report.rep.rep_dinfo.del_type); if (rp_isbad(write_cont(buffer, FALSE))) return RP_BAD; } } else { char *diag; (void) sprintf(buffer, "FAILURE reason %s (%d);", rcmd_srch(ix -> rr_report.rep.rep_ndinfo.nd_rcode, rr_rcode), ix -> rr_report.rep.rep_ndinfo.nd_rcode); if (rp_isbad(write_cont(buffer, FALSE))) return RP_BAD; if ((diag = rcmd_srch(ix -> rr_report.rep.rep_ndinfo.nd_dcode, rr_dcode)) != NULL) { (void) sprintf(buffer,"diagnostic %s (%d);", diag, ix -> rr_report.rep.rep_ndinfo.nd_dcode); if (rp_isbad(write_cont(buffer, FALSE))) return RP_BAD; } } if (DRstruct.dr_subject_intermediate_trace != NULL) { (void) sprintf(buffer,"last trace"); if (PPQuePtr -> encodedinfo.eit_types != 0) { encinfo2rfc(&PPQuePtr -> encodedinfo, &(temp[0])); (void) sprintf(buffer,"%s (%s)", buffer, temp); } localtime = utclocalise (DRstruct.dr_subject_intermediate_trace->trace_DomSinfo.dsi_time); UTC2rfc(localtime, &temp[0]); if (localtime) free ((char *) localtime); sprintf(buffer,"%s %s;",buffer, temp); if (rp_isbad(write_cont(buffer, FALSE))) return RP_BAD; } if (ix -> rr_converted != NULL) { encinfo2rfc (ix -> rr_converted, &temp[0]); if (temp[0] != '\0') { (void) sprintf(buffer, "converted eits %s;", temp); if (rp_isbad(write_cont(buffer, TRUE))) return RP_BAD; } } if (ix -> rr_originally_intended_recip != NULL) { (void) sprintf(buffer, "originally intended recipient %s, %s;", ix -> rr_originally_intended_recip -> fn_dn, ix -> rr_originally_intended_recip -> fn_addr); if (rp_isbad(write_cont(buffer, TRUE))) return RP_BAD; } if (ix -> rr_supplementary != NULL) { (void) sprintf(buffer, "supplementary info \"%s\";", ix -> rr_supplementary); if (rp_isbad(write_cont(buffer, TRUE))) return RP_BAD; } if (ix -> rr_redirect_history != NULL) { Redirection *rix = ix -> rr_redirect_history; temp[0] = '\0'; if (rp_isbad(write_cont("redirection history", FALSE))) return RP_BAD; while (rix != NULL) { if (rix -> rd_next != NULL) (void) sprintf(buffer, "%s,", rix -> rd_addr); else (void) sprintf(buffer, "%s;", rix -> rd_addr); if (rp_isbad(write_cont(buffer, TRUE))) return RP_BAD; rix = rix -> rd_next; } } if (ix -> rr_physical_fwd_addr != NULL) { (void) sprintf(buffer, "physical forwarding address %s;", ix -> rr_physical_fwd_addr -> fn_addr); if (rp_isbad(write_cont(buffer, FALSE))) return RP_BAD; } if (rp_isbad(write_end())) return RP_BAD; ix = ix -> rr_next; } end_admin_info(); /* dr-content-return */ /* if (PPQuePtr -> content_return_request != TRUE) { if (rp_isbad (io_tdend (rp)) || rp_isbad(io_tend(rp))) { PP_LOG(LLOG_EXCEPTIONS, ("wr_body/io_tend fails")); return RP_BAD; } else return RP_OK; } */ avail = FALSE; if (PPQuePtr -> content_return_request == TRUE) { while (avail != TRUE && recip->ad_rcnt >= 0) { if (qid2dir (this_msg, recip, TRUE, &dir) == NOTOK) { PP_LOG (LLOG_EXCEPTIONS, ("qid2dir failed")); dir = NULLCP; } else if (msg_rinit (dir) == NOTOK) PP_LOG (LLOG_EXCEPTIONS, ("msg_rinit failed")); else if ((retval = msg_rfile (filename)) == RP_OK) { if ((cix = rindex(filename, '/')) == NULLCP) cix = filename; else cix++; if (strncmp(cix, hdr_822_bp, strlen(hdr_822_bp)) != 0) { PP_LOG(LLOG_EXCEPTIONS, ("Unable to find a hdr.822 for original message")); msg_rend(); } else avail = TRUE; } else msg_rend(); if (avail == FALSE) { recip->ad_rcnt--; if (dir != NULLCP) free(dir); } } } if (avail == TRUE) { dirlen = strlen(dir) + 1; if (PPQuePtr -> msgsize <= max_include_msg) (void) sprintf(buffer, "\nThe Original Message follows:\n\n"); else (void) sprintf(buffer, "\nThe Original Message follows but for size reasons has been truncated:\n\n"); } else (void) sprintf(buffer, "\nThe Original Message is not available\n"); if (rp_isbad(io_tdata (buffer, strlen(buffer)))) { PP_LOG (LLOG_EXCEPTIONS, ("Error writing message")); (void) sprintf(error, "io_tdata error"); stop_io(); return RP_BAD; } if (rp_isbad (io_tdend (rp))) { PP_LOG (LLOG_EXCEPTIONS, ("dr2rfc/wr_body/io_tdend fails")); (void) sprintf(error, "io_tdend error"); stop_io(); return RP_BAD; } if (avail == FALSE) if (rp_isbad (io_tend (rp))) { PP_LOG (LLOG_EXCEPTIONS, ("dr2rfc/wr_body/io_tend fails")); (void) sprintf(error, "io_tend error"); stop_io(); return RP_BAD; } else return RP_OK; /* copy header no matter what size */ if (rp_isbad (retval = copy (filename))) { PP_LOG (LLOG_EXCEPTIONS, ("failed to copy header '%s'", filename)); (void) sprintf (error, "Failed to submit header '%s'", filename); return RP_BAD; } if (PPQuePtr -> msgsize <= max_include_msg) while ((retval = msg_rfile (filename)) == RP_OK) { if (rp_isbad (retval = copy (filename))) break; } else { int numLines = 0; while ((retval = msg_rfile (filename)) == RP_OK && numLines < num_include_lines) { if (rp_isbad (retval = linecopy (filename, &numLines))) break; } } if (dir) free(dir); if (rp_isbad (retval)) { PP_LOG (LLOG_EXCEPTIONS, ("message copy failed")); return RP_BAD; } if (rp_isbad (retval = msg_rend ())) { PP_LOG (LLOG_EXCEPTIONS, ("msg_rend () failed")); (void) sprintf (error, "msg_rend failed"); return RP_BAD; } if (rp_isbad (io_tend (rp))) { PP_LOG (LLOG_EXCEPTIONS, ("dr2rfc/wr_body/io_tend fails")); (void) sprintf (error, "io_tend failed"); stop_io(); return RP_BAD; } return RP_OK; } static int do_subject_intermediate_trace(trace) Trace *trace; { char *j, oldj, buffer[BUFSIZ]; if (trace->trace_next != NULL && rp_isbad(do_subject_intermediate_trace(trace->trace_next))) return RP_BAD; trace2rfc(trace, buffer); j = buffer; while (*j != '\0' && *j != ';') j++; if (*j != '\0') j++; oldj = *j; *j = '\0'; if (rp_isbad(write_start("Subject-Intermediate-Trace-Information: ", buffer))) return RP_BAD; if (oldj != '\0') { *j = oldj; if (rp_isbad(write_cont(j,FALSE))) return RP_BAD; } if (rp_isbad(write_end())) return RP_BAD; return RP_OK; } static int linecopy (file, pnumlines) char *file; int *pnumlines; { FILE *fp; RP_Buf rps, *rp = &rps; int retval = RP_OK; char buf[BUFSIZ], *ix; ix = file + dirlen; if (recip_err != NULLCP) (void) sprintf(buf, "2.ipm/2.ipm/%s", ix); else (void) sprintf(buf, "2.ipm/%s", ix); if (rp_isbad(io_tpart (buf, FALSE, rp))) { PP_TRACE (("dr2rfc/wr_body/tpart blows %s", rp -> rp_line)); stop_io(); return RP_BAD; } if ((fp = fopen (file, "r")) == NULL) { PP_SLOG (LLOG_EXCEPTIONS, file, ("Can't open file")); (void) sprintf (error, "Can't open file '%s'", file); stop_io(); return RP_FOPN; } while (*pnumlines < num_include_lines && fgets (buf, sizeof buf, fp) != NULL) { if (io_tdata (buf, strlen(buf)) != RP_OK) { PP_LOG (LLOG_EXCEPTIONS, ("io_tdata error")); (void) sprintf (error, "io_tdata error"); stop_io(); retval = RP_FIO; break; } (*pnumlines)++; } if (*pnumlines >= num_include_lines) { if (io_tdata("......(message truncated)\n", strlen("......(message truncated)\n")) != RP_OK) { PP_LOG (LLOG_EXCEPTIONS, ("io_tdata error")); (void) sprintf (error, "io_tdata error"); stop_io(); retval = RP_FIO; } } (void) fclose (fp); if (rp_isbad (io_tdend (rp))) { PP_LOG (LLOG_EXCEPTIONS, ("dr2rfc/wr_body/io_tdend fails")); (void) sprintf (error, "io_tdend fails"); stop_io(); return RP_BAD; } return retval; } static int copy (file) char *file; { FILE *fp; RP_Buf rps, *rp = &rps; int retval = RP_OK; extern char *hdr_822_bp; char buf[BUFSIZ], *ix, *top; int n; ix = strdup(file + dirlen); /* strip of following -us or -uk from hdr_822_bp's */ if ((top = rindex(ix, '/')) == NULLCP) top = ix; if (lexnequ(top, hdr_822_bp, strlen(hdr_822_bp)) == 0) *(top+strlen(hdr_822_bp)) = '\0'; if (recip_err != NULLCP) (void) sprintf(buf, "2.ipm/2.ipm/%s", ix); else (void) sprintf(buf, "2.ipm/%s", ix); free(ix); if (rp_isbad(io_tpart (buf, FALSE, rp))) { PP_LOG(LLOG_EXCEPTIONS, ("dr2rfc/wr_body/tpart blows %s", rp -> rp_line)); stop_io(); return RP_BAD; } if ((fp = fopen (file, "r")) == NULL) { PP_SLOG (LLOG_EXCEPTIONS, file, ("Can't open file")); (void) sprintf (error, "Can't open file '%s'", file); stop_io(); return RP_FOPN; } while ((n = fread (buf, sizeof (char), sizeof buf, fp)) > 0) { if (io_tdata (buf, n) != RP_OK) { PP_LOG (LLOG_EXCEPTIONS, ("io_tdata error")); (void) sprintf(error, "io_tdata error"); stop_io(); retval = RP_FIO; break; } } (void) fclose (fp); if (rp_isbad (io_tdend (rp))) { PP_LOG (LLOG_EXCEPTIONS, ("dr2rfc/wr_body/io_tdend fails")); (void) sprintf(error, "io_tdend fails"); stop_io(); return RP_BAD; } return retval; } #define DEFAULT_FOLD_LENGTH 70 int chnum, tab = 8, foldlength = DEFAULT_FOLD_LENGTH; static int admin_info = FALSE; static int start_admin_info () { write_start ("***** The following information is directed towards the local administrator\n***** and is not intended for the end user\n*", ""); write_end (); admin_info = TRUE; } static int end_admin_info() { admin_info = FALSE; write_start("****** End of administration information", ""); write_end(); } static int write_start(key, value) char *key, *value; { int retval; char buffer[BUFSIZ]; if (key == NULLCP) { PP_LOG(LLOG_EXCEPTIONS, ("Null key in output")); return RP_BAD; } (void) sprintf(buffer, "%s%s %s", (admin_info == TRUE) ? "* " : "", key, value); if (rp_isbad(retval = io_tdata(buffer, strlen(buffer)))) { PP_LOG(LLOG_EXCEPTIONS, ("io_tdata error")); (void) sprintf(error, "io_tdata error"); stop_io(); } chnum = strlen(buffer); return retval; } static int write_cont(value, fold) char *value; int fold; { int retval, len, i; char buffer[BUFSIZ], *ix, *base, *lastix, *foldpt, savech; if (value == NULLCP) { PP_LOG(LLOG_EXCEPTIONS, ("Null value in output")); return RP_BAD; } len = strlen(value); bzero(buffer, sizeof buffer); if (fold == FALSE) { if (chnum + len > foldlength) { (void) sprintf(buffer, "\n%s%*s%s", (admin_info == TRUE) ? "* ": "", tab, "", value); chnum = tab; } else (void) sprintf(buffer, " %s", value); chnum += len; } else { ix = lastix = base = value; /* write_cont assume big start new line */ (void) sprintf (buffer, "\n%s%*s", (admin_info == TRUE) ? "* " : "", tab, ""); chnum = tab; while (ix != NULLCP && *ix != '\0') { while (*ix != '\0' && !isspace(*ix)) ix++; if (chnum + (ix - base) > foldlength) { /* need to fold */ if (lastix == base) foldpt = ix; else foldpt = lastix; savech = *foldpt; *foldpt = '\0'; (void) sprintf (buffer, "%s%s\n%s%*s", buffer, base, (admin_info == TRUE) ? "* " : "", tab, ""); *foldpt = savech; base = foldpt; if (savech != '\0') /* skip last space */ base++; chnum = tab; } lastix = ix; if (*ix != '\0') ix++; } /* flush rest */ if (base != ix) { if (chnum + (ix - base) > foldlength) { (void) sprintf(buffer, "%s\n%s%*s%s", buffer, (admin_info == TRUE) ? "* " : "", tab, "", base); chnum = tab; } else strcat (buffer, base); chnum += ix - base; } } if (rp_isbad(retval = io_tdata(buffer, strlen(buffer)))) { PP_LOG(LLOG_EXCEPTIONS, ("io_tdata error")); (void) sprintf(error, "io_tdata error"); stop_io(); } return retval; } static int write_end() { int retval; if (rp_isbad(retval = io_tdata("\n", strlen("\n")))) { PP_LOG(LLOG_EXCEPTIONS, ("io_tdata error")); (void) sprintf(error, "io_tdata error"); stop_io(); } return retval; } static int DR_write (key, value) char *key; char *value; { char buffer[BUFSIZ]; int retval; if (value == NULLCP) { PP_LOG (LLOG_EXCEPTIONS, ("No value for key %s", key)); return RP_BAD; } bzero (buffer, sizeof buffer); if (admin_info == TRUE) (void) strcat (buffer, "* "); if (key) (void) strcat (buffer, key); (void) strcat (buffer, value); (void) strcat (buffer, "\n"); if (rp_isbad (retval = io_tdata (buffer, strlen (buffer)))) { PP_LOG (LLOG_EXCEPTIONS, ("io_tdata error")); (void) sprintf (error, "io_tdata error"); stop_io(); } return retval; } static int DR_print (key, value) char *key; char *value; { char buffer [BUFSIZ]; char obuf[BUFSIZ]; int retval; if (value == NULLCP) { PP_LOG (LLOG_EXCEPTIONS, ("No value for key %s", key)); return RP_BAD; } bzero (buffer, sizeof buffer); if (admin_info == TRUE) (void) strcat (buffer, "* "); if (key) (void) strcat (buffer, key); (void) strcat (buffer, value); rfctxtfold (buffer, obuf, 66); if (rp_isbad (retval = io_tdata (obuf, strlen (obuf)))) { PP_LOG (LLOG_EXCEPTIONS, ("io_tdata error")); (void) sprintf (error, "io_tdata error"); stop_io(); } return retval; } /* output string padding newlines with some indentation */ pretty_output(str) char *str; { char buffer[BUFSIZ]; int i = 0; if (str == NULL) return RP_BAD; while (*str != '\0') { if (i == BUFSIZ-1) { /* flush buffer */ buffer[i] = '\0'; if (rp_isbad(io_tdata(buffer, strlen(buffer)))) { PP_LOG (LLOG_EXCEPTIONS, ("Error writing message")); (void) sprintf (error, "io_tdata error"); stop_io(); return RP_BAD; } i = 0; } buffer[i++] = *str; if (*str++ == '\n') { if (i >= BUFSIZ - 3) { /* flush buffer */ buffer[i] = '\0'; if (rp_isbad(io_tdata(buffer, strlen(buffer)))) { PP_LOG (LLOG_EXCEPTIONS, ("Error writing message")); (void) sprintf (error, "io_tdata error"); stop_io(); return RP_BAD; } i = 0; } /* pad newlines */ buffer[i++] = ' '; buffer[i++] = ' '; } } if (i > 0) { /* flush buffer */ buffer[i] = '\0'; if (rp_isbad(io_tdata(buffer, strlen(buffer)))) { PP_LOG (LLOG_EXCEPTIONS, ("Error writing message")); stop_io(); return RP_BAD; } } return RP_OK; } /* \f */ static char *parseSubject(file) char *file; { char buf[BUFSIZ], *ret = NULLCP, *ix; int subject = FALSE, len; FILE *fd; if ((fd = fopen(file, "r")) == NULL) return NULLCP; while (subject == FALSE && fgets(buf, BUFSIZ, fd) != NULLCP) { if ((ix = index(buf, ':')) != NULLCP) { *ix = '\0'; if (lexequ("subject",buf) == 0) { subject = TRUE; ix++; while (*ix && isspace(*ix)) ix++; len = strlen(ix); *(ix + len - 1) = '\0'; ret = strdup(ix); } } } fclose(fd); return ret; } extern char *hdr_822_bp; static int isHdr(entry) struct dirent *entry; { if (strncmp(entry->d_name, hdr_822_bp, strlen(hdr_822_bp)) == 0) return 1; return 0; } static char *getSubject(msg_id, recip) char *msg_id; ADDR *recip; { char *dir = NULLCP, hdr[FILNSIZE], *subject = NULLCP; struct dirent **namelist = NULL; int gothdr = FALSE, rcnt = recip->ad_rcnt; recip->ad_rcnt = 0; while (gothdr == FALSE && recip->ad_rcnt <= rcnt) { if (qid2dir(msg_id, recip, TRUE, &dir) == OK) { if (_scandir(dir, &namelist, isHdr, NULLIFP) > 0) gothdr = TRUE; free(dir); } recip->ad_rcnt++; } recip->ad_rcnt = rcnt; if (gothdr == FALSE) return NULLCP; if ((*namelist)->d_name[0] != '/') (void) sprintf(hdr, "%s/%s", dir, (*namelist)->d_name); else strcpy(hdr, (*namelist)->d_name); subject = parseSubject(hdr); free((char *) namelist); free(dir); return subject; } static int getMailbox(ix, pmailbox) Rrinfo *ix; char **pmailbox; { ADDR *ad; char buf[BUFSIZ]; *pmailbox = NULLCP; for (ad = PPQuePtr -> Raddress; ad; ad = ad->ad_next) if (ad -> ad_no == ix -> rr_recip) break; if (ad == NULL) (void) sprintf(buf,"recipient %d", ix -> rr_recip); else if (ad -> ad_type == AD_822_TYPE && ad -> ad_r822adr != NULL) { char *str = NULLCP; ap_s2s (ad -> ad_r822adr, &str, order_pref); if (str != NULLCP) { (void) sprintf(buf, "%s", str); free(str); } else (void) sprintf(buf, "%s", ad -> ad_r822adr); } else if (ad -> ad_type == AD_X400_TYPE && ad -> ad_r400adr != NULL) (void) sprintf(buf, "%s", ad -> ad_r400adr); else if (ad -> ad_value != NULL) (void) sprintf(buf, "%s", ad -> ad_value); else { PP_LOG (LLOG_EXCEPTIONS, ("Error no address string given for recip '%d'\n", ix -> rr_recip)); return RP_BAD; } *pmailbox = strdup(buf); return RP_OK; } static int get822Mailbox(ix, pmailbox) Rrinfo *ix; char **pmailbox; { ADDR *ad; char buf[BUFSIZ]; *pmailbox = NULLCP; for (ad = PPQuePtr -> Raddress; ad; ad = ad->ad_next) if (ad -> ad_no == ix -> rr_recip) break; if (ad == NULL) (void) sprintf(buf,"recipient %d", ix -> rr_recip); else if (ad -> ad_r822adr != NULL) { char *str = NULLCP; ap_s2s (ad -> ad_r822adr, &str, order_pref); if (str != NULLCP) { (void) sprintf(buf, "%s", str); free(str); } else (void) sprintf(buf, "%s", ad -> ad_r822adr); } else if (ad -> ad_value != NULL) (void) sprintf(buf, "%s", ad -> ad_value); else if (ad -> ad_type == AD_X400_TYPE && ad -> ad_r400adr != NULL) (void) sprintf(buf, "%s", ad -> ad_r400adr); else { PP_LOG (LLOG_EXCEPTIONS, ("Error no address string given for recip '%d'\n", ix -> rr_recip)); return RP_BAD; } *pmailbox = strdup(buf); return RP_OK; } static int allSameType(ix, type) Rrinfo *ix; int type; { if (ix == NULL) return FALSE; while (ix != NULL && ix->rr_report.rep_type == type) ix = ix -> rr_next; if (ix == NULL) return TRUE; else return FALSE; } static int allSameMta(ix, pmta) Rrinfo *ix; char **pmta; { ADDR *ad; int first = TRUE, allSame = TRUE; while (ix != NULL) { for (ad = PPQuePtr -> Raddress; ad; ad = ad->ad_next) if (ad -> ad_no == ix -> rr_recip) break; if (ad != NULL && ad -> ad_outchan != NULL && ad -> ad_outchan -> li_mta) { if (first == TRUE) { *pmta = strdup(ad -> ad_outchan -> li_mta); first = FALSE; } else if (lexequ(*pmta, ad -> ad_outchan -> li_mta) != 0) allSame = FALSE; } ix = ix -> rr_next; } if (first == FALSE && allSame == TRUE) return TRUE; return FALSE; }