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 = {
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
send_reply(sptr, RPL_LISTUSAGE,
" \002T>\002\037min_minutes\037 ; Channels with a topic last "
"set more than \037min_minutes\037 ago.");
- if (IsAnOper(sptr))
+ 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,
+ " \002M\002 ; Show channel modes.");
+ }
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 */
}
int is_time = 0;
char dir;
unsigned int val;
+ char *tmp1, *tmp2;
assert(0 != args);
if (*param != ',' && *param != ' ' && *param != '\0') /* check syntax */
return show_usage(sptr);
- if (is_time && val < 80000000) /* Toggle UTC/offset */
- val = TStime() - val * 60;
+ if (is_time && val < 80000000) {
+ /* Convert age to timestamp and reverse direction */
+ val = TStime() - val * 60;
+ dir = (dir == '>') ? '<' : '>';
+ }
switch (is_time) {
case 0: /* number of users on channel */
args->min_users = val;
break;
- case 1: /* channel topic */
+ case 1: /* channel creation time */
if (dir == '<')
- args->min_topic_time = val;
+ args->max_time = val;
else
- args->max_topic_time = val;
+ args->min_time = val;
break;
- case 2: /* channel creation time */
+ case 2: /* channel topic */
if (dir == '<')
- args->min_time = val;
+ args->max_topic_time = val;
else
- args->max_time = val;
+ args->min_topic_time = val;
break;
}
break;
return show_usage(sptr);
break;
- default: /* channel name? */
+ case 'M':
+ case 'm':
+ if (!IsAnOper(sptr) || !HasPriv(sptr, PRIV_LIST_CHAN))
+ return show_usage(sptr);
+
+ args->flags |= LISTARG_SHOWMODES;
+ param++;
+
+ if (*param != ',' && *param != ' ' && *param != '\0') /* check syntax */
+ return show_usage(sptr);
+ break;
+
+ 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);
return LPARAM_CHANNEL;
- break;
}
if (!*param) /* hit end of string? */
if (cli_listing(sptr)) /* Already listing ? */
{
+ if (cli_listing(sptr))
MyFree(cli_listing(sptr));
cli_listing(sptr) = 0;
send_reply(sptr, RPL_LISTEND);
switch (param_parse(sptr, parv[param], &args, parc == 2)) {
case LPARAM_ERROR: /* error encountered, usage already sent, return */
return 0;
- break;
case LPARAM_CHANNEL: /* show channel instead */
show_channels++;