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 },