diff --git a/modules/m_privs.c b/modules/m_privs.c index a650203c..7ff25a6b 100644 --- a/modules/m_privs.c +++ b/modules/m_privs.c @@ -81,45 +81,52 @@ static struct mode_table auth_client_table[] = { DECLARE_MODULE_AV2(privs, NULL, NULL, privs_clist, NULL, NULL, NULL, NULL, privs_desc); +static void append_priv(struct Client *source_p, struct Client *target_p, char *buf, const char *s1, const char *s2) +{ + /* 510 - ":" - " 270 " - " " - " :* " */ + size_t sourcelen = strlen(source_p->name); + if (sourcelen < 9) sourcelen = 9; + size_t limit = 499 - strlen(me.name) - sourcelen - strlen(target_p->name); + if (strlen(s1) + strlen(s2) + strlen(buf) + 1 > limit) + { + sendto_one_numeric(source_p, RPL_PRIVS, "%s :* %s", target_p->name, buf); + buf[0] = '\0'; + } + if (buf[0] != '\0') + rb_strlcat(buf, " ", BUFSIZE); + rb_strlcat(buf, s1, BUFSIZE); + rb_strlcat(buf, s2, BUFSIZE); +} + static void show_privs(struct Client *source_p, struct Client *target_p) { - char buf[512]; + char buf[BUFSIZE]; struct mode_table *p; buf[0] = '\0'; + if (target_p->user->privset) - rb_strlcat(buf, target_p->user->privset->privs, sizeof buf); + for (const char *s = strtok(target_p->user->privset->privs, " "); s != NULL; s = strtok(NULL, " ")) + append_priv(source_p, target_p, buf, s, ""); + if (IsOper(target_p)) { if (target_p->user->opername) - { - if (buf[0] != '\0') - rb_strlcat(buf, " ", sizeof buf); - rb_strlcat(buf, "operator:", sizeof buf); - rb_strlcat(buf, target_p->user->opername, sizeof buf); - } + append_priv(source_p, target_p, buf, "operator:", target_p->user->opername); if (target_p->user->privset) - { - if (buf[0] != '\0') - rb_strlcat(buf, " ", sizeof buf); - rb_strlcat(buf, "privset:", sizeof buf); - rb_strlcat(buf, target_p->user->privset->name, sizeof buf); - } + append_priv(source_p, target_p, buf, "privset:", target_p->user->privset->name); } p = &auth_client_table[0]; while (p->name != NULL) { if (target_p->flags & p->mode) - { - if (buf[0] != '\0') - rb_strlcat(buf, " ", sizeof buf); - rb_strlcat(buf, p->name, sizeof buf); - } + append_priv(source_p, target_p, buf, p->name, ""); p++; } - sendto_one_numeric(source_p, RPL_PRIVS, form_str(RPL_PRIVS), - target_p->name, buf); + + if (buf[0] != '\0') + sendto_one_numeric(source_p, RPL_PRIVS, "%s :%s", target_p->name, buf); } static void