summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlexander Barton <alex@barton.de>2012-11-05 23:34:21 +0100
committerAlexander Barton <alex@barton.de>2012-11-05 23:34:21 +0100
commit35ed57e6c160dc13c2bbca2ca042406285d4ced3 (patch)
tree9017a97bc8c5e68e5bd5192553d12a8c330760a9
parent79731a57f3f35744236407f128cdd09c32b700fa (diff)
downloadngircd-35ed57e6c160dc13c2bbca2ca042406285d4ced3.tar.gz
ngircd-35ed57e6c160dc13c2bbca2ca042406285d4ced3.zip
Implement METADATA command to update client metadata
The METADATA command can be used by other servers to update "metadata"
of registered clients, like the client info text ("real name"), user
name, and hostname:

  :<prefix> METADATA <target> <key> :<value>

It is distributed in the network, unknown <key> names are silently ignored
and passed on, too. This allows for further extensions.
-rw-r--r--contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj6
-rw-r--r--src/ngircd/defines.h2
-rw-r--r--src/ngircd/irc-metadata.c94
-rw-r--r--src/ngircd/irc-metadata.h24
-rw-r--r--src/ngircd/parse.c2
5 files changed, 127 insertions, 1 deletions
diff --git a/contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj b/contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj
index b904c763..e4722bd5 100644
--- a/contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj
+++ b/contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj
@@ -36,6 +36,7 @@
 		FA322DBE0CEF7766001761B3 /* tool.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322D330CEF74B1001761B3 /* tool.c */; };
 		FA322DC10CEF77CB001761B3 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FA322DC00CEF77CB001761B3 /* libz.dylib */; };
 		FA407F2E0DB159F400271AF1 /* ng_ipaddr.c in Sources */ = {isa = PBXBuildFile; fileRef = FA407F2C0DB159F400271AF1 /* ng_ipaddr.c */; };
+		FA4F165A164836B100DBD011 /* irc-metadata.c in Sources */ = {isa = PBXBuildFile; fileRef = FA4F1659164836B100DBD011 /* irc-metadata.c */; };
 		FA6BBC631605F0AC0004247A /* conn-encoding.c in Sources */ = {isa = PBXBuildFile; fileRef = FA6BBC5F1605F0AB0004247A /* conn-encoding.c */; };
 		FA6BBC641605F0AC0004247A /* irc-encoding.c in Sources */ = {isa = PBXBuildFile; fileRef = FA6BBC611605F0AC0004247A /* irc-encoding.c */; };
 		FA6BBC661605F6D60004247A /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FA6BBC651605F6D60004247A /* libiconv.dylib */; };
@@ -206,6 +207,8 @@
 		FA4B08E613E7F91700765BA3 /* ngIRCd-Logo.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = "ngIRCd-Logo.gif"; sourceTree = "<group>"; };
 		FA4B08E713E7F91700765BA3 /* ngircd-redhat.init */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "ngircd-redhat.init"; sourceTree = "<group>"; };
 		FA4B08E813E7F91C00765BA3 /* platformtest.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = platformtest.sh; sourceTree = "<group>"; };
+		FA4F1659164836B100DBD011 /* irc-metadata.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "irc-metadata.c"; sourceTree = "<group>"; };
+		FA4F165C164836BF00DBD011 /* irc-metadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "irc-metadata.h"; sourceTree = "<group>"; };
 		FA6BBC5F1605F0AB0004247A /* conn-encoding.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "conn-encoding.c"; sourceTree = "<group>"; };
 		FA6BBC601605F0AC0004247A /* conn-encoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "conn-encoding.h"; sourceTree = "<group>"; };
 		FA6BBC611605F0AC0004247A /* irc-encoding.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "irc-encoding.c"; sourceTree = "<group>"; };
@@ -365,6 +368,8 @@
 				FA322CEF0CEF74B1001761B3 /* irc-info.h */,
 				FA322CF00CEF74B1001761B3 /* irc-login.c */,
 				FA322CF10CEF74B1001761B3 /* irc-login.h */,
+				FA4F1659164836B100DBD011 /* irc-metadata.c */,
+				FA4F165C164836BF00DBD011 /* irc-metadata.h */,
 				FA322CF20CEF74B1001761B3 /* irc-mode.c */,
 				FA322CF30CEF74B1001761B3 /* irc-mode.h */,
 				FA322CF40CEF74B1001761B3 /* irc-op.c */,
@@ -766,6 +771,7 @@
 				FAD5853815272C2600328741 /* login.c in Sources */,
 				FA6BBC631605F0AC0004247A /* conn-encoding.c in Sources */,
 				FA6BBC641605F0AC0004247A /* irc-encoding.c in Sources */,
+				FA4F165A164836B100DBD011 /* irc-metadata.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
diff --git a/src/ngircd/defines.h b/src/ngircd/defines.h
index 49abf579..b2de98d5 100644
--- a/src/ngircd/defines.h
+++ b/src/ngircd/defines.h
@@ -157,7 +157,7 @@
 
 #ifdef IRCPLUS
 /** Standard IRC+ flags. */
