From 1d41500eefb767aa366f3997e5348b837017ab21 Mon Sep 17 00:00:00 2001
From: rswindell <>
Date: Mon, 4 Jun 2018 21:50:12 +0000
Subject: [PATCH] When the system has multiple configured FidoNet addressess
 (AKAs), let the user choose which address to use as the source address when
 composing a netmail message (the default being the most appropriate for the
 dest zone/net). This change only works with SBBSecho v3.05 or later. Some
 other incremental and safety improvements to sbbs_t::netmail() too. FTN
 netmail file attachments needs some more work however (the "FA:" subject
 prefix trick) - just remove it?

---
 src/sbbs3/fido.cpp        | 71 ++++++++++++++++++++++-----------------
 src/sbbs3/text.h          |  1 +
 src/sbbs3/text_defaults.c |  1 +
 3 files changed, 43 insertions(+), 30 deletions(-)

diff --git a/src/sbbs3/fido.cpp b/src/sbbs3/fido.cpp
index 5e237e803b..ce7948710f 100644
--- a/src/sbbs3/fido.cpp
+++ b/src/sbbs3/fido.cpp
@@ -70,7 +70,7 @@ bool sbbs_t::lookup_netuser(char *into)
 
 	if(strchr(into,'@'))
 		return(false);
-	strcpy(to,into);
+	SAFECOPY(to,into);
 	strupr(to);
 	sprintf(str,"%sqnet/users.dat", cfg.data_dir);
 	if((stream=fnopen(&i,str,O_RDONLY))==NULL)
@@ -80,7 +80,7 @@ bool sbbs_t::lookup_netuser(char *into)
 			break;
 		str[25]=0;
 		truncsp(str);
-		strcpy(name,str);
+		SAFECOPY(name,str);
 		strupr(name);
 		str[35]=0;
 		truncsp(str+27);
@@ -102,7 +102,10 @@ bool sbbs_t::lookup_netuser(char *into)
 /****************************************************************************/
 bool sbbs_t::netmail(const char *into, const char *title, long mode)
 {
-	char	str[256],subj[128],to[256],fname[128],*buf,*p,ch;
+	char	str[256],fname[128],*buf,*p,ch;
+	char	to[FIDO_NAME_LEN];
+	char	from[FIDO_NAME_LEN];
+	char	subj[FIDO_SUBJ_LEN];
 	char	msgpath[MAX_PATH+1];
 	char 	tmp[512];
 	char*	editor=NULL;
@@ -112,7 +115,6 @@ bool sbbs_t::netmail(const char *into, const char *title, long mode)
 	faddr_t src_addr;
 	faddr_t dest_addr;
 	uint16_t net_type;
-	fmsghdr_t hdr;
 	smbmsg_t msg;
 	memset(&msg, 0, sizeof(msg));
 
@@ -126,14 +128,13 @@ bool sbbs_t::netmail(const char *into, const char *title, long mode)
 		return false;
 	}
 
-	SAFECOPY(subj,title);
-
-	strcpy(to,into);
+	SAFECOPY(subj, title);
+	SAFECOPY(to, into);
 
 	lookup_netuser(to);
 
 	net_type = smb_netaddr_type(to);
