From b27bd426189091d77992edcbaa306978720b7aca Mon Sep 17 00:00:00 2001
From: "Rob Swindell (on Windows 11)" <rob@synchro.net>
Date: Wed, 22 Nov 2023 03:13:17 -0800
Subject: [PATCH] Support @-code expansion in node messages and short user
 msgs/telegrams

In response to Nelgin's inquiry:
DigitalMan would it be difficult to add login/logoff date/time to these
messages?
Node  2: xxuserxx logged on Telnet
Node  2: xxuserxx  logged off

Now, you can just use @-codes to add that kind of thing to these text.dat
strings.
---
 src/sbbs3/bulkmail.cpp |  4 ++--
 src/sbbs3/chat.cpp     | 20 ++++++++++----------
 src/sbbs3/email.cpp    |  4 ++--
 src/sbbs3/file.cpp     |  4 ++--
 src/sbbs3/logon.cpp    |  2 +-
 src/sbbs3/logout.cpp   |  2 +-
 src/sbbs3/mail.cpp     |  4 ++--
 src/sbbs3/main.cpp     |  2 +-
 src/sbbs3/postmsg.cpp  |  2 +-
 src/sbbs3/putmsg.cpp   | 14 ++++++++++++++
 src/sbbs3/sbbs.h       |  8 ++++++--
 src/sbbs3/un_qwk.cpp   |  6 +++---
 src/sbbs3/un_rep.cpp   |  8 ++++----
 src/sbbs3/writemsg.cpp |  4 ++--
 14 files changed, 51 insertions(+), 33 deletions(-)

diff --git a/src/sbbs3/bulkmail.cpp b/src/sbbs3/bulkmail.cpp
index dab3bc53f0..22d4741d32 100644
--- a/src/sbbs3/bulkmail.cpp
+++ b/src/sbbs3/bulkmail.cpp
@@ -207,13 +207,13 @@ int sbbs_t::bulkmailhdr(smb_t* smb, smbmsg_t* msg, uint usernum)
 		if(node.useron==usernum && !(node.misc&NODE_POFF)
 			&& (node.status==NODE_INUSE || node.status==NODE_QUIET)) {
 			SAFEPRINTF2(str,text[EmailNodeMsg],cfg.node_num,useron.alias);
-			putnmsg(&cfg,i,str);
+			putnmsg(i,str);
 			break; 
 		} 
 	}
 	if(i>cfg.sys_nodes) {   /* User wasn't online, so leave short msg */
 		SAFEPRINTF(str,text[UserSentYouMail],useron.alias);
-		putsmsg(&cfg,usernum,str); 
+		putsmsg(usernum,str);
 	}
 	return(0);
 }
diff --git a/src/sbbs3/chat.cpp b/src/sbbs3/chat.cpp
index 2275eb6984..ff934d5d28 100644
--- a/src/sbbs3/chat.cpp
+++ b/src/sbbs3/chat.cpp
@@ -349,7 +349,7 @@ void sbbs_t::multinodechat(int channel)
 						SAFECAT(buf,crlf);
 						if(useron.chat&CHAT_ECHO)
 							bputs(buf);
-						putnmsg(&cfg,j,buf);
+						putnmsg(j,buf);
 						break;
 					case 'Q':	/* quit */
 						done=1;
@@ -479,7 +479,7 @@ void sbbs_t::multinodechat(int channel)
 									? text[UNKNOWN_USER] : useron.alias
 									,"you");
 								SAFECAT(buf,crlf);
-								putnmsg(&cfg,usr[j],buf);
+								putnmsg(usr[j],buf);
 							}
 
 
@@ -494,11 +494,11 @@ void sbbs_t::multinodechat(int channel)
 								if(i==j)
 									continue;
 								getnodedat(usr[i],&node,0);
-								putnmsg(&cfg,usr[i],buf);
+								putnmsg(usr[i],buf);
 							}
 							for(i=0;i<qusrs;i++) {
 								getnodedat(qusr[i],&node,0);
-								putnmsg(&cfg,qusr[i],buf);
+								putnmsg(qusr[i],buf);
 							}
 							continue;
 						}
