Commit Diff


commit - c5da48368569383d064a2325ab3b99d10287a085
commit + d9a97f2857bffb30c8161e4752e7d75bb5fe0359
blob - a9317873a92192454883ff23006a6e0fb01097c6
blob + 61d5e8f66a7cdb83a4fdbe0adf98e6c2420f5f18
--- doc/Modes.txt
+++ doc/Modes.txt
@@ -2,7 +2,7 @@
                      ngIRCd - Next Generation IRC Server
                            http://ngircd.barton.de/
 
-               (c)2001-2014 Alexander Barton and Contributors.
+               (c)2001-2015 Alexander Barton and Contributors.
                ngIRCd is free software and published under the
                    terms of the GNU General Public License.
 
@@ -28,6 +28,7 @@ channels he is using at the moment.
   C	19	Only users that share a channel are allowed to send messages.
   F	22	Relaxed flood protection (only settable by IRC Operators).
   i	0.0.1	User is "invisible".
+  I 23	No channels are shown on WHOIS (IRC Operators can always see those).
   o	0.0.1	User is IRC operator.
   q	20	User is protected, can not be kicked from a channel.
   r	0.0.1	User is restricted.
blob - 456c4c9351f78f44735c859cf08767df519b71b4
blob + ff849bbeacb2b157c1a747b6a3f0783bafe612b5
--- src/ngircd/defines.h
+++ src/ngircd/defines.h
@@ -177,7 +177,7 @@
 #endif
 
 /** Supported user modes. */
-#define USERMODES "abBcCFioqrRswx"
+#define USERMODES "abBcCFiIoqrRswx"
 
 /** Supported channel modes. */
 #define CHANMODES "abehiIklmMnoOPqQrRstvVz"
blob - 61c6239c465ef3bd4cfc82fd6ff960d9e18927e3
blob + ba7a2b74243cd4cc21bfc8917510502104387d5a
--- src/ngircd/irc-info.c
+++ src/ngircd/irc-info.c
@@ -313,48 +313,50 @@ IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIE
 				Client_Info(Client_Introducer(c))))
 		return DISCONNECTED;
 
-	/* Channels */
-	snprintf(str, sizeof(str), RPL_WHOISCHANNELS_MSG,
-		 Client_ID(from), Client_ID(c));
-	cl2chan = Channel_FirstChannelOf(c);
-	while (cl2chan) {
-		chan = Channel_GetChannel(cl2chan);
-		assert(chan != NULL);
+	/* Channels, show only if client has no +I or if from is oper */
+	if(!(Client_HasMode(c, 'I')) || Client_HasMode(from, 'o'))  {
+		snprintf(str, sizeof(str), RPL_WHOISCHANNELS_MSG,
+			 Client_ID(from), Client_ID(c));
+		cl2chan = Channel_FirstChannelOf(c);
+		while (cl2chan) {
+			chan = Channel_GetChannel(cl2chan);
+			assert(chan != NULL);
 
-		/* next */
-		cl2chan = Channel_NextChannelOf(c, cl2chan);
+			/* next */
+			cl2chan = Channel_NextChannelOf(c, cl2chan);
 
-		/* Secret channel? */
-		if (Channel_HasMode(chan, 's')
-		    && !Channel_IsMemberOf(chan, Client))
-			continue;
+			/* Secret channel? */
+			if (Channel_HasMode(chan, 's')
+			    && !Channel_IsMemberOf(chan, Client))
+				continue;
 
-		/* Local channel and request is not from a user? */
-		if (Client_Type(Client) == CLIENT_SERVER
-		    && Channel_IsLocal(chan))
-			continue;
-
-		/* Concatenate channel names */
-		if (str[strlen(str) - 1] != ':')
-			strlcat(str, " ", sizeof(str));
+			/* Local channel and request is not from a user? */
+			if (Client_Type(Client) == CLIENT_SERVER
+			    && Channel_IsLocal(chan))
+				continue;
 
-		who_flags_qualifier(Client, Channel_UserModes(chan, c),
-				    str, sizeof(str));
-		strlcat(str, Channel_Name(chan), sizeof(str));
+			/* Concatenate channel names */
+			if (str[strlen(str) - 1] != ':')
+				strlcat(str, " ", sizeof(str));
 
-		if (strlen(str) > (COMMAND_LEN - CHANNEL_NAME_LEN - 4)) {
-			/* Line becomes too long: send it! */
+			who_flags_qualifier(Client, Channel_UserModes(chan, c),
+			                    str, sizeof(str));
+			strlcat(str, Channel_Name(chan), sizeof(str));
+
+			if (strlen(str) > (COMMAND_LEN - CHANNEL_NAME_LEN - 4)) {
+				/* Line becomes too long: send it! */
+				if (!IRC_WriteStrClient(Client, "%s", str))
+					return DISCONNECTED;
+				snprintf(str, sizeof(str), RPL_WHOISCHANNELS_MSG,
+					 Client_ID(from), Client_ID(c));
+			}
+		}
+		if(str[strlen(str) - 1] != ':') {
+			/* There is data left to send: */
 			if (!IRC_WriteStrClient(Client, "%s", str))
 				return DISCONNECTED;
-			snprintf(str, sizeof(str), RPL_WHOISCHANNELS_MSG,
-				 Client_ID(from), Client_ID(c));
 		}
 	}
-	if(str[strlen(str) - 1] != ':') {
-		/* There is data left to send: */
-		if (!IRC_WriteStrClient(Client, "%s", str))
-			return DISCONNECTED;
-	}
 
 	/* IRC-Services? */
 	if (Client_Type(c) == CLIENT_SERVICE &&
blob - cde573bf83faa98db98e9702bdd234f5fbe21203
blob + ec7d53c488a788be68eba3033100047ce77ea008
--- src/ngircd/irc-mode.c
+++ src/ngircd/irc-mode.c
@@ -206,6 +206,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Ori
 		case 'b': /* Block private msgs */
 		case 'C': /* Only messages from clients sharing a channel */
 		case 'i': /* Invisible */
+		case 'I': /* Hide channel list from WHOIS */
 		case 's': /* Server messages */
 		case 'w': /* Wallops messages */
 			x[0] = *mode_ptr;