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 userhost-in-names capability #1374

Merged
merged 13 commits into from
Jan 20, 2024
10 changes: 9 additions & 1 deletion doc/sphinx_source/using/ircv3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ The following capabilities are supported by Eggdrop:
* Monitor
* server-time
* setname
* userhost-in-names
* +typing

Copyright (C) 2010 - 2024 Eggheads Development Team
------
Errata
------

* Enabling echo-message will cause Eggdrop to trigger PUB/PUBM binds on its own messages (because now it can actually see them). This may cause unintentional functionality with some scripts
* Enabling userhost-in-names will cause Eggdrop's internal mechanisms to mark a channel's userlist as synch'd upon receiving the NAMES list after a join, instead of waiting for a full WHO listing. This is done because the assumption is that userhost-in-names was enabled as a response to WHO queries being disabled on a server, which prevents Eggdrop from populating its userlist. To avoid unintended functionality, it is suggested that this capability only be enabled on servers that disable WHO queries.

Copyright (C) 2010 - 2024 Eggheads Development Team
62 changes: 61 additions & 1 deletion src/mod/irc.mod/chan.c
Original file line number Diff line number Diff line change
Expand Up @@ -1214,7 +1214,7 @@ static int got354(char *from, char *msg)
}
return 0;
}

/* React to IRCv3 CHGHOST command. CHGHOST changes the hostname and/or
* ident of the user. Format:
* :[email protected] CHGHOST tehgeo foo.io
Expand Down Expand Up @@ -1251,6 +1251,65 @@ static int gotchghost(char *from, char *msg){
return 0;
}

/* got 353: NAMES
* <server> 353 <client> <symbol> <chan> :[+/@]nick [+/@]nick ....
*
* if userhost-in-names is enabled, nick is [email protected]
* this function is added solely to handle userhost-in-names stuff, and will
* update hostnames for nicks received
*/
static int got353(char *from, char *msg)
{
char prefixchars[64];
char *nameptr, *chname, *uhost, *nick, *p, *host;
struct chanset_t *chan;
int i;

if (find_capability("userhost-in-names")) {
strlcpy(prefixchars, isupport_get_prefixchars(), sizeof prefixchars);
newsplit(&msg);
newsplit(&msg); /* Get rid of =, @, or * symbol */
chname = newsplit(&msg);
nameptr = newsplit(&msg);
fixcolon(nameptr);
while ((uhost = newsplit(&nameptr))) {
if (!strcmp(uhost, "")) {
break;
}
fixcolon(uhost);
vanosg marked this conversation as resolved.
Show resolved Hide resolved
nick = splitnick(&uhost);
/* Strip @, +, etc chars prefixed to nicks in NAMES */
vanosg marked this conversation as resolved.
Show resolved Hide resolved
for (i = 0; prefixchars[i]; i++) {
if(nick[0] == prefixchars[i]) {
nick=nick+1;
}
}
if ((nick[0] == '+') || (nick[0] == '%')) {
nick=nick+1;
}
p = strchr(uhost, '@');
if (p) {
*p = 0;
host = p+1;
}
chan = findchan(chname); /* See if I'm on channel */
if (chan && host) {
/* Pretend we got a WHO and pass the info we got from NAMES */
got352or4(chan, uhost, host, nick, "", NULL);
vanosg marked this conversation as resolved.
Show resolved Hide resolved
}
}
/* The assumption here is the user enabled userhost-in-names because WHO
* is disabled. We remove the pending flag here because we'll never get a
* a WHO to do it
*/
if (chan) {
chan->status |= CHAN_ACTIVE;
chan->status &= ~CHAN_PEND;
}
}
return 0;
}

/* React to 396 numeric (HOSTHIDDEN), sent when user mode +x (hostmasking) was
* successfully set. Format:
* :barjavel.freenode.net 396 BeerBot unaffiliated/geo/bot/beerbot :is now your hidden host (set by services.)
Expand Down Expand Up @@ -2820,6 +2879,7 @@ static int gotrawt(char *from, char *msg, Tcl_Obj *tags) {
static cmd_t irc_raw[] = {
{"324", "", (IntFunc) got324, "irc:324"},
{"352", "", (IntFunc) got352, "irc:352"},
{"353", "", (IntFunc) got353, "irc:353"},
{"354", "", (IntFunc) got354, "irc:354"},
{"315", "", (IntFunc) got315, "irc:315"},
{"366", "", (IntFunc) gottwitch366, "irc:t366"},
Expand Down
12 changes: 12 additions & 0 deletions src/mod/server.mod/isupport.c
Original file line number Diff line number Diff line change
Expand Up @@ -509,3 +509,15 @@ void isupport_report(int idx, const char *prefix, int details)
}
}

static const char *isupport_get_prefixchars(void)
{
const char *str = isupport_get("PREFIX", strlen("PREFIX"));

if (str) {
str = strchr(str, ')');
if (str && str[1]) {
return str + 1;
}
}
return "+%@&~";
}
3 changes: 2 additions & 1 deletion src/mod/server.mod/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -2385,7 +2385,8 @@ static Function server_table[] = {
(Function) & find_capability,
(Function) encode_msgtags,
/* 52 - 55 */
(Function) & H_monitor
(Function) & H_monitor,
(Function) isupport_get_prefixchars
};

char *server_start(Function *global_funcs)
Expand Down
5 changes: 5 additions & 0 deletions src/mod/server.mod/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@
/* #define check_tcl_account NULL */
#define find_capability ((struct capability *(*)(char *))(server_funcs[50]))
#define encode_msgtags ((char *(*)(Tcl_Obj *))(server_funcs[51]))
/* 52 - 55 */
#define H_monitor (*(p_tcl_bind_list *)(server_funcs[52]))
#define isupport_get_prefixchars ((const char *(*)(void))server_funcs[53])


#endif /* MAKING_SERVER */

struct server_list {
Expand Down