@@ -513,11 +513,11 @@ void sbbs_t::multinodechat(int channel)
 						bputs(buf);
 					for(i=0;i<usrs;i++) {
 						getnodedat(usr[i],&node,0);
-						putnmsg(&cfg,usr[i],buf);
+						putnmsg(usr[i],buf);
 					}
 					for(i=0;i<qusrs;i++) {
 						getnodedat(qusr[i],&node,0);
-						putnmsg(&cfg,qusr[i],buf);
+						putnmsg(qusr[i],buf);
 					}
 					if(!usrs && channel && gurubuf
 						&& cfg.chan[channel-1]->misc&CHAN_GURU)
@@ -734,7 +734,7 @@ void sbbs_t::privchat(bool forced, int node_num)
 				sprintf(str,text[NodePChatPageMsg]
 					,cfg.node_num,thisnode.misc&NODE_ANON
 						? text[UNKNOWN_USER] : useron.alias);
-				putnmsg(&cfg,n,str);
+				putnmsg(n,str);
 				sprintf(str,"paged %s on node %d to private chat"
 					,username(&cfg,node.useron,tmp),n);
 				logline("C",str);
@@ -1379,7 +1379,7 @@ void sbbs_t::nodemsg()
 					CRLF;
 					break;
 				}
-				putsmsg(&cfg,usernumber,buf);
+				putsmsg(usernumber,buf);
 				sprintf(str,"sent telegram to %s #%u"
 					,username(&cfg,usernumber,tmp),usernumber);
 				logline("C",str);
@@ -1409,7 +1409,7 @@ void sbbs_t::nodemsg()
 						sprintf(buf,text[NodeMsgFmt],cfg.node_num
 							,thisnode.misc&NODE_ANON
 								? text[UNKNOWN_USER] : useron.alias,line);
-						putnmsg(&cfg,i,buf);
+						putnmsg(i,buf);
 						if(!(node.misc&NODE_ANON))
 							bprintf(text[MsgSentToUser],"Message"
 								,username(&cfg,usernumber,tmp),usernumber);
@@ -1433,7 +1433,7 @@ void sbbs_t::nodemsg()
 						if((node.status==NODE_INUSE
 							|| (SYSOP && node.status==NODE_QUIET))
 							&& (SYSOP || !(node.misc&NODE_POFF)))
-							putnmsg(&cfg,i,buf);
+							putnmsg(i,buf);
 					}
 					SAFECOPY(str,"sent message to all nodes");
 					logline("C",str);
diff --git a/src/sbbs3/email.cpp b/src/sbbs3/email.cpp
index dc18614cc7..1668d01c9c 100644
--- a/src/sbbs3/email.cpp
+++ b/src/sbbs3/email.cpp
@@ -326,13 +326,13 @@ bool sbbs_t::email(int usernumber, const char *top, const char *subj, int mode,
 		if(node.useron==usernumber && !(node.misc&NODE_POFF)
 			&& (node.status==NODE_INUSE || node.status==NODE_QUIET)) {
 			safe_snprintf(str,sizeof(str),text[EmailNodeMsg],cfg.node_num,useron.alias);
-			putnmsg(&cfg,i,str);
+			putnmsg(i,str);
 			break; 
 		} 
 	}
 	if(i>cfg.sys_nodes) {	/* User wasn't online, so leave short msg */
 		safe_snprintf(str,sizeof(str),text[UserSentYouMail],useron.alias);
-		putsmsg(&cfg,usernumber,str); 
+		putsmsg(usernumber,str);
 	}
 	return(true);
 }
diff --git a/src/sbbs3/file.cpp b/src/sbbs3/file.cpp
index 24513c3ae8..852dc72728 100644
--- a/src/sbbs3/file.cpp
+++ b/src/sbbs3/file.cpp
@@ -181,7 +181,7 @@ bool sbbs_t::removefcdt(file_t* f)
 		sprintf(str,"%lu minute",cdt);
 		sprintf(tmp,text[FileRemovedUserMsg]
 			,f->name,cdt ? str : text[No]);
