]>
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"
11 #include "../lib/version.h"
15 CommandTree
*searchTree
;
17 int do_nicksearch(void *source
, int cargc
, char **cargv
);
18 struct searchNode
*search_parse(int type
, char *input
);
20 void registersearchterm(char *term
, parseFunc parsefunc
);
21 void deregistersearchterm(char *term
, parseFunc parsefunc
);
23 void *trueval(int type
);
24 void *falseval(int type
);
26 const char *parseError
;
29 searchTree
=newcommandtree();
31 /* Boolean operations */
32 registersearchterm("and",and_parse
);
33 registersearchterm("not",not_parse
);
34 registersearchterm("or",or_parse
);
36 registersearchterm("eq",eq_parse
);
38 registersearchterm("lt",lt_parse
);
39 registersearchterm("gt",gt_parse
);
41 /* String operations */
42 registersearchterm("match",match_parse
);
43 registersearchterm("regex",regex_parse
);
45 /* Nickname operations */
46 registersearchterm("hostmask",hostmask_parse
);
47 registersearchterm("realname",realname_parse
);
48 registersearchterm("nick",nick_parse
);
49 registersearchterm("authname",authname_parse
);
50 registersearchterm("ident",ident_parse
);
51 registersearchterm("host",host_parse
);
52 registersearchterm("channel",channel_parse
);
53 registersearchterm("timestamp",timestamp_parse
);
54 registersearchterm("country",country_parse
);
55 registersearchterm("ip",ip_parse
);
57 /* Nickname / channel operations */
58 registersearchterm("modes",modes_parse
);
60 registercontrolhelpcmd("nicksearch",NO_OPER
,4,do_nicksearch
, "Usage: nicksearch <criteria>\nSearches for nicknames with the given criteria.");
64 destroycommandtree(searchTree
);
65 deregistercontrolcmd("nicksearch", do_nicksearch
);
68 void registersearchterm(char *term
, parseFunc parsefunc
) {
69 addcommandtotree(searchTree
, term
, 0, 0, (CommandHandler
) parsefunc
);
72 void deregistersearchterm(char *term
, parseFunc parsefunc
) {
73 deletecommandfromtree(searchTree
, term
, (CommandHandler
) parsefunc
);
76 void printnick(nick
*sender
, nick
*np
) {
77 char hostbuf
[HOSTLEN
+NICKLEN
+USERLEN
+4];
79 controlreply(sender
,"%s [%s] (%s) (%s)",visiblehostmask(np
,hostbuf
),
80 IPtostr(np
->p_ipaddr
), printflags(np
->umodes
, umodeflags
), np
->realname
->name
->content
);
83 int do_nicksearch(void *source
, int cargc
, char **cargv
) {
84 nick
*sender
=source
, *np
;
86 struct searchNode
*search
;
87 int limit
=500,matches
=0;
94 if (*cargv
[0] == '-') {
98 for (ch
=cargv
[0]+1;*ch
;ch
++) {
102 controlreply(sender
,"Error: -l switch requires an argument");
105 limit
=strtoul(cargv
[arg
++],NULL
,10);
109 controlreply(sender
,"Unrecognised flag -%c.",*ch
);
115 controlreply(sender
,"No search terms - aborting.");
120 rejoinline(cargv
[arg
],cargc
-arg
);
123 if (!(search
= search_parse(SEARCHTYPE_NICK
, cargv
[arg
]))) {
124 controlreply(sender
,"Parse error: %s",parseError
);
128 for (i
=0;i
<NICKHASHSIZE
;i
++) {
129 for (np
=nicktable
[i
];np
;np
=np
->next
) {
130 if ((search
->exe
)(search
, RETURNTYPE_BOOL
, np
)) {
132 printnick(sender
, np
);
134 controlreply(sender
, "--- More than %d matches, skipping the rest",limit
);
140 (search
->free
)(search
);
142 controlreply(sender
,"--- End of list: %d matches", matches
);
147 void *trueval(int type
) {
151 case RETURNTYPE_BOOL
:
154 case RETURNTYPE_STRING
:
159 void *falseval(int type
) {
163 case RETURNTYPE_BOOL
:
166 case RETURNTYPE_STRING
:
173 * LITERAL node type: used by the top level parse function
176 struct literal_localdata
{
182 void literal_free(struct searchNode
*thenode
);
183 void *literal_exe(struct searchNode
*thenode
, int type
, void *theinput
);
186 * Given an input string, return a searchNode.
189 struct searchNode
*search_parse(int type
, char *input
) {
190 /* OK, we need to split the input into chunks on spaces and brackets.. */
191 char *argvector
[100];
195 struct searchNode
*thenode
;
196 struct literal_localdata
*localdata
;
198 /* If it starts with a bracket, it's a function call.. */
200 /* Skip past string */
201 for (ch
=input
;*ch
;ch
++);
202 if (*(ch
-1) != ')') {
203 parseError
= "Bracket mismatch!";
209 /* Split further args */
210 i
=-1; /* i = -1 BoW, 0 = inword, 1 = bracket nest depth */
211 j
=0; /* j = current arg */
213 for (ch
=input
;*ch
;ch
++) {
218 } else if (*ch
!= ' ') {
225 if(j
>= (sizeof(argvector
) / sizeof(*argvector
))) {
226 parseError
= "Too many arguments";
234 } else if (*ch
==')') {
241 parseError
= "Bracket mismatch!";
245 if (*(ch
-1) == 0) /* if the last character was a space */
246 j
--; /* remove an argument */
248 if (!(cmd
=findcommandintree(searchTree
,argvector
[0],1))) {
249 parseError
= "Unknown command";
252 return ((parseFunc
)cmd
->handler
)(type
, j
, argvector
+1);
256 thenode
=(struct searchNode
*)malloc(sizeof(struct searchNode
));
257 localdata
=(struct literal_localdata
*)malloc(sizeof (struct literal_localdata
));
259 localdata
->stringval
=getsstring(input
,512);
260 localdata
->intval
=strtol(input
,NULL
,10);
261 if (input
==NULL
|| *input
=='\0') {
262 localdata
->boolval
= 0;
264 localdata
->boolval
= 1;
267 thenode
->localdata
= localdata
;
268 thenode
->returntype
= RETURNTYPE_CONST
| RETURNTYPE_STRING
;
269 thenode
->exe
= literal_exe
;
270 thenode
->free
= literal_free
;
276 void *literal_exe(struct searchNode
*thenode
, int type
, void *theinput
) {
277 struct literal_localdata
*localdata
;
279 localdata
=thenode
->localdata
;
282 case RETURNTYPE_STRING
:
283 return (void *)(localdata
->stringval
->content
);
286 case RETURNTYPE_BOOL
:
287 return (void *)(localdata
->boolval
);
290 return (void *)(localdata
->intval
);
294 void literal_free(struct searchNode
*thenode
) {
295 struct literal_localdata
*localdata
;
297 localdata
=thenode
->localdata
;
299 freesstring(localdata
->stringval
);