/* * Deliver list messages to everyone on the list ... efficiently */ void network_deliver_list(struct CtdlMessage *msg, SpoolControl *sc, const char *RoomName) { recptypes *valid; char bounce_to[256]; /* Don't do this if there were no recipients! */ if (sc->Users[listrecp] == NULL) return; /* Now generate the delivery instructions */ /* Where do we want bounces and other noise to be heard? * Surely not the list members! */ snprintf(bounce_to, sizeof bounce_to, "room_aide@%s", config.c_fqdn); /* Now submit the message */ valid = validate_recipients(ChrPtr(sc->Users[listrecp]), NULL, 0); if (valid != NULL) { valid->bounce_to = strdup(bounce_to); valid->envelope_from = strdup(bounce_to); valid->sending_room = strdup(RoomName); CtdlSubmitMsg(msg, valid, NULL, 0); free_recipients(valid); } /* Do not call CM_Free(msg) here; the caller will free it. */ }
/* * Deliver digest messages */ void network_deliver_digest(SpoolControl *sc) { struct CitContext *CCC = CC; long len; char buf[SIZ]; char *pbuf; struct CtdlMessage *msg = NULL; long msglen; recptypes *valid; char bounce_to[256]; if (sc->Users[digestrecp] == NULL) return; msg = malloc(sizeof(struct CtdlMessage)); memset(msg, 0, sizeof(struct CtdlMessage)); msg->cm_magic = CTDLMESSAGE_MAGIC; msg->cm_format_type = FMT_RFC822; msg->cm_anon_type = MES_NORMAL; CM_SetFieldLONG(msg, eTimestamp, time(NULL)); CM_SetField(msg, eAuthor, CCC->room.QRname, strlen(CCC->room.QRname)); len = snprintf(buf, sizeof buf, "[%s]", CCC->room.QRname); CM_SetField(msg, eMsgSubject, buf, len); CM_SetField(msg, erFc822Addr, SKEY(sc->Users[roommailalias])); CM_SetField(msg, eRecipient, SKEY(sc->Users[roommailalias])); /* Set the 'List-ID' header */ CM_SetField(msg, eListID, SKEY(sc->ListID)); /* * Go fetch the contents of the digest */ fseek(sc->digestfp, 0L, SEEK_END); msglen = ftell(sc->digestfp); pbuf = malloc(msglen + 1); fseek(sc->digestfp, 0L, SEEK_SET); fread(pbuf, (size_t)msglen, 1, sc->digestfp); pbuf[msglen] = '\0'; CM_SetAsField(msg, eMesageText, &pbuf, msglen); /* Now generate the delivery instructions */ /* Where do we want bounces and other noise to be heard? * Surely not the list members! */ snprintf(bounce_to, sizeof bounce_to, "room_aide@%s", config.c_fqdn); /* Now submit the message */ valid = validate_recipients(ChrPtr(sc->Users[digestrecp]), NULL, 0); if (valid != NULL) { valid->bounce_to = strdup(bounce_to); valid->envelope_from = strdup(bounce_to); CtdlSubmitMsg(msg, valid, NULL, 0); } CM_Free(msg); free_recipients(valid); }
void network_process_participate(SpoolControl *sc, struct CtdlMessage *omsg, long *delete_after_send) { struct CtdlMessage *msg = NULL; int ok_to_participate = 0; StrBuf *Buf = NULL; recptypes *valid; /* * Process client-side list participations for this room */ if (sc->Users[participate] == NULL) return; msg = CM_Duplicate(omsg); /* Only send messages which originated on our own * Citadel network, otherwise we'll end up sending the * remote mailing list's messages back to it, which * is rude... */ ok_to_participate = 0; if (!CM_IsEmpty(msg, eNodeName)) { if (!strcasecmp(msg->cm_fields[eNodeName], config.c_nodename)) { ok_to_participate = 1; } Buf = NewStrBufPlain(CM_KEY(msg, eNodeName)); if (CtdlIsValidNode(NULL, NULL, Buf, sc->working_ignetcfg, sc->the_netmap) == 0) { ok_to_participate = 1; } } if (ok_to_participate) { /* Replace the Internet email address of the * actual author with the email address of the * room itself, so the remote listserv doesn't * reject us. */ CM_SetField(msg, erFc822Addr, SKEY(sc->Users[roommailalias])); valid = validate_recipients(ChrPtr(sc->Users[participate]) , NULL, 0); CM_SetField(msg, eRecipient, SKEY(sc->Users[roommailalias])); CtdlSubmitMsg(msg, valid, "", 0); free_recipients(valid); } FreeStrBuf(&Buf); CM_Free(msg); }
/* * Determine whether a given Internet address belongs to the current user */ int CtdlIsMe(char *addr, int addr_buf_len) { recptypes *recp; int i; recp = validate_recipients(addr, NULL, 0); if (recp == NULL) return(0); if (recp->num_local == 0) { free_recipients(recp); return(0); } for (i=0; i<recp->num_local; ++i) { extract_token(addr, recp->recp_local, i, '|', addr_buf_len); if (!strcasecmp(addr, CC->user.fullname)) { free_recipients(recp); return(1); } } free_recipients(recp); return(0); }
/* * Called by JournalRunQueue() to send an individual message. */ void JournalRunQueueMsg(struct jnlq *jmsg) { struct CtdlMessage *journal_msg = NULL; recptypes *journal_recps = NULL; StrBuf *message_text = NULL; char mime_boundary[256]; long mblen; long rfc822len; char recipient[256]; char inetemail[256]; static int seq = 0; int i; if (jmsg == NULL) return; journal_recps = validate_recipients(config.c_journal_dest, NULL, 0); if (journal_recps != NULL) { if ( (journal_recps->num_local > 0) || (journal_recps->num_internet > 0) || (journal_recps->num_ignet > 0) || (journal_recps->num_room > 0) ) { /* * Construct journal message. * Note that we are transferring ownership of some of the memory here. */ journal_msg = malloc(sizeof(struct CtdlMessage)); memset(journal_msg, 0, sizeof(struct CtdlMessage)); journal_msg->cm_magic = CTDLMESSAGE_MAGIC; journal_msg->cm_anon_type = MES_NORMAL; journal_msg->cm_format_type = FMT_RFC822; CM_SetField(journal_msg, eJournal, HKEY("is journal")); CM_SetField(journal_msg, eAuthor, jmsg->from, strlen(jmsg->from)); CM_SetField(journal_msg, eNodeName, jmsg->node, strlen(jmsg->node)); CM_SetField(journal_msg, erFc822Addr, jmsg->rfca, strlen(jmsg->rfca)); CM_SetField(journal_msg, eMsgSubject, jmsg->subj, strlen(jmsg->subj)); mblen = snprintf(mime_boundary, sizeof(mime_boundary), "--Citadel-Journal-%08lx-%04x--", time(NULL), ++seq); rfc822len = strlen(jmsg->rfc822); message_text = NewStrBufPlain(NULL, rfc822len + sizeof(recptypes) + 1024); /* * Here is where we begin to compose the journalized message. * NOTE: the superfluous "Content-Identifer: ExJournalReport" header was * requested by a paying customer, and yes, it is intentionally * spelled wrong. Do NOT remove or change it. */ StrBufAppendBufPlain( message_text, HKEY("Content-type: multipart/mixed; boundary=\""), 0); StrBufAppendBufPlain(message_text, mime_boundary, mblen, 0); StrBufAppendBufPlain( message_text, HKEY("\"\r\n" "Content-Identifer: ExJournalReport\r\n" "MIME-Version: 1.0\r\n" "\n" "--"), 0); StrBufAppendBufPlain(message_text, mime_boundary, mblen, 0); StrBufAppendBufPlain( message_text, HKEY("\r\n" "Content-type: text/plain\r\n" "\r\n" "Sender: "), 0); if (CM_IsEmpty(journal_msg, eAuthor)) StrBufAppendBufPlain( message_text, journal_msg->cm_fields[eAuthor], -1, 0); else StrBufAppendBufPlain( message_text, HKEY("(null)"), 0); if (!CM_IsEmpty(journal_msg, erFc822Addr)) { StrBufAppendPrintf(message_text, " <%s>", journal_msg->cm_fields[erFc822Addr]); } else if (!CM_IsEmpty(journal_msg, eNodeName)) { StrBufAppendPrintf(message_text, " @ %s", journal_msg->cm_fields[eNodeName]); } else StrBufAppendBufPlain( message_text, HKEY(" "), 0); StrBufAppendBufPlain( message_text, HKEY("\r\n" "Message-ID: <"), 0); StrBufAppendBufPlain(message_text, jmsg->msgn, -1, 0); StrBufAppendBufPlain( message_text, HKEY(">\r\n" "Recipients:\r\n"), 0); if (jmsg->recps.num_local > 0) { for (i=0; i<jmsg->recps.num_local; ++i) { extract_token(recipient, jmsg->recps.recp_local, i, '|', sizeof recipient); local_to_inetemail(inetemail, recipient, sizeof inetemail); StrBufAppendPrintf(message_text, " %s <%s>\r\n", recipient, inetemail); } } if (jmsg->recps.num_ignet > 0) { for (i=0; i<jmsg->recps.num_ignet; ++i) { extract_token(recipient, jmsg->recps.recp_ignet, i, '|', sizeof recipient); StrBufAppendPrintf(message_text, " %s\r\n", recipient); } } if (jmsg->recps.num_internet > 0) { for (i=0; i<jmsg->recps.num_internet; ++i) { extract_token(recipient, jmsg->recps.recp_internet, i, '|', sizeof recipient); StrBufAppendPrintf(message_text, " %s\r\n", recipient); } } StrBufAppendBufPlain( message_text, HKEY("\r\n" "--"), 0); StrBufAppendBufPlain(message_text, mime_boundary, mblen, 0); StrBufAppendBufPlain( message_text, HKEY("\r\n" "Content-type: message/rfc822\r\n" "\r\n"), 0); StrBufAppendBufPlain(message_text, jmsg->rfc822, rfc822len, 0); StrBufAppendBufPlain( message_text, HKEY("--"), 0); StrBufAppendBufPlain(message_text, mime_boundary, mblen, 0); StrBufAppendBufPlain( message_text, HKEY("--\r\n"), 0); CM_SetAsFieldSB(journal_msg, eMesageText, &message_text); free(jmsg->rfc822); free(jmsg->msgn); jmsg->rfc822 = NULL; jmsg->msgn = NULL; /* Submit journal message */ CtdlSubmitMsg(journal_msg, journal_recps, "", 0); CM_Free(journal_msg); } free_recipients(journal_recps); } /* We are responsible for freeing this memory. */ free(jmsg); }
/* * smtp_do_bounce() is caled by smtp_do_procmsg() to scan a set of delivery * instructions for "5" codes (permanent fatal errors) and produce/deliver * a "bounce" message (delivery status notification). */ void smtp_do_bounce(char *instr, StrBuf *OMsgTxt) { int i; int lines; int status; char buf[1024]; char key[1024]; char addr[1024]; char dsn[1024]; char bounceto[1024]; StrBuf *boundary; int num_bounces = 0; int bounce_this = 0; time_t submitted = 0L; struct CtdlMessage *bmsg = NULL; int give_up = 0; recptypes *valid; int successful_bounce = 0; static int seq = 0; StrBuf *BounceMB; long omsgid = (-1); syslog(LOG_DEBUG, "smtp_do_bounce() called\n"); strcpy(bounceto, ""); boundary = NewStrBufPlain(HKEY("=_Citadel_Multipart_")); StrBufAppendPrintf(boundary, "%s_%04x%04x", CtdlGetConfigStr("c_fqdn"), getpid(), ++seq); lines = num_tokens(instr, '\n'); /* See if it's time to give up on delivery of this message */ for (i=0; i<lines; ++i) { extract_token(buf, instr, i, '\n', sizeof buf); extract_token(key, buf, 0, '|', sizeof key); extract_token(addr, buf, 1, '|', sizeof addr); if (!strcasecmp(key, "submitted")) { submitted = atol(addr); } } if ( (time(NULL) - submitted) > SMTP_GIVE_UP ) { give_up = 1; } /* Start building our bounce message */ bmsg = (struct CtdlMessage *) malloc(sizeof(struct CtdlMessage)); if (bmsg == NULL) return; memset(bmsg, 0, sizeof(struct CtdlMessage)); BounceMB = NewStrBufPlain(NULL, 1024); bmsg->cm_magic = CTDLMESSAGE_MAGIC; bmsg->cm_anon_type = MES_NORMAL; bmsg->cm_format_type = FMT_RFC822; CM_SetField(bmsg, eAuthor, HKEY("Citadel")); CM_SetField(bmsg, eOriginalRoom, HKEY(MAILROOM)); CM_SetField(bmsg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename"))); CM_SetField(bmsg, eMsgSubject, HKEY("Delivery Status Notification (Failure)")); StrBufAppendBufPlain(BounceMB, HKEY("Content-type: multipart/mixed; boundary=\""), 0); StrBufAppendBuf(BounceMB, boundary, 0); StrBufAppendBufPlain(BounceMB, HKEY("\"\r\n"), 0); StrBufAppendBufPlain(BounceMB, HKEY("MIME-Version: 1.0\r\n"), 0); StrBufAppendBufPlain(BounceMB, HKEY("X-Mailer: " CITADEL "\r\n"), 0); StrBufAppendBufPlain( BounceMB, HKEY("\r\nThis is a multipart message in MIME format." "\r\n\r\n"), 0); StrBufAppendBufPlain(BounceMB, HKEY("--"), 0); StrBufAppendBuf(BounceMB, boundary, 0); StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0); StrBufAppendBufPlain(BounceMB, HKEY("Content-type: text/plain\r\n\r\n"), 0); if (give_up) { StrBufAppendBufPlain( BounceMB, HKEY("A message you sent could not be delivered " "to some or all of its recipients\ndue to " "prolonged unavailability of its destination(s).\n" "Giving up on the following addresses:\n\n"), 0); } else { StrBufAppendBufPlain( BounceMB, HKEY("A message you sent could not be delivered " "to some or all of its recipients.\n" "The following addresses were undeliverable:\n\n" ), 0); } /* * Now go through the instructions checking for stuff. */ for (i=0; i<lines; ++i) { long addrlen; long dsnlen; extract_token(buf, instr, i, '\n', sizeof buf); extract_token(key, buf, 0, '|', sizeof key); addrlen = extract_token(addr, buf, 1, '|', sizeof addr); status = extract_int(buf, 2); dsnlen = extract_token(dsn, buf, 3, '|', sizeof dsn); bounce_this = 0; syslog(LOG_DEBUG, "key=<%s> addr=<%s> status=%d dsn=<%s>\n", key, addr, status, dsn); if (!strcasecmp(key, "bounceto")) { strcpy(bounceto, addr); } if (!strcasecmp(key, "msgid")) { omsgid = atol(addr); } if (!strcasecmp(key, "remote")) { if (status == 5) bounce_this = 1; if (give_up) bounce_this = 1; } if (bounce_this) { ++num_bounces; StrBufAppendBufPlain(BounceMB, addr, addrlen, 0); StrBufAppendBufPlain(BounceMB, HKEY(": "), 0); StrBufAppendBufPlain(BounceMB, dsn, dsnlen, 0); StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0); remove_token(instr, i, '\n'); --i; --lines; } } /* Attach the original message */ if (omsgid >= 0) { StrBufAppendBufPlain(BounceMB, HKEY("--"), 0); StrBufAppendBuf(BounceMB, boundary, 0); StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0); StrBufAppendBufPlain( BounceMB, HKEY("Content-type: message/rfc822\r\n"), 0); StrBufAppendBufPlain( BounceMB, HKEY("Content-Transfer-Encoding: 7bit\r\n"), 0); StrBufAppendBufPlain( BounceMB, HKEY("Content-Disposition: inline\r\n"), 0); StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0); if (OMsgTxt == NULL) { CC->redirect_buffer = NewStrBufPlain(NULL, SIZ); CtdlOutputMsg(omsgid, MT_RFC822, HEADERS_ALL, 0, 1, NULL, 0, NULL, NULL, NULL); StrBufAppendBuf(BounceMB, CC->redirect_buffer, 0); FreeStrBuf(&CC->redirect_buffer); } else { StrBufAppendBuf(BounceMB, OMsgTxt, 0); } } /* Close the multipart MIME scope */ StrBufAppendBufPlain(BounceMB, HKEY("--"), 0); StrBufAppendBuf(BounceMB, boundary, 0); StrBufAppendBufPlain(BounceMB, HKEY("--\r\n"), 0); CM_SetAsFieldSB(bmsg, eMesageText, &BounceMB); /* Deliver the bounce if there's anything worth mentioning */ syslog(LOG_DEBUG, "num_bounces = %d\n", num_bounces); if (num_bounces > 0) { /* First try the user who sent the message */ if (IsEmptyStr(bounceto)) syslog(LOG_ERR, "No bounce address specified\n"); else syslog(LOG_DEBUG, "bounce to user <%s>\n", bounceto); /* Can we deliver the bounce to the original sender? */ valid = validate_recipients(bounceto, smtp_get_Recipients (), 0); if (valid != NULL) { if (valid->num_error == 0) { CtdlSubmitMsg(bmsg, valid, "", QP_EADDR); successful_bounce = 1; } } /* If not, post it in the Aide> room */ if (successful_bounce == 0) { CtdlSubmitMsg(bmsg, NULL, CtdlGetConfigStr("c_aideroom"), QP_EADDR); } /* Free up the memory we used */ if (valid != NULL) { free_recipients(valid); } } FreeStrBuf(&boundary); CM_Free(bmsg); syslog(LOG_DEBUG, "Done processing bounces\n"); }
/* * smtp_do_bounce() is caled by smtp_do_procmsg() to scan a set of delivery * instructions for "5" codes (permanent fatal errors) and produce/deliver * a "bounce" message (delivery status notification). */ void smtpq_do_bounce(OneQueItem *MyQItem, StrBuf *OMsgTxt, ParsedURL *Relay) { static int seq = 0; struct CtdlMessage *bmsg = NULL; StrBuf *boundary; StrBuf *Msg = NULL; StrBuf *BounceMB; recptypes *valid; time_t now; HashPos *It; void *vQE; long len; const char *Key; int first_attempt = 0; int successful_bounce = 0; int num_bounces = 0; int give_up = 0; SMTPCM_syslog(LOG_DEBUG, "smtp_do_bounce() called\n"); if (MyQItem->SendBounceMail == 0) return; now = time (NULL); //ev_time(); if ( (now - MyQItem->Submitted) > SMTP_GIVE_UP ) { give_up = 1; } if (MyQItem->Retry == SMTP_RETRY_INTERVAL) { first_attempt = 1; } /* * Now go through the instructions checking for stuff. */ Msg = NewStrBufPlain(NULL, 1024); It = GetNewHashPos(MyQItem->MailQEntries, 0); while (GetNextHashPos(MyQItem->MailQEntries, It, &len, &Key, &vQE)) { MailQEntry *ThisItem = vQE; if ((ThisItem->Active && (ThisItem->Status == 5)) || /* failed now? */ ((give_up == 1) && (ThisItem->Status != 2)) || ((first_attempt == 1) && (ThisItem->Status != 2))) /* giving up after failed attempts... */ { ++num_bounces; StrBufAppendBufPlain(Msg, HKEY(" "), 0); StrBufAppendBuf(Msg, ThisItem->Recipient, 0); StrBufAppendBufPlain(Msg, HKEY(": "), 0); if (ThisItem->AllStatusMessages != NULL) StrBufAppendBuf(Msg, ThisItem->AllStatusMessages, 0); else StrBufAppendBuf(Msg, ThisItem->StatusMessage, 0); StrBufAppendBufPlain(Msg, HKEY("\r\n"), 0); } } DeleteHashPos(&It); /* Deliver the bounce if there's anything worth mentioning */ SMTPC_syslog(LOG_DEBUG, "num_bounces = %d\n", num_bounces); if (num_bounces == 0) { FreeStrBuf(&Msg); return; } if ((StrLength(MyQItem->SenderRoom) == 0) && MyQItem->HaveRelay) { const char *RelayUrlStr = "[not found]"; /* one message that relaying is broken is enough; no extra room error message. */ StrBuf *RelayDetails = NewStrBuf(); if (Relay != NULL) RelayUrlStr = ChrPtr(Relay->URL); StrBufPrintf(RelayDetails, "Relaying via %s failed permanently. \n Reason:\n%s\n Revalidate your relay configuration.", RelayUrlStr, ChrPtr(Msg)); CtdlAideMessage(ChrPtr(RelayDetails), "Relaying Failed"); FreeStrBuf(&RelayDetails); } boundary = NewStrBufPlain(HKEY("=_Citadel_Multipart_")); StrBufAppendPrintf(boundary, "%s_%04x%04x", CtdlGetConfigStr("c_fqdn"), getpid(), ++seq); /* Start building our bounce message; go shopping for memory first. */ BounceMB = NewStrBufPlain( NULL, 1024 + /* mime stuff.... */ StrLength(Msg) + /* the bounce information... */ StrLength(OMsgTxt)); /* the original message */ if (BounceMB == NULL) { FreeStrBuf(&boundary); SMTPCM_syslog(LOG_ERR, "Failed to alloc() bounce message.\n"); return; } bmsg = (struct CtdlMessage *) malloc(sizeof(struct CtdlMessage)); if (bmsg == NULL) { FreeStrBuf(&boundary); FreeStrBuf(&BounceMB); SMTPCM_syslog(LOG_ERR, "Failed to alloc() bounce message.\n"); return; } memset(bmsg, 0, sizeof(struct CtdlMessage)); StrBufAppendBufPlain(BounceMB, HKEY("Content-type: multipart/mixed; boundary=\""), 0); StrBufAppendBuf(BounceMB, boundary, 0); StrBufAppendBufPlain(BounceMB, HKEY("\"\r\n"), 0); StrBufAppendBufPlain(BounceMB, HKEY("MIME-Version: 1.0\r\n"), 0); StrBufAppendBufPlain(BounceMB, HKEY("X-Mailer: " CITADEL "\r\n"), 0); StrBufAppendBufPlain(BounceMB, HKEY("\r\nThis is a multipart message in MIME format.\r\n\r\n"), 0); StrBufAppendBufPlain(BounceMB, HKEY("--"), 0); StrBufAppendBuf(BounceMB, boundary, 0); StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0); StrBufAppendBufPlain(BounceMB, HKEY("Content-type: text/plain\r\n\r\n"), 0); if (give_up) StrBufAppendBufPlain( BounceMB, HKEY( "A message you sent could not be delivered " "to some or all of its recipients\n" "due to prolonged unavailability " "of its destination(s).\n" "Giving up on the following addresses:\n\n" ), 0); else StrBufAppendBufPlain( BounceMB, HKEY( "A message you sent could not be delivered " "to some or all of its recipients.\n" "The following addresses " "were undeliverable:\n\n" ), 0); StrBufAppendBuf(BounceMB, Msg, 0); FreeStrBuf(&Msg); if (StrLength(MyQItem->SenderRoom) > 0) { StrBufAppendBufPlain( BounceMB, HKEY("The message was originaly posted in: "), 0); StrBufAppendBuf(BounceMB, MyQItem->SenderRoom, 0); StrBufAppendBufPlain( BounceMB, HKEY("\n"), 0); } /* Attach the original message */ StrBufAppendBufPlain(BounceMB, HKEY("\r\n--"), 0); StrBufAppendBuf(BounceMB, boundary, 0); StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0); StrBufAppendBufPlain(BounceMB, HKEY("Content-type: message/rfc822\r\n"), 0); StrBufAppendBufPlain(BounceMB, HKEY("Content-Transfer-Encoding: 7bit\r\n"), 0); StrBufAppendBufPlain(BounceMB, HKEY("Content-Disposition: inline\r\n"), 0); StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0); StrBufAppendBuf(BounceMB, OMsgTxt, 0); /* Close the multipart MIME scope */ StrBufAppendBufPlain(BounceMB, HKEY("--"), 0); StrBufAppendBuf(BounceMB, boundary, 0); StrBufAppendBufPlain(BounceMB, HKEY("--\r\n"), 0); bmsg->cm_magic = CTDLMESSAGE_MAGIC; bmsg->cm_anon_type = MES_NORMAL; bmsg->cm_format_type = FMT_RFC822; CM_SetField(bmsg, eOriginalRoom, HKEY(MAILROOM)); CM_SetField(bmsg, eAuthor, HKEY("Citadel")); CM_SetField(bmsg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename"))); CM_SetField(bmsg, eMsgSubject, HKEY("Delivery Status Notification (Failure)")); CM_SetAsFieldSB(bmsg, eMesageText, &BounceMB); /* First try the user who sent the message */ if (StrLength(MyQItem->BounceTo) == 0) { SMTPCM_syslog(LOG_ERR, "No bounce address specified\n"); } else { SMTPC_syslog(LOG_DEBUG, "bounce to user? <%s>\n", ChrPtr(MyQItem->BounceTo)); } /* Can we deliver the bounce to the original sender? */ valid = validate_recipients(ChrPtr(MyQItem->BounceTo), NULL, 0); if ((valid != NULL) && (valid->num_error == 0)) { CtdlSubmitMsg(bmsg, valid, "", QP_EADDR); successful_bounce = 1; } /* If not, post it in the Aide> room */ if (successful_bounce == 0) { CtdlSubmitMsg(bmsg, NULL, CtdlGetConfigStr("c_aideroom"), QP_EADDR); } /* Free up the memory we used */ free_recipients(valid); FreeStrBuf(&boundary); CM_Free(bmsg); SMTPCM_syslog(LOG_DEBUG, "Done processing bounces\n"); }