Commit d79e9514 authored by Rob Swindell's avatar Rob Swindell 💬
Browse files

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()
parent 4a824f52
...@@ -743,11 +743,8 @@ bool sbbs_t::writemsg(const char *fname, const char *top, char *subj, long mode, ...@@ -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) void sbbs_t::editor_info_to_msg(smbmsg_t* msg, const char* editor, const char* charset)
{ {
if(editor != NULL) smb_hfield_string(msg, SMB_EDITOR, editor);
smb_hfield_str(msg, SMB_EDITOR, editor); smb_hfield_string(msg, FIDOCHARSET, charset);
if(charset != NULL)
smb_hfield_str(msg, FIDOCHARSET, charset);
ushort useron_xedit = useron.xedit; ushort useron_xedit = useron.xedit;
...@@ -1375,7 +1372,7 @@ bool sbbs_t::forwardmail(smbmsg_t* orgmsg, const char* to, const char* subject, ...@@ -1375,7 +1372,7 @@ bool sbbs_t::forwardmail(smbmsg_t* orgmsg, const char* to, const char* subject,
if(subject == NULL) { if(subject == NULL) {
subject = subj; subject = subj;
SAFECOPY(subj, orgmsg->subj); SAFEPRINTF(subj, "Fwd: %s", orgmsg->subj);
bputs(text[SubjectPrompt]); bputs(text[SubjectPrompt]);
if(!getstr(subj, sizeof(subj) - 1, K_LINE | K_EDIT | K_AUTODEL | K_TRIM)) if(!getstr(subj, sizeof(subj) - 1, K_LINE | K_EDIT | K_AUTODEL | K_TRIM))
return false; return false;
...@@ -1441,33 +1438,57 @@ bool sbbs_t::forwardmail(smbmsg_t* orgmsg, const char* to, const char* subject, ...@@ -1441,33 +1438,57 @@ bool sbbs_t::forwardmail(smbmsg_t* orgmsg, const char* to, const char* subject,
time32_t now32 = time32(NULL); time32_t now32 = time32(NULL);
smb_hfield(&msg, FORWARDED, sizeof(now32), &now32); 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 = "&lt;";
gt = "&gt;";
br = "<br>";
pg = "<p>";
}
if(comment == NULL) { if(comment == NULL) {
while(online) { while(online && !msgabort()) {
bputs(text[UeditComment]); bputs(text[UeditComment]);
if(!getstr(str, 70, K_WRAP)) if(!getstr(str, 70, K_WRAP))
break; 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 { } else {
if(*comment) 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) 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 else
safe_snprintf(str, sizeof(str), "From: %s", orgmsg->from); 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)); 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) 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 else
safe_snprintf(str, sizeof(str), "To: %s", orgmsg->to); 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); safe_snprintf(str, sizeof(str), "Subject: %s", orgmsg->subj);
smb_hfield_str(&msg, SMB_COMMENT, str); smb_hfield_string(&msg, SMB_COMMENT, str);
smb_hfield_str(&msg, SMB_COMMENT, nulstr); smb_hfield_string(&msg, SMB_COMMENT, pg);
// Re-use the original message's data // Re-use the original message's data
if((result = smb_open_da(&smb)) != SMB_SUCCESS) { if((result = smb_open_da(&smb)) != SMB_SUCCESS) {
......
...@@ -1218,13 +1218,23 @@ int SMBCALL smb_hfield_add_list(smbmsg_t* msg, hfield_t** hfield_list, void** hf ...@@ -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) 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); 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 */ /* Convenience function to a network address header field to msg */
/* Pass NULL for net_type to have the auto-detected net_type hfield added */ /* Pass NULL for net_type to have the auto-detected net_type hfield added */
......
...@@ -160,6 +160,7 @@ SMBEXPORT int SMBCALL smb_hfield_append(smbmsg_t* msg, uint16_t type, size_t le ...@@ -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_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_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_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: */ /* Convenience macro: */
#define smb_hfield_bin(msg, type, data) smb_hfield_add(msg, type, sizeof(data), &(data), /* insert: */FALSE) #define smb_hfield_bin(msg, type, data) smb_hfield_add(msg, type, sizeof(data), &(data), /* insert: */FALSE)
/* Backward compatibility macros: */ /* Backward compatibility macros: */
......
...@@ -495,7 +495,6 @@ char* SMBCALL smb_getplaintext(smbmsg_t* msg, char* buf) ...@@ -495,7 +495,6 @@ char* SMBCALL smb_getplaintext(smbmsg_t* msg, char* buf)
const char* txt; const char* txt;
enum content_transfer_encoding xfer_encoding = CONTENT_TRANFER_ENCODING_NONE; 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 */ if(msg->mime_version == NULL || msg->content_type == NULL) /* not MIME */
return NULL; return NULL;
txt = mime_getcontent(buf, msg->content_type, "text/plain", 0, &xfer_encoding, &msg->text_charset 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) ...@@ -505,9 +504,12 @@ char* SMBCALL smb_getplaintext(smbmsg_t* msg, char* buf)
,/* attachment: */NULL, /* attachment_len: */0, /* index: */0); ,/* attachment: */NULL, /* attachment_len: */0, /* index: */0);
if(txt == NULL) if(txt == NULL)
return NULL; return NULL;
free(msg->text_subtype);
msg->text_subtype = strdup("html"); msg->text_subtype = strdup("html");
} else } else {
free(msg->text_subtype);
msg->text_subtype = strdup("plain"); msg->text_subtype = strdup("plain");
}
memmove(buf, txt, strlen(txt)+1); memmove(buf, txt, strlen(txt)+1);
if(*buf == 0) /* No decoding necessary */ if(*buf == 0) /* No decoding necessary */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment