Implement METADATA command to update client metadata
authorAlexander Barton <alex@barton.de>
Mon, 5 Nov 2012 22:34:21 +0000 (23:34 +0100)
committerAlexander Barton <alex@barton.de>
Mon, 5 Nov 2012 22:34:21 +0000 (23:34 +0100)
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.

contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj
src/ngircd/defines.h
src/ngircd/irc-metadata.c [new file with mode: 0644]
src/ngircd/irc-metadata.h [new file with mode: 0644]
src/ngircd/parse.c

index b904c76..e4722bd 100644 (file)
@@ -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 */; };
                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>"; };
                                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 */,
                                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;
                };
index 49abf57..b2de98d 100644 (file)
 
 #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 (file)
index 0000000..5cef833
--- /dev/null
@@ -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 (file)
index 0000000..3a2f0bb
--- /dev/null
@@ -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- */
index 446180b..5ff9fcc 100644 (file)
@@ -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 },