]> jfr.im git - irc/quakenet/newserv.git/blame - patriciasearch/patriciasearch.c
output tree is part of context ;/
[irc/quakenet/newserv.git] / patriciasearch / patriciasearch.c
CommitLineData
3128667f
P
1#include <stdio.h>
2#include <stdarg.h>
3#include <string.h>
4
5#include "../control/control.h"
6#include "../irc/irc_config.h"
7#include "../lib/irc_string.h"
8#include "../parser/parser.h"
9#include "../lib/splitline.h"
10#include "../lib/version.h"
11#include "../lib/stringbuf.h"
12#include "../lib/strlfunc.h"
13#include "patriciasearch.h"
14
3128667f
P
15searchCmd *reg_nodesearch;
16
17int do_pnodesearch(void *source, int cargc, char **cargv);
18
19NodeDisplayFunc defaultpnodefn = printnode;
20
3128667f 21void _init() {
3128667f
P
22 reg_nodesearch = (searchCmd *)registersearchcommand("nodesearch",NO_OPER,do_pnodesearch, printnode);
23
ea634fc1
P
24 registersearchterm(reg_nodesearch, "users", ps_users_parse, 0, "");
25 registersearchterm(reg_nodesearch, "nick", ps_nick_parse, 0, "");
3128667f
P
26}
27
28void _fini() {
3128667f
P
29 deregistersearchcommand( reg_nodesearch );
30}
31
32static void controlwallwrapper(int level, char *format, ...) {
33 char buf[1024];
34 va_list ap;
35
36 va_start(ap, format);
37 vsnprintf(buf, sizeof(buf), format, ap);
38 controlwall(NO_OPER, level, "%s", buf);
39 va_end(ap);
40}
41
42int do_pnodesearch_real(replyFunc reply, wallFunc wall, void *source, int cargc, char **cargv) {
43 nick *sender = senderNSExtern = source;
44 struct searchNode *search;
45 int limit=500;
46 int arg=0;
47 NodeDisplayFunc display=defaultpnodefn;
48 searchCtx ctx;
49 int ret;
50 patricia_node_t *subset = iptree->head;
51
52 if (cargc<1)
53 return CMD_USAGE;
54
6cb1b086 55 ret = parseopts(cargc, cargv, &arg, &limit, (void *)&subset, (void *)&display, reg_nodesearch->outputtree, reply, sender);
3128667f
P
56 if(ret != CMD_OK)
57 return ret;
58
59 if (arg>=cargc) {
60 reply(sender,"No search terms - aborting.");
61 return CMD_ERROR;
62 }
63
64 if (arg<(cargc-1)) {
65 rejoinline(cargv[arg],cargc-arg);
66 }
67
ea634fc1 68 newsearch_ctxinit(&ctx, search_parse, reply, wall, NULL, reg_nodesearch, sender);
3128667f
P
69
70 if (!(search = ctx.parser(&ctx, cargv[arg]))) {
71 reply(sender,"Parse error: %s",parseError);
72 return CMD_ERROR;
73 }
74
75 pnodesearch_exe(search, &ctx, sender, display, limit, subset);
76
77 (search->free)(&ctx, search);
78
79 return CMD_OK;
80}
81
82int do_pnodesearch(void *source, int cargc, char **cargv) {
83 return do_pnodesearch_real(controlreply, controlwallwrapper, source, cargc, cargv);
84}
85
86void pnodesearch_exe(struct searchNode *search, searchCtx *ctx, nick *sender, NodeDisplayFunc display, int limit, patricia_node_t *subset) {
87 int matches = 0;
88 patricia_node_t *node;
89
90 /* Get a marker value to mark "seen" channels for unique count */
91 //nmarker=nextnodemarker();
92
93 /* The top-level node needs to return a BOOL */
94 search=coerceNode(ctx, search, RETURNTYPE_BOOL);
95
96 PATRICIA_WALK(subset, node) {
97 if ((search->exe)(ctx, search, node)) {
98 if (matches<limit)
99 display(ctx, sender, node);
100
101 if (matches==limit)
102 ctx->reply(sender, "--- More than %d matches, skipping the rest",limit);
103 matches++;
104 }
105 }
106 PATRICIA_WALK_END;
107
108 ctx->reply(sender,"--- End of list: %d matches",
109 matches);
110}
111
112