Skip to content

Commit

Permalink
message-tags: facility to manipulate client-tags
Browse files Browse the repository at this point in the history
It provides for hook facilities to client-only tags:

- messages can be dropped silently ;
- messages can be edited ;
- messages can be stripped from a client-only tag
  • Loading branch information
RaitoBezarius committed Jul 24, 2022
1 parent cd36b6a commit d25e9ab
Show file tree
Hide file tree
Showing 11 changed files with 206 additions and 45 deletions.
12 changes: 9 additions & 3 deletions include/client_tags.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,15 @@
#ifndef INCLUDED_client_tags_h
#define INCLUDED_client_tags_h

// TODO: uniformize this
struct entity;
#define MAX_CLIENT_TAGS 100
#define CLIENT_TAG_MAX_LENGTH 100

extern int accept_client_tag(const char *, const char*, struct entity*);
struct client_tag_support {
char name[CLIENT_TAG_MAX_LENGTH];
};

extern int add_client_tag(const char *);
extern void remove_client_tag(const char *);
extern void format_client_tags(char *, size_t, const char *, const char *);

#endif /* INCLUDED_client_tags_h */
9 changes: 9 additions & 0 deletions include/hook.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ extern int h_outbound_msgbuf;
extern int h_rehash;
extern int h_priv_change;
extern int h_cap_change;
extern int h_client_tag_accept;

void init_hook(void);
int register_hook(const char *name);
Expand Down Expand Up @@ -156,6 +157,14 @@ typedef struct
int del;
} hook_data_cap_change;

typedef struct
{
struct Client *client;
struct MsgBuf *outgoing_msgbuf;
const struct MsgTag *incoming_tag;
bool drop;
} hook_data_client_tag_accept;

enum message_type {
MESSAGE_TYPE_NOTICE,
MESSAGE_TYPE_PRIVMSG,
Expand Down
6 changes: 6 additions & 0 deletions include/msgbuf.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ struct MsgBuf_cache {
*/
int msgbuf_parse(struct MsgBuf *msgbuf, char *line);

/*
* Parse partially a msgbuf without tags
* assuming msgbuf is already initialized.
*/
int msgbuf_partial_parse(struct MsgBuf *msgbuf, char *line);

/*
* Unparse the tail of a msgbuf perfectly, preserving framing details
* msgbuf->para[n] will reach to the end of the line
Expand Down
52 changes: 49 additions & 3 deletions ircd/client_tags.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,55 @@
#include "stdinc.h"
#include "client_tags.h"

struct client_tag_support *supported_client_tags;
size_t num_client_tags = 0;
size_t max_client_tags = MAX_CLIENT_TAGS;

void
init_client_tags(void)
{
supported_client_tags = rb_malloc(sizeof(struct client_tag_support) * MAX_CLIENT_TAGS);
}

int
accept_client_tag(const char* tag_key, const char* tag_value, struct entity* target)
add_client_tag(const char *name)
{
int i;

if (num_client_tags >= max_client_tags)
return -1;

strcpy(supported_client_tags[num_client_tags].name, name);
num_client_tags++;

return num_client_tags - 1;
}

void
remove_client_tag(const char *name)
{
return (1); // accepts
return (0); // refuses
for (size_t index = 0 ; index < num_client_tags ; index++)
{
if (strcmp(supported_client_tags[index].name, name)) {
strcpy(supported_client_tags[index].name, supported_client_tags[num_client_tags - 1].name);
num_client_tags--;
break;
}
}
}

void
format_client_tags(char *dst, size_t dst_sz, const char *individual_fmt, const char *join_sep)
{
size_t start = 0;
for (size_t index = 0 ; index < num_client_tags ; index++) {
if (start >= dst_sz)
break;

if (index > 0) {
dst[start] = ',';
start++;
}
start += snprintf((dst + start), dst_sz - start, individual_fmt, supported_client_tags[index].name);
}
}
2 changes: 2 additions & 0 deletions ircd/hook.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ int h_outbound_msgbuf;
int h_rehash;
int h_priv_change;
int h_cap_change;
int h_client_tag_accept;

void
init_hook(void)
Expand All @@ -99,6 +100,7 @@ init_hook(void)
h_rehash = register_hook("rehash");
h_priv_change = register_hook("priv_change");
h_cap_change = register_hook("cap_change");
h_client_tag_accept = register_hook("client_tag_accept");
}

/* grow_hooktable()
Expand Down
8 changes: 8 additions & 0 deletions ircd/msgbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,14 @@ msgbuf_parse(struct MsgBuf *msgbuf, char *line)
return 1;
}
}

msgbuf_partial_parse(msgbuf, ch);
}

int
msgbuf_partial_parse(struct MsgBuf *msgbuf, char *line)
{
char *ch = line;

/* truncate message if it's too long */
if (strlen(ch) > DATALEN) {
Expand Down
52 changes: 28 additions & 24 deletions ircd/send.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,11 +266,14 @@ linebuf_put_msgf(buf_head_t *linebuf, const rb_strf_t *message, const char *form
* notes - to make this reentrant, find a solution for `buf` below
*/
static void
build_msgbuf_tags(struct MsgBuf *msgbuf, struct Client *from)
build_msgbuf_tags(struct MsgBuf *msgbuf, struct Client *from, char* buf)
{
hook_data hdata;

msgbuf_init(msgbuf);
if (buf != NULL) {
msgbuf_partial_parse(msgbuf, buf);
}

hdata.client = from;
hdata.arg1 = msgbuf;
Expand Down Expand Up @@ -301,7 +304,7 @@ sendto_one(struct Client *target_p, const char *pattern, ...)

rb_linebuf_newbuf(&linebuf);

build_msgbuf_tags(&msgbuf, &me);
build_msgbuf_tags(&msgbuf, &me, NULL);
va_start(args, pattern);
linebuf_put_tags(&linebuf, &msgbuf, target_p, &strings);
va_end(args);
Expand Down Expand Up @@ -335,8 +338,8 @@ sendto_one_prefix(struct Client *target_p, struct Client *source_p,
sendto_realops_snomask(SNO_GENERAL, L_ALL, "Trying to send to myself!");
return;
}

build_msgbuf_tags(&msgbuf, source_p);
build_msgbuf_tags(&msgbuf, source_p, NULL);

rb_linebuf_newbuf(&linebuf);
va_start(args, pattern);
Expand Down Expand Up @@ -374,7 +377,7 @@ sendto_one_notice(struct Client *target_p, const char *pattern, ...)
return;
}

build_msgbuf_tags(&msgbuf, &me);
build_msgbuf_tags(&msgbuf, &me, NULL);

rb_linebuf_newbuf(&linebuf);
va_start(args, pattern);
Expand Down Expand Up @@ -413,7 +416,7 @@ sendto_one_numeric(struct Client *target_p, int numeric, const char *pattern, ..
return;
}

build_msgbuf_tags(&msgbuf, &me);
build_msgbuf_tags(&msgbuf, &me, NULL);

rb_linebuf_newbuf(&linebuf);
va_start(args, pattern);
Expand Down Expand Up @@ -513,12 +516,13 @@ sendto_channel_flags(struct Client *one, int type, struct Client *source_p,

current_serial++;

build_msgbuf_tags(&msgbuf, source_p);

va_start(args, pattern);
vsnprintf(buf, sizeof buf, pattern, args);
va_end(args);

build_msgbuf_tags(&msgbuf, source_p, buf);

// TODO: linebuf_put_msgf should not exist.
linebuf_put_msgf(&rb_linebuf_remote, NULL, ":%s %s", use_id(source_p), buf);
msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
IsPerson(source_p) ? ":%1$s!%2$s@%3$s " : ":%1$s ",
Expand Down Expand Up @@ -597,7 +601,7 @@ sendto_channel_opmod(struct Client *one, struct Client *source_p,
rb_linebuf_newbuf(&rb_linebuf_old);
rb_linebuf_newbuf(&rb_linebuf_new);

build_msgbuf_tags(&msgbuf, source_p);
build_msgbuf_tags(&msgbuf, source_p, NULL);

current_serial++;
const char *statusmsg_prefix = (ConfigChannel.opmod_send_statusmsg ? "@" : "");
Expand Down Expand Up @@ -694,7 +698,7 @@ _sendto_channel_local(struct Client *source_p, int type, const char *priv, struc
struct MsgBuf_cache msgbuf_cache;
rb_strf_t strings = { .format = pattern, .format_args = args, .next = NULL };

build_msgbuf_tags(&msgbuf, source_p);
build_msgbuf_tags(&msgbuf, source_p, NULL);

msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);

Expand Down Expand Up @@ -765,7 +769,7 @@ _sendto_channel_local_with_capability_butone(struct Client *source_p, struct Cli
struct MsgBuf_cache msgbuf_cache;
rb_strf_t strings = { .format = pattern, .format_args = args, .next = NULL };

build_msgbuf_tags(&msgbuf, source_p);
build_msgbuf_tags(&msgbuf, source_p, NULL);
msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);

RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
Expand Down Expand Up @@ -844,7 +848,7 @@ sendto_channel_local_butone(struct Client *one, int type, struct Channel *chptr,
struct MsgBuf_cache msgbuf_cache;
rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };

build_msgbuf_tags(&msgbuf, one);
build_msgbuf_tags(&msgbuf, one, NULL);

va_start(args, pattern);
msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
Expand Down Expand Up @@ -899,7 +903,7 @@ sendto_common_channels_local(struct Client *user, int cap, int negcap, const cha
struct MsgBuf_cache msgbuf_cache;
rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };

build_msgbuf_tags(&msgbuf, user);
build_msgbuf_tags(&msgbuf, user, NULL);

va_start(args, pattern);
msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
Expand Down Expand Up @@ -966,7 +970,7 @@ sendto_common_channels_local_butone(struct Client *user, int cap, int negcap, co
struct MsgBuf_cache msgbuf_cache;
rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };

build_msgbuf_tags(&msgbuf, user);
build_msgbuf_tags(&msgbuf, user, NULL);

va_start(args, pattern);
msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
Expand Down Expand Up @@ -1022,12 +1026,12 @@ sendto_match_butone(struct Client *one, struct Client *source_p,

rb_linebuf_newbuf(&rb_linebuf_remote);

build_msgbuf_tags(&msgbuf, source_p);

va_start(args, pattern);
vsnprintf(buf, sizeof(buf), pattern, args);
va_end(args);

build_msgbuf_tags(&msgbuf, source_p, buf);

msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
IsServer(source_p) ? ":%s " : ":%s!%s@%s ",
source_p->name, source_p->username, source_p->host);
Expand Down Expand Up @@ -1145,7 +1149,7 @@ sendto_local_clients_with_capability(int cap, const char *pattern, ...)
struct MsgBuf_cache msgbuf_cache;
rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };

build_msgbuf_tags(&msgbuf, &me);
build_msgbuf_tags(&msgbuf, &me, NULL);

va_start(args, pattern);
msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
Expand Down Expand Up @@ -1181,7 +1185,7 @@ sendto_monitor(struct Client *source_p, struct monitor *monptr, const char *patt
struct MsgBuf_cache msgbuf_cache;
rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };

build_msgbuf_tags(&msgbuf, source_p);
build_msgbuf_tags(&msgbuf, source_p, NULL);

va_start(args, pattern);
msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
Expand Down Expand Up @@ -1224,7 +1228,7 @@ _sendto_anywhere(struct Client *dest_p, struct Client *target_p,
} else {
struct MsgBuf msgbuf;

build_msgbuf_tags(&msgbuf, source_p);
build_msgbuf_tags(&msgbuf, source_p, NULL);

linebuf_put_tagsf(&linebuf, &msgbuf, dest_p, &strings,
IsPerson(source_p) ? ":%1$s!%4$s@%5$s %2$s %3$s " : ":%1$s %2$s %3$s ",
Expand Down Expand Up @@ -1299,13 +1303,13 @@ sendto_realops_snomask(int flags, int level, const char *pattern, ...)
struct MsgBuf msgbuf;
struct MsgBuf_cache msgbuf_cache;

build_msgbuf_tags(&msgbuf, &me);

/* rather a lot of copying around, oh well -- jilles */
va_start(args, pattern);
vsnprintf(buf, sizeof(buf), pattern, args);
va_end(args);

build_msgbuf_tags(&msgbuf, &me, buf);

msgbuf_cache_initf(&msgbuf_cache, &msgbuf, NULL,
":%s NOTICE * :*** Notice -- %s", me.name, buf);

Expand Down Expand Up @@ -1361,7 +1365,7 @@ sendto_realops_snomask_from(int flags, int level, struct Client *source_p,
struct MsgBuf_cache msgbuf_cache;
rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };

build_msgbuf_tags(&msgbuf, &me);
build_msgbuf_tags(&msgbuf, &me, NULL);

va_start(args, pattern);
msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
Expand Down Expand Up @@ -1407,7 +1411,7 @@ sendto_wallops_flags(int flags, struct Client *source_p, const char *pattern, ..
struct MsgBuf_cache msgbuf_cache;
rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };

build_msgbuf_tags(&msgbuf, source_p);
build_msgbuf_tags(&msgbuf, source_p, NULL);

va_start(args, pattern);
if (IsPerson(source_p)) {
Expand Down Expand Up @@ -1446,7 +1450,7 @@ kill_client(struct Client *target_p, struct Client *diedie, const char *pattern,
struct MsgBuf msgbuf;
rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };

build_msgbuf_tags(&msgbuf, &me);
build_msgbuf_tags(&msgbuf, &me, NULL);

rb_linebuf_newbuf(&linebuf);

Expand Down
12 changes: 9 additions & 3 deletions ircd/supported.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
#include "supported.h"
#include "chmode.h"
#include "send.h"
#include "client_tags.h"

static char allowed_chantypes[BUFSIZE];
rb_dlink_list isupportlist;
Expand Down Expand Up @@ -304,9 +305,14 @@ static const char *
isupport_client_tag_deny(const void *ptr)
{
static char result[200];
// TODO: iterate over allowed client tags declared by modules
// add -x, -y, -z for each of them.
snprintf(result, sizeof result, "%s", "*");
static char exceptions[198];

format_client_tags(exceptions, sizeof exceptions, "-%s", ",");

if (EmptyString(exceptions))
snprintf(result, sizeof result, "%s", "*");
else
snprintf(result, sizeof result, "%s,%s", "*", exceptions);
return result;
}

Expand Down
1 change: 1 addition & 0 deletions modules/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ LIBS += $(top_srcdir)/ircd/libircd.la
auto_load_moddir=@moduledir@/autoload

auto_load_mod_LTLIBRARIES = \
cap_message_tags.la \
cap_account_tag.la \
cap_server_time.la \
chm_nocolour.la \
Expand Down
Loading

0 comments on commit d25e9ab

Please sign in to comment.