]>
jfr.im git - irc/quakenet/newserv.git/blob - newsearch/newsearch.c
5 #include "../irc/irc_config.h"
6 #include "../nick/nick.h"
7 #include "../lib/irc_string.h"
8 #include "../parser/parser.h"
9 #include "../control/control.h"
10 #include "../lib/splitline.h"
12 CommandTree
*searchTree
;
14 int do_nicksearch(void *source
, int cargc
, char **cargv
);
15 struct searchNode
*search_parse(int type
, char *input
);
17 void registersearchterm(char *term
, parseFunc parsefunc
);
18 void deregistersearchterm(char *term
, parseFunc parsefunc
);
20 void *trueval(int type
);
21 void *falseval(int type
);
23 const char *parseError
;
26 searchTree
=newcommandtree();
28 /* Boolean operations */
29 registersearchterm("and",and_parse
);
30 registersearchterm("not",not_parse
);
31 registersearchterm("or",or_parse
);
33 registersearchterm("eq",eq_parse
);
35 /* String operations */
36 registersearchterm("match",match_parse
);
37 registersearchterm("regex",regex_parse
);
39 /* Nickname operations */
40 registersearchterm("hostmask",hostmask_parse
);
41 registersearchterm("realname",realname_parse
);
42 registersearchterm("nick",nick_parse
);
43 registersearchterm("ident",ident_parse
);
44 registersearchterm("host",host_parse
);
45 registersearchterm("channel",channel_parse
);
47 /* Nickname / channel operations */
48 registersearchterm("modes",modes_parse
);
50 registercontrolhelpcmd("nicksearch",NO_OPER
,4,do_nicksearch
, "Usage: nicksearch <criteria>\nSearches for nicknames with the given criteria.");
54 destroycommandtree(searchTree
);
55 deregistercontrolcmd("nicksearch", do_nicksearch
);
58 void registersearchterm(char *term
, parseFunc parsefunc
) {
59 addcommandtotree(searchTree
, term
, 0, 0, (CommandHandler
) parsefunc
);
62 void deregistersearchterm(char *term
, parseFunc parsefunc
) {
63 deletecommandfromtree(searchTree
, term
, (CommandHandler
) parsefunc
);
66 void printnick(nick
*sender
, nick
*np
) {
67 char hostbuf
[HOSTLEN
+NICKLEN
+USERLEN
+4];
69 controlreply(sender
,"%s [%s] (%s) (%s)",visiblehostmask(np
,hostbuf
),
70 IPtostr(np
->ipaddress
), printflags(np
->umodes
, umodeflags
), np
->realname
->name
->content
);
73 int do_nicksearch(void *source
, int cargc
, char **cargv
) {
74 nick
*sender
=source
, *np
;
76 struct searchNode
*search
;
77 int limit
=500,matches
=0;
84 if (*cargv
[0] == '-') {
88 for (ch
=cargv
[0]+1;*ch
;ch
++) {
92 controlreply(sender
,"Error: -l switch requires an argument");
95 limit
=strtoul(cargv
[arg
++],NULL
,10);
99 controlreply(sender
,"Unrecognised flag -%c.",*ch
);
105 controlreply(sender
,"No search terms - aborting.");
110 rejoinline(cargv
[arg
],cargc
-arg
);
113 if (!(search
= search_parse(SEARCHTYPE_NICK
, cargv
[arg
]))) {
114 controlreply(sender
,"Parse error: %s",parseError
);
118 for (i
=0;i
<NICKHASHSIZE
;i
++) {
119 for (np
=nicktable
[i
];np
;np
=np
->next
) {
120 if ((search
->exe
)(search
, RETURNTYPE_BOOL
, np
)) {
122 printnick(sender
, np
);
124 controlreply(sender
, "--- More than %d matches, skipping the rest",limit
);
130 (search
->free
)(search
);
132 controlreply(sender
,"--- End of list: %d matches", matches
);
137 void *trueval(int type
) {
141 case RETURNTYPE_BOOL
:
144 case RETURNTYPE_STRING
:
149 void *falseval(int type
) {
153 case RETURNTYPE_BOOL
:
156 case RETURNTYPE_STRING
:
163 * LITERAL node type: used by the top level parse function
166 struct literal_localdata
{
172 void literal_free(struct searchNode
*thenode
);
173 void *literal_exe(struct searchNode
*thenode
, int type
, void *theinput
);
176 * Given an input string, return a searchNode.
179 struct searchNode
*search_parse(int type
, char *input
) {
180 /* OK, we need to split the input into chunks on spaces and brackets.. */
181 char *argvector
[100];
185 struct searchNode
*thenode
;
186 struct literal_localdata
*localdata
;
188 /* If it starts with a bracket, it's a function call.. */
190 /* Skip past string */
191 for (ch
=input
;*ch
;ch
++);
192 if (*(ch
-1) != ')') {
193 parseError
= "Bracket mismatch!";
199 /* Split further args */
200 i
=-1; /* i = -1 BoW, 0 = inword, 1 = bracket nest depth */
201 j
=0; /* j = current arg */
203 for (ch
=input
;*ch
;ch
++) {
208 } else if (*ch
!= ' ') {
215 if(j
>= (sizeof(argvector
) / sizeof(*argvector
))) {
216 parseError
= "Too many arguments";
224 } else if (*ch
==')') {
231 parseError
= "Bracket mismatch!";
235 if (*(ch
-1) == 0) /* if the last character was a space */
236 j
--; /* remove an argument */
238 if (!(cmd
=findcommandintree(searchTree
,argvector
[0],1))) {
239 parseError
= "Unknown command";
242 return ((parseFunc
)cmd
->handler
)(type
, j
, argvector
+1);
246 thenode
=(struct searchNode
*)malloc(sizeof(struct searchNode
));
247 localdata
=(struct literal_localdata
*)malloc(sizeof (struct literal_localdata
));
249 localdata
->stringval
=getsstring(input
,512);
250 localdata
->intval
=strtol(input
,NULL
,10);
251 if (input
==NULL
|| *input
=='\0') {
252 localdata
->boolval
= 0;
254 localdata
->boolval
= 1;
257 thenode
->localdata
= localdata
;
258 thenode
->returntype
= RETURNTYPE_CONST
| RETURNTYPE_STRING
;
259 thenode
->exe
= literal_exe
;
260 thenode
->free
= literal_free
;
266 void *literal_exe(struct searchNode
*thenode
, int type
, void *theinput
) {
267 struct literal_localdata
*localdata
;
269 localdata
=thenode
->localdata
;
272 case RETURNTYPE_STRING
:
273 return (void *)(localdata
->stringval
->content
);
276 case RETURNTYPE_BOOL
:
277 return (void *)(localdata
->boolval
);
280 return (void *)(localdata
->intval
);
284 void literal_free(struct searchNode
*thenode
) {
285 struct literal_localdata
*localdata
;
287 localdata
=thenode
->localdata
;
289 freesstring(localdata
->stringval
);