[srvx-commits] CVS: services/src opserv.c,1.239,1.240 opserv.help,1.41,1.42
Brought to you by:
entrope
|
From: Zoot <zo...@us...> - 2002-07-03 03:01:20
|
Update of /cvsroot/srvx/services/src
In directory usw-pr-cvs1:/tmp/cvs-serv6059/src
Modified Files:
opserv.c opserv.help
Log Message:
Introduce the long-awaited channel searching command "csearch" into
OperServ.
Index: opserv.c
===================================================================
RCS file: /cvsroot/srvx/services/src/opserv.c,v
retrieving revision 1.239
retrieving revision 1.240
diff -C2 -r1.239 -r1.240
*** opserv.c 3 Jul 2002 02:52:10 -0000 1.239
--- opserv.c 3 Jul 2002 03:01:17 -0000 1.240
***************
*** 3615,3618 ****
--- 3615,3620 ----
discrim->max_ts = now - (ParseInterval(cmp+1) - 1);
}
+ } else {
+ discrim->min_ts = now - ParseInterval(cmp+2);
}
} else if (strcasecmp(argv[i], "access") == 0) {
***************
*** 3634,3638 ****
}
} else {
! opserv_notice(user, MSG_INVALID_CRITERIA, cmp);
}
} else if ((strcasecmp(argv[i], "abuse") == 0)
--- 3636,3640 ----
}
} else {
! discrim->min_level = strtoul(cmp+2, NULL, 0);
}
} else if ((strcasecmp(argv[i], "abuse") == 0)
***************
*** 3983,3986 ****
--- 3985,4164 ----
}
+ typedef void (*cdiscrim_search_func)(struct chanNode *match, void *data);
+
+ typedef struct channel_discrim {
+ char *name, *topic;
+
+ unsigned int min_users, max_users;
+ time_t min_ts, max_ts;
+ unsigned int limit;
+ } *cdiscrim_t;
+
+ static cdiscrim_t opserv_cdiscrim_create(struct userNode *user, unsigned int argc, unsigned char *argv[]);
+ static unsigned int opserv_cdiscrim_search(cdiscrim_t discrim, cdiscrim_search_func dsf, void *data);
+
+ static cdiscrim_t
+ opserv_cdiscrim_create(struct userNode *user, unsigned int argc, unsigned char *argv[])
+ {
+ cdiscrim_t discrim;
+ unsigned int i;
+
+ discrim = calloc(1, sizeof(*discrim));
+ discrim->limit = 25;
+
+ for(i = 0; i < argc; i++) {
+ /* Assume all criteria require arguments. */
+ if(i == (argc - 1)) {
+ opserv_notice(user, MSG_MISSING_PARAMS, argv[i]);
+ return NULL;
+ }
+
+ if(!strcasecmp(argv[i], "name")) {
+ discrim->name = argv[++i];
+ } else if(!strcasecmp(argv[i], "topic")) {
+ discrim->topic = argv[++i];
+ } else if(!strcasecmp(argv[i], "users")) {
+ const char *cmp = argv[++i];
+ if (cmp[0] == '<') {
+ if (cmp[1] == '=') {
+ discrim->max_users = strtoul(cmp+2, NULL, 0);
+ } else {
+ discrim->max_users = strtoul(cmp+1, NULL, 0) - 1;
+ }
+ } else if (cmp[0] == '=') {
+ discrim->min_users = discrim->max_users = strtoul(cmp+1, NULL, 0);
+ } else if (cmp[0] == '>') {
+ if (cmp[1] == '=') {
+ discrim->min_users = strtoul(cmp+2, NULL, 0);
+ } else {
+ discrim->min_users = strtoul(cmp+1, NULL, 0) + 1;
+ }
+ } else {
+ discrim->min_users = strtoul(cmp+2, NULL, 0);
+ }
+ } else if(!strcasecmp(argv[i], "timestamp")) {
+ const char *cmp = argv[++i];
+ if (cmp[0] == '<') {
+ if (cmp[1] == '=') {
+ discrim->max_ts = (!cmp[strspn(cmp+2, "0123456789")]) ? atoi(cmp+2) : (now - ParseInterval(cmp+2));
+ } else {
+ discrim->max_ts = ((!cmp[strspn(cmp+1, "0123456789")]) ? atoi(cmp+1) : (now - ParseInterval(cmp+1))) - 1;
+ }
+ } else if (cmp[0] == '=') {
+ discrim->min_ts = discrim->max_ts = (!cmp[strspn(cmp+1, "0123456789")]) ? atoi(cmp+1) : (now - ParseInterval(cmp+1));
+ } else if (cmp[0] == '>') {
+ if (cmp[1] == '=') {
+ discrim->min_ts = (!cmp[strspn(cmp+2, "0123456789")]) ? atoi(cmp+2) : (now - ParseInterval(cmp+2));
+ } else {
+ discrim->min_ts = ((!cmp[strspn(cmp+1, "0123456789")]) ? atoi(cmp+1) : (now - ParseInterval(cmp+1))) + 1;
+ }
+ } else {
+ discrim->min_ts = (!cmp[strspn(cmp+2, "0123456789")]) ? atoi(cmp+2) : (now - ParseInterval(cmp+2));
+ }
+ } else if(!strcasecmp(argv[i], "limit")) {
+ discrim->limit = strtoul(argv[++i], NULL, 10);
+ } else {
+ opserv_notice(user, MSG_INVALID_CRITERIA, argv[i]);
+ goto fail;
+ }
+ }
+
+ if(discrim->name && !strcmp(discrim->name, "*")) {
+ discrim->name = 0;
+ }
+ if(discrim->topic && !strcmp(discrim->topic, "*")) {
+ discrim->topic = 0;
+ }
+
+ return discrim;
+ fail:
+ free(discrim);
+ return NULL;
+ }
+
+ static int
+ cdiscrim_match(cdiscrim_t discrim, struct chanNode *chan)
+ {
+ if((discrim->name && !match_ircglob(chan->name, discrim->name)) ||
+ (discrim->topic && !match_ircglob(chan->topic, discrim->topic)) ||
+ (discrim->min_users && chan->members.used < discrim->min_users) ||
+ (discrim->max_users && chan->members.used > discrim->max_users) ||
+ (discrim->min_ts && chan->timestamp < discrim->min_ts) ||
+ (discrim->max_ts && chan->timestamp > discrim->max_ts)) {
+ return 0;
+ }
+ return 1;
+ }
+
+ static unsigned int opserv_cdiscrim_search(cdiscrim_t discrim, cdiscrim_search_func dsf, void *data)
+ {
+ unsigned int count = 0;
+ dict_iterator_t it, next;
+
+ for(it = dict_first(channels); it && count < discrim->limit ; it = next) {
+ struct chanNode *chan = iter_data(it);
+
+ /* Hold on to the next channel in case we decide to
+ add actions that destructively modify the channel. */
+ next = iter_next(it);
+ if(cdiscrim_match(discrim, chan)) {
+ dsf(chan, data);
+ count++;
+ }
+ }
+
+ return count;
+ }
+
+ void channel_count(struct chanNode *channel, void *data)
+ {
+ (void)channel;(void)data;
+ }
+
+ void channel_print(struct chanNode *channel, void *data)
+ {
+ opserv_notice(data, "%s [%d users]", channel->name, channel->members.used);
+ }
+
+ static OPSERV_FUNC(cmd_csearch)
+ {
+ cdiscrim_t discrim;
+ unsigned int matches;
+ cdiscrim_search_func action;
+
+ OPSERV_MIN_PARMS(3, false);
+
+ if(!strcasecmp(argv[1], "count")) {
+ action = channel_count;
+ } else if(!strcasecmp(argv[1], "print")) {
+ action = channel_print;
+ } else {
+ opserv_notice(user, OSMSG_BAD_ACTION, argv[1]);
+ return 0;
+ }
+
+ discrim = opserv_cdiscrim_create(user, argc - 2, argv + 2);
+ if(!discrim) {
+ return 0;
+ }
+
+ if(action == channel_print) {
+ opserv_notice(user, MSG_SEARCH_RESULTS, "channels");
+ } else if(action == channel_count) {
+ discrim->limit = INT_MAX;
+ }
+
+ matches = opserv_cdiscrim_search(discrim, action, user);
+
+ if (matches) {
+ opserv_notice(user, MSG_MATCH_COUNT, matches);
+ } else {
+ opserv_notice(user, MSG_NO_MATCHES);
+ }
+
+ free(discrim);
+ return 1;
+ }
+
static OPSERV_FUNC(cmd_gsync)
{
***************
*** 4724,4727 ****
--- 4902,4906 ----
opserv_define_func("TRACE GAG", NULL, 600);
opserv_define_func("TRACE KILL", NULL, 600);
+ opserv_define_func("CSEARCH", cmd_csearch, 100);
opserv_define_func("GSYNC", cmd_gsync, 600);
opserv_define_func("GTRACE", cmd_gtrace, 100);
Index: opserv.help
===================================================================
RCS file: /cvsroot/srvx/services/src/opserv.help,v
retrieving revision 1.41
retrieving revision 1.42
diff -C2 -r1.41 -r1.42
*** opserv.help 3 Jul 2002 02:57:40 -0000 1.41
--- opserv.help 3 Jul 2002 03:01:17 -0000 1.42
***************
*** 59,63 ****
"/msg $O TRACE <action> <criteria> <value> [<criteria> <value>]...",
"Searches through the current users for those matching the specified criteria, and applies the specified action to them. A list of actions can be found in $bhelp trace action$b and a list of criteria in $bhelp trace criteria$b.",
! "$uSee Also:$u help trace action, help trace criteria");
"TRACE ACTION" ("$bTRACE ACTION$b",
"Options for action in $btrace$b are:",
--- 59,63 ----
"/msg $O TRACE <action> <criteria> <value> [<criteria> <value>]...",
"Searches through the current users for those matching the specified criteria, and applies the specified action to them. A list of actions can be found in $bhelp trace action$b and a list of criteria in $bhelp trace criteria$b.",
! "$uSee Also:$u trace action, trace criteria");
"TRACE ACTION" ("$bTRACE ACTION$b",
"Options for action in $btrace$b are:",
***************
*** 95,103 ****
"CHANNEL" ("$bCHANNEL SUB-CATEGORIES$b",
! "Channel information and control. (No searching yet, because the developers are lazy.)",
" CHANNEL REACTIONS - Automated reactions based on channel names",
" CHANNEL CONTROL - Channel information and control",
"There are also some miscellaneous channel-related commands:",
" CHANINFO [${level/chaninfo}]",
" JOIN [${level/join}]",
" PART [${level/part}]");
--- 95,104 ----
"CHANNEL" ("$bCHANNEL SUB-CATEGORIES$b",
! "Channel information, control, and searching.",
" CHANNEL REACTIONS - Automated reactions based on channel names",
" CHANNEL CONTROL - Channel information and control",
"There are also some miscellaneous channel-related commands:",
" CHANINFO [${level/chaninfo}]",
+ " CSEARCH [${level/csearch}]",
" JOIN [${level/join}]",
" PART [${level/part}]");
***************
*** 106,109 ****
--- 107,125 ----
"Displays very detailed information on the specified channel. If the channel is omited, then $bchaninfo$b will be done on the channel where the command was given. You must give a second parameter ($busers$b) to list users in the channel.",
"$uSee Also:$u whois");
+ "CSEARCH"("$bCSEARCH$b",
+ "/msg $O CSEARCH <action> <criteria> <value> [<criteria> <value>]...",
+ "Searches through the network's channels for those matching the specified criteria, and applies the specified action to them. A list of actions can be found under $bhelp csearch action$b and a list of criteria in $bhelp csearch criteria$b.",
+ "$uSee Also:$u csearch action, csearch criteria");
+ "CSEARCH ACTION" ("$bCSEARCH ACTION$b",
+ "Options for action in $bcsearch$b are:",
+ "$bPRINT$b: Display the channel and user count.",
+ "$bCOUNT$b: Count all matching channels.");
+ "CSEARCH CRITERIA" ("$bCSEARCH CRITERIA$b",
+ "Criteria and values for $bcsearch$b (a search with $bcsearch$b must match all specified items):",
+ "$bNAME$b name Specifies a name to search for.",
+ "$bTOPIC$b topic Specifies a topic to search for.",
+ "$bUSERS$b cmp User count constraint (<Nu, <=Nu, =Nu, >=Nu or >Nu)",
+ "$bTIMESTAMP$b cmp Timestamp constraint (<Nu, <=Nu, =Nu, >=Nu or >Nu; supports interval notation)",
+ "$bLIMIT$b 50 Limits the number of responses to a certain number.");
"JOIN" ("$bJOIN$b",
"/msg $O JOIN <#channel> ",
|