Implement tracker item #1031606(relating to wildcards in /list).
authorAndrew Miller <a1kmm@amxl.com>
Mon, 20 Jun 2005 13:22:46 +0000 (13:22 +0000)
committerAndrew Miller <a1kmm@amxl.com>
Mon, 20 Jun 2005 13:22:46 +0000 (13:22 +0000)
git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/trunk@1432 c9e4aea6-c8fd-4c43-8297-357d70d61c8c

ChangeLog
include/channel.h
ircd/hash.c
ircd/m_list.c

index 3f618b3dca566ba947d0d3dc5b5495c07be0bb2b..dcef9041234911c44764978786135ba1788242ab 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2005-06-21  Andrew Miller  <a1kmm@amxl.com>
+
+       * 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  <a1kmm@amxl.com>
 
        * ircd/ircd_res.c (proc_answer): Deal with unexpected record types more
index 210c4df1c8ecaa381f6dd54c6049b2e246cacce0..e0aca8dac01daf76f34f82b787378c5ec35e36f8 100644 (file)
@@ -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 {
index 571a5023da922a46c581922a7f49f0a90081e14b..2b6c3a5c09d68653df26a37059c113664c0a2e6b 100644 (file)
@@ -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
index 28755b03c40c7afa75e1e036f1ac253612a373b8..381c14ada554d0f027b66babc38c0fcb07245c5e 100644 (file)
@@ -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);