-		putsmsg(&cfg,u,tmp);
+		putsmsg(u,tmp);
 	}
 	else {
 		if(cfg.dir[f->dir]->misc&DIR_CDTUL)
@@ -201,7 +201,7 @@ bool sbbs_t::removefcdt(file_t* f)
 		adjustuserval(&cfg, u, USER_CDT, -cdt);
 		sprintf(tmp,text[FileRemovedUserMsg]
 			,f->name,cdt ? ultoac(cdt,str) : text[No]);
-		putsmsg(&cfg,u,tmp);
+		putsmsg(u,tmp);
 	}
 
 	adjustuserval(&cfg, u, USER_ULB, -f->size);
diff --git a/src/sbbs3/logon.cpp b/src/sbbs3/logon.cpp
index 99c7cf1099..d9db5d8252 100644
--- a/src/sbbs3/logon.cpp
+++ b/src/sbbs3/logon.cpp
@@ -549,7 +549,7 @@ bool sbbs_t::logon()
 					,cfg.node_num
 					,thisnode.misc&NODE_ANON ? text[UNKNOWN_USER] : useron.alias
 					,connection);
-				putnmsg(&cfg,i,str); 
+				putnmsg(i, str);
 			} 
 		}
 
diff --git a/src/sbbs3/logout.cpp b/src/sbbs3/logout.cpp
index e9cf622c49..c3de6296bf 100644
--- a/src/sbbs3/logout.cpp
+++ b/src/sbbs3/logout.cpp
@@ -69,7 +69,7 @@ void sbbs_t::logout()
 					SAFEPRINTF2(str,text[NodeLoggedOff],cfg.node_num
 						,thisnode.misc&NODE_ANON
 						? text[UNKNOWN_USER] : useron.alias);
-					putnmsg(&cfg,i,str); 
+					putnmsg(i, str);
 				}
 			}
 
diff --git a/src/sbbs3/mail.cpp b/src/sbbs3/mail.cpp
index c067bc0387..c3ceb97977 100644
--- a/src/sbbs3/mail.cpp
+++ b/src/sbbs3/mail.cpp
@@ -143,7 +143,7 @@ void sbbs_t::telluser(smbmsg_t* msg)
 			sprintf(str
 				,text[UserReadYourMailNodeMsg]
 				,cfg.node_num,useron.alias);
-			putnmsg(&cfg,n,str);
+			putnmsg(n,str);
 			break; 
 		} 
 	}
@@ -151,7 +151,7 @@ void sbbs_t::telluser(smbmsg_t* msg)
 		now=time(NULL);
 		sprintf(str,text[UserReadYourMail]
 			,useron.alias,timestr(now));
-		putsmsg(&cfg,usernumber,str); 
+		putsmsg(usernumber,str);
 	}
 }
 
diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp
index 714575b351..310dedbb5f 100644
--- a/src/sbbs3/main.cpp
+++ b/src/sbbs3/main.cpp
@@ -4556,7 +4556,7 @@ void sbbs_t::daily_maint(void)
 
 		if(!(user.misc&(DELETED|INACTIVE))
 			&& user.expire && (uint)user.expire<=(uint)now) {
-			putsmsg(&cfg,user.number,text[AccountHasExpired]);
+			putsmsg(user.number,text[AccountHasExpired]);
 			SAFEPRINTF2(str,"DAILY: %s #%u Expired",user.alias,user.number);
 			lputs(LOG_NOTICE, str);
 			if(cfg.level_misc[user.level]&LEVEL_EXPTOVAL
diff --git a/src/sbbs3/postmsg.cpp b/src/sbbs3/postmsg.cpp
index 194b5f6c21..0f621086d0 100644
--- a/src/sbbs3/postmsg.cpp
+++ b/src/sbbs3/postmsg.cpp
@@ -350,7 +350,7 @@ bool sbbs_t::postmsg(int subnum, int wm_mode, smb_t* resmb, smbmsg_t* remsg)
 				,cfg.sub[subnum]->misc&SUB_NAME ? useron.name : useron.alias
 				,connection
 				,cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->lname);
-			putsmsg(&cfg, i, str);
+			putsmsg(i, str);
 		}
 	}
 
