From 6ddf4642ff99a29511a815d2222c0c5341ef88f0 Mon Sep 17 00:00:00 2001
From: Alexander Barton <alex@barton.de>
Date: Sat, 29 Jan 2011 16:33:52 +0100
Subject: [PATCH] Implement user mode 'S': indicate that this is an IRC service

The user mode 'S' is only settable by remote servers to indicate that
this "user" (registered using NICK) is an IRC servce in reality.

This mode is inspired by Unreal ircd. It can't be unset.
---
 src/ngircd/defines.h   |    2 +-
 src/ngircd/irc-login.c |    9 +++++++--
 src/ngircd/irc-mode.c  |   11 +++++++++++
 3 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/src/ngircd/defines.h b/src/ngircd/defines.h
index 3f1122c..717a5a0 100644
--- a/src/ngircd/defines.h
+++ b/src/ngircd/defines.h
@@ -80,7 +80,7 @@
 #define RECONNECT_DELAY 3		/* Time to delay re-connect attempts
 					   in seconds. */
 
-#define USERMODES "aciorswx"		/* Supported user modes. */
+#define USERMODES "aciorsSwx"		/* Supported user modes. */
 #define CHANMODES "biIklmnoOPstvz"	/* Supported channel modes. */
 
 #define CONNECTED true			/* Internal status codes. */
diff --git a/src/ngircd/irc-login.c b/src/ngircd/irc-login.c
index 8af4df9..f6d5026 100644
--- a/src/ngircd/irc-login.c
+++ b/src/ngircd/irc-login.c
@@ -369,8 +369,13 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
 			LogDebug("Client \"%s\" is being registered (RFC 1459) ...",
 				 Client_Mask(c));
 			Client_SetType(c, CLIENT_GOTNICK);
-		} else
-			Introduce_Client(Client, c, CLIENT_USER);
+		} else {
+			if (strchr(modes, 'S'))
+				Introduce_Client(Client, c, CLIENT_SERVICE);
+			else
+				Introduce_Client(Client, c, CLIENT_USER);
+
+		}
 
 		return CONNECTED;
 	}
diff --git a/src/ngircd/irc-mode.c b/src/ngircd/irc-mode.c
index dd69aa6..915e9de 100644
--- a/src/ngircd/irc-mode.c
+++ b/src/ngircd/irc-mode.c
@@ -200,6 +200,17 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
 				else ok = IRC_WriteStrClient( Origin, ERR_RESTRICTED_MSG, Client_ID( Origin ));
 				break;
 
+			case 'S': /* IRC Service indicator */
+				if (set && Client_Type(Client) == CLIENT_SERVER
+				    && Client_Type(Target) == CLIENT_USER) {
+					Client_SetType(Target, CLIENT_SERVICE);
+					x[0] = 'S';
+				} else
+					ok = IRC_WriteStrClient(Origin,
+							ERR_NOPRIVILEGES_MSG,
+							Client_ID(Origin));
+				break;
+
 			case 'x': /* Cloak hostname */
 				if (Client_HasMode(Client, 'r'))
 					ok = IRC_WriteStrClient(Origin,
-- 
1.7.3.5