-	lprintf(LOG_DEBUG, "parsed net type of '%s' is %s\r\n", to, smb_nettype((enum smb_net_type)net_type));
+	lprintf(LOG_DEBUG, "parsed net type of '%s' is %s", to, smb_nettype((enum smb_net_type)net_type));
 	if(net_type == NET_QWK) {
 		if(mode&WM_FILE) {
 			bputs(text[EmailFilesNotAllowed]);
@@ -174,9 +175,7 @@ bool sbbs_t::netmail(const char *into, const char *title, long mode)
 
 	truncsp(to);				/* Truncate off space */
 
-	memset(&hdr,0,sizeof(hdr));   /* Initialize header to null */
-	SAFECOPY(hdr.from, cfg.netmail_misc&NMAIL_ALIAS ? useron.alias : useron.name);
-	SAFECOPY(hdr.to,to);
+	SAFECOPY(from, cfg.netmail_misc&NMAIL_ALIAS ? useron.alias : useron.name);
 
 	/* Look-up in nodelist? */
 
@@ -200,10 +199,19 @@ bool sbbs_t::netmail(const char *into, const char *title, long mode)
 	}
 	if(i >= cfg.total_faddrs)
 		i=0;
+
+	if(cfg.total_faddrs > 1) {
+		for(uint j=0; j < cfg.total_faddrs; j++)
+			uselect(/* add: */TRUE, j, text[OriginFidoAddr], smb_faddrtoa(&cfg.faddr[j], tmp), /* ar: */NULL);
+		int choice = uselect(/* add: */FALSE, /* default: */i, NULL, NULL, NULL);
+		if(choice < 0)
+			return false;
+		i = choice;
+	}
 	src_addr = cfg.faddr[i];
 
-	smb_faddrtoa(&cfg.faddr[i],str);
-	bprintf(text[NetMailing],hdr.to,smb_faddrtoa(&dest_addr,tmp),hdr.from,str);
+	smb_faddrtoa(&cfg.faddr[i], str);
+	bprintf(text[NetMailing], to, smb_faddrtoa(&dest_addr,tmp), from, str);
 
 	if(cfg.netmail_misc&NMAIL_CRASH) msg.hdr.netattr |= MSG_CRASH;
 	if(cfg.netmail_misc&NMAIL_HOLD)  msg.hdr.netattr |= MSG_HOLD;
@@ -211,20 +219,20 @@ bool sbbs_t::netmail(const char *into, const char *title, long mode)
 	if(mode&WM_FILE) msg.hdr.auxattr |= MSG_FILEATTACH; 
 
 	msg_tmp_fname(useron.xedit, msgpath, sizeof(msgpath));
-	if(!writemsg(msgpath,nulstr,subj,WM_NETMAIL|mode,INVALID_SUB,into,hdr.from,&editor)) {
+	if(!writemsg(msgpath,nulstr,subj,WM_NETMAIL|mode,INVALID_SUB, into, from, &editor)) {
 		bputs(text[Aborted]);
 		return(false); 
 	}
 
 	if(mode&WM_FILE) {
-		strcpy(fname,subj);
+		SAFECOPY(fname, subj);
 		sprintf(str,"%sfile/%04u.out", cfg.data_dir, useron.number);
 		MKDIR(str);
-		strcpy(tmp, cfg.data_dir);
+		SAFECOPY(tmp, cfg.data_dir);
 		if(tmp[0]=='.')    /* Relative path */
 			sprintf(tmp,"%s%s", cfg.node_dir, cfg.data_dir);
 		sprintf(str,"%sfile/%04u.out/%s",tmp,useron.number,fname);
-		strcpy(subj,str);
+		SAFECOPY(subj, str);
 		if(fexistcase(str)) {
 			bputs(text[FileAlreadyThere]);
 			return(false); 
@@ -267,32 +275,33 @@ bool sbbs_t::netmail(const char *into, const char *title, long mode)
 	if((SYSOP || useron.exempt&FLAG('F'))
 		&& !strnicmp(p,"CR:",3)) {     /* Crash over-ride by sysop */
 		p+=3;				/* skip CR: */
-		if(*p==' ') p++; 	/* skip extra space if it exists */
+		SKIP_WHITESPACE(p);
 		msg.hdr.netattr |= MSG_CRASH; 
 	}
 
 	if((SYSOP || useron.exempt&FLAG('F'))
 		&& !strnicmp(p,"FR:",3)) {     /* File request */
 		p+=3;				/* skip FR: */
-		if(*p==' ') p++;
+		SKIP_WHITESPACE(p);
 		msg.hdr.auxattr |= MSG_FILEREQUEST; 
 	}
 
 	if((SYSOP || useron.exempt&FLAG('F'))
 		&& !strnicmp(p,"RR:",3)) {     /* Return receipt request */
 		p+=3;				/* skip RR: */
-		if(*p==' ') p++;
+		SKIP_WHITESPACE(p);
 		msg.hdr.auxattr |= MSG_RECEIPTREQ; 
 	}
 
 	if((SYSOP || useron.exempt&FLAG('F'))
 		&& !strnicmp(p,"FA:",3)) {     /* File Attachment */
 		p+=3;				/* skip FA: */
-		if(*p==' ') p++;
-		hdr.attr|=FIDO_FILE; 
+		SKIP_WHITESPACE(p);
+//		hdr.attr|=FIDO_FILE;	TODO
 	}
 
-	SAFECOPY(hdr.subj,p);
+	if(p != subj)
+		SAFECOPY(subj, p);
 
 	if((file=nopen(msgpath,O_RDONLY))==-1) {
 		errormsg(WHERE,ERR_OPEN,msgpath,O_RDONLY);
@@ -307,16 +316,18 @@ bool sbbs_t::netmail(const char *into, const char *title, long mode)
 	read(file,buf,length);
 	close(file);
 
-	smb_hfield_str(&msg,SENDER,hdr.from);
+	smb_net_type_t nettype = NET_FIDO;
+	smb_hfield_str(&msg,SENDER, from);
 	sprintf(str,"%u",useron.number);
 	smb_hfield_str(&msg,SENDEREXT,str);
+	smb_hfield(&msg,SENDERNETTYPE, sizeof(nettype), &nettype); 
+	smb_hfield(&msg,SENDERNETADDR, sizeof(dest_addr), &src_addr); 
 
-	smb_hfield_str(&msg,RECIPIENT,hdr.to);
-	smb_net_type_t nettype = NET_FIDO;
+	smb_hfield_str(&msg,RECIPIENT, to);
 	smb_hfield(&msg,RECIPIENTNETTYPE, sizeof(nettype), &nettype); 
 	smb_hfield(&msg,RECIPIENTNETADDR, sizeof(dest_addr), &dest_addr); 
 
-	smb_hfield_str(&msg,SUBJECT,hdr.subj);
+	smb_hfield_str(&msg,SUBJECT, subj);
 
 	if(editor!=NULL)
 		smb_hfield_str(&msg,SMB_EDITOR,editor);
@@ -332,7 +343,7 @@ bool sbbs_t::netmail(const char *into, const char *title, long mode)
 	smb_close(&smb);
 	smb_freemsgmem(&msg);
 	if(result != SMB_SUCCESS) {
-		errormsg(WHERE, ERR_WRITE, smb.file, result);
+		errormsg(WHERE, ERR_WRITE, smb.file, result, smb.last_error);
 		return false;
 	}
 
@@ -344,11 +355,11 @@ bool sbbs_t::netmail(const char *into, const char *title, long mode)
 	if(mode&WM_FILE)
 		SAFEPRINTF3(str,"%s sent NetMail file attachment to %s (%s)"
 			,useron.alias
-			,hdr.to,smb_faddrtoa(&dest_addr,tmp));
+			,to, smb_faddrtoa(&dest_addr,tmp));
 	else
 		SAFEPRINTF3(str,"%s sent NetMail to %s (%s)"
 			,useron.alias
-			,hdr.to,smb_faddrtoa(&dest_addr,tmp));
+			,to, smb_faddrtoa(&dest_addr,tmp));
 	logline("EN",str);
 
 	return true;
diff --git a/src/sbbs3/text.h b/src/sbbs3/text.h
index bdde5b392d..34ed059021 100644
--- a/src/sbbs3/text.h
+++ b/src/sbbs3/text.h
@@ -811,6 +811,7 @@ enum {
 	,MsgHdrBodySeparator
 	,FileHdrDescSeparator
 	,RemoveFileQ
+	,OriginFidoAddr
 
 	,TOTAL_TEXT
 };
diff --git a/src/sbbs3/text_defaults.c b/src/sbbs3/text_defaults.c
index ca6a53b785..13a6d07126 100644
--- a/src/sbbs3/text_defaults.c
+++ b/src/sbbs3/text_defaults.c
@@ -1323,4 +1323,5 @@ const char * const text_defaults[TOTAL_TEXT]={
 	,"\x01\x2f\x40\x45\x58\x45\x43\x3a\x53\x48\x4f\x57\x4d\x53\x47\x41\x56\x41\x54\x41\x52\x40\x0d\x0a" // 798 MsgHdrBodySeparator
 	,"\x01\x2f\x0d\x0a\x40\x45\x58\x45\x43\x3a\x53\x48\x4f\x57\x46\x49\x4c\x45\x41\x56\x41\x54\x41\x52\x40" // 799 FileHdrDescSeparator
 	,"\x52\x65\x6d\x6f\x76\x65\x20\x66\x69\x6c\x65" // 800 RemoveFileQ
+	,"\x4f\x72\x69\x67\x69\x6e\x61\x74\x69\x6e\x67\x20\x41\x64\x64\x72\x65\x73\x73" // 801 OriginFidoAddr
 };
-- 
GitLab