From 35ed57e6c160dc13c2bbca2ca042406285d4ced3 Mon Sep 17 00:00:00 2001 From: Alexander Barton Date: Mon, 5 Nov 2012 23:34:21 +0100 Subject: [PATCH] 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: : METADATA : It is distributed in the network, unknown names are silently ignored and passed on, too. This allows for further extensions. --- .../MacOSX/ngIRCd.xcodeproj/project.pbxproj | 6 ++ src/ngircd/defines.h | 2 +- src/ngircd/irc-metadata.c | 94 +++++++++++++++++++ src/ngircd/irc-metadata.h | 24 +++++ src/ngircd/parse.c | 2 + 5 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 src/ngircd/irc-metadata.c create mode 100644 src/ngircd/irc-metadata.h 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 = ""; }; FA4B08E713E7F91700765BA3 /* ngircd-redhat.init */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "ngircd-redhat.init"; sourceTree = ""; }; FA4B08E813E7F91C00765BA3 /* platformtest.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = platformtest.sh; sourceTree = ""; }; + FA4F1659164836B100DBD011 /* irc-metadata.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "irc-metadata.c"; sourceTree = ""; }; + FA4F165C164836BF00DBD011 /* irc-metadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "irc-metadata.h"; sourceTree = ""; }; FA6BBC5F1605F0AB0004247A /* conn-encoding.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "conn-encoding.c"; sourceTree = ""; }; FA6BBC601605F0AC0004247A /* conn-encoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "conn-encoding.h"; sourceTree = ""; }; FA6BBC611605F0AC0004247A /* irc-encoding.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "irc-encoding.c"; sourceTree = ""; }; @@ -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 +#include +#include + +#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 },