]>
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"
13 MODULE_VERSION("$Id: newsearch.c 663 2006-05-16 17:27:36Z newserv $")
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
);
56 /* Nickname / channel operations */
57 registersearchterm("modes",modes_parse
);
59 registercontrolhelpcmd("nicksearch",NO_OPER
,4,do_nicksearch
, "Usage: nicksearch <criteria>\nSearches for nicknames with the given criteria.");
63 destroycommandtree(searchTree
);
64 deregistercontrolcmd("nicksearch", do_nicksearch
);
67 void registersearchterm(char *term
, parseFunc parsefunc
) {
68 addcommandtotree(searchTree
, term
, 0, 0, (CommandHandler
) parsefunc
);
71 void deregistersearchterm(char *term
, parseFunc parsefunc
) {
72 deletecommandfromtree(searchTree
, term
, (CommandHandler
) parsefunc
);
75 void printnick(nick
*sender
, nick
*np
) {
76 char hostbuf
[HOSTLEN
+NICKLEN
+USERLEN
+4];
78 controlreply(sender
,"%s [%s] (%s) (%s)",visiblehostmask(np
,hostbuf
),
79 IPtostr(np
->ipaddress
), printflags(np
->umodes
, umodeflags
), np
->realname
->name
->content
);
82 int do_nicksearch(void *source
, int cargc
, char **cargv
) {
83 nick
*sender
=source
, *np
;
85 struct searchNode
*search
;
86 int limit
=500,matches
=0;
93 if (*cargv
[0] == '-') {
97 for (ch
=cargv
[0]+1;*ch
;ch
++) {
101 controlreply(sender
,"Error: -l switch requires an argument");
104 limit
=strtoul(cargv
[arg
++],NULL
,10);
108 controlreply(sender
,"Unrecognised flag -%c.",*ch
);
114 controlreply(sender
,"No search terms - aborting.");
119 rejoinline(cargv
[arg
],cargc
-arg
);
122 if (!(search
= search_parse(SEARCHTYPE_NICK
, cargv
[arg
]))) {
123 controlreply(sender
,"Parse error: %s",parseError
);
127 for (i
=0;i
<NICKHASHSIZE
;i
++) {
128 for (np
=nicktable
[i
];np
;np
=np
->next
) {
129 if ((search
->exe
)(search
, RETURNTYPE_BOOL
, np
)) {
131 printnick(sender
, np
);
133 controlreply(sender
, "--- More than %d matches, skipping the rest",limit
);
139 (search
->free
)(search
);
141 controlreply(sender
,"--- End of list: %d matches", matches
);
146 void *trueval(int type
) {
150 case RETURNTYPE_BOOL
:
153 case RETURNTYPE_STRING
:
158 void *falseval(int type
) {
162 case RETURNTYPE_BOOL
:
165 case RETURNTYPE_STRING
:
172 * LITERAL node type: used by the top level parse function
175 struct literal_localdata
{
181 void literal_free(struct searchNode
*thenode
);
182 void *literal_exe(struct searchNode
*thenode
, int type
, void *theinput
);
185 * Given an input string, return a searchNode.
188 struct searchNode
*search_parse(int type
, char *input
) {
189 /* OK, we need to split the input into chunks on spaces and brackets.. */
190 char *argvector
[100];
194 struct searchNode
*thenode
;
195 struct literal_localdata
*localdata
;
197 /* If it starts with a bracket, it's a function call.. */
199 /* Skip past string */
200 for (ch
=input
;*ch
;ch
++);
201 if (*(ch
-1) != ')') {
202 parseError
= "Bracket mismatch!";
208 /* Split further args */
209 i
=-1; /* i = -1 BoW, 0 = inword, 1 = bracket nest depth */
210 j
=0; /* j = current arg */
212 for (ch
=input
;*ch
;ch
++) {
217 } else if (*ch
!= ' ') {
224 if(j
>= (sizeof(argvector
) / sizeof(*argvector
))) {
225 parseError
= "Too many arguments";
233 } else if (*ch
==')') {
240 parseError
= "Bracket mismatch!";
244 if (*(ch
-1) == 0) /* if the last character was a space */
245 j
--; /* remove an argument */
247 if (!(cmd
=findcommandintree(searchTree
,argvector
[0],1))) {
248 parseError
= "Unknown command";
251 return ((parseFunc
)cmd
->handler
)(type
, j
, argvector
+1);
255 thenode
=(struct searchNode
*)malloc(sizeof(struct searchNode
));
256 localdata
=(struct literal_localdata
*)malloc(sizeof (struct literal_localdata
));
258 localdata
->stringval
=getsstring(input
,512);
259 localdata
->intval
=strtol(input
,NULL
,10);
260 if (input
==NULL
|| *input
=='\0') {
261 localdata
->boolval
= 0;
263 localdata
->boolval
= 1;
266 thenode
->localdata
= localdata
;
267 thenode
->returntype
= RETURNTYPE_CONST
| RETURNTYPE_STRING
;
268 thenode
->exe
= literal_exe
;
269 thenode
->free
= literal_free
;
275 void *literal_exe(struct searchNode
*thenode
, int type
, void *theinput
) {
276 struct literal_localdata
*localdata
;
278 localdata
=thenode
->localdata
;
281 case RETURNTYPE_STRING
:
282 return (void *)(localdata
->stringval
->content
);
285 case RETURNTYPE_BOOL
:
286 return (void *)(localdata
->boolval
);
289 return (void *)(localdata
->intval
);
293 void literal_free(struct searchNode
*thenode
) {
294 struct literal_localdata
*localdata
;
296 localdata
=thenode
->localdata
;
298 freesstring(localdata
->stringval
);