repo: ngircd
action: commit
revision: 
path_from: 
revision_from: 3a4c149736327a32da070bc02d2212a4aa8368ec:
path_to: 
revision_to: 
git.thebackupbox.net
ngircd
git clone git://git.thebackupbox.net/ngircd
commit 3a4c149736327a32da070bc02d2212a4aa8368ec
Author: 9pfs 
Date:   Mon Dec 12 02:21:48 2022 +0000

    Implement IRCv3 extended-join client capability

diff --git a/src/ngircd/client-cap.h b/src/ngircd/client-cap.h
index 5532d3310aa0df658f7f58580bb1ccf8aed742b1..
index ..c06c305ba3ac83f2a59f3a59a0792ebfd348e98a 100644
--- a/src/ngircd/client-cap.h
+++ b/src/ngircd/client-cap.h
@@ -21,6 +21,7 @@
 #define CLIENT_CAP_SUPPORTED 2		/* Client supports IRC capabilities */

 #define CLIENT_CAP_MULTI_PREFIX 4	/* multi-prefix */
+#define CLIENT_CAP_EXTENDED_JOIN 7	/* extended-join */

 GLOBAL int Client_Cap PARAMS((CLIENT *Client));

diff --git a/src/ngircd/irc-cap.c b/src/ngircd/irc-cap.c
index bf4c9cd0c42a84a6e49ccb7e0c045ebc43034b6f..
index ..b42cf85e4a9bf47f7eae358043a17b1dd7af64ff 100644
--- a/src/ngircd/irc-cap.c
+++ b/src/ngircd/irc-cap.c
@@ -71,12 +71,16 @@ Parse_CAP(int Capabilities, char *Args)
 			ptr++;
 			if (strcmp(ptr, "multi-prefix") == 0)
 				Capabilities &= ~CLIENT_CAP_MULTI_PREFIX;
+			if (strcmp(ptr, "extended-join") == 0)
+				Capabilities &= ~CLIENT_CAP_EXTENDED_JOIN;
 			else
 				return -1;
 		} else {
 			/* request capabilities */
 			if (strcmp(ptr, "multi-prefix") == 0)
 				Capabilities |= CLIENT_CAP_MULTI_PREFIX;
+			else if (strcmp(ptr, "extended-join") == 0)
+				Capabilities |= CLIENT_CAP_EXTENDED_JOIN;
 			else
 				return -1;
 		}
@@ -103,7 +107,7 @@ Get_CAP_String(int Capabilities)
 	txt[0] = '\0';

 	if (Capabilities & CLIENT_CAP_MULTI_PREFIX)
-		strlcat(txt, "multi-prefix ", sizeof(txt));
+		strlcat(txt, "multi-prefix extended-join ", sizeof(txt));

 	return txt;
 }
@@ -123,7 +127,7 @@ Handle_CAP_LS(CLIENT *Client, UNUSED char *Arg)
 	Set_CAP_Negotiation(Client);

 	return IRC_WriteStrClient(Client,
-				  "CAP %s LS :multi-prefix",
+				  "CAP %s LS :multi-prefix extended-join",
 				  Client_ID(Client));
 }

diff --git a/src/ngircd/irc-channel.c b/src/ngircd/irc-channel.c
index 812429bbf33eadc2a0dbd5174522bb673572f121..
index ..bb828e0c25b9788ec0761a4bf30d92718e76a50f 100644
--- a/src/ngircd/irc-channel.c
+++ b/src/ngircd/irc-channel.c
@@ -34,6 +34,7 @@
 #include "irc-macros.h"
 #include "irc-write.h"
 #include "conf.h"
+#include "client-cap.h"

 #include "irc-channel.h"

@@ -236,8 +237,56 @@ join_forward(CLIENT *Client, CLIENT *target, CHANNEL *chan,
 	}

 	/* tell users in this channel about the new client */
+		#define IMPLEMENT_EXTENDED_JOIN
+	#ifndef IMPLEMENT_EXTENDED_JOIN
 	IRC_WriteStrChannelPrefix(Client, chan, target, false,
 				  "JOIN :%s",  channame);
+	#endif
+	#ifdef IMPLEMENT_EXTENDED_JOIN
+	CLIENT *c;
+	// Pointless alias
+	CHANNEL *Chan;
+	CONN_ID conn;
+	CL2CHAN *cl2chan;
+	Chan = chan;
+	cl2chan = Channel_FirstMember( Chan );
+	while(cl2chan) {
+		c = Channel_GetClient( cl2chan );
+		//if (!Remote) {
+			if (Client_Conn(c) <= NONE)
+				c = NULL;
+			else if(Client_Type(c) == CLIENT_SERVER)
+				c = NULL;
+		//}
+		if(c)
+			c = Client_NextHop(c);
+
+		if(c && c != Client) {
+			/* Ok, another Client */
+			conn = Client_Conn(c);
+			/*if (Client_Type(c) == CLIENT_SERVER)
+				//Conn_SetFlag(conn, SEND_TO_SERVER);
+				//Conn_WriteStr(conn, ":%s JOIN :%s",
+						//Client_ID(Prefix), channame);
+			else*/
+				if(Client_Cap(c) & CLIENT_CAP_EXTENDED_JOIN) {
+					char * account_name;
+					if(Client_AccountName(Client)) {
+						account_name = Client_AccountName(Client);
+					}
+					else {
+						account_name = "*";
+					}
+					Conn_WriteStr(conn, ":%s JOIN %s %s :%s", Client_MaskCloaked(Client), channame, account_name, Client_Info(Client));
+				}
+				else {
+					Conn_WriteStr(conn, ":%s JOIN %s", Client_MaskCloaked(Client), channame);
+				}
+				//Conn_SetFlag(conn, SEND_TO_USER);
+		}
+		cl2chan = Channel_NextMember(Chan, cl2chan);
+	}
+	#endif

 	/* synchronize channel modes */
 	if (modes[1]) {
@@ -264,8 +313,27 @@ join_send_topic(CLIENT *Client, CLIENT *target, CHANNEL *chan,
 	if (Client_Type(Client) != CLIENT_USER)
 		return true;
 	/* acknowledge join */
+	#ifndef IMPLEMENT_EXTENDED_JOIN
 	if (!IRC_WriteStrClientPrefix(Client, target, "JOIN :%s", channame))
 		return false;
+	#endif
+	#ifdef IMPLEMENT_EXTENDED_JOIN
+	CONN_ID conn;
+	conn = Client_Conn(Client);
+	if(Client_Cap(Client) & CLIENT_CAP_EXTENDED_JOIN) {
+		char * account_name;
+		if(Client_AccountName(Client)) {
+			account_name = Client_AccountName(Client);
+		}
+		else {
+			account_name = "*";
+		}
+		Conn_WriteStr(conn, ":%s JOIN %s %s :%s", Client_MaskCloaked(Client), channame, account_name, Client_Info(Client));
+		}
+		else {
+			Conn_WriteStr(conn, ":%s JOIN %s", Client_MaskCloaked(Client), channame);
+		}
+	#endif

 	/* Send topic to client, if any */
 	topic = Channel_Topic(chan);

-----END OF PAGE-----