From d79e9514b39faee53db1fae0b4e1fb4e81edaeb7 Mon Sep 17 00:00:00 2001 From: Rob Swindell <rob@synchro.net> Date: Thu, 10 Dec 2020 17:42:41 -0800 Subject: [PATCH] Support forwarding of single-part HTML emails, add "Fwd:" subject prefix When forwarding a single-part MIME-encoded HTML email, the preamble (original message header info) and any user comments, need to be HTML-encoded. Add the commonly-used "Fwd: " prefix to the default message subject, when forwarding. This required that smb_getplaintext() no longer always-NULLify the message's text_subtype (e.g. "html"). For single-part messages, this element was getting freed and NULLed. Add/use a new SMBLIB convenience function to add a string header field, but only if non-NULL: smb_hfield_string() --- src/sbbs3/writemsg.cpp | 55 +++++++++++++++++++++++++++++------------- src/smblib/smblib.c | 12 ++++++++- src/smblib/smblib.h | 1 + src/smblib/smbtxt.c | 6 +++-- 4 files changed, 54 insertions(+), 20 deletions(-) diff --git a/src/sbbs3/writemsg.cpp b/src/sbbs3/writemsg.cpp index f23d137d0d..784ef5e38b 100644 --- a/src/sbbs3/writemsg.cpp +++ b/src/sbbs3/writemsg.cpp @@ -743,11 +743,8 @@ bool sbbs_t::writemsg(const char *fname, const char *top, char *subj, long mode, void sbbs_t::editor_info_to_msg(smbmsg_t* msg, const char* editor, const char* charset) { - if(editor != NULL) - smb_hfield_str(msg, SMB_EDITOR, editor); - - if(charset != NULL) - smb_hfield_str(msg, FIDOCHARSET, charset); + smb_hfield_string(msg, SMB_EDITOR, editor); + smb_hfield_string(msg, FIDOCHARSET, charset); ushort useron_xedit = useron.xedit; @@ -1375,7 +1372,7 @@ bool sbbs_t::forwardmail(smbmsg_t* orgmsg, const char* to, const char* subject, if(subject == NULL) { subject = subj; - SAFECOPY(subj, orgmsg->subj); + SAFEPRINTF(subj, "Fwd: %s", orgmsg->subj); bputs(text[SubjectPrompt]); if(!getstr(subj, sizeof(subj) - 1, K_LINE | K_EDIT | K_AUTODEL | K_TRIM)) return false; @@ -1441,33 +1438,57 @@ bool sbbs_t::forwardmail(smbmsg_t* orgmsg, const char* to, const char* subject, time32_t now32 = time32(NULL); smb_hfield(&msg, FORWARDED, sizeof(now32), &now32); + char* br = NULL; + char* pg = nulstr; + char* lt = "<"; + char* gt = ">"; + if(orgmsg->text_subtype != NULL && stricmp(orgmsg->text_subtype, "html") == 0) { + lt = "<"; + gt = ">"; + br = "<br>"; + pg = "<p>"; + } + if(comment == NULL) { - while(online) { + while(online && !msgabort()) { bputs(text[UeditComment]); if(!getstr(str, 70, K_WRAP)) break; - smb_hfield_str(&msg, SMB_COMMENT, str); + smb_hfield_string(&msg, SMB_COMMENT, str); + smb_hfield_string(&msg, SMB_COMMENT, br); + } + if(!online || msgabort()) { + smb_freemsgmem(&msg); + return false; } } else { if(*comment) - smb_hfield_str(&msg, SMB_COMMENT, comment); + smb_hfield_string(&msg, SMB_COMMENT, comment); } - smb_hfield_str(&msg, SMB_COMMENT, "-----Forwarded Message-----"); + if(smb_get_hfield(&msg, SMB_COMMENT, NULL) != NULL) + smb_hfield_string(&msg, SMB_COMMENT, pg); + smb_hfield_string(&msg, SMB_COMMENT, "-----Forwarded Message-----"); + smb_hfield_string(&msg, SMB_COMMENT, br); if(orgmsg->from_net.addr != NULL) - safe_snprintf(str, sizeof(str), "From: %s <%s>",orgmsg->from, smb_netaddrstr(&orgmsg->from_net, tmp)); + safe_snprintf(str, sizeof(str), "From: %s %s%s%s" + ,orgmsg->from, lt, smb_netaddrstr(&orgmsg->from_net, tmp), gt); else safe_snprintf(str, sizeof(str), "From: %s", orgmsg->from); - smb_hfield_str(&msg, SMB_COMMENT, str); + smb_hfield_string(&msg, SMB_COMMENT, str); + smb_hfield_string(&msg, SMB_COMMENT, br); safe_snprintf(str, sizeof(str), "Date: %s", msgdate(orgmsg->hdr.when_written, tmp)); - smb_hfield_str(&msg, SMB_COMMENT, str); + smb_hfield_string(&msg, SMB_COMMENT, str); + smb_hfield_string(&msg, SMB_COMMENT, br); if(orgmsg->to_net.addr != NULL) - safe_snprintf(str, sizeof(str), "To: %s <%s>", orgmsg->to, smb_netaddrstr(&orgmsg->to_net, tmp)); + safe_snprintf(str, sizeof(str), "To: %s %s%s%s" + ,orgmsg->to, lt, smb_netaddrstr(&orgmsg->to_net, tmp), gt); else safe_snprintf(str, sizeof(str), "To: %s", orgmsg->to); - smb_hfield_str(&msg, SMB_COMMENT, str); + smb_hfield_string(&msg, SMB_COMMENT, str); + smb_hfield_string(&msg, SMB_COMMENT, br); safe_snprintf(str, sizeof(str), "Subject: %s", orgmsg->subj); - smb_hfield_str(&msg, SMB_COMMENT, str); - smb_hfield_str(&msg, SMB_COMMENT, nulstr); + smb_hfield_string(&msg, SMB_COMMENT, str); + smb_hfield_string(&msg, SMB_COMMENT, pg); // Re-use the original message's data if((result = smb_open_da(&smb)) != SMB_SUCCESS) { diff --git a/src/smblib/smblib.c b/src/smblib/smblib.c index 14b669f878..9f77bbeb88 100644 --- a/src/smblib/smblib.c +++ b/src/smblib/smblib.c @@ -1218,13 +1218,23 @@ int SMBCALL smb_hfield_add_list(smbmsg_t* msg, hfield_t** hfield_list, void** hf } /****************************************************************************/ -/* Convenience function to add an ASCIIZ string header field */ +/* Convenience function to add an ASCIIZ string header field (or blank) */ /****************************************************************************/ int SMBCALL smb_hfield_add_str(smbmsg_t* msg, uint16_t type, const char* str, BOOL insert) { return smb_hfield_add(msg, type, str==NULL ? 0:strlen(str), (void*)str, insert); } +/****************************************************************************/ +/* Convenience function to add an ASCIIZ string header field (NULL ignored) */ +/****************************************************************************/ +int SMBCALL smb_hfield_string(smbmsg_t* msg, uint16_t type, const char* str) +{ + if(str == NULL) + return SMB_ERR_HDR_FIELD; + return smb_hfield_add(msg, type, strlen(str), (void*)str, /* insert */FALSE); +} + /****************************************************************************/ /* Convenience function to a network address header field to msg */ /* Pass NULL for net_type to have the auto-detected net_type hfield added */ diff --git a/src/smblib/smblib.h b/src/smblib/smblib.h index 5c1c55e7a9..fbe37ffbf9 100644 --- a/src/smblib/smblib.h +++ b/src/smblib/smblib.h @@ -160,6 +160,7 @@ SMBEXPORT int SMBCALL smb_hfield_append(smbmsg_t* msg, uint16_t type, size_t le SMBEXPORT int SMBCALL smb_hfield_append_str(smbmsg_t* msg, uint16_t type, const char* data); SMBEXPORT int SMBCALL smb_hfield_add_list(smbmsg_t* msg, hfield_t** hfield_list, void** hfield_dat, BOOL insert); SMBEXPORT int SMBCALL smb_hfield_add_netaddr(smbmsg_t* msg, uint16_t type, const char* str, uint16_t* nettype, BOOL insert); +SMBEXPORT int SMBCALL smb_hfield_string(smbmsg_t*, uint16_t type, const char*); /* Convenience macro: */ #define smb_hfield_bin(msg, type, data) smb_hfield_add(msg, type, sizeof(data), &(data), /* insert: */FALSE) /* Backward compatibility macros: */ diff --git a/src/smblib/smbtxt.c b/src/smblib/smbtxt.c index 4b65c9c429..0ffce0d1d5 100644 --- a/src/smblib/smbtxt.c +++ b/src/smblib/smbtxt.c @@ -495,7 +495,6 @@ char* SMBCALL smb_getplaintext(smbmsg_t* msg, char* buf) const char* txt; enum content_transfer_encoding xfer_encoding = CONTENT_TRANFER_ENCODING_NONE; - FREE_AND_NULL(msg->text_subtype); if(msg->mime_version == NULL || msg->content_type == NULL) /* not MIME */ return NULL; txt = mime_getcontent(buf, msg->content_type, "text/plain", 0, &xfer_encoding, &msg->text_charset @@ -505,9 +504,12 @@ char* SMBCALL smb_getplaintext(smbmsg_t* msg, char* buf) ,/* attachment: */NULL, /* attachment_len: */0, /* index: */0); if(txt == NULL) return NULL; + free(msg->text_subtype); msg->text_subtype = strdup("html"); - } else + } else { + free(msg->text_subtype); msg->text_subtype = strdup("plain"); + } memmove(buf, txt, strlen(txt)+1); if(*buf == 0) /* No decoding necessary */ -- GitLab