Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for the draft/extended-monitor capability #254

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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_EXTENDED_MONITOR;

/*
* XXX: this is kind of ugly, but this allows us to have backwards
Expand Down
1 change: 1 addition & 0 deletions include/send.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ extern void sendto_match_butone(struct Client *, struct Client *,
extern void sendto_match_servs(struct Client *source_p, const char *mask,
int capab, int, const char *, ...) AFP(5, 6);

extern void sendto_monitor_with_capability_butserial(struct Client *, struct monitor *monptr, int caps, int negcaps, bool skipserial, const char *, ...) AFP(6, 7);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eliminate current_serial abuse

Suggested change
extern void sendto_monitor_with_capability_butserial(struct Client *, struct monitor *monptr, int caps, int negcaps, bool skipserial, const char *, ...) AFP(6, 7);
extern void sendto_monitor_with_capability(struct Client *, struct monitor *monptr, int caps, int negcaps, const char *, ...) AFP(5, 6);

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

extern void sendto_anywhere(struct Client *, struct Client *, const char *,
Expand Down
2 changes: 2 additions & 0 deletions ircd/s_serv.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ unsigned int CLICAP_USERHOST_IN_NAMES;
unsigned int CLICAP_CAP_NOTIFY;
unsigned int CLICAP_CHGHOST;
unsigned int CLICAP_ECHO_MESSAGE;
unsigned int CLICAP_EXTENDED_MONITOR;

/*
* initialize our builtin capability table. --nenolod
Expand Down Expand Up @@ -142,6 +143,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_EXTENDED_MONITOR = capability_put(cli_capindex, "draft/extended-monitor", &high_priority);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this need high priority? It's a draft cap, and anybody supporting it should support 3.2-style CAP LS (which doesn't need priority)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense 👍

}

static CNCB serv_connect_callback;
Expand Down
4 changes: 4 additions & 0 deletions ircd/s_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -1637,6 +1637,10 @@ change_nick_user_host(struct Client *target_p, const char *nick, const char *use
sendto_common_channels_local_butone(target_p, CLICAP_CHGHOST, NOCAPS,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of abusing current_serial semantics, this should exclude users with extended-monitor enabled:

Suggested change
sendto_common_channels_local_butone(target_p, CLICAP_CHGHOST, NOCAPS,
sendto_common_channels_local_butone(target_p, CLICAP_CHGHOST, CLICAP_EXTENDED_MONITOR,

Copy link
Author

@delthas delthas Jul 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still want to sent messages to users sharing a channel and who have the extended-monitor cap but who are not currently monitoring the user. That's why we can't just send to neighbours first, excluding those who have the cap, then send to all those who are monitoring the user.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Err, yes. The correct implementation would end up being more complex than this, my brain just failed to process it correctly.

":%s!%s@%s CHGHOST %s %s",
target_p->name, target_p->username, target_p->host, user, host);
struct monitor *monptr = find_monitor(target_p->name, 0);
if(monptr)
sendto_monitor_with_capability_butserial(target_p, monptr, CLICAP_EXTENDED_MONITOR | CLICAP_CHGHOST, NOCAPS, true, ":%s!%s@%s CHGHOST %s %s",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eliminate current_serial abuse

Suggested change
sendto_monitor_with_capability_butserial(target_p, monptr, CLICAP_EXTENDED_MONITOR | CLICAP_CHGHOST, NOCAPS, true, ":%s!%s@%s CHGHOST %s %s",
sendto_monitor_with_capability(target_p, monptr, CLICAP_EXTENDED_MONITOR | CLICAP_CHGHOST, NOCAPS, ":%s!%s@%s CHGHOST %s %s",

target_p->name, target_p->username, target_p->host, user, host);

if(MyClient(target_p) && changed_case)
sendto_one(target_p, ":%s!%s@%s NICK %s",
Expand Down
51 changes: 41 additions & 10 deletions ircd/send.c
Original file line number Diff line number Diff line change
Expand Up @@ -1163,34 +1163,33 @@ sendto_local_clients_with_capability(int cap, const char *pattern, ...)
msgbuf_cache_free(&msgbuf_cache);
}

/* sendto_monitor()
/*
* _sendto_monitor_with_capability_butserial()
*
* inputs - monitor nick to send to, format, va_args
* outputs - message to local users monitoring the given nick
* side effects -
* Shared implementation of sendto_monitor_with_capability_butserial and _sendto_monitor
*/
void
sendto_monitor(struct Client *source_p, struct monitor *monptr, const char *pattern, ...)
_sendto_monitor_with_capability_butserial(struct Client *source_p, struct monitor *monptr, int caps, int negcaps, bool skipserial, const char *pattern, va_list * args)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eliminate current_serial abuse