diff --git a/src/sbbs3/putmsg.cpp b/src/sbbs3/putmsg.cpp
index 9b87afacdf..8fd446289c 100644
--- a/src/sbbs3/putmsg.cpp
+++ b/src/sbbs3/putmsg.cpp
@@ -552,3 +552,17 @@ char sbbs_t::putmsgfrag(const char* buf, int& mode, int org_cols, JSObject* obj)
 
 	return str[l];
 }
+
+// Write short message (telegram) to user, supports @-codes
+bool sbbs_t::putsmsg(int user_num, const char* str)
+{
+	char buf[256];
+	return ::putsmsg(&cfg, user_num, expand_atcodes(str, buf, sizeof buf)) == 0;
+}
+
+// Write short message to node in-use, supports @-codes
+bool sbbs_t::putnmsg(int node_num, const char* str)
+{
+	char buf[256];
+	return ::putnmsg(&cfg, node_num, expand_atcodes(str, buf, sizeof buf)) == 0;
+}
diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h
index 8115232e2d..9ca0dd785f 100644
--- a/src/sbbs3/sbbs.h
+++ b/src/sbbs3/sbbs.h
@@ -768,14 +768,18 @@ public:
 	void	time_bank(void);
 	void	change_user(void);
 
+	/* putmsg.cpp */
+	char	putmsg(const char *str, int mode, int org_cols = 0, JSObject* obj = NULL);
+	char	putmsgfrag(const char* str, int& mode, int org_cols = 0, JSObject* obj = NULL);
+	bool	putnmsg(int node_num, const char*);
+	bool	putsmsg(int user_num, const char*);
+
 	/* writemsg.cpp */
 	void	automsg(void);
 	bool	writemsg(const char *str, const char *top, char *subj, int mode, int subnum
 				,const char *to, const char* from, const char** editor=NULL, const char** charset=NULL);
 	char*	quotes_fname(int xedit, char* buf, size_t len);
 	char*	msg_tmp_fname(int xedit, char* fname, size_t len);
-	char	putmsg(const char *str, int mode, int org_cols = 0, JSObject* obj = NULL);
-	char	putmsgfrag(const char* str, int& mode, int org_cols = 0, JSObject* obj = NULL);
 	bool	msgabort(bool clear = false);
 	void	clearabort() { sys_status &= ~SS_ABORT; }
 	bool	email(int usernumber, const char *top = NULL, const char *title = NULL
diff --git a/src/sbbs3/un_qwk.cpp b/src/sbbs3/un_qwk.cpp
index 91fe091851..e051c08c42 100644
--- a/src/sbbs3/un_qwk.cpp
+++ b/src/sbbs3/un_qwk.cpp
@@ -251,7 +251,7 @@ bool sbbs_t::unpack_qwk(char *packet,uint hubnum)
 			if(qwk_import_msg(qwk, (char *)block, blocks, hubnum+1, &smb, usernum, &msg, &dupe)) {
 				lprintf(LOG_INFO,"Imported QWK mail message from %s to %s #%u", msg.from, msg.to, usernum);
 				SAFEPRINTF(str,text[UserSentYouMail],msg.from);
-				putsmsg(&cfg,usernum,str);
+				putsmsg(usernum,str);
 				tmsgs++;
 			} else {
 				if(dupe)
@@ -337,7 +337,7 @@ bool sbbs_t::unpack_qwk(char *packet,uint hubnum)
 					,msg.from
 					,cfg.qhub[hubnum]->id
 					,cfg.grp[cfg.sub[j]->grp]->sname, cfg.sub[j]->lname);
-				putsmsg(&cfg, destuser, str);
+				putsmsg( destuser, str);
 			}
 		} else {
 			if(dupe)
@@ -399,7 +399,7 @@ bool sbbs_t::unpack_qwk(char *packet,uint hubnum)
 		SAFEPRINTF2(fname,"%s/%s",inbox,dirent->d_name);
 		mv(str,fname,1 /* overwrite */);
 		sprintf(str,text[ReceivedFileViaQWK],dirent->d_name,cfg.qhub[hubnum]->id);
-		putsmsg(&cfg,1,str);
+		putsmsg(1,str);
 		lprintf(LOG_INFO,"Received file from %s: %s", cfg.qhub[hubnum]->id, dirent->d_name);
 	}
 	if(dir!=NULL)
