From 669a24ecfc453366d9be3727aaea68108ed2e29e Mon Sep 17 00:00:00 2001 From: Andrew Miller Date: Mon, 20 Jun 2005 13:22:46 +0000 Subject: [PATCH] Implement tracker item #1031606(relating to wildcards in /list). git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/trunk@1432 c9e4aea6-c8fd-4c43-8297-357d70d61c8c --- ChangeLog | 7 +++++ include/channel.h | 2 ++ ircd/hash.c | 4 +++ ircd/m_list.c | 66 ++++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 72 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3f618b3..dcef904 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2005-06-21 Andrew Miller + + * ircd/m_list.c (param_parse): Add support for channel wildcards. + * ircd/m_list.c (show_usage): Document the new format. + * ircd/hash.c (list_next_channels): Check channel wildcard in list. + * include/channel.h (ListingArgs): Add the wildcard member. + 2005-06-19 Andrew Miller * ircd/ircd_res.c (proc_answer): Deal with unexpected record types more diff --git a/include/channel.h b/include/channel.h index 210c4df..e0aca8d 100644 --- a/include/channel.h +++ b/include/channel.h @@ -149,6 +149,7 @@ typedef enum ChannelGetType { #define LISTARG_TOPICLIMITS 0x0001 #define LISTARG_SHOWSECRET 0x0002 +#define LISTARG_NEGATEWILDCARD 0x0004 /** * Maximum acceptable lag time in seconds: A channel younger than @@ -303,6 +304,7 @@ struct ListingArgs { time_t max_topic_time; time_t min_topic_time; unsigned int bucket; + char wildcard[CHANNELLEN]; }; struct ModeBuf { diff --git a/ircd/hash.c b/ircd/hash.c index 571a502..2b6c3a5 100644 --- a/ircd/hash.c +++ b/ircd/hash.c @@ -440,6 +440,10 @@ void list_next_channels(struct Client *cptr) && chptr->users < args->max_users && chptr->creationtime > args->min_time && chptr->creationtime < args->max_time + && (!args->wildcard[0] || (args->flags & LISTARG_NEGATEWILDCARD) || + (!match(args->wildcard, chptr->chname))) + && (!(args->flags & LISTARG_NEGATEWILDCARD) || + match(args->wildcard, chptr->chname)) && (!(args->flags & LISTARG_TOPICLIMITS) || (chptr->topic[0] && chptr->topic_time > args->min_topic_time diff --git a/ircd/m_list.c b/ircd/m_list.c index 28755b0..381c14a 100644 --- a/ircd/m_list.c +++ b/ircd/m_list.c @@ -110,10 +110,11 @@ static struct ListingArgs la_init = { 0, /* min_time */ 4294967295U, /* max_users */ 0, /* min_users */ - 0, /* topic_limits */ + 0, /* flags */ 2147483647, /* max_topic_time */ 0, /* min_topic_time */ - 0 /* chptr */ + 0, /* bucket */ + {0} /* wildcard */ }; static struct ListingArgs la_default = { @@ -121,10 +122,11 @@ static struct ListingArgs la_default = { 0, /* min_time */ 4294967295U, /* max_users */ 0, /* min_users */ - 0, /* topic_limits */ + 0, /* flags */ 2147483647, /* max_topic_time */ 0, /* min_topic_time */ - 0 /* chptr */ + 0, /* bucket */ + {0} /* wildcard */ }; static int @@ -158,12 +160,20 @@ show_usage(struct Client *sptr) send_reply(sptr, RPL_LISTUSAGE, " \002T>\002\037min_minutes\037 ; Channels with a topic last " "set more than \037min_minutes\037 ago."); + send_reply(sptr, RPL_LISTUSAGE, + " \037pattern\037 ; Channels with names matching " + "\037pattern\037. "); + send_reply(sptr, RPL_LISTUSAGE, + " !\037pattern\037 ; Channels with names not " + "matching \037pattern\037. "); + send_reply(sptr, RPL_LISTUSAGE, "Note: Patterns may contain * and ?. " + "You may only give one pattern match constraint."); if (IsAnOper(sptr)) send_reply(sptr, RPL_LISTUSAGE, " \002S\002 ; Show secret channels."); send_reply(sptr, RPL_LISTUSAGE, - "Example: LIST <3,>1,C<10,T>0 ; 2 users, younger than 10 " - "min., topic set."); + "Example: LIST <3,>1,C<10,T>0,#a* ; 2 users, younger than 10 " + "min., topic set., starts with #a"); return LPARAM_ERROR; /* return error condition */ } @@ -175,6 +185,7 @@ param_parse(struct Client *sptr, const char *param, struct ListingArgs *args, int is_time = 0; char dir; unsigned int val; + char *tmp1, *tmp2; assert(0 != args); @@ -248,7 +259,47 @@ param_parse(struct Client *sptr, const char *param, struct ListingArgs *args, return show_usage(sptr); break; - default: /* channel name? */ + default: + /* It might be a wildcard... */ + if (strchr(param, '*') || + strchr(param, '?')) + { + if (param[0] == '!') + { + param++; + args->flags |= LISTARG_NEGATEWILDCARD; + } + + /* Only one wildcard allowed... */ + if (args->wildcard[0] != 0) + return show_usage(sptr); + + /* If its not going to match anything, don't bother. */ + if (param[0] != '*' && + param[0] != '?' && + param[0] != '#' && + param[0] != '&') + return show_usage(sptr); + + tmp1 = strchr(param, ','); + tmp2 = strchr(param, ' '); + if (tmp2 && (!tmp1 || (tmp2 < tmp1))) + tmp1 = tmp2; + + if (tmp1) + *tmp1++ = 0; + + ircd_strncpy(args->wildcard, param, CHANNELLEN-1); + args->wildcard[CHANNELLEN-1] = 0; + + if (tmp1 == NULL) + return LPARAM_SUCCESS; + + param = tmp1; + continue; + } + + /* channel name? */ if (!permit_chan || !IsChannelName(param)) return show_usage(sptr); @@ -291,6 +342,7 @@ int m_list(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) if (cli_listing(sptr)) /* Already listing ? */ { + if (cli_listing(sptr)) MyFree(cli_listing(sptr)); cli_listing(sptr) = 0; send_reply(sptr, RPL_LISTEND); -- 2.20.1