]> jfr.im git - irc/quakenet/newserv.git/blob - patriciasearch/patriciasearch.c
output tree is part of context ;/
[irc/quakenet/newserv.git] / patriciasearch / patriciasearch.c
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
15 searchCmd *reg_nodesearch;
16
17 int do_pnodesearch(void *source, int cargc, char **cargv);
18
19 NodeDisplayFunc defaultpnodefn = printnode;
20
21 void _init() {
22 reg_nodesearch = (searchCmd *)registersearchcommand("nodesearch",NO_OPER,do_pnodesearch, printnode);
23
24 registersearchterm(reg_nodesearch, "users", ps_users_parse, 0, "");
25 registersearchterm(reg_nodesearch, "nick", ps_nick_parse, 0, "");
26 }
27
28 void _fini() {
29 deregistersearchcommand( reg_nodesearch );
30 }
31
32 static 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
42 int 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
55 ret = parseopts(cargc, cargv, &arg, &limit, (void *)&subset, (void *)&display, reg_nodesearch->outputtree, reply, sender);
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
68 newsearch_ctxinit(&ctx, search_parse, reply, wall, NULL, reg_nodesearch, sender);
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
82 int do_pnodesearch(void *source, int cargc, char **cargv) {
83 return do_pnodesearch_real(controlreply, controlwallwrapper, source, cargc, cargv);
84 }
85
86 void 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