]>
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 registercontrolcmd("nicksearch",10,4,do_nicksearch
);
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;
82 controlreply(sender
,"Usage: nicksearch (criteria)");
86 if (*cargv
[0] == '-') {
90 for (ch
=cargv
[0]+1;*ch
;ch
++) {
94 controlreply(sender
,"Error: -l switch requires an argument");
97 limit
=strtoul(cargv
[arg
++],NULL
,10);
101 controlreply(sender
,"Unrecognised flag -%c.",*ch
);
107 controlreply(sender
,"No search terms - aborting.");
112 rejoinline(cargv
[arg
],cargc
-arg
);
115 if (!(search
= search_parse(SEARCHTYPE_NICK
, cargv
[arg
]))) {
116 controlreply(sender
,"Parse error: %s",parseError
);
120 for (i
=0;i
<NICKHASHSIZE
;i
++) {
121 for (np
=nicktable
[i
];np
;np
=np
->next
) {
122 if ((search
->exe
)(search
, RETURNTYPE_BOOL
, np
)) {
124 printnick(sender
, np
);
126 controlreply(sender
, "--- More than %d matches, skipping the rest",limit
);
132 (search
->free
)(search
);
134 controlreply(sender
,"--- End of list: %d matches", matches
);
139 void *trueval(int type
) {
143 case RETURNTYPE_BOOL
:
146 case RETURNTYPE_STRING
:
151 void *falseval(int type
) {
155 case RETURNTYPE_BOOL
:
158 case RETURNTYPE_STRING
:
165 * LITERAL node type: used by the top level parse function
168 struct literal_localdata
{
174 void literal_free(struct searchNode
*thenode
);
175 void *literal_exe(struct searchNode
*thenode
, int type
, void *theinput
);
178 * Given an input string, return a searchNode.
181 struct searchNode
*search_parse(int type
, char *input
) {
182 /* OK, we need to split the input into chunks on spaces and brackets.. */
183 char *argvector
[100];
187 struct searchNode
*thenode
;
188 struct literal_localdata
*localdata
;
190 /* If it starts with a bracket, it's a function call.. */
192 /* Skip past string */
193 for (ch
=input
;*ch
;ch
++);
194 if (*(ch
-1) != ')') {
195 parseError
= "Bracket mismatch!";
201 /* Split further args */
202 i
=-1; /* i = -1 BoW, 0 = inword, 1 = bracket nest depth */
203 j
=0; /* j = current arg */
205 for (ch
=input
;*ch
;ch
++) {
210 } else if (*ch
!= ' ') {
217 if(j
>= (sizeof(argvector
) / sizeof(*argvector
))) {
218 parseError
= "Too many arguments";
226 } else if (*ch
==')') {
233 parseError
= "Bracket mismatch!";
237 if (*(ch
-1) == 0) /* if the last character was a space */
238 j
--; /* remove an argument */
240 if (!(cmd
=findcommandintree(searchTree
,argvector
[0],1))) {
241 parseError
= "Unknown command";
244 return ((parseFunc
)cmd
->handler
)(type
, j
, argvector
+1);
248 thenode
=(struct searchNode
*)malloc(sizeof(struct searchNode
));
249 localdata
=(struct literal_localdata
*)malloc(sizeof (struct literal_localdata
));
251 localdata
->stringval
=getsstring(input
,512);
252 localdata
->intval
=strtol(input
,NULL
,10);
253 if (input
==NULL
|| *input
=='\0') {
254 localdata
->boolval
= 0;
256 localdata
->boolval
= 1;
259 thenode
->localdata
= localdata
;
260 thenode
->returntype
= RETURNTYPE_CONST
| RETURNTYPE_STRING
;
261 thenode
->exe
= literal_exe
;
262 thenode
->free
= literal_free
;
268 void *literal_exe(struct searchNode
*thenode
, int type
, void *theinput
) {
269 struct literal_localdata
*localdata
;
271 localdata
=thenode
->localdata
;
274 case RETURNTYPE_STRING
:
275 return (void *)(localdata
->stringval
->content
);
278 case RETURNTYPE_BOOL
:
279 return (void *)(localdata
->boolval
);
282 return (void *)(localdata
->intval
);
286 void literal_free(struct searchNode
*thenode
) {
287 struct literal_localdata
*localdata
;
289 localdata
=thenode
->localdata
;
291 freesstring(localdata
->stringval
);