diff --git a/src/sbbs3/un_rep.cpp b/src/sbbs3/un_rep.cpp
index 23bb28e1b4..1ddb6657e0 100644
--- a/src/sbbs3/un_rep.cpp
+++ b/src/sbbs3/un_rep.cpp
@@ -340,14 +340,14 @@ bool sbbs_t::unpack_rep(char* repfile)
 							|| node.status==NODE_QUIET)) {
 							SAFEPRINTF2(str,text[EmailNodeMsg]
 								,cfg.node_num,msg.from);
-							putnmsg(&cfg,k,str);
+							putnmsg(k,str);
 							break;
 						}
 					}
 				}
 				if(cfg.node_num==0 || k>cfg.sys_nodes) {
 					SAFEPRINTF(str,text[UserSentYouMail],msg.from);
-					putsmsg(&cfg,usernum,str);
+					putsmsg(usernum,str);
 				}
 				tmsgs++;
 			} else {
@@ -498,7 +498,7 @@ bool sbbs_t::unpack_rep(char* repfile)
 						,msg.from
 						,(useron.rest&FLAG('Q')) ? useron.alias : "QWK"
 						,cfg.grp[cfg.sub[n]->grp]->sname, cfg.sub[n]->lname);
-					putsmsg(&cfg, destuser, str);
+					putsmsg(destuser, str);
 				}
 				if(!(useron.rest&FLAG('Q')))
 					user_event(EVENT_POST);
@@ -607,7 +607,7 @@ bool sbbs_t::unpack_rep(char* repfile)
 			SAFEPRINTF2(fname,"%s/%s",inbox,dirent->d_name);
 			mv(str,fname,1);
 			SAFEPRINTF2(str,text[ReceivedFileViaQWK],dirent->d_name,useron.alias);
-			putsmsg(&cfg,1,str);
+			putsmsg(1,str);
 			lprintf(LOG_NOTICE, "Received file: %s", dirent->d_name);
 		}
 		if(dir!=NULL)
diff --git a/src/sbbs3/writemsg.cpp b/src/sbbs3/writemsg.cpp
index 901c61e163..5600ef8f3b 100644
--- a/src/sbbs3/writemsg.cpp
+++ b/src/sbbs3/writemsg.cpp
@@ -1592,13 +1592,13 @@ bool sbbs_t::forwardmsg(smb_t* smb, smbmsg_t* orgmsg, const char* to, const char
 			if(node.useron==usernumber && !(node.misc&NODE_POFF)
 				&& (node.status==NODE_INUSE || node.status==NODE_QUIET)) {
 				SAFEPRINTF2(str,text[EmailNodeMsg],cfg.node_num,useron.alias);
-				putnmsg(&cfg,i,str);
+				putnmsg(i,str);
 				break;
 			}
 		}
 		if(i>cfg.sys_nodes) {	/* User wasn't online, so leave short msg */
 			SAFEPRINTF(str,text[UserSentYouMail],useron.alias);
-			putsmsg(&cfg,usernumber,str);
+			putsmsg(usernumber,str);
 		}
 	} else {
 		if(net_type == NET_FIDO && cfg.netmail_sem[0])
-- 
GitLab