Skip to content

Commit

Permalink
m_message: proper tag propagation
Browse files Browse the repository at this point in the history
This introduces an handler to accept or not the propagation of a tag.
Basic sketch API is provided for modules to hook for providing their own
policy for specific tag propagation.
  • Loading branch information
RaitoBezarius committed Jul 19, 2022
1 parent 5f018ae commit cd3825b
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 9 deletions.
50 changes: 50 additions & 0 deletions include/client_tags.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Solanum: a slightly advanced ircd
* client_tags.h: client tags (message-tags)
*
* Copyright (C) 2022 Ryan Lahfa
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1.Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2.Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3.The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef INCLUDED_client_tags_h
#define INCLUDED_client_tags_h

// TODO: uniformize this
struct entity
{
void* ptr;
int type;
int flags;
};

extern void add_client_tags(const char *, const char *(*)(const void *), const void *);
extern void remove_client_tags(const char *);

extern int accept_client_tag(const char *, const char*, struct entity*);

extern void init_client_tags(void);

#endif /* INCLUDED_client_tags_h */
1 change: 1 addition & 0 deletions include/hook.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ enum message_type {
MESSAGE_TYPE_NOTICE,
MESSAGE_TYPE_PRIVMSG,
MESSAGE_TYPE_PART,
MESSAGE_TYPE_TAGMSG,
MESSAGE_TYPE_COUNT
};

Expand Down
1 change: 1 addition & 0 deletions include/s_serv.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ extern unsigned int CLICAP_USERHOST_IN_NAMES;
extern unsigned int CLICAP_CAP_NOTIFY;
extern unsigned int CLICAP_CHGHOST;
extern unsigned int CLICAP_ECHO_MESSAGE;
extern unsigned int CLICAP_MESSAGE_TAGS;