-# define IRCPLUSFLAGS "CHLS"
+# define IRCPLUSFLAGS "CHLMS"
 #endif
 
 /** Supported user modes. */
diff --git a/src/ngircd/irc-metadata.c b/src/ngircd/irc-metadata.c
new file mode 100644
index 00000000..5cef8333
--- /dev/null
+++ b/src/ngircd/irc-metadata.c
@@ -0,0 +1,94 @@
+/*
+ * ngIRCd -- The Next Generation IRC Daemon
+ * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * Please read the file COPYING, README and AUTHORS for more information.
+ */
+
+#define __irc_metadata_c__
+
+#include "portab.h"
+
+/**
+ * @file
+ * IRC metadata commands
+ */
+
+#include "imp.h"
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "conn-func.h"
+#include "channel.h"
+#include "conn-encoding.h"
+#include "irc-write.h"
+#include "log.h"
+#include "messages.h"
+#include "parse.h"
+#include "tool.h"
+
+#include "exp.h"
+#include "irc-metadata.h"
+
+/**
+ * Handler for the IRC+ "METADATA" command.
+ *
+ * @param Client The client from which this command has been received.
+ * @param Req Request structure with prefix and all parameters.
+ * @returns CONNECTED or DISCONNECTED.
+ */
+GLOBAL bool
+IRC_METADATA(CLIENT *Client, REQUEST *Req)
+{
+	CLIENT *prefix, *target;
+	char new_flags[COMMAND_LEN];
+
+	assert(Client != NULL);
+	assert(Req != NULL);
+
+	if (Req->argc != 3)
+		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
+					  Client_ID(Client), Req->command);
+
+	prefix = Client_Search(Req->prefix);
+	if (!prefix)
+		return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
+					  Client_ID(Client), Req->prefix);
+
+	target = Client_Search(Req->argv[0]);
+	if (!target)
+		return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
+					  Client_ID(Client), Req->argv[0]);
+
+	LogDebug("Got \"METADATA\" command from \"%s\" for client \"%s\": \"%s=%s\".",
+		 Client_ID(Client), Client_ID(target),
+		 Req->argv[1], Req->argv[2]);
+
+	/* Mark client: it has receiveda a METADATA command */
+	if (!strchr(Client_Flags(target), 'M')) {
+		snprintf(new_flags, sizeof new_flags, "%sM",
+			 Client_Flags(target));
+		Client_SetFlags(target, new_flags);
+	}
+
+	if (*Req->argv[2] && strcasecmp(Req->argv[1], "host") == 0)
+		Client_SetHostname(target, Req->argv[2]);
+	else if (strcasecmp(Req->argv[1], "info") == 0)
+		Client_SetInfo(target, Req->argv[2]);
+	else if (*Req->argv[2] && strcasecmp(Req->argv[1], "user") == 0)
+		Client_SetUser(target, Req->argv[2], true);
+	else
+		Log(LOG_WARNING,
+		    "Ignored metadata update from \"%s\" for client \"%s\": \"%s=%s\" - unknown key!",
+		    Client_ID(Client), Client_ID(target),
+		    Req->argv[1], Req->argv[2]);
+
+	IRC_WriteStrServersPrefixFlag(Client, prefix, 'M', "METADATA %s %s :%s",
+				Client_ID(target), Req->argv[1], Req->argv[2]);
+	return CONNECTED;
+}
diff --git a/src/ngircd/irc-metadata.h b/src/ngircd/irc-metadata.h
new file mode 100644
index 00000000..3a2f0bbf
--- /dev/null
+++ b/src/ngircd/irc-metadata.h
@@ -0,0 +1,24 @@
+/*
+ * ngIRCd -- The Next Generation IRC Daemon
+ * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * Please read the file COPYING, README and AUTHORS for more information.
+ */
+
+#ifndef __irc_metadata_h__
+#define __irc_metadata_h__
+
+/**
+ * @file
+ * IRC metadata commands (header)
+ */
+
+GLOBAL bool IRC_METADATA PARAMS((CLIENT *Client, REQUEST *Req));
+
+#endif
+
+/* -eof- */
diff --git a/src/ngircd/parse.c b/src/ngircd/parse.c
index 446180b5..5ff9fcc2 100644
--- a/src/ngircd/parse.c
+++ b/src/ngircd/parse.c
@@ -41,6 +41,7 @@
 #include "irc-encoding.h"
 #include "irc-info.h"
 #include "irc-login.h"
+#include "irc-metadata.h"
 #include "irc-mode.h"
 #include "irc-op.h"
 #include "irc-oper.h"
@@ -78,6 +79,7 @@ static COMMAND My_Commands[] =
 	{ "LINKS", IRC_LINKS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 	{ "LIST", IRC_LIST, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 	{ "LUSERS", IRC_LUSERS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
+	{ "METADATA", IRC_METADATA, CLIENT_SERVER, 0, 0, 0 },
 	{ "MODE", IRC_MODE, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 	{ "MOTD", IRC_MOTD, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 	{ "NAMES", IRC_NAMES, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },