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 registercontrolhelpcmd("chansearch",NO_OPER
,19,&dochansearch
,
50 "Usage: chansearch <search terms>\n"
51 " Valid search terms are: name, exists, size, nick, namelen, keyed, secret, invite\n"
52 " Terms can be inverted with !");
55 void finichansearch() {
56 deregistercontrolcmd("chansearch",&dochansearch
);
57 destroycommandtree(searchfilters
);
60 void regchansearchfunc(const char *name
, int args
, CommandHandler handler
) {
61 addcommandtotree(searchfilters
, name
, 0, args
, handler
);
64 void unregchansearchfunc(const char *name
, CommandHandler handler
) {
65 deletecommandfromtree(searchfilters
, name
, handler
);
68 int dochansearch(void *source
, int cargc
, char **cargv
) {
69 nick
*sender
=(nick
*)source
;
70 filterterm terms
[MAXTERMS
];
83 if (cargv
[i
][0]=='!') {
85 terms
[numterms
].invert
=1;
88 terms
[numterms
].invert
=0;
91 if ((mc
=findcommandintree(searchfilters
, &cargv
[i
][offset
], 1))==NULL
) {
92 controlreply(sender
,"Unrecognised search term: %s",cargv
[i
]);
95 if ((cargc
-i
-1) < mc
->maxparams
) {
96 controlreply(sender
,"Not enough arguments supplied for %s",cargv
[i
]);
99 terms
[numterms
].searchfunc
=mc
->handler
;
100 terms
[numterms
].params
=mc
->maxparams
;
101 terms
[numterms
].args
=cargv
+i
+1;
102 i
+=(mc
->maxparams
+1);
105 if (numterms
==MAXTERMS
)
109 controlreply(sender
,"The following channels match your criteria:");
111 for(i
=0;i
<CHANNELHASHSIZE
;i
++) {
112 for(cip
=chantable
[i
];cip
;cip
=cip
->next
) {
113 for(j
=0;j
<numterms
;j
++) {
114 res
=(terms
[j
].searchfunc
)((void *)cip
,terms
[j
].params
,terms
[j
].args
);
115 if (res
==0 && terms
[j
].invert
)
117 if (res
==1 && !terms
[j
].invert
)
121 if (matched
== MAXMATCHES
) {
122 controlreply(sender
,"--- More than %d matches, truncating list.",MAXMATCHES
);
124 if (matched
< MAXMATCHES
) {
125 cs_describe(sender
, cip
);
133 controlreply(sender
,"--- No matches found.");
135 controlreply(sender
,"--- End of list: %d match(es).",matched
);
141 int cs_name(void *chan
, int cargc
, char **cargv
) {
142 chanindex
*cip
=(chanindex
*)chan
;
144 return !match2strings(cargv
[0],cip
->name
->content
);
147 int cs_exists(void *chan
, int cargc
, char **cargv
) {
148 chanindex
*cip
=(chanindex
*)chan
;
150 return (cip
->channel
==NULL
);
153 int cs_nick(void *chan
, int cargc
, char **cargv
) {
154 chanindex
*cip
=(chanindex
*)chan
;
157 if (cip
->channel
==NULL
) {
161 if ((np
=getnickbynick(cargv
[0]))==NULL
) {
165 if ((getnumerichandlefromchanhash(cip
->channel
->users
, np
->numeric
))==NULL
) {
172 int cs_size(void *chan
, int cargc
, char **cargv
) {
173 chanindex
*cip
=(chanindex
*)chan
;
175 if (cip
->channel
==NULL
) {
179 return numcompare(cargv
[0],cip
->channel
->users
->totalusers
);
182 int cs_namelen(void *chan
, int cargc
, char **cargv
) {
183 chanindex
*cip
=(chanindex
*)chan
;
185 return numcompare(cargv
[0],cip
->name
->length
);
188 int cs_keyed(void *chan
, int cargc
, char **cargv
) {
189 chanindex
*cip
=(chanindex
*)chan
;
191 if (cip
->channel
==NULL
) {
195 return !IsKey(cip
->channel
);
198 int cs_secret(void *chan
, int cargc
, char **cargv
) {
199 chanindex
*cip
=(chanindex
*)chan
;
201 if (cip
->channel
==NULL
) {
205 return !IsSecret(cip
->channel
);
208 int cs_invite(void *chan
, int cargc
, char **cargv
) {
209 chanindex
*cip
=(chanindex
*)chan
;
211 if (cip
->channel
==NULL
) {
215 return !IsInviteOnly(cip
->channel
);
218 int cs_moderated(void *chan
, int cargc
, char **cargv
) {
219 chanindex
*cip
=(chanindex
*)chan
;
221 if (cip
->channel
==NULL
) {
225 return !IsModerated(cip
->channel
);
228 int cs_modes(void *chan
, int cargc
, char **cargv
) {
230 chanindex
*cip
=(chanindex
*)chan
;
232 if (cip
->channel
==NULL
) {
236 setflags(&flags
, CHANMODE_ALL
, cargv
[0], cmodeflags
, REJECT_NONE
);
238 if ((cip
->channel
->flags
& flags
)!=flags
) {
243 setflags(&flags
, CHANMODE_ALL
, cargv
[0], cmodeflags
, REJECT_NONE
);
245 if ((cip
->channel
->flags
& ~flags
)) {
252 int numcompare(char *cmp
, unsigned int num
) {
253 int sz
=strtol(&cmp
[1],NULL
,10);
256 case '>': if (num
> sz
)
260 case '<': if (num
< sz
)
264 case '=': if (num
== sz
)
274 void cs_describe(nick
*sender
, chanindex
*cip
) {
281 op
=voice
=peon
=oper
=service
=0;
283 if (cip
->channel
==NULL
) {
284 controlreply(sender
,"[ Channel currently empty ] %s",cip
->name
->content
);
286 cuhp
=cip
->channel
->users
;
287 for (i
=0;i
<cuhp
->hashsize
;i
++) {
288 if (cuhp
->content
[i
]!=nouser
) {
289 if (cuhp
->content
[i
]&CUMODE_OP
) {
291 } else if (cuhp
->content
[i
]&CUMODE_VOICE
) {
296 if ((np
=getnickbynumeric(cuhp
->content
[i
]&CU_NUMERICMASK
))!=NULL
) {
306 controlreply(sender
,"[ %4dU %4d@ %4d+ %4d %4d* %4dk ] %s",cuhp
->totalusers
,op
,voice
,peon
,oper
,service
,cip
->name
->content
);