/*
* XXX: this is kind of ugly, but this allows us to have backwards
Expand Down
84 changes: 84 additions & 0 deletions ircd/client_tags.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Solanum: a slightly advanced ircd
* client_tags.c: client tags support
*
* Copyright (C) 2022 Ryan Lahfa
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1.Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2.Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3.The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#include "stdinc.h"
#include "client_tags.h"

rb_dlink_list client_tags_list;

struct client_tag_item
{
const char *name;
int (*func)(const void *);
const void *param;
rb_dlink_node node;
};

void
add_client_tag(const char *name, int (*func)(const void *), const void *param)
{
struct client_tag_item *item;

item = rb_malloc(sizeof(struct client_tag_item));
item->name = name;
item->func = func;
item->param = param;
rb_dlinkAddTail(item, &item->node, &client_tags_list);
}

void
remove_client_tag(const char *name)
{
rb_dlink_node *ptr, *next_ptr;
struct client_tag_item *item;

RB_DLINK_FOREACH_SAFE(ptr, next_ptr, client_tags_list.head)
{
item = ptr->data;

if (!strcmp(item->name, name))
{
rb_dlinkDelete(ptr, &client_tags_list);
rb_free(item);
}
}
}

int
accept_client_tag(const char* tag_key, const char* tag_value, struct entity* target)
{
return (0); // refuses
}

void
init_client_tags(void)
{
}
2 changes: 2 additions & 0 deletions ircd/s_serv.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ unsigned int CLICAP_USERHOST_IN_NAMES;
unsigned int CLICAP_CAP_NOTIFY;
unsigned int CLICAP_CHGHOST;
unsigned int CLICAP_ECHO_MESSAGE;
unsigned int CLICAP_MESSAGE_TAGS;

/*
* initialize our builtin capability table. --nenolod
Expand Down Expand Up @@ -144,6 +145,7 @@ init_builtin_capabs(void)
CLICAP_CAP_NOTIFY = capability_put(cli_capindex, "cap-notify", NULL);
CLICAP_CHGHOST = capability_put(cli_capindex, "chghost", &high_priority);
CLICAP_ECHO_MESSAGE = capability_put(cli_capindex, "echo-message", NULL);
CLICAP_MESSAGE_TAGS = capability_put(cli_capindex, "message-tags", NULL);
}

static CNCB serv_connect_callback;
Expand Down
39 changes: 30 additions & 9 deletions modules/core/m_message.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,17 @@
#include "s_newconf.h"
#include "s_stats.h"
#include "tgchange.h"
#include "client_tags.h"
#include "inline/stringops.h"

static const char message_desc[] =
"Provides the PRIVMSG and NOTICE commands to send messages to users and channels";
"Provides the PRIVMSG, NOTICE, TAGMSG commands to send messages to users and channels with a support for echo-message";

static void process_client_tags(struct MsgBuf *, struct Client *);
static void m_message(enum message_type, struct MsgBuf *, struct Client *, struct Client *, int, const char **);
static void m_privmsg(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
static void m_notice(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
static void m_tagmsg(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
static void m_echo(struct MsgBuf *, struct Client *, struct Client *, int, const char **);

static void echo_msg(struct Client *, struct Client *, enum message_type, const char *);
Expand All @@ -57,6 +60,7 @@ static void expire_tgchange(void *unused);
static struct ev_entry *expire_tgchange_event;

static unsigned int CAP_ECHO;
static unsigned int CAP_TAGS;

static int
modinit(void)
Expand All @@ -80,27 +84,25 @@ struct Message notice_msgtab = {
"NOTICE", 0, 0, 0, 0,
{mg_unreg, {m_notice, 0}, {m_notice, 0}, {m_notice, 0}, mg_ignore, {m_notice, 0}}
};
struct Message tagmsg_msgtab = {
"TAGMSG", 0, 0, 0, 0,
{mg_unreg, {m_tagmsg, 0}, {m_tagmsg, 0}, mg_ignore, mg_ignore, {m_tagmsg, 0}}
};
struct Message echo_msgtab = {
"ECHO", 0, 0, 0, 0,
{mg_unreg, mg_ignore, {m_echo, 3}, mg_ignore, mg_ignore, mg_ignore}
};

mapi_clist_av1 message_clist[] = { &privmsg_msgtab, &notice_msgtab, &echo_msgtab, NULL };
mapi_clist_av1 message_clist[] = { &privmsg_msgtab, &notice_msgtab, &echo_msgtab, &tagmsg_msgtab, NULL };

mapi_cap_list_av2 message_cap_list[] = {
{ MAPI_CAP_SERVER, "ECHO", NULL, &CAP_ECHO },
{ MAPI_CAP_SERVER, "TAGS", NULL, &CAP_TAGS },
{ 0, NULL, NULL, NULL }
};

DECLARE_MODULE_AV2(message, modinit, moddeinit, message_clist, NULL, NULL, message_cap_list, NULL, message_desc);

struct entity
{
void *ptr;
int type;
int flags;
};

static int build_target_list(enum message_type msgtype,
struct Client *client_p,
struct Client *source_p, const char *nicks_channels, const char *text);
Expand Down Expand Up @@ -163,6 +165,7 @@ static void handle_special(enum message_type msgtype,
const char *cmdname[MESSAGE_TYPE_COUNT] = {
[MESSAGE_TYPE_PRIVMSG] = "PRIVMSG",
[MESSAGE_TYPE_NOTICE] = "NOTICE",
[MESSAGE_TYPE_TAGMSG] = "TAGMSG"
};

static void
Expand All @@ -177,6 +180,12 @@ m_notice(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
m_message(MESSAGE_TYPE_NOTICE, msgbuf_p, client_p, source_p, parc, parv);
}

static void
m_tagmsg(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) {
// TODO: test if target supports tags, if not, ignore.
m_message(MESSAGE_TYPE_TAGMSG, msgbuf_p, client_p, source_p, parc, parv);
}

/*
* inputs - flag privmsg or notice
* - pointer to client_p
Expand Down Expand Up @@ -217,6 +226,17 @@ m_message(enum message_type msgtype, struct MsgBuf *msgbuf_p,

for(i = 0; i < ntargets; i++)
{
/* Process client tags for each target
*/
if (incoming_client != NULL) {
for (size_t tag_index = 0; tag_index < incoming_message->n_tags ; tag_index++) {
struct MsgTag tag = incoming_message->tags[tag_index];
if (!accept_client_tag(tag.key, tag.value, &targets[i])) {
msgbuf_append_tag(msgbuf_p, tag.key, tag.value, CLICAP_MESSAGE_TAGS);
}
}
}

switch (targets[i].type)
{
case ENTITY_CHANNEL:
Expand Down Expand Up @@ -257,6 +277,7 @@ m_echo(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
{
case 'P': msgtype = MESSAGE_TYPE_PRIVMSG; break;
case 'N': msgtype = MESSAGE_TYPE_NOTICE; break;
case 'T': msgtype = MESSAGE_TYPE_TAGMSG; break;
default: return;
}

Expand Down

0 comments on commit cd3825b

Please sign in to comment.