Skip to content
Snippets Groups Projects
Commit 7b5c33e2 authored by Rob Swindell's avatar Rob Swindell :speech_balloon:
Browse files

Overhauled message forwarding, allow comments

No longer derive the new message header from the original - too many problems. Simplified the forwarding support smblib (multiple SENDER* and RECIPIENT* header fields no longer expected/supported). Technically, the FORWARDED header field really serves no important purpose now.
A comment can be passed into forwardmail() or (if NULL), will be prompted for. There is an issue where the added comment can be obscured by the receiving mail program if the original message is a multi-part MIME message. Not sure the best solution for that. Still a WIP in that regard.
parent 97ac3bbf
No related branches found
No related tags found
1 merge request!463MRC mods by Codefenix (2024-10-20)
...@@ -681,7 +681,7 @@ public: ...@@ -681,7 +681,7 @@ public:
bool msgabort(void); bool msgabort(void);
bool email(int usernumber, const char *top = NULL, const char *title = NULL bool email(int usernumber, const char *top = NULL, const char *title = NULL
, long mode = WM_NONE, smb_t* resmb = NULL, smbmsg_t* remsg = NULL); , long mode = WM_NONE, smb_t* resmb = NULL, smbmsg_t* remsg = NULL);
bool forwardmail(smbmsg_t* msg, const char* to); bool forwardmail(smbmsg_t* msg, const char* to, const char* comment = NULL);
void removeline(char *str, char *str2, char num, char skip); void removeline(char *str, char *str2, char num, char skip);
ulong msgeditor(char *buf, const char *top, char *title); ulong msgeditor(char *buf, const char *top, char *title);
bool editfile(char *path, bool msg=false); bool editfile(char *path, bool msg=false);
...@@ -690,7 +690,7 @@ public: ...@@ -690,7 +690,7 @@ public:
void editmsg(smbmsg_t* msg, uint subnum); void editmsg(smbmsg_t* msg, uint subnum);
void editor_inf(int xeditnum, const char *to, const char* from, const char *subj, long mode void editor_inf(int xeditnum, const char *to, const char* from, const char *subj, long mode
,uint subnum, const char* tagfile); ,uint subnum, const char* tagfile);
void copyfattach(uint to, uint from, char *title); bool copyfattach(uint to, uint from, const char* subj);
bool movemsg(smbmsg_t* msg, uint subnum); bool movemsg(smbmsg_t* msg, uint subnum);
int process_edited_text(char* buf, FILE* stream, long mode, unsigned* lines, unsigned maxlines); int process_edited_text(char* buf, FILE* stream, long mode, unsigned* lines, unsigned maxlines);
int process_edited_file(const char* src, const char* dest, long mode, unsigned* lines, unsigned maxlines); int process_edited_file(const char* src, const char* dest, long mode, unsigned* lines, unsigned maxlines);
......
...@@ -1297,11 +1297,12 @@ bool sbbs_t::editfile(char *fname, bool msg) ...@@ -1297,11 +1297,12 @@ bool sbbs_t::editfile(char *fname, bool msg)
/*************************/ /*************************/
/* Copy file attachments */ /* Copy file attachments */
/*************************/ /*************************/
void sbbs_t::copyfattach(uint to, uint from, char *title) bool sbbs_t::copyfattach(uint to, uint from, const char* subj)
{ {
char str[128],str2[128],str3[128],*tp,*sp,*p; char str[128],str2[128],str3[128],*tp,*sp,*p;
bool result = false;
strcpy(str,title); strcpy(str, subj);
tp=str; tp=str;
while(1) { while(1) {
p=strchr(tp,' '); p=strchr(tp,' ');
...@@ -1313,38 +1314,42 @@ void sbbs_t::copyfattach(uint to, uint from, char *title) ...@@ -1313,38 +1314,42 @@ void sbbs_t::copyfattach(uint to, uint from, char *title)
,cfg.data_dir,to,tp); ,cfg.data_dir,to,tp);
SAFEPRINTF3(str3,"%sfile/%04u.in/%s" /* str2 is path/fname */ SAFEPRINTF3(str3,"%sfile/%04u.in/%s" /* str2 is path/fname */
,cfg.data_dir,from,tp); ,cfg.data_dir,from,tp);
if(strcmp(str2,str3)) if(strcmp(str2,str3)) {
mv(str3,str2,1); if(mv(str3, str2, /* copy */true) != 0)
return false;
result = true;
}
if(!p) if(!p)
break; break;
tp=p+1; tp=p+1;
} }
return result;
} }
/****************************************************************************/ /****************************************************************************/
/* Forwards mail 'msg' to 'to' */ /* Forwards mail 'orgmsg' to 'to' with optional 'comment'. */
/* If comment is NULL, comment lines will be prompted for. */
/* If comment is a zero-length string, no comments will be included. */
/****************************************************************************/ /****************************************************************************/
bool sbbs_t::forwardmail(smbmsg_t* msg, const char* to) bool sbbs_t::forwardmail(smbmsg_t* orgmsg, const char* to, const char* comment)
{ {
char str[256],touser[128]; char str[256],touser[128];
char tmp[512]; char tmp[512];
int i; int result;
smbmsg_t msg;
node_t node; node_t node;
msghdr_t hdr=msg->hdr;
idxrec_t idx=msg->idx;
time32_t now32;
uint usernumber = 0; uint usernumber = 0;
if(to == NULL) if(to == NULL)
return false; return false;
uint16_t net_type = smb_netaddr_type(to); uint16_t net_type = NET_NONE;
if(net_type == NET_NONE || net_type == NET_UNKNOWN) { if(strchr(to, '@') != NULL)
net_type = smb_netaddr_type(to);
if(net_type == NET_NONE) {
usernumber = finduser(to); usernumber = finduser(to);
if(usernumber < 1) if(usernumber < 1)
return false; return false;
net_type = NET_NONE;
} else if(!is_supported_netmail_addr(&cfg, to)) { } else if(!is_supported_netmail_addr(&cfg, to)) {
bprintf(text[InvalidNetMailAddr], to); bprintf(text[InvalidNetMailAddr], to);
return false; return false;
...@@ -1367,64 +1372,114 @@ bool sbbs_t::forwardmail(smbmsg_t* msg, const char* to) ...@@ -1367,64 +1372,114 @@ bool sbbs_t::forwardmail(smbmsg_t* msg, const char* to)
return false; return false;
} }
msg->idx.attr&=~(MSG_READ|MSG_DELETE); memset(&msg, 0, sizeof(msg));
msg->hdr.attr=msg->idx.attr; msg.hdr.auxattr = orgmsg->hdr.auxattr & (MSG_HFIELDS_UTF8 | MSG_MIMEATTACH);
msg.hdr.when_imported.time = time32(NULL);
msg.hdr.when_imported.zone = sys_timezone(&cfg);
msg.hdr.when_written = msg.hdr.when_imported;
now32=time32(NULL); smb_hfield_str(&msg, SUBJECT, orgmsg->subj);
smb_hfield(msg,FORWARDED,sizeof(now32),&now32); add_msg_ids(&cfg, &smb, &msg, orgmsg);
smb_hfield_str(msg,SENDER,useron.alias); smb_hfield_str(&msg,SENDER,useron.alias);
SAFEPRINTF(str,"%u",useron.number); SAFEPRINTF(str,"%u",useron.number);
smb_hfield_str(msg,SENDEREXT,str); smb_hfield_str(&msg,SENDEREXT,str);
/* Security logging */ /* Security logging */
msg_client_hfields(msg,&client); msg_client_hfields(&msg,&client);
smb_hfield_str(msg,SENDERSERVER, server_host_name()); smb_hfield_str(&msg,SENDERSERVER, server_host_name());
if(usernumber > 0) { if(usernumber > 0) {
username(&cfg,usernumber,touser); username(&cfg,usernumber,touser);
smb_hfield_str(msg,RECIPIENT,touser); smb_hfield_str(&msg, RECIPIENT,touser);
SAFEPRINTF(str,"%u",usernumber); SAFEPRINTF(str,"%u",usernumber);
smb_hfield_str(msg,RECIPIENTEXT,str); smb_hfield_str(&msg, RECIPIENTEXT,str);
msg->idx.to=usernumber;
} else { } else {
SAFECOPY(touser, to); SAFECOPY(touser, to);
char* addr = touser; char* addr = touser;
char* p = strchr(addr, '@'); char* p = strchr(addr, '@');
if(net_type != NET_INTERNET && p != NULL) if(net_type != NET_INTERNET && p != NULL)
addr = p + 1; addr = p + 1;
smb_hfield_netaddr(msg, RECIPIENTNETADDR, addr, NULL); smb_hfield_netaddr(&msg, RECIPIENTNETADDR, addr, NULL);
if(p != NULL) if(p != NULL)
*p = '\0'; *p = '\0';
smb_hfield_str(msg, RECIPIENT, touser); smb_hfield_str(&msg, RECIPIENT, touser);
SAFECOPY(touser, to); SAFECOPY(touser, to);
msg->idx.to=0;
} }
if(orgmsg->mime_version != NULL) {
safe_snprintf(str, sizeof(str), "MIME-Version: %s", orgmsg->mime_version);
smb_hfield_str(&msg, RFC822HEADER, str);
}
if(orgmsg->content_type != NULL) {
safe_snprintf(str, sizeof(str), "Content-type: %s", orgmsg->content_type);
smb_hfield_str(&msg, RFC822HEADER, str);
}
// This header field not strictly required any more:
time32_t now32 = time32(NULL);
smb_hfield(&msg, FORWARDED, sizeof(now32), &now32);
if((i=smb_open_da(&smb))!=SMB_SUCCESS) { if(comment == NULL) {
errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); while(online) {
bputs(text[UeditComment]);
if(!getstr(str, 70, K_WRAP))
break;
smb_hfield_str(&msg, SMB_COMMENT, str);
}
} else {
if(*comment)
smb_hfield_str(&msg, SMB_COMMENT, comment);
}
smb_hfield_str(&msg, SMB_COMMENT, "-----Forwarded Message-----");
if(orgmsg->from_net.addr != NULL)
safe_snprintf(str, sizeof(str), "From: %s <%s>",orgmsg->from, smb_netaddrstr(&orgmsg->from_net, tmp));
else
safe_snprintf(str, sizeof(str), "From: %s", orgmsg->from);
smb_hfield_str(&msg, SMB_COMMENT, str);
safe_snprintf(str, sizeof(str), "Date: %s", msgdate(orgmsg->hdr.when_written, tmp));
smb_hfield_str(&msg, SMB_COMMENT, str);
if(orgmsg->to_net.addr != NULL)
safe_snprintf(str, sizeof(str), "To: %s <%s>", orgmsg->to, smb_netaddrstr(&orgmsg->to_net, tmp));
else
safe_snprintf(str, sizeof(str), "To: %s", orgmsg->to);
smb_hfield_str(&msg, SMB_COMMENT, str);
safe_snprintf(str, sizeof(str), "Subject: %s", orgmsg->subj);
smb_hfield_str(&msg, SMB_COMMENT, str);
smb_hfield_str(&msg, SMB_COMMENT, nulstr);
// Re-use the original message's data
if((result = smb_open_da(&smb)) != SMB_SUCCESS) {
smb_freemsgmem(&msg);
errormsg(WHERE, ERR_OPEN, smb.file, result, smb.last_error);
return false; return false;
} }
if((i=smb_incmsg_dfields(&smb,msg,1))!=SMB_SUCCESS) { if((result = smb_incmsg_dfields(&smb, orgmsg, 1)) != SMB_SUCCESS) {
errormsg(WHERE,ERR_WRITE,smb.file,i); smb_freemsgmem(&msg);
errormsg(WHERE, ERR_WRITE, smb.file, result, smb.last_error);
return false; return false;
} }
smb_close_da(&smb); smb_close_da(&smb);
if((i=smb_addmsghdr(&smb,msg,smb_storage_mode(&cfg, &smb)))!=SMB_SUCCESS) { msg.dfield = orgmsg->dfield;
errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error); msg.hdr.offset = orgmsg->hdr.offset;
smb_freemsg_dfields(&smb,msg,1); msg.hdr.total_dfields = orgmsg->hdr.total_dfields;
return false;
if(orgmsg->hdr.auxattr&MSG_FILEATTACH) {
copyfattach(usernumber, useron.number, orgmsg->subj);
msg.hdr.auxattr |= MSG_FILEATTACH;
} }
if(msg->hdr.auxattr&MSG_FILEATTACH) result = smb_addmsghdr(&smb, &msg, smb_storage_mode(&cfg, &smb));
copyfattach(usernumber,useron.number,msg->subj); msg.dfield = NULL;
smb_freemsgmem(&msg);
if(result != SMB_SUCCESS) {
errormsg(WHERE, ERR_WRITE, smb.file, result, smb.last_error);
smb_freemsg_dfields(&smb, orgmsg, 1);
return false;
}
bprintf(text[Forwarded], touser, usernumber); bprintf(text[Forwarded], touser, usernumber);
SAFEPRINTF(str, "forwarded mail to %s", touser); SAFEPRINTF(str, "forwarded mail to %s", touser);
logline("E+",str); logline("E+",str);
msg->idx=idx;
msg->hdr=hdr;
if(usernumber==1) { if(usernumber==1) {
useron.fbacks++; useron.fbacks++;
...@@ -1440,6 +1495,7 @@ bool sbbs_t::forwardmail(smbmsg_t* msg, const char* to) ...@@ -1440,6 +1495,7 @@ bool sbbs_t::forwardmail(smbmsg_t* msg, const char* to)
putuserrec(&cfg,useron.number,U_ETODAY,5,ultoa(useron.etoday,tmp,10)); putuserrec(&cfg,useron.number,U_ETODAY,5,ultoa(useron.etoday,tmp,10));
if(usernumber > 0) { if(usernumber > 0) {
int i;
for(i=1;i<=cfg.sys_nodes;i++) { /* Tell user, if online */ for(i=1;i<=cfg.sys_nodes;i++) { /* Tell user, if online */
getnodedat(i,&node,0); getnodedat(i,&node,0);
if(node.useron==usernumber && !(node.misc&NODE_POFF) if(node.useron==usernumber && !(node.misc&NODE_POFF)
......
...@@ -713,33 +713,24 @@ static void set_convenience_ptr(smbmsg_t* msg, uint16_t hfield_type, void* hfiel ...@@ -713,33 +713,24 @@ static void set_convenience_ptr(smbmsg_t* msg, uint16_t hfield_type, void* hfiel
{ {
switch(hfield_type) { /* convenience variables */ switch(hfield_type) { /* convenience variables */
case SENDER: case SENDER:
if(msg->from==NULL || *(msg->from)==0) {
msg->from=(char*)hfield_dat; msg->from=(char*)hfield_dat;
break; break;
} case FORWARDED:
case FORWARDED: /* fall through */
msg->forwarded = TRUE; msg->forwarded = TRUE;
msg->to_ext = NULL;
memset(&msg->to_net, 0, sizeof(msg->to_net));
break; break;
case SENDERAGENT: case SENDERAGENT:
if(!msg->forwarded)
msg->from_agent=*(uint16_t *)hfield_dat; msg->from_agent=*(uint16_t *)hfield_dat;
break; break;
case SENDEREXT: case SENDEREXT:
if(!msg->forwarded)
msg->from_ext=(char*)hfield_dat; msg->from_ext=(char*)hfield_dat;
break; break;
case SENDERORG: case SENDERORG:
if(!msg->forwarded)
msg->from_org=(char*)hfield_dat; msg->from_org=(char*)hfield_dat;
break; break;
case SENDERNETTYPE: case SENDERNETTYPE:
if(!msg->forwarded)
msg->from_net.type=*(uint16_t *)hfield_dat; msg->from_net.type=*(uint16_t *)hfield_dat;
break; break;
case SENDERNETADDR: case SENDERNETADDR:
if(!msg->forwarded)
msg->from_net.addr=(char*)hfield_dat; msg->from_net.addr=(char*)hfield_dat;
break; break;
case SENDERIPADDR: case SENDERIPADDR:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment