]> jfr.im git - irc/quakenet/newserv.git/blob - patriciasearch/patriciasearch.c
update for newsearchchanges
[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 CommandTree *pnodeOutputTree;
16 searchCmd *reg_nodesearch;
17
18 int do_pnodesearch(void *source, int cargc, char **cargv);
19
20 NodeDisplayFunc defaultpnodefn = printnode;
21
22 void regpnodedisp(const char *name, NodeDisplayFunc handler) {
23 addcommandtotree(pnodeOutputTree, name, 0, 0, (CommandHandler)handler);
24 }
25
26 void unregpnodedisp(const char *name, NodeDisplayFunc handler) {
27 deletecommandfromtree(pnodeOutputTree, name, (CommandHandler)handler);
28 }
29
30 void _init() {
31 pnodeOutputTree=newcommandtree();
32
33 reg_nodesearch = (searchCmd *)registersearchcommand("nodesearch",NO_OPER,do_pnodesearch, printnode);
34
35 registersearchterm(reg_nodesearch, "users", ps_users_parse, 0, "");
36 registersearchterm(reg_nodesearch, "nick", ps_nick_parse, 0, "");
37 }
38
39 void _fini() {
40 destroycommandtree(pnodeOutputTree);
41
42 deregistersearchcommand( reg_nodesearch );
43 }
44
45 static void controlwallwrapper(int level, char *format, ...) {
46 char buf[1024];
47 va_list ap;
48
49 va_start(ap, format);
50 vsnprintf(buf, sizeof(buf), format, ap);
51 controlwall(NO_OPER, level, "%s", buf);
52 va_end(ap);
53 }
54
55 int do_pnodesearch_real(replyFunc reply, wallFunc wall, void *source, int cargc, char **cargv) {
56 nick *sender = senderNSExtern = source;
57 struct searchNode *search;
58 int limit=500;
59 int arg=0;
60 NodeDisplayFunc display=defaultpnodefn;
61 searchCtx ctx;
62 int ret;
63 patricia_node_t *subset = iptree->head;
64
65 if (cargc<1)
66 return CMD_USAGE;
67
68 ret = parseopts(cargc, cargv, &arg, &limit, (void *)&subset, (void **)&display, reg_nodesearch->outputtree, reply, sender);
69 if(ret != CMD_OK)
70 return ret;
71
72 if (arg>=cargc) {
73 reply(sender,"No search terms - aborting.");
74 return CMD_ERROR;
75 }
76
77 if (arg<(cargc-1)) {
78 rejoinline(cargv[arg],cargc-arg);
79 }
80
81 newsearch_ctxinit(&ctx, search_parse, reply, wall, NULL, reg_nodesearch, sender);
82
83 if (!(search = ctx.parser(&ctx, cargv[arg]))) {
84 reply(sender,"Parse error: %s",parseError);
85 return CMD_ERROR;
86 }
87
88 pnodesearch_exe(search, &ctx, sender, display, limit, subset);
89
90 (search->free)(&ctx, search);
91
92 return CMD_OK;
93 }
94
95 int do_pnodesearch(void *source, int cargc, char **cargv) {
96 return do_pnodesearch_real(controlreply, controlwallwrapper, source, cargc, cargv);
97 }
98
99 void pnodesearch_exe(struct searchNode *search, searchCtx *ctx, nick *sender, NodeDisplayFunc display, int limit, patricia_node_t *subset) {
100 int matches = 0;
101 patricia_node_t *node;
102
103 /* Get a marker value to mark "seen" channels for unique count */
104 //nmarker=nextnodemarker();
105
106 /* The top-level node needs to return a BOOL */
107 search=coerceNode(ctx, search, RETURNTYPE_BOOL);
108
109 PATRICIA_WALK(subset, node) {
110 if ((search->exe)(ctx, search, node)) {
111 if (matches<limit)
112 display(ctx, sender, node);
113
114 if (matches==limit)
115 ctx->reply(sender, "--- More than %d matches, skipping the rest",limit);
116 matches++;
117 }
118 }
119 PATRICIA_WALK_END;
120
121 ctx->reply(sender,"--- End of list: %d matches",
122 matches);
123 }
124
125