110 lines
3.4 KiB
C
110 lines
3.4 KiB
C
/*
|
|
* ngIRCd -- The Next Generation IRC Daemon
|
|
* Copyright (c)2001-2013 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);
|
|
|
|
prefix = Client_Search(Req->prefix);
|
|
if (!prefix)
|
|
return IRC_WriteErrClient(Client, ERR_NOSUCHNICK_MSG,
|
|
Client_ID(Client), Req->prefix);
|
|
|
|
target = Client_Search(Req->argv[0]);
|
|
if (!target)
|
|
return IRC_WriteErrClient(Client, ERR_NOSUCHNICK_MSG,
|
|
Client_ID(Client), Req->argv[0]);
|
|
|
|
LogDebug("Got \"METADATA\" command from \"%s\" for client \"%s\": \"%s=%s\".",
|
|
Client_ID(prefix), Client_ID(target),
|
|
Req->argv[1], Req->argv[2]);
|
|
|
|
/* Mark client: it has received a METADATA command */
|
|
if (!Client_HasFlag(target, 'M')) {
|
|
snprintf(new_flags, sizeof new_flags, "%sM",
|
|
Client_Flags(target));
|
|
Client_SetFlags(target, new_flags);
|
|
}
|
|
|
|
if (strcasecmp(Req->argv[1], "cloakhost") == 0) {
|
|
Client_UpdateCloakedHostname(target, prefix, Req->argv[2]);
|
|
if (Client_Conn(target) > NONE && Client_HasMode(target, 'x'))
|
|
IRC_WriteStrClientPrefix(target, prefix,
|
|
RPL_HOSTHIDDEN_MSG, Client_ID(target),
|
|
Client_HostnameDisplayed(target));
|
|
/* The Client_UpdateCloakedHostname() function already
|
|
* forwarded the METADATA command, don't do it twice: */
|
|
return CONNECTED;
|
|
}
|
|
else if (*Req->argv[2] && strcasecmp(Req->argv[1], "host") == 0) {
|
|
Client_SetHostname(target, Req->argv[2]);
|
|
if (Client_Conn(target) > NONE && !Client_HasMode(target, 'x'))
|
|
IRC_WriteStrClientPrefix(target, prefix,
|
|
RPL_HOSTHIDDEN_MSG, Client_ID(target),
|
|
Client_HostnameDisplayed(target));
|
|
} 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 if (strcasecmp(Req->argv[1], "accountname") == 0)
|
|
Client_SetAccountName(target, Req->argv[2]);
|
|
else if (*Req->argv[2] && strcasecmp(Req->argv[1], "certfp") == 0)
|
|
Conn_SetCertFp(Client_Conn(target), Req->argv[2]);
|
|
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]);
|
|
|
|
/* Forward the METADATA command to peers that support it: */
|
|
IRC_WriteStrServersPrefixFlag(Client, prefix, 'M', "METADATA %s %s :%s",
|
|
Client_ID(target), Req->argv[1], Req->argv[2]);
|
|
return CONNECTED;
|
|
}
|