diff --git a/doc/example.conf b/doc/example.conf index 7d881228..bb13f837 100644 --- a/doc/example.conf +++ b/doc/example.conf @@ -922,6 +922,7 @@ features # "CAP_ECHOMESSAGE" = "TRUE"; # "CAP_EXTJOIN" = "TRUE"; # "CAP_INVITENOTIFY" = "TRUE"; +# "CAP_UHNAMES" = "TRUE"; # These were introduced by Undernet CFV-165 to add "Head-In-Sand" (HIS) # behavior to hide most network topology from users. # "HIS_SNOTICES" = "TRUE"; diff --git a/include/capab.h b/include/capab.h index 972fd4cd..d5225719 100644 --- a/include/capab.h +++ b/include/capab.h @@ -42,7 +42,8 @@ _CAP(CHGHOST, FEAT_CAP_CHGHOST, 0, "chghost"), \ _CAP(ECHOMESSAGE, FEAT_CAP_ECHOMESSAGE, 0, "echo-message"), \ _CAP(EXTJOIN, FEAT_CAP_EXTJOIN, 0, "extended-join"), \ - _CAP(INVITENOTIFY, FEAT_CAP_INVITENOTIFY, 0, "invite-notify") + _CAP(INVITENOTIFY, FEAT_CAP_INVITENOTIFY, 0, "invite-notify"), \ + _CAP(UHNAMES, FEAT_CAP_UHNAMES, 0, "userhost-in-names") /** Client capabilities, counting by index. */ enum Capab { diff --git a/include/ircd_features.h b/include/ircd_features.h index 10167947..53015ed7 100644 --- a/include/ircd_features.h +++ b/include/ircd_features.h @@ -111,6 +111,7 @@ enum Feature { FEAT_CAP_ECHOMESSAGE, FEAT_CAP_EXTJOIN, FEAT_CAP_INVITENOTIFY, + FEAT_CAP_UHNAMES, /* HEAD_IN_SAND Features */ FEAT_HIS_SNOTICES, diff --git a/ircd/ircd_features.c b/ircd/ircd_features.c index 6410099b..3ac42540 100644 --- a/ircd/ircd_features.c +++ b/ircd/ircd_features.c @@ -376,6 +376,7 @@ static struct FeatureDesc { F_B(CAP_ECHOMESSAGE, 0, 1, 0), F_B(CAP_EXTJOIN, 0, 1, 0), F_B(CAP_INVITENOTIFY, 0, 1, 0), + F_B(CAP_UHNAMES, 0, 1, 0), /* HEAD_IN_SAND Features */ F_B(HIS_SNOTICES, 0, 1, 0), diff --git a/ircd/m_names.c b/ircd/m_names.c index 157b7ee5..cd1cf64c 100644 --- a/ircd/m_names.c +++ b/ircd/m_names.c @@ -116,6 +116,7 @@ void do_names(struct Client* sptr, struct Channel* chptr, int filter) int flag; int needs_space; int len; + int cap_extra = CapHas(cli_active(sptr), CAP_UHNAMES) ? (1 + USERLEN + 1 + HOSTLEN) : 0; char buf[BUFSIZE]; struct Client *c2ptr; struct Membership* member; @@ -174,8 +175,18 @@ void do_names(struct Client* sptr, struct Channel* chptr, int filter) buf[idx++] = '+'; strcpy(buf + idx, cli_name(c2ptr)); idx += strlen(cli_name(c2ptr)); + + if (CapHas(cli_active(sptr), CAP_UHNAMES)) { + buf[idx++] = '!'; + strcpy(buf + idx, cli_user(c2ptr)->username); + idx += strlen(cli_user(c2ptr)->username); + buf[idx++] = '@'; + strcpy(buf + idx, cli_user(c2ptr)->host); + idx += strlen(cli_user(c2ptr)->host); + } + flag = 1; - if (mlen + idx + NICKLEN + 5 > BUFSIZE) + if (mlen + idx + NICKLEN + 5 + cap_extra > BUFSIZE) /* space, modifier, nick, \r \n \0 */ { send_reply(sptr, (filter & NAMES_DEL) ? RPL_DELNAMREPLY : RPL_NAMREPLY, buf);