3 #include "../parser/parser.h"
4 #include "../nick/nick.h"
5 #include "../channel/channel.h"
6 #include "../control/control.h"
7 #include "../lib/flags.h"
8 #include "../lib/irc_string.h"
11 #define MAXMATCHES 500
13 CommandTree
*searchfilters
;
16 CommandHandler searchfunc
;
22 void cs_describe(nick
*sender
, chanindex
*cip
);
23 int numcompare(char *cmp
, unsigned int num
);
24 int cs_exists(void *chan
, int cargc
, char **cargv
);
25 int cs_nick(void *chan
, int cargc
, char **cargv
);
26 int cs_size(void *chan
, int cargc
, char **cargv
);
27 int cs_namelen(void *chan
, int cargc
, char **cargv
);
28 int cs_keyed(void *chan
, int cargc
, char **cargv
);
29 int cs_secret(void *chan
, int cargc
, char **cargv
);
30 int cs_invite(void *chan
, int cargc
, char **cargv
);
31 int cs_moderated(void *chan
, int cargc
, char **cargv
);
32 int cs_modes(void *chan
, int cargc
, char **cargv
);
33 int cs_name(void *chan
, int cargc
, char **cargv
);
35 void initchansearch() {
36 searchfilters
=newcommandtree();
38 regchansearchfunc("name", 1, cs_name
);
39 regchansearchfunc("exists", 0, cs_exists
);
40 regchansearchfunc("nick", 1, cs_nick
);
41 regchansearchfunc("size", 1, cs_size
);
42 regchansearchfunc("namelen", 1, cs_namelen
);
43 regchansearchfunc("keyed", 0, cs_keyed
);
44 regchansearchfunc("secret", 0, cs_secret
);
45 regchansearchfunc("invite", 0, cs_invite
);
46 regchansearchfunc("moderated", 0, cs_moderated
);
47 regchansearchfunc("modes", 1, cs_modes
);
49 registercontrolcmd("chansearch",10,19,&dochansearch
);
52 void finichansearch() {
53 deregistercontrolcmd("chansearch",&dochansearch
);
54 destroycommandtree(searchfilters
);
57 void regchansearchfunc(const char *name
, int args
, CommandHandler handler
) {
58 addcommandtotree(searchfilters
, name
, 0, args
, handler
);
61 void unregchansearchfunc(const char *name
, CommandHandler handler
) {
62 deletecommandfromtree(searchfilters
, name
, handler
);
65 int dochansearch(void *source
, int cargc
, char **cargv
) {
66 nick
*sender
=(nick
*)source
;
67 filterterm terms
[MAXTERMS
];
77 controlreply(sender
,"Usage: chansearch (search terms)");
78 controlreply(sender
," Valid search terms are: name, exists, size, nick, namelen, keyed, secret, invite");
79 controlreply(sender
," Terms can be inverted with !");
84 if (cargv
[i
][0]=='!') {
86 terms
[numterms
].invert
=1;
89 terms
[numterms
].invert
=0;
92 if ((mc
=findcommandintree(searchfilters
, &cargv
[i
][offset
], 1))==NULL
) {
93 controlreply(sender
,"Unrecognised search term: %s",cargv
[i
]);
96 if ((cargc
-i
-1) < mc
->maxparams
) {
97 controlreply(sender
,"Not enough arguments supplied for %s",cargv
[i
]);
100 terms
[numterms
].searchfunc
=mc
->handler
;
101 terms
[numterms
].params
=mc
->maxparams
;
102 terms
[numterms
].args
=cargv
+i
+1;
103 i
+=(mc
->maxparams
+1);
106 if (numterms
==MAXTERMS
)
110 controlreply(sender
,"The following channels match your criteria:");
112 for(i
=0;i
<CHANNELHASHSIZE
;i
++) {
113 for(cip
=chantable
[i
];cip
;cip
=cip
->next
) {
114 for(j
=0;j
<numterms
;j
++) {
115 res
=(terms
[j
].searchfunc
)((void *)cip
,terms
[j
].params
,terms
[j
].args
);
116 if (res
==0 && terms
[j
].invert
)
118 if (res
==1 && !terms
[j
].invert
)
122 if (matched
== MAXMATCHES
) {
123 controlreply(sender
,"--- More than %d matches, truncating list.",MAXMATCHES
);
125 if (matched
< MAXMATCHES
) {
126 cs_describe(sender
, cip
);
134 controlreply(sender
,"--- No matches found.");
136 controlreply(sender
,"--- End of list: %d match(es).",matched
);
142 int cs_name(void *chan
, int cargc
, char **cargv
) {
143 chanindex
*cip
=(chanindex
*)chan
;
145 return !match2strings(cargv
[0],cip
->name
->content
);
148 int cs_exists(void *chan
, int cargc
, char **cargv
) {
149 chanindex
*cip
=(chanindex
*)chan
;
151 return (cip
->channel
==NULL
);
154 int cs_nick(void *chan
, int cargc
, char **cargv
) {
155 chanindex
*cip
=(chanindex
*)chan
;
158 if (cip
->channel
==NULL
) {
162 if ((np
=getnickbynick(cargv
[0]))==NULL
) {
166 if ((getnumerichandlefromchanhash(cip
->channel
->users
, np
->numeric
))==NULL
) {
173 int cs_size(void *chan
, int cargc
, char **cargv
) {
174 chanindex
*cip
=(chanindex
*)chan
;
176 if (cip
->channel
==NULL
) {
180 return numcompare(cargv
[0],cip
->channel
->users
->totalusers
);
183 int cs_namelen(void *chan
, int cargc
, char **cargv
) {
184 chanindex
*cip
=(chanindex
*)chan
;
186 return numcompare(cargv
[0],cip
->name
->length
);
189 int cs_keyed(void *chan
, int cargc
, char **cargv
) {
190 chanindex
*cip
=(chanindex
*)chan
;
192 if (cip
->channel
==NULL
) {
196 return !IsKey(cip
->channel
);
199 int cs_secret(void *chan
, int cargc
, char **cargv
) {
200 chanindex
*cip
=(chanindex
*)chan
;
202 if (cip
->channel
==NULL
) {
206 return !IsSecret(cip
->channel
);
209 int cs_invite(void *chan
, int cargc
, char **cargv
) {
210 chanindex
*cip
=(chanindex
*)chan
;
212 if (cip
->channel
==NULL
) {
216 return !IsInviteOnly(cip
->channel
);
219 int cs_moderated(void *chan
, int cargc
, char **cargv
) {
220 chanindex
*cip
=(chanindex
*)chan
;
222 if (cip
->channel
==NULL
) {
226 return !IsModerated(cip
->channel
);
229 int cs_modes(void *chan
, int cargc
, char **cargv
) {
231 chanindex
*cip
=(chanindex
*)chan
;
233 if (cip
->channel
==NULL
) {
237 setflags(&flags
, CHANMODE_ALL
, cargv
[0], cmodeflags
, REJECT_NONE
);
239 if ((cip
->channel
->flags
& flags
)!=flags
) {
244 setflags(&flags
, CHANMODE_ALL
, cargv
[0], cmodeflags
, REJECT_NONE
);
246 if ((cip
->channel
->flags
& ~flags
)) {
253 int numcompare(char *cmp
, unsigned int num
) {
254 int sz
=strtol(&cmp
[1],NULL
,10);
257 case '>': if (num
> sz
)
261 case '<': if (num
< sz
)
265 case '=': if (num
== sz
)
275 void cs_describe(nick
*sender
, chanindex
*cip
) {
282 op
=voice
=peon
=oper
=service
=0;
284 if (cip
->channel
==NULL
) {
285 controlreply(sender
,"[ Channel currently empty ] %s",cip
->name
->content
);
287 cuhp
=cip
->channel
->users
;
288 for (i
=0;i
<cuhp
->hashsize
;i
++) {
289 if (cuhp
->content
[i
]!=nouser
) {
290 if (cuhp
->content
[i
]&CUMODE_OP
) {
292 } else if (cuhp
->content
[i
]&CUMODE_VOICE
) {
297 if ((np
=getnickbynumeric(cuhp
->content
[i
]&CU_NUMERICMASK
))!=NULL
) {
307 controlreply(sender
,"[ %4dU %4d@ %4d+ %4d %4d* %4dk ] %s",cuhp
->totalusers
,op
,voice
,peon
,oper
,service
,cip
->name
->content
);