From: JD Horelick Date: Wed, 19 Jan 2011 20:45:45 +0000 (-0500) Subject: Add topic TS and channel TS constraints for /LIST. X-Git-Url: https://jfr.im/git/irc/rqf/shadowircd.git/commitdiff_plain/e8e3ef0dfb6fbe28c07e34599f0f48336792b4b3 Add topic TS and channel TS constraints for /LIST. --- diff --git a/help/opers/list b/help/opers/list index 0cc3ae7..4fe895e 100644 --- a/help/opers/list +++ b/help/opers/list @@ -12,5 +12,11 @@ the statistics for the given channel. Modifiers are also supported, seperated by a comma: n - List channels with more than n users + Cn - List channels older than n minutes + Tn - List channels whose topics were last changed + more than n minutes ago eg LIST <100,>20 diff --git a/include/client.h b/include/client.h index 24bbf67..41ee5af 100644 --- a/include/client.h +++ b/include/client.h @@ -306,11 +306,8 @@ struct ListClient { unsigned int hash_indice; unsigned int users_min, users_max; + time_t created_min, created_max, topic_min, topic_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 0274443..6574080 100644 --- a/modules/m_list.c +++ b/modules/m_list.c @@ -140,7 +140,7 @@ static int m_list(struct Client *client_p, struct Client *source_p, int parc, co */ static int mo_list(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { - struct ListClient params; + struct ListClient *params; char *p, *args; int i; @@ -151,19 +151,31 @@ static int mo_list(struct Client *client_p, struct Client *source_p, int parc, c return 0; } + /* Single channel. */ + if (parc > 1 && IsChannelName(parv[1])) + { + safelist_channel_named(source_p, parv[1]); + return 0; + } + + /* Multiple channels, possibly with parameters. */ + params = rb_malloc(sizeof(struct ListClient)); + /* Let the user set it */ - params.users_min = ConfigFileEntry.hide_channel_below_users; - params.users_max = INT_MAX; - params.operspy = 0; + params->users_min = ConfigFileEntry.hide_channel_below_users; + params->users_max = INT_MAX; + params->operspy = 0; + params->created_min = params->topic_min = + params->created_max = params->topic_max = 0; - if (parc > 1 && parv[1] != NULL && !IsChannelName(parv[1])) + if (parc > 1 && !EmptyString(parv[1])) { args = LOCAL_COPY(parv[1]); /* Cancel out default minimum. */ - params.users_min = 0; + params->users_min = 0; - for (i = 0; i < 2; i++) + for (i = 0; i < 7; i++) { if ((p = strchr(args, ',')) != NULL) *p++ = '\0'; @@ -173,27 +185,69 @@ static int mo_list(struct Client *client_p, struct Client *source_p, int parc, c args++; if (IsDigit(*args)) { - params.users_max = atoi(args); - if (params.users_max == 0) - params.users_max = INT_MAX; + params->users_max = atoi(args); + if (params->users_max == 0) + params->users_max = INT_MAX; else - params.users_max--; + params->users_max--; } - else - params.users_max = INT_MAX; } else if (*args == '>') { args++; if (IsDigit(*args)) - params.users_min = atoi(args) + 1; + params->users_min = atoi(args) + 1; else - params.users_min = 0; + params->users_min = 0; + } + else if (*args == 'C' || *args == 'c') + { + args++; + if (*args == '>') + { + /* Creation time earlier than last x minutes. */ + args++; + if (IsDigit(*args)) + { + params->created_max = rb_current_time() - (60 * atoi(args)); + } + } + else if (*args == '<') + { + /* Creation time within last x minutes. */ + args++; + if (IsDigit(*args)) + { + params->created_min = rb_current_time() - (60 * atoi(args)); + } + } + } + else if (*args == 'T' || *args == 't') + { + args++; + if (*args == '>') + { + /* Topic change time earlier than last x minutes. */ + args++; + if (IsDigit(*args)) + { + params->topic_max = rb_current_time() - (60 * atoi(args)); + } + } + else if (*args == '<') + { + /* Topic change time within last x minutes. */ + args++; + if (IsDigit(*args)) + { + params->topic_min = rb_current_time() - (60 * atoi(args)); + } + } } /* Only accept operspy as the first option. */ else if (*args == '!' && IsOperSpy(source_p) && i == 0) { - params.operspy = 1; + params->operspy = 1; report_operspy(source_p, "LIST", p); } @@ -203,13 +257,8 @@ static int mo_list(struct Client *client_p, struct Client *source_p, int parc, c args = p; } } - else if (parc > 1 && IsChannelName(parv[1])) - { - safelist_channel_named(source_p, parv[1]); - return 0; - } - safelist_client_instantiate(source_p, ¶ms); + safelist_client_instantiate(source_p, params); return 0; } @@ -237,7 +286,7 @@ static int safelist_sendq_exceeded(struct Client *client_p) * safelist_client_instantiate() * * inputs - pointer to Client to be listed, - * struct ListClient to copy for params + * pointer to ListClient for params * outputs - none * side effects - the safelist process begins for a * client. @@ -247,19 +296,10 @@ static int safelist_sendq_exceeded(struct Client *client_p) */ static void safelist_client_instantiate(struct Client *client_p, struct ListClient *params) { - struct ListClient *self; - s_assert(MyClient(client_p)); s_assert(params != NULL); - self = rb_malloc(sizeof(struct ListClient)); - - 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; + client_p->localClient->safelist_data = params; sendto_one(client_p, form_str(RPL_LISTSTART), me.name, client_p->name); @@ -356,6 +396,20 @@ static void safelist_one_channel(struct Client *source_p, struct Channel *chptr) || (unsigned int)chptr->members.length > safelist_data->users_max) return; + if (safelist_data->topic_min && chptr->topic_time < safelist_data->topic_min) + return; + + /* If a topic TS is provided, don't show channels without a topic set. */ + if (safelist_data->topic_max && (chptr->topic_time > safelist_data->topic_max + || chptr->topic_time == 0)) + return; + + if (safelist_data->created_min && chptr->channelts < safelist_data->created_min) + return; + + if (safelist_data->created_max && chptr->channelts > safelist_data->created_max) + return; + 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), diff --git a/src/supported.c b/src/supported.c index 6fd8c39..2bf4ba1 100644 --- a/src/supported.c +++ b/src/supported.c @@ -332,7 +332,7 @@ init_isupport(void) add_isupport("STATUSMSG", isupport_string, "@+"); add_isupport("CALLERID", isupport_string, "g"); add_isupport("SAFELIST", isupport_string, ""); - add_isupport("ELIST", isupport_string, "U"); + add_isupport("ELIST", isupport_string, "CTU"); add_isupport("CASEMAPPING", isupport_string, "rfc1459"); add_isupport("CHARSET", isupport_string, "ascii"); add_isupport("NICKLEN", isupport_intptr, &nicklen);