git: 9front

Download patch

ref: a97542bf723a772cc92534c985040115f32a2404
parent: f9a9d1272e0e6dc773cd2faa592ba0a4bb42d8f5
author: noodle <noodle@pastanoggin.com>
date: Tue Jan 13 16:30:17 EST 2026

ircrc: fix title not matching actual target, make /p update target, and relax chanlist parsing

Fix a bug where init code and /j handler call title() *before* target
is changed to the last element in a joinlist, resulting in a mismatch
between the title and target; make /p update target after PART; and
relax channel list parsing to ignore extra commas, so that a command
like "/j #a," updates target to "#a".  (IRCD's ignore extra commas in
commands like JOIN/PRIVMSG/PART/etc too.)

Fix a side effect in out() due to a sub() call on $0 by assigning $0
to a variable.

--- a/rc/bin/ircrc
+++ b/rc/bin/ircrc
@@ -31,19 +31,27 @@
 	echo NICK $nick
 	if (~ $#pass 1)
 		echo PRIVMSG NickServ :IDENTIFY $pass
-	if(! ~ $target ''){
-		title $target
-		echo JOIN $target
-	}
 	awk -v 'target='^$"target '
 	BEGIN{
-		if(target ~ /.+,.+/){
-			n = split(target, a, ",")
-			target = a[n]
+		if(last = listlast(target)){
+			print "JOIN", target
+			victims[last]
+			title()
 		}
 	}
+	function listlast(list, a){
+		for(i=split(list, a, ",+"); i>=1; i--)
+			if(a[i] != "")
+				return a[i]
+		return ""
+	}
+	function mktarget(s){
+		for(v in victims)
+			s = s "," v
+		return substr(s, 2)
+	}
 	function title(){
-		system("title ''"target"''")
+		system("title ''"mktarget()"''")
 	}
 	function etime(c, t){
 		c = "date -f ''[\\[]hh:mm[\\]]''"
@@ -51,23 +59,26 @@
 		close(c)
 		return t
 	}
-	function out(nskip, space, pref, echo){
+	function out(nskip, space, pref, echo,	line, r){
+		line = $0
 		if(nskip){
 			r = "^";
 			for(i = 0; i < nskip; i++)
 				r = r "[^\t ]+[\t ]*"
-			sub(r, "")
+			sub(r, "", line)
 		}
 		if(echo)
-			print echo $0 >"/dev/cons"
-		print pref (space&&$0 ? " " : "") $0
+			print echo line >"/dev/cons"
+		print pref (space&&line ? " " : "") line
 	}
 	$1 !~ /^\//{
+		target = mktarget()
 		out(0, 0, "PRIVMSG "target" :", NF>0 ? etime()" ("target")	⇐	" : "")
 		next
 	}
 	$1 == "/!"{
 		if(NF > 1){
+			target = mktarget()
 			c = substr($0, index($0, $2))
 			while(c | getline)
 				out(0, 0, "PRIVMSG "target" :", "PRIVMSG "target" :")
@@ -80,12 +91,11 @@
 	$1 == "/T"{ if(NF > 1) out(1, 1, "TOPIC"); next }
 	$1 == "/W"{ out(1, 1, "WHOIS"); next }
 	$1 == "/a"{ out(1, 0, "AWAY :"); next }
-	$1 == "/j"{
-		if(NF == 2 || NF == 3){
-			target = $2
+	$1 == "/j" && (NF==2 || NF==3){
+		if(last = listlast($2)){
+			delete victims
+			victims[last]
 			title()
-			if(target ~ /.+,.+/)
-				target = a[split(target, a, ",")]
 			out(1, 1, "JOIN")
 		}
 		next
@@ -97,9 +107,26 @@
 		next
 	}
 	$1 == "/n"{ nick = $2; out(1, 1, "NICK"); next }
-	$1 == "/p"{ if(NF > 1) out(2, 0, "PART "$2" :"); next }
+	$1 == "/p"{
+		if(NF > 1){
+			out(2, 0, "PART "$2" :")
+			split($2, a, ",+")
+			for(v in a)
+				delete victims[a[v]]
+			title()
+		}
+		next
+	}
 	$1 == "/q"{ out(1, 0); next }
-	$1 == "/t"{ target = $2; title(); next }
+	$1 == "/t"{
+		delete victims
+		split($2, a, ",+")
+		for(v in a)
+			if(a[v])
+				victims[a[v]]
+		title();
+		next
+	}
 	$1 == "/u"{ out(1, 1, "USERS"); next }
 	$1 == "/w"{ out(1, 1, "WHO"); next }
 	$1 == "/x"{ out(1, 0, "QUIT :"); exit }
--