]>
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("authname",authname_parse
);
44 registersearchterm("ident",ident_parse
);
45 registersearchterm("host",host_parse
);
46 registersearchterm("channel",channel_parse
);
48 /* Nickname / channel operations */
49 registersearchterm("modes",modes_parse
);
51 registercontrolcmd("nicksearch",10,4,do_nicksearch
);
55 destroycommandtree(searchTree
);
56 deregistercontrolcmd("nicksearch", do_nicksearch
);
59 void registersearchterm(char *term
, parseFunc parsefunc
) {
60 addcommandtotree(searchTree
, term
, 0, 0, (CommandHandler
) parsefunc
);
63 void deregistersearchterm(char *term
, parseFunc parsefunc
) {
64 deletecommandfromtree(searchTree
, term
, (CommandHandler
) parsefunc
);
67 void printnick(nick
*sender
, nick
*np
) {
68 char hostbuf
[HOSTLEN
+NICKLEN
+USERLEN
+4];
70 controlreply(sender
,"%s [%s] (%s) (%s)",visiblehostmask(np
,hostbuf
),
71 IPtostr(np
->ipaddress
), printflags(np
->umodes
, umodeflags
), np
->realname
->name
->content
);
74 int do_nicksearch(void *source
, int cargc
, char **cargv
) {
75 nick
*sender
=source
, *np
;
77 struct searchNode
*search
;
78 int limit
=500,matches
=0;
83 controlreply(sender
,"Usage: nicksearch (criteria)");
87 if (*cargv
[0] == '-') {
91 for (ch
=cargv
[0]+1;*ch
;ch
++) {
95 controlreply(sender
,"Error: -l switch requires an argument");
98 limit
=strtoul(cargv
[arg
++],NULL
,10);
102 controlreply(sender
,"Unrecognised flag -%c.",*ch
);
108 controlreply(sender
,"No search terms - aborting.");
113 rejoinline(cargv
[arg
],cargc
-arg
);
116 if (!(search
= search_parse(SEARCHTYPE_NICK
, cargv
[arg
]))) {
117 controlreply(sender
,"Parse error: %s",parseError
);
121 for (i
=0;i
<NICKHASHSIZE
;i
++) {
122 for (np
=nicktable
[i
];np
;np
=np
->next
) {
123 if ((search
->exe
)(search
, RETURNTYPE_BOOL
, np
)) {
125 printnick(sender
, np
);
127 controlreply(sender
, "--- More than %d matches, skipping the rest",limit
);
133 (search
->free
)(search
);
135 controlreply(sender
,"--- End of list: %d matches", matches
);
140 void *trueval(int type
) {
144 case RETURNTYPE_BOOL
:
147 case RETURNTYPE_STRING
:
152 void *falseval(int type
) {
156 case RETURNTYPE_BOOL
:
159 case RETURNTYPE_STRING
:
166 * LITERAL node type: used by the top level parse function
169 struct literal_localdata
{
175 void literal_free(struct searchNode
*thenode
);
176 void *literal_exe(struct searchNode
*thenode
, int type
, void *theinput
);
179 * Given an input string, return a searchNode.
182 struct searchNode
*search_parse(int type
, char *input
) {
183 /* OK, we need to split the input into chunks on spaces and brackets.. */
184 char *argvector
[100];
188 struct searchNode
*thenode
;
189 struct literal_localdata
*localdata
;
191 /* If it starts with a bracket, it's a function call.. */
193 /* Skip past string */
194 for (ch
=input
;*ch
;ch
++);
195 if (*(ch
-1) != ')') {
196 parseError
= "Bracket mismatch!";
202 /* Split further args */
203 i
=-1; /* i = -1 BoW, 0 = inword, 1 = bracket nest depth */
204 j
=0; /* j = current arg */
206 for (ch
=input
;*ch
;ch
++) {
211 } else if (*ch
!= ' ') {
218 if(j
>= (sizeof(argvector
) / sizeof(*argvector
))) {
219 parseError
= "Too many arguments";
227 } else if (*ch
==')') {
234 parseError
= "Bracket mismatch!";
238 if (*(ch
-1) == 0) /* if the last character was a space */
239 j
--; /* remove an argument */
241 if (!(cmd
=findcommandintree(searchTree
,argvector
[0],1))) {
242 parseError
= "Unknown command";
245 return ((parseFunc
)cmd
->handler
)(type
, j
, argvector
+1);
249 thenode
=(struct searchNode
*)malloc(sizeof(struct searchNode
));
250 localdata
=(struct literal_localdata
*)malloc(sizeof (struct literal_localdata
));
252 localdata
->stringval
=getsstring(input
,512);
253 localdata
->intval
=strtol(input
,NULL
,10);
254 if (input
==NULL
|| *input
=='\0') {
255 localdata
->boolval
= 0;
257 localdata
->boolval
= 1;
260 thenode
->localdata
= localdata
;
261 thenode
->returntype
= RETURNTYPE_CONST
| RETURNTYPE_STRING
;
262 thenode
->exe
= literal_exe
;
263 thenode
->free
= literal_free
;
269 void *literal_exe(struct searchNode
*thenode
, int type
, void *theinput
) {
270 struct literal_localdata
*localdata
;
272 localdata
=thenode
->localdata
;
275 case RETURNTYPE_STRING
:
276 return (void *)(localdata
->stringval
->content
);
279 case RETURNTYPE_BOOL
:
280 return (void *)(localdata
->boolval
);
283 return (void *)(localdata
->intval
);
287 void literal_free(struct searchNode
*thenode
) {
288 struct literal_localdata
*localdata
;
290 localdata
=thenode
->localdata
;
292 freesstring(localdata
->stringval
);