diff --git a/extensions/m_olist.c b/extensions/m_olist.c index 7588d5113..f153f9ff9 100644 --- a/extensions/m_olist.c +++ b/extensions/m_olist.c @@ -107,7 +107,7 @@ list_all_channels(struct Client *source_p) chptr = ptr->data; sendto_one(source_p, form_str(RPL_LIST), - me.name, source_p->name, chptr->chname, + me.name, source_p->name, "", chptr->chname, rb_dlink_list_length(&chptr->members), chptr->topic == NULL ? "" : chptr->topic); } @@ -145,7 +145,7 @@ list_named_channel(struct Client *source_p, const char *name) sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL, form_str(ERR_NOSUCHCHANNEL), n); else - sendto_one(source_p, form_str(RPL_LIST), me.name, source_p->name, + sendto_one(source_p, form_str(RPL_LIST), me.name, source_p->name, "", chptr->chname, rb_dlink_list_length(&chptr->members), chptr->topic ? chptr->topic : ""); } diff --git a/help/opers/operspy b/help/opers/operspy index 2b60cc0da..3633d7727 100644 --- a/help/opers/operspy +++ b/help/opers/operspy @@ -12,3 +12,4 @@ mode !#channel - Gives the full modes of a channel including any keys. chantrace !#channel - Gives full output despite not being on channel. masktrace !nick!user@host :gecos - Lists matching users on all servers. topic !#channel - Gives full output despite not being on channel. +list ![,options...] - Lists all channels, including secret channels. diff --git a/include/client.h b/include/client.h index 61e55c03c..0885b08f0 100644 --- a/include/client.h +++ b/include/client.h @@ -303,6 +303,7 @@ struct ListClient { unsigned int hash_indice; unsigned int users_min, users_max; + int operspy; /* It would be nice to add other modifiers, * but not for 1.1 --nenolod diff --git a/modules/m_list.c b/modules/m_list.c index 8901dbc67..bb3da4992 100644 --- a/modules/m_list.c +++ b/modules/m_list.c @@ -41,6 +41,7 @@ #include "ircd.h" #include "numeric.h" #include "s_conf.h" +#include "s_newconf.h" #include "s_serv.h" #include "send.h" #include "msg.h" @@ -154,13 +155,14 @@ static int mo_list(struct Client *client_p, struct Client *source_p, int parc, c /* XXX rather arbitrary -- jilles */ params.users_min = 3; params.users_max = INT_MAX; + params.operspy = 0; if (parc > 1 && parv[1] != NULL && !IsChannelName(parv[1])) { args = LOCAL_COPY(parv[1]); - /* Make any specification cancel out defaults */ - if (*args == '<') - params.users_min = 0; + + /* Cancel out default minimum. */ + params.users_min = 0; for (i = 0; i < 2; i++) { @@ -189,6 +191,12 @@ static int mo_list(struct Client *client_p, struct Client *source_p, int parc, c else params.users_min = 0; } + /* Only accept operspy as the first option. */ + else if (*args == '!' && IsOperSpy(source_p) && i == 0) + { + params.operspy = 1; + report_operspy(source_p, "LIST", p); + } if (EmptyString(p)) break; @@ -250,6 +258,7 @@ static void safelist_client_instantiate(struct Client *client_p, struct ListClie self->hash_indice = 0; self->users_min = params->users_min; self->users_max = params->users_max; + self->operspy = params->operspy; client_p->localClient->safelist_data = self; @@ -321,8 +330,8 @@ static void safelist_channel_named(struct Client *source_p, const char *name) } if (!SecretChannel(chptr) || IsMember(source_p, chptr)) - sendto_one(source_p, form_str(RPL_LIST), me.name, source_p->name, chptr->chname, - rb_dlink_list_length(&chptr->members), + sendto_one(source_p, form_str(RPL_LIST), me.name, source_p->name, "", + chptr->chname, rb_dlink_list_length(&chptr->members), chptr->topic == NULL ? "" : chptr->topic); sendto_one(source_p, form_str(RPL_LISTEND), me.name, source_p->name); @@ -341,15 +350,17 @@ static void safelist_one_channel(struct Client *source_p, struct Channel *chptr) { struct ListClient *safelist_data = source_p->localClient->safelist_data; - if (SecretChannel(chptr) && !IsMember(source_p, chptr)) + if (SecretChannel(chptr) && !IsMember(source_p, chptr) && !safelist_data->operspy) return; if ((unsigned int)chptr->members.length < safelist_data->users_min || (unsigned int)chptr->members.length > safelist_data->users_max) return; - sendto_one(source_p, form_str(RPL_LIST), me.name, source_p->name, chptr->chname, - chptr->members.length, chptr->topic == NULL ? "" : chptr->topic); + sendto_one(source_p, form_str(RPL_LIST), me.name, source_p->name, + (safelist_data->operspy && SecretChannel(chptr)) ? "!" : "", + chptr->chname, rb_dlink_list_length(&chptr->members), + chptr->topic == NULL ? "" : chptr->topic); } /* diff --git a/src/messages.tab b/src/messages.tab index ca196302a..9dfa77be1 100644 --- a/src/messages.tab +++ b/src/messages.tab @@ -343,7 +343,7 @@ static const char * replies[] = { /* 319 RPL_WHOISCHANNELS, */ ":%s 319 %s %s :", /* 320 */ NULL, /* 321 RPL_LISTSTART, */ ":%s 321 %s Channel :Users Name", -/* 322 RPL_LIST, */ ":%s 322 %s %s %d :%s", +/* 322 RPL_LIST, */ ":%s 322 %s %s%s %d :%s", /* 323 RPL_LISTEND, */ ":%s 323 %s :End of /LIST", /* 324 RPL_CHANNELMODEIS, */ ":%s 324 %s %s %s", /* 325 RPL_CHANNELMLOCKIS, */ ":%s 325 %s %s %s :is the current channel mode-lock",