Skip to content

Commit a45bada

Browse files
committed
core(send,msgbuf): add facility to initialize tags at send interface, use it for tags propagation
1 parent cd36b6a commit a45bada

File tree

5 files changed

+176
-49
lines changed

5 files changed

+176
-49
lines changed

include/msgbuf.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#define SOLANUM__MSGBUF_H
2424

2525
#define MAXPARA (15)
26+
#define min(a, b) (a < b ? a : b)
2627

2728
/* a key-value structure for each message tag. */
2829
struct MsgTag {
@@ -31,6 +32,12 @@ struct MsgTag {
3132
unsigned int capmask; /* the capability mask this tag belongs to (used only when sending) */
3233
};
3334

35+
/* a list of message tags */
36+
struct MsgTags {
37+
size_t n_tags;
38+
struct MsgTag tags[MAXPARA];
39+
};
40+
3441
struct MsgBuf {
3542
size_t n_tags; /* the number of tags in the MsgBuf */
3643
struct MsgTag tags[MAXPARA]; /* the tags themselves, upto MAXPARA tags available */
@@ -116,6 +123,35 @@ msgbuf_init(struct MsgBuf *msgbuf)
116123
memset(msgbuf, 0, sizeof(*msgbuf));
117124
}
118125

126+
static inline void
127+
msgtags_init(struct MsgTags *msgtags)
128+
{
129+
memset(msgtags, 0, sizeof(*msgtags));
130+
}
131+
132+
133+
static inline void
134+
msgbuf_init_tags(struct MsgBuf *msgbuf, struct MsgTags *msgtags) {
135+
if (msgtags != NULL) {
136+
size_t n_tags = min(msgtags->n_tags, MAXPARA);
137+
msgbuf->n_tags = n_tags;
138+
for (size_t i = 0 ; i < n_tags ; i++) {
139+
msgbuf->tags[i].key = msgtags->tags[i].key;
140+
msgbuf->tags[i].value = msgtags->tags[i].value;
141+
msgbuf->tags[i].capmask = msgtags->tags[i].capmask;
142+
}
143+
}
144+
}
145+
146+
static inline void
147+
msgtags_append_tag(struct MsgTags *msgtags, const char *key, const char *value, unsigned int capmask) {
148+
if (msgtags->n_tags < MAXPARA) {
149+
msgtags->tags[msgtags->n_tags].key = key;
150+
msgtags->tags[msgtags->n_tags].value = value;
151+
msgtags->tags[msgtags->n_tags].capmask = capmask;
152+
msgtags->n_tags++;
153+
}
154+
}
119155
static inline void
120156
msgbuf_append_tag(struct MsgBuf *msgbuf, const char *key, const char *value, unsigned int capmask)
121157
{

include/send.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "rb_lib.h"
2929
#include "ircd_defs.h"
3030

31+
struct MsgTags;
3132
struct Client;
3233
struct Channel;
3334
struct monitor;
@@ -41,6 +42,7 @@ extern void send_pop_queue(struct Client *);
4142

4243
extern void send_queued(struct Client *to);
4344

45+
extern void sendto_one_with_tags(struct Client *target_p, struct MsgTags *initial_tags, const char *pattern, ...) AFP(3, 4);
4446
extern void sendto_one(struct Client *target_p, const char *, ...) AFP(2, 3);
4547
extern void sendto_one_notice(struct Client *target_p,const char *, ...) AFP(2, 3);
4648
extern void sendto_one_prefix(struct Client *target_p, struct Client *source_p,
@@ -53,8 +55,9 @@ extern void sendto_server(struct Client *one, struct Channel *chptr,
5355
const char *format, ...) AFP(5, 6);
5456

5557
extern void sendto_channel_flags(struct Client *one, int type, struct Client *source_p,
56-
struct Channel *chptr, const char *, ...) AFP(5, 6);
58+
struct MsgTags *initial_tags, struct Channel *chptr, const char *, ...) AFP(6, 7);
5759
extern void sendto_channel_opmod(struct Client *one, struct Client *source_p,
60+
struct MsgTags *initial_tags,
5861
struct Channel *chptr, const char *command,
5962
const char *text);
6063

@@ -77,6 +80,7 @@ extern void sendto_match_servs(struct Client *source_p, const char *mask,
7780

7881
extern void sendto_monitor(struct Client *, struct monitor *monptr, const char *, ...) AFP(3, 4);
7982

83+
extern void sendto_anywhere_with_tags(struct Client *, struct Client *, struct MsgTags *, const char *, const char *, ...) AFP(5, 6);
8084
extern void sendto_anywhere(struct Client *, struct Client *, const char *,
8185
const char *, ...) AFP(4, 5);
8286
extern void sendto_anywhere_echo(struct Client *, struct Client *, const char *,

ircd/parse.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ do_numeric(int numeric, struct Client *client_p, struct Client *source_p, int pa
514514
return;
515515
}
516516
else if((chptr = find_channel(parv[1])) != NULL)
517-
sendto_channel_flags(client_p, ALL_MEMBERS, source_p, chptr,
517+
sendto_channel_flags(client_p, ALL_MEMBERS, source_p, NULL, chptr,
518518
"%03d %s%s",
519519
numeric, chptr->chname, buffer);
520520
}

ircd/send.c

Lines changed: 68 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -260,24 +260,52 @@ linebuf_put_msgf(buf_head_t *linebuf, const rb_strf_t *message, const char *form
260260

261261
/* build_msgbuf_tags
262262
*
263-
* inputs - msgbuf object, client the message is from
263+
* inputs - msgbuf object, client the message is from, initial tags (potentially NULL)
264264
* outputs - none
265265
* side effects - a msgbuf object is populated with an origin and relevant tags
266266
* notes - to make this reentrant, find a solution for `buf` below
267267
*/
268268
static void
269-
build_msgbuf_tags(struct MsgBuf *msgbuf, struct Client *from)
269+
build_msgbuf_tags(struct MsgBuf *msgbuf, struct Client *from, struct MsgTags* initial_tags)
270270
{
271271
hook_data hdata;
272272

273273
msgbuf_init(msgbuf);
274+
msgbuf_init_tags(msgbuf, initial_tags);
274275

275276
hdata.client = from;
276277
hdata.arg1 = msgbuf;
277278

278279
call_hook(h_outbound_msgbuf, &hdata);
279280
}
280281

282+
void
283+
sendto_one_with_tags(struct Client *target_p, struct MsgTags *initial_tags, const char *pattern, ...) {
284+
va_list args;
285+
struct MsgBuf msgbuf;
286+
buf_head_t linebuf;
287+
rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
288+
289+
/* send remote if to->from non NULL */
290+
if(target_p->from != NULL)
291+
target_p = target_p->from;
292+
293+
if(IsIOError(target_p))
294+
return;
295+
296+
rb_linebuf_newbuf(&linebuf);
297+
298+
build_msgbuf_tags(&msgbuf, &me, initial_tags);
299+
300+
va_start(args, pattern);
301+
linebuf_put_tags(&linebuf, &msgbuf, target_p, &strings);
302+
va_end(args);
303+
304+
_send_linebuf(target_p, &linebuf);
305+
306+
rb_linebuf_donebuf(&linebuf);
307+
}
308+
281309
/* sendto_one()
282310
*
283311
* inputs - client to send to, va_args
@@ -301,7 +329,7 @@ sendto_one(struct Client *target_p, const char *pattern, ...)
301329

302330
rb_linebuf_newbuf(&linebuf);
303331

304-
build_msgbuf_tags(&msgbuf, &me);
332+
build_msgbuf_tags(&msgbuf, &me, NULL);
305333
va_start(args, pattern);
306334
linebuf_put_tags(&linebuf, &msgbuf, target_p, &strings);
307335
va_end(args);
@@ -336,7 +364,7 @@ sendto_one_prefix(struct Client *target_p, struct Client *source_p,
336364
return;
337365
}
338366

339-
build_msgbuf_tags(&msgbuf, source_p);
367+
build_msgbuf_tags(&msgbuf, source_p, NULL);
340368

341369
rb_linebuf_newbuf(&linebuf);
342370
va_start(args, pattern);
@@ -374,7 +402,7 @@ sendto_one_notice(struct Client *target_p, const char *pattern, ...)
374402
return;
375403
}
376404

377-
build_msgbuf_tags(&msgbuf, &me);
405+
build_msgbuf_tags(&msgbuf, &me, NULL);
378406

379407
rb_linebuf_newbuf(&linebuf);
380408
va_start(args, pattern);
@@ -413,7 +441,7 @@ sendto_one_numeric(struct Client *target_p, int numeric, const char *pattern, ..
413441
return;
414442
}
415443

416-
build_msgbuf_tags(&msgbuf, &me);
444+
build_msgbuf_tags(&msgbuf, &me, NULL);
417445

418446
rb_linebuf_newbuf(&linebuf);
419447
va_start(args, pattern);
@@ -490,12 +518,13 @@ sendto_server(struct Client *one, struct Channel *chptr, unsigned long caps,
490518

491519
/* sendto_channel_flags()
492520
*
493-
* inputs - server not to send to, flags needed, source, channel, va_args
521+
* inputs - server not to send to, flags needed, source, initial tags to propagate, channel, va_args
494522
* outputs - message is sent to channel members
495523
* side effects -
496524
*/
497525
void
498526
sendto_channel_flags(struct Client *one, int type, struct Client *source_p,
527+
struct MsgTags* initial_tags,
499528
struct Channel *chptr, const char *pattern, ...)
500529
{
501530
static char buf[BUFSIZE];
@@ -513,7 +542,7 @@ sendto_channel_flags(struct Client *one, int type, struct Client *source_p,
513542

514543
current_serial++;
515544

516-
build_msgbuf_tags(&msgbuf, source_p);
545+
build_msgbuf_tags(&msgbuf, source_p, initial_tags);
517546

518547
va_start(args, pattern);
519548
vsnprintf(buf, sizeof buf, pattern, args);
@@ -581,6 +610,7 @@ sendto_channel_flags(struct Client *one, int type, struct Client *source_p,
581610
*/
582611
void
583612
sendto_channel_opmod(struct Client *one, struct Client *source_p,
613+
struct MsgTags *initial_tags,
584614
struct Channel *chptr, const char *command,
585615
const char *text)
586616
{
@@ -597,7 +627,7 @@ sendto_channel_opmod(struct Client *one, struct Client *source_p,
597627
rb_linebuf_newbuf(&rb_linebuf_old);
598628
rb_linebuf_newbuf(&rb_linebuf_new);
599629

600-
build_msgbuf_tags(&msgbuf, source_p);
630+
build_msgbuf_tags(&msgbuf, source_p, initial_tags);
601631

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

697-
build_msgbuf_tags(&msgbuf, source_p);
727+
build_msgbuf_tags(&msgbuf, source_p, NULL);
698728

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

@@ -765,7 +795,7 @@ _sendto_channel_local_with_capability_butone(struct Client *source_p, struct Cli
765795
struct MsgBuf_cache msgbuf_cache;
766796
rb_strf_t strings = { .format = pattern, .format_args = args, .next = NULL };
767797

768-
build_msgbuf_tags(&msgbuf, source_p);
798+
build_msgbuf_tags(&msgbuf, source_p, NULL);
769799
msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
770800

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

847-
build_msgbuf_tags(&msgbuf, one);
877+
build_msgbuf_tags(&msgbuf, one, NULL);
848878

849879
va_start(args, pattern);
850880
msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
@@ -899,7 +929,7 @@ sendto_common_channels_local(struct Client *user, int cap, int negcap, const cha
899929
struct MsgBuf_cache msgbuf_cache;
900930
rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
901931

902-
build_msgbuf_tags(&msgbuf, user);
932+
build_msgbuf_tags(&msgbuf, user, NULL);
903933

904934
va_start(args, pattern);
905935
msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
@@ -966,7 +996,7 @@ sendto_common_channels_local_butone(struct Client *user, int cap, int negcap, co
966996
struct MsgBuf_cache msgbuf_cache;
967997
rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
968998

969-
build_msgbuf_tags(&msgbuf, user);
999+
build_msgbuf_tags(&msgbuf, user, NULL);
9701000

9711001
va_start(args, pattern);
9721002
msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
@@ -1022,7 +1052,7 @@ sendto_match_butone(struct Client *one, struct Client *source_p,
10221052

10231053
rb_linebuf_newbuf(&rb_linebuf_remote);
10241054

1025-
build_msgbuf_tags(&msgbuf, source_p);
1055+
build_msgbuf_tags(&msgbuf, source_p, NULL);
10261056

10271057
va_start(args, pattern);
10281058
vsnprintf(buf, sizeof(buf), pattern, args);
@@ -1145,7 +1175,7 @@ sendto_local_clients_with_capability(int cap, const char *pattern, ...)
11451175
struct MsgBuf_cache msgbuf_cache;
11461176
rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
11471177

1148-
build_msgbuf_tags(&msgbuf, &me);
1178+
build_msgbuf_tags(&msgbuf, &me, NULL);
11491179

11501180
va_start(args, pattern);
11511181
msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
@@ -1181,7 +1211,7 @@ sendto_monitor(struct Client *source_p, struct monitor *monptr, const char *patt
11811211
struct MsgBuf_cache msgbuf_cache;
11821212
rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
11831213

1184-
build_msgbuf_tags(&msgbuf, source_p);
1214+
build_msgbuf_tags(&msgbuf, source_p, NULL);
11851215

11861216
va_start(args, pattern);
11871217
msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
@@ -1208,7 +1238,7 @@ sendto_monitor(struct Client *source_p, struct monitor *monptr, const char *patt
12081238
*/
12091239
static void
12101240
_sendto_anywhere(struct Client *dest_p, struct Client *target_p,
1211-
struct Client *source_p, const char *command,
1241+
struct Client *source_p, struct MsgTags *initial_tags, const char *command,
12121242
const char *pattern, va_list *args)
12131243
{
12141244
buf_head_t linebuf;
@@ -1224,7 +1254,7 @@ _sendto_anywhere(struct Client *dest_p, struct Client *target_p,
12241254
} else {
12251255
struct MsgBuf msgbuf;
12261256

1227-
build_msgbuf_tags(&msgbuf, source_p);
1257+
build_msgbuf_tags(&msgbuf, source_p, initial_tags);
12281258

12291259
linebuf_put_tagsf(&linebuf, &msgbuf, dest_p, &strings,
12301260
IsPerson(source_p) ? ":%1$s!%4$s@%5$s %2$s %3$s " : ":%1$s %2$s %3$s ",
@@ -1244,6 +1274,19 @@ _sendto_anywhere(struct Client *dest_p, struct Client *target_p,
12441274
rb_linebuf_donebuf(&linebuf);
12451275
}
12461276

1277+
void
1278+
sendto_anywhere_with_tags(struct Client *target_p, struct Client *source_p,
1279+
struct MsgTags *initial_tags,
1280+
const char *command, const char *pattern, ...)
1281+
{
1282+
va_list args;
1283+
1284+
va_start(args, pattern);
1285+
_sendto_anywhere(target_p, target_p, source_p, initial_tags, command, pattern, &args);
1286+
va_end(args);
1287+
1288+
}
1289+
12471290
/* sendto_anywhere()
12481291
*
12491292
* inputs - target, source, va_args
@@ -1257,7 +1300,7 @@ sendto_anywhere(struct Client *target_p, struct Client *source_p,
12571300
va_list args;
12581301

12591302
va_start(args, pattern);
1260-
_sendto_anywhere(target_p, target_p, source_p, command, pattern, &args);
1303+
_sendto_anywhere(target_p, target_p, source_p, NULL, command, pattern, &args);
12611304
va_end(args);
12621305
}
12631306

@@ -1277,7 +1320,7 @@ sendto_anywhere_echo(struct Client *target_p, struct Client *source_p,
12771320
s_assert(!IsServer(source_p));
12781321

12791322
va_start(args, pattern);
1280-
_sendto_anywhere(source_p, target_p, source_p, command, pattern, &args);
1323+
_sendto_anywhere(source_p, target_p, source_p, NULL, command, pattern, &args);
12811324
va_end(args);
12821325
}
12831326

@@ -1299,7 +1342,7 @@ sendto_realops_snomask(int flags, int level, const char *pattern, ...)
12991342
struct MsgBuf msgbuf;
13001343
struct MsgBuf_cache msgbuf_cache;
13011344

1302-
build_msgbuf_tags(&msgbuf, &me);
1345+
build_msgbuf_tags(&msgbuf, &me, NULL);
13031346

13041347
/* rather a lot of copying around, oh well -- jilles */
13051348
va_start(args, pattern);
@@ -1361,7 +1404,7 @@ sendto_realops_snomask_from(int flags, int level, struct Client *source_p,
13611404
struct MsgBuf_cache msgbuf_cache;
13621405
rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
13631406

1364-
build_msgbuf_tags(&msgbuf, &me);
1407+
build_msgbuf_tags(&msgbuf, &me, NULL);
13651408

13661409
va_start(args, pattern);
13671410
msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
@@ -1407,7 +1450,7 @@ sendto_wallops_flags(int flags, struct Client *source_p, const char *pattern, ..
14071450
struct MsgBuf_cache msgbuf_cache;
14081451
rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
14091452

1410-
build_msgbuf_tags(&msgbuf, source_p);
1453+
build_msgbuf_tags(&msgbuf, source_p, NULL);
14111454

14121455
va_start(args, pattern);
14131456
if (IsPerson(source_p)) {
@@ -1446,7 +1489,7 @@ kill_client(struct Client *target_p, struct Client *diedie, const char *pattern,
14461489
struct MsgBuf msgbuf;
14471490
rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
14481491

1449-
build_msgbuf_tags(&msgbuf, &me);
1492+
build_msgbuf_tags(&msgbuf, &me, NULL);
14501493

14511494
rb_linebuf_newbuf(&linebuf);
14521495

0 commit comments

Comments
 (0)