Suggested change
_sendto_monitor_with_capability_butserial(struct Client *source_p, struct monitor *monptr, int caps, int negcaps, bool skipserial, const char *pattern, va_list * args)
_sendto_monitor_with_capability(struct Client *source_p, struct monitor *monptr, int caps, int negcaps, const char *pattern, va_list * args)

{
va_list args;
struct Client *target_p;
rb_dlink_node *ptr;
rb_dlink_node *next_ptr;
struct MsgBuf msgbuf;
struct MsgBuf_cache msgbuf_cache;
rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
rb_strf_t strings = { .format = pattern, .format_args = args, .next = NULL };

build_msgbuf_tags(&msgbuf, source_p);

va_start(args, pattern);
msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
va_end(args);

RB_DLINK_FOREACH_SAFE(ptr, next_ptr, monptr->users.head)
{
target_p = ptr->data;

if(IsIOError(target_p))
if(IsIOError(target_p) ||
(skipserial && target_p->serial == current_serial) ||
!IsCapable(target_p, caps) ||
Comment on lines +1189 to +1191
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eliminate current_serial abuse

Suggested change
if(IsIOError(target_p) ||
(skipserial && target_p->serial == current_serial) ||
!IsCapable(target_p, caps) ||
if(IsIOError(target_p) ||
!IsCapable(target_p, caps) ||

!NotCapable(target_p, negcaps))
continue;

_send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
Expand All @@ -1199,6 +1198,38 @@ sendto_monitor(struct Client *source_p, struct monitor *monptr, const char *patt
msgbuf_cache_free(&msgbuf_cache);
}

/* sendto_monitor_with_capability_butserial()
*
* inputs - monitor nick to send to, caps, negate caps, whether to send to clients having current serial, format, va_args
* outputs - message to local users monitoring the given nick
* side effects -
*/
void
sendto_monitor_with_capability_butserial(struct Client *source_p, struct monitor *monptr, int caps, int negcaps, bool skipserial, const char *pattern, ...)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eliminate current_serial abuse

Suggested change
sendto_monitor_with_capability_butserial(struct Client *source_p, struct monitor *monptr, int caps, int negcaps, bool skipserial, const char *pattern, ...)
sendto_monitor_with_capability(struct Client *source_p, struct monitor *monptr, int caps, int negcaps, const char *pattern, ...)

{
va_list args;

va_start(args, pattern);
_sendto_monitor_with_capability_butserial(source_p, monptr, caps, negcaps, skipserial, pattern, &args);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eliminate current_serial abuse

Suggested change
_sendto_monitor_with_capability_butserial(source_p, monptr, caps, negcaps, skipserial, pattern, &args);
_sendto_monitor_with_capability(source_p, monptr, caps, negcaps, pattern, &args);

va_end(args);
}

/* sendto_monitor()
*
* inputs - monitor nick to send to, format, va_args
* outputs - message to local users monitoring the given nick
* side effects -
*/
void
sendto_monitor(struct Client *source_p, struct monitor *monptr, const char *pattern, ...)
{
va_list args;

va_start(args, pattern);
_sendto_monitor_with_capability_butserial(source_p, monptr, NOCAPS, NOCAPS, false, pattern, &args);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eliminate current_serial abuse

Suggested change
_sendto_monitor_with_capability_butserial(source_p, monptr, NOCAPS, NOCAPS, false, pattern, &args);
_sendto_monitor_with_capability(source_p, monptr, NOCAPS, NOCAPS, pattern, &args);

va_end(args);
}

/* _sendto_anywhere()
*
* inputs - real_target, target, source, va_args
Expand Down
13 changes: 13 additions & 0 deletions modules/m_away.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "client.h"
#include "match.h"
#include "ircd.h"
#include "monitor.h"
#include "numeric.h"
#include "send.h"
#include "msg.h"
Expand Down Expand Up @@ -89,6 +90,10 @@ m_away(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p

sendto_common_channels_local_butone(source_p, CLICAP_AWAY_NOTIFY, NOCAPS, ":%s!%s@%s AWAY",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exclude extended-monitor

Suggested change
sendto_common_channels_local_butone(source_p, CLICAP_AWAY_NOTIFY, NOCAPS, ":%s!%s@%s AWAY",
sendto_common_channels_local_butone(source_p, CLICAP_AWAY_NOTIFY, CLICAP_EXTENDED_MONITOR, ":%s!%s@%s AWAY",

source_p->name, source_p->username, source_p->host);
struct monitor *monptr = find_monitor(source_p->name, 0);
if(monptr)
sendto_monitor_with_capability_butserial(source_p, monptr, CLICAP_EXTENDED_MONITOR | CLICAP_AWAY_NOTIFY, NOCAPS, true, ":%s!%s@%s AWAY",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eliminate current_serial abuse

Suggested change
sendto_monitor_with_capability_butserial(source_p, monptr, CLICAP_EXTENDED_MONITOR | CLICAP_AWAY_NOTIFY, NOCAPS, true, ":%s!%s@%s AWAY",
sendto_monitor_with_capability(source_p, monptr, CLICAP_EXTENDED_MONITOR | CLICAP_AWAY_NOTIFY, NOCAPS, ":%s!%s@%s AWAY",

source_p->name, source_p->username, source_p->host);
}
if(MyConnect(source_p))
sendto_one_numeric(source_p, RPL_UNAWAY, form_str(RPL_UNAWAY));
Expand Down Expand Up @@ -127,6 +132,14 @@ m_away(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
source_p->username,
source_p->host,
source_p->user->away);
struct monitor *monptr = find_monitor(source_p->name, 0);
if(monptr)
sendto_monitor_with_capability_butserial(source_p, monptr, CLICAP_EXTENDED_MONITOR | CLICAP_AWAY_NOTIFY, NOCAPS, true,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adjust the regular away-notify to exclude extended-monitor (due to a GitHub limitation, I can't comment on that line). Eliminate current_serial abuse

Suggested change
sendto_monitor_with_capability_butserial(source_p, monptr, CLICAP_EXTENDED_MONITOR | CLICAP_AWAY_NOTIFY, NOCAPS, true,
sendto_monitor_with_capability(source_p, monptr, CLICAP_EXTENDED_MONITOR | CLICAP_AWAY_NOTIFY, NOCAPS,

":%s!%s@%s AWAY :%s",
source_p->name,
source_p->username,
source_p->host,
source_p->user->away);
}

if(MyConnect(source_p))
Expand Down
5 changes: 5 additions & 0 deletions modules/m_services.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ me_su(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p,
sendto_common_channels_local(target_p, CLICAP_ACCOUNT_NOTIFY, NOCAPS, ":%s!%s@%s ACCOUNT %s",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exclude extended-monitor

Suggested change
sendto_common_channels_local(target_p, CLICAP_ACCOUNT_NOTIFY, NOCAPS, ":%s!%s@%s ACCOUNT %s",
sendto_common_channels_local(target_p, CLICAP_ACCOUNT_NOTIFY, CLICAP_EXTENDED_MONITOR, ":%s!%s@%s ACCOUNT %s",

target_p->name, target_p->username, target_p->host,
EmptyString(target_p->user->suser) ? "*" : target_p->user->suser);
struct monitor *monptr = find_monitor(target_p->name, 0);
if(monptr)
sendto_monitor_with_capability_butserial(target_p, monptr, CLICAP_EXTENDED_MONITOR | CLICAP_ACCOUNT_NOTIFY, NOCAPS, true, ":%s!%s@%s ACCOUNT %s",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eliminate current_serial abuse

Suggested change
sendto_monitor_with_capability_butserial(target_p, monptr, CLICAP_EXTENDED_MONITOR | CLICAP_ACCOUNT_NOTIFY, NOCAPS, true, ":%s!%s@%s ACCOUNT %s",
sendto_monitor_with_capability(target_p, monptr, CLICAP_EXTENDED_MONITOR | CLICAP_ACCOUNT_NOTIFY, NOCAPS, ":%s!%s@%s ACCOUNT %s",

target_p->name, target_p->username, target_p->host,
EmptyString(target_p->user->suser) ? "*" : target_p->user->suser);

invalidate_bancache_user(target_p);
}
Expand Down