From 366e662da2cdb0767af34fce2d5ad13e58391dc5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Deuc=D0=B5?= <shurd@sasktel.net>
Date: Fri, 11 Apr 2025 01:17:37 -0400
Subject: [PATCH] Clear line counter when clearing SS_ABORT

Also, always use clearabort() to clear SS_ABORT now, and move the
method body into con_out.cpp (where msgabort() is) since it actually
does a thing now.

Fixes issue #907
---
 src/sbbs3/ansi_terminal.cpp |  2 +-
 src/sbbs3/bat_xfer.cpp      |  2 +-
 src/sbbs3/chat.cpp          | 11 ++++++-----
 src/sbbs3/con_out.cpp       | 10 +++++++++-
 src/sbbs3/exec.cpp          |  6 +++---
 src/sbbs3/getkey.cpp        |  2 +-
 src/sbbs3/getstr.cpp        |  2 +-
 src/sbbs3/js_console.cpp    |  2 +-
 src/sbbs3/main.cpp          |  2 +-
 src/sbbs3/prntfile.cpp      |  6 +++---
 src/sbbs3/putmsg.cpp        |  6 +++---
 src/sbbs3/readmail.cpp      |  2 +-
 src/sbbs3/readmsgs.cpp      |  4 ++--
 src/sbbs3/sbbs.h            |  2 +-
 src/sbbs3/str.cpp           |  2 +-
 src/sbbs3/viewfile.cpp      |  2 +-
 16 files changed, 36 insertions(+), 27 deletions(-)

diff --git a/src/sbbs3/ansi_terminal.cpp b/src/sbbs3/ansi_terminal.cpp
index 4e2d4a178e..d2e681e8d5 100644
--- a/src/sbbs3/ansi_terminal.cpp
+++ b/src/sbbs3/ansi_terminal.cpp
@@ -349,7 +349,7 @@ bool ANSI_Terminal::getxy(unsigned* x, unsigned* y)
 	sbbs->term_out("\x1b[6n");  /* Request cursor position */
 
 	time_t start = time(NULL);
-	sbbs->sys_status &= ~SS_ABORT;
+	sbbs->clearabort();
 	while (sbbs->online && !(sbbs->sys_status & SS_ABORT) && rsp < sizeof(str) - 1) {
 		if ((ch = sbbs->incom(1000)) != NOINP) {
 			str[rsp++] = ch;
diff --git a/src/sbbs3/bat_xfer.cpp b/src/sbbs3/bat_xfer.cpp
index 23f0b13902..84d55184f8 100644
--- a/src/sbbs3/bat_xfer.cpp
+++ b/src/sbbs3/bat_xfer.cpp
@@ -52,7 +52,7 @@ void sbbs_t::batchmenu()
 	term->lncntr = 0;
 	while (online && (cfg.upload_dir != INVALID_DIR || batdn_total() || batup_total())) {
 		if (!(useron.misc & (EXPERT | RIP))) {
-			sys_status &= ~SS_ABORT;
+			clearabort();
 			if (term->lncntr) {
 				sync();
 				CRLF;
diff --git a/src/sbbs3/chat.cpp b/src/sbbs3/chat.cpp
index 6eb629bf22..52eb21e62f 100644
--- a/src/sbbs3/chat.cpp
+++ b/src/sbbs3/chat.cpp
@@ -163,7 +163,7 @@ void sbbs_t::multinodechat(int channel)
 			preusr[i] = usr[i];
 		attr(cfg.color[clr_multichat]);
 		sync();
-		sys_status &= ~SS_ABORT;
+		clearabort();
 		if ((ch = inkey(K_NONE, 250)) != 0 || wordwrap[0]) {
 			if (ch == '/') {
 				bputs(text[MultiChatCommandPrompt]);
@@ -1163,7 +1163,8 @@ void sbbs_t::privchat(bool forced, int node_num)
 	}
 	if (sys_status & SS_SPLITP)
 		CLS;
-	sys_status &= ~(SS_SPLITP | SS_ABORT);
+	clearabort();
+	sys_status &= ~(SS_SPLITP);
 	close(in);
 	close(out);
 }
@@ -1211,7 +1212,7 @@ int sbbs_t::getnodetopage(int all, int telegram)
 	SAFECOPY(str, lastnodemsguser);
 	getstr(str, LEN_ALIAS, K_LINE | K_EDIT | K_AUTODEL);
 	if (sys_status & SS_ABORT) {
-		sys_status &= ~SS_ABORT;
+		clearabort();
 		return 0;
 	}
 	if (!str[0])
@@ -1309,7 +1310,7 @@ void sbbs_t::nodemsg()
 		}
 		sync();
 		mnemonics(text[PrivateMsgPrompt]);
-		sys_status &= ~SS_ABORT;
+		clearabort();
 		while (online) {      /* Watch for incoming messages */
 			ch = toupper(inkey(K_NONE, 1000));
 			if (ch && strchr("TMCQ\r", ch))
@@ -1335,7 +1336,7 @@ void sbbs_t::nodemsg()
 		}
 
 		if (!online || sys_status & SS_ABORT) {
-			sys_status &= ~SS_ABORT;
+			clearabort();
 			CRLF;
 			break;
 		}
diff --git a/src/sbbs3/con_out.cpp b/src/sbbs3/con_out.cpp
index b1e416363d..918fe7f98b 100644
--- a/src/sbbs3/con_out.cpp
+++ b/src/sbbs3/con_out.cpp
@@ -1088,7 +1088,7 @@ bool sbbs_t::msgabort(bool clear)
 
 	if (sys_status & SS_ABORT) {
 		if (clear)
-			sys_status &= ~SS_ABORT;
+			clearabort();
 		return true;
 	}
 	if (!online)
@@ -1096,6 +1096,14 @@ bool sbbs_t::msgabort(bool clear)
 	return false;
 }
 
+void sbbs_t::clearabort()
+{
+	if (sys_status | SS_ABORT) {
+		term->lncntr = 0;
+		sys_status &= ~SS_ABORT;
+	}
+}
+
 int sbbs_t::backfill(const char* instr, float pct, int full_attr, int empty_attr)
 {
 	uint  atr;
diff --git a/src/sbbs3/exec.cpp b/src/sbbs3/exec.cpp
index ba555119b3..7d6bcea59a 100644
--- a/src/sbbs3/exec.cpp
+++ b/src/sbbs3/exec.cpp
@@ -691,7 +691,7 @@ int sbbs_t::js_execfile(const char *cmd, const char* startup_dir, JSObject* scop
 	if (!JS_ExecuteScript(js_cx, js_scope, js_script, &rval))
 		result = -1;
 	js_handle_events(js_cx, &js_callback, &terminated);
-//	sys_status &=~ SS_ABORT;
+//	clearabort();
 
 	JS_GetProperty(js_cx, js_scope, "exit_code", &rval);
 	if (rval != JSVAL_VOID)
@@ -868,7 +868,7 @@ int sbbs_t::exec_bin(const char *cmdline, csi_t *csi, const char* startup_dir)
 	freevars(&bin);
 	free(bin.cs);
 	csi->logic = bin.logic;
-//	sys_status &=~ SS_ABORT;
+//	clearabort();
 	return bin.retval;
 }
 
@@ -1936,7 +1936,7 @@ int sbbs_t::exec(csi_t *csi)
 			return 0;
 
 		case CS_CLEAR_ABORT:
-			sys_status &= ~SS_ABORT;
+			clearabort();
 			return 0;
 		case CS_FINDUSER:
 			i = finduser(csi->str);
diff --git a/src/sbbs3/getkey.cpp b/src/sbbs3/getkey.cpp
index e07d2931e8..558417883e 100644
--- a/src/sbbs3/getkey.cpp
+++ b/src/sbbs3/getkey.cpp
@@ -42,7 +42,7 @@ char sbbs_t::getkey(int mode)
 		YIELD();    // just in case someone is looping on getkey() when they shouldn't
 		return 0;
 	}
-	sys_status &= ~SS_ABORT;
+	clearabort();
 	if ((sys_status & SS_USERON || action == NODE_DFLT) && !(mode & (K_GETSTR | K_NOSPIN)))
 		mode |= (useron.misc & SPIN);
 	term->lncntr = 0;
diff --git a/src/sbbs3/getstr.cpp b/src/sbbs3/getstr.cpp
index 0df5afce0c..b57a5a321c 100644
--- a/src/sbbs3/getstr.cpp
+++ b/src/sbbs3/getstr.cpp
@@ -44,7 +44,7 @@ size_t sbbs_t::getstr(char *strout, size_t maxlen, int mode, const str_list_t hi
 	console &= ~(CON_UPARROW | CON_DOWNARROW | CON_LEFTARROW | CON_RIGHTARROW | CON_BACKSPACE | CON_DELETELINE);
 	if (!(mode & K_WORDWRAP))
 		console &= ~CON_INSERT;
-	sys_status &= ~SS_ABORT;
+	clearabort();
 	if (!(mode & K_LINEWRAP) && term->cols >= TERM_COLS_MIN && !(mode & K_NOECHO) && !(console & CON_R_ECHOX)
 	    && term->column + (int)maxlen >= term->cols)    /* Don't allow the terminal to auto line-wrap */
 		maxlen = term->cols - term->column - 1;
diff --git a/src/sbbs3/js_console.cpp b/src/sbbs3/js_console.cpp
index 7b84d5a0e6..e6de4096de 100644
--- a/src/sbbs3/js_console.cpp
+++ b/src/sbbs3/js_console.cpp
@@ -351,7 +351,7 @@ static JSBool js_console_set(JSContext *cx, JSObject *obj, jsid id, JSBool stric
 			if (val)
 				sbbs->sys_status |= SS_ABORT;
 			else
-				sbbs->sys_status &= ~SS_ABORT;
+				sbbs->clearabort();
 			break;
 		case CON_PROP_ABORTABLE:
 			sbbs->rio_abortable = val
diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp
index 3eb33bad3d..a25613ff0c 100644
--- a/src/sbbs3/main.cpp
+++ b/src/sbbs3/main.cpp
@@ -4236,7 +4236,7 @@ int sbbs_t::rioctl(ushort action)
 
 	if ((action & 0xff) == IOCS) {   /* Clear state */
 		if (action & ABORT)
-			sys_status &= ~SS_ABORT;
+			clearabort();
 		return 0;
 	}
 
diff --git a/src/sbbs3/prntfile.cpp b/src/sbbs3/prntfile.cpp
index 5266f11e14..1b292034d3 100644
--- a/src/sbbs3/prntfile.cpp
+++ b/src/sbbs3/prntfile.cpp
@@ -73,7 +73,7 @@ bool sbbs_t::printfile(const char* inpath, int mode, int org_cols, JSObject* obj
 			rioctl(IOCM | ABORT);
 			rioctl(IOCS | ABORT);
 		}
-		sys_status &= ~SS_ABORT;
+		clearabort();
 	}
 
 	if (!(mode & P_NOXATTRS))
@@ -205,7 +205,7 @@ bool sbbs_t::printtail(const char* fname, int lines, int mode, int org_cols, JSO
 			rioctl(IOCM | ABORT);
 			rioctl(IOCS | ABORT);
 		}
-		sys_status &= ~SS_ABORT;
+		clearabort();
 	}
 	if ((fp = fnopen(&file, fpath, O_RDONLY | O_DENYNONE)) == NULL) {
 		if (!(mode & P_NOERROR)) {
@@ -287,7 +287,7 @@ bool sbbs_t::menu(const char *code, int mode, JSObject* obj)
 	if (strcspn(code, "*?") != strlen(code))
 		return random_menu(code, mode, obj);
 
-	sys_status &= ~SS_ABORT;
+	clearabort();
 	if (menu_file[0])
 		SAFECOPY(path, menu_file);
 	else {
diff --git a/src/sbbs3/putmsg.cpp b/src/sbbs3/putmsg.cpp
index 756219f47a..dfe3f464cc 100644
--- a/src/sbbs3/putmsg.cpp
+++ b/src/sbbs3/putmsg.cpp
@@ -233,7 +233,7 @@ char sbbs_t::putmsgfrag(const char* buf, int& mode, unsigned org_cols, JSObject*
 				bool was_tos = (term->row == 0);
 				ctrl_a(str[l + 1]);
 				if (term->row == 0 && !was_tos && (sys_status & SS_ABORT) && !lines_printed) /* Aborted at (auto) pause prompt (e.g. due to CLS)? */
-					sys_status &= ~SS_ABORT;                /* Clear the abort flag (keep displaying the msg/file) */
+					clearabort();                /* Clear the abort flag (keep displaying the msg/file) */
 				l += 2;
 			}
 		}
@@ -452,7 +452,7 @@ char sbbs_t::putmsgfrag(const char* buf, int& mode, unsigned org_cols, JSObject*
 					break;
 				if (memcmp(str + l, "@CLEAR@", 7) == 0) {
 					CLS;
-					sys_status &= ~SS_ABORT;
+					clearabort();
 					l += 7;
 					while (str[l] != 0 && (str[l] == '\r' || str[l] == '\n'))
 						l++;
@@ -524,7 +524,7 @@ char sbbs_t::putmsgfrag(const char* buf, int& mode, unsigned org_cols, JSObject*
 				i = show_atcode((char *)str + l, obj);  /* returns 0 if not valid @ code */
 				l += i;                   /* i is length of code string */
 				if (term->row > 0 && !was_tos && (sys_status & SS_ABORT) && !lines_printed)  /* Aborted at (auto) pause prompt (e.g. due to CLS)? */
-					sys_status &= ~SS_ABORT;                /* Clear the abort flag (keep displaying the msg/file) */
+					clearabort();                /* Clear the abort flag (keep displaying the msg/file) */
 				if (i)                   /* if valid string, go to top */
 					continue;
 			}
diff --git a/src/sbbs3/readmail.cpp b/src/sbbs3/readmail.cpp
index e2fd06aaa2..9b8c6eecdf 100644
--- a/src/sbbs3/readmail.cpp
+++ b/src/sbbs3/readmail.cpp
@@ -181,7 +181,7 @@ int sbbs_t::readmail(uint usernumber, int which, int lm_mode)
 			else
 				smb.curmsg = l;
 		}
-		sys_status &= ~SS_ABORT;
+		clearabort();
 	}
 	else {
 		smb.curmsg = 0;
diff --git a/src/sbbs3/readmsgs.cpp b/src/sbbs3/readmsgs.cpp
index edb5300583..2e6a16d1e1 100644
--- a/src/sbbs3/readmsgs.cpp
+++ b/src/sbbs3/readmsgs.cpp
@@ -1009,13 +1009,13 @@ int sbbs_t::scanposts(int subnum, int mode, const char *find)
 					break;
 				i = (int)i64;
 				listmsgs(subnum, 0, post, i, smb.msgs);
-				sys_status &= ~SS_ABORT;
+				clearabort();
 				break;
 			case 'N':   /* New messages */
 				domsg = 0;
 				if (!listmsgs(subnum, SCAN_NEW, post, 0, smb.msgs))
 					bputs(text[NoMessagesFound]);
-				sys_status &= ~SS_ABORT;
+				clearabort();
 				break;
 			case 'M':   /* Reply to last post in mail */
 				domsg = 0;
diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h
index fdceefaa46..512e3aefb5 100644
--- a/src/sbbs3/sbbs.h
+++ b/src/sbbs3/sbbs.h
@@ -822,7 +822,7 @@ public:
 	char*	quotes_fname(int xedit, char* buf, size_t len);
 	char*	msg_tmp_fname(int xedit, char* fname, size_t len);
 	bool	msgabort(bool clear = false);
-	void	clearabort() { sys_status &= ~SS_ABORT; }
+	void	clearabort();
 	bool	email(int usernumber, const char *top = NULL, const char *title = NULL
 				, int mode = WM_NONE, smb_t* resmb = NULL, smbmsg_t* remsg = NULL);
 	bool	forwardmsg(smb_t*, smbmsg_t*, const char* to, const char* subject = NULL, const char* comment = NULL);
diff --git a/src/sbbs3/str.cpp b/src/sbbs3/str.cpp
index a77ac323f1..81d069f449 100644
--- a/src/sbbs3/str.cpp
+++ b/src/sbbs3/str.cpp
@@ -652,7 +652,7 @@ size_t sbbs_t::gettmplt(char *strout, const char *templt, int mode)
 	char   tmplt[128];
 	size_t t = strlen(templt), c = 0;
 
-	sys_status &= ~SS_ABORT;
+	clearabort();
 	SAFECOPY(tmplt, templt);
 	strupr(tmplt);
 	// MODE7: This was ANSI-only, added support for PETSCII, 
diff --git a/src/sbbs3/viewfile.cpp b/src/sbbs3/viewfile.cpp
index 680025da19..10a1614c55 100644
--- a/src/sbbs3/viewfile.cpp
+++ b/src/sbbs3/viewfile.cpp
@@ -37,7 +37,7 @@ int sbbs_t::viewfile(file_t* f, bool ext)
 	curdirnum = f->dir;   /* for ARS */
 	bool can_edit = dir_op(f->dir) || useron.exempt & FLAG('R') || stricmp(f->from, useron.alias) == 0;
 	while (online) {
-		sys_status &= ~SS_ABORT;
+		clearabort();
 		SAFEPRINTF(str, text[FileInfoPrompt], fname);
 		if (ext) {
 			showfileinfo(f);
-- 
GitLab