]>
jfr.im git - irc/quakenet/newserv.git/blob - newsearch/ns-kill.c
10 #include "../control/control.h"
11 #include "../localuser/localuser.h" /* killuser() */
12 #include "../lib/irc_string.h" /* IPtostr() */
13 #include "../lib/strlfunc.h"
15 /* used for *_free functions that need to warn users of certain things
16 i.e. hitting too many users in a (kill) or (gline) - declared in newsearch.c */
17 extern nick
*senderNSExtern
;
19 void *kill_exe(searchCtx
*ctx
, struct searchNode
*thenode
, void *theinput
);
20 void kill_free(searchCtx
*ctx
, struct searchNode
*thenode
);
21 static const char *defaultreason
= "You (%n) have been disconnected for violating our terms of service";
23 struct kill_localdata
{
26 char reason
[NSMAX_REASON_LEN
];
29 struct searchNode
*kill_parse(searchCtx
*ctx
, int argc
, char **argv
) {
30 struct kill_localdata
*localdata
;
31 struct searchNode
*thenode
;
33 if (!(localdata
= (struct kill_localdata
*) malloc(sizeof(struct kill_localdata
)))) {
34 parseError
= "malloc: could not allocate memory for this search.";
38 if (ctx
->searchcmd
== reg_chansearch
)
39 localdata
->marker
= nextchanmarker();
40 else if (ctx
->searchcmd
== reg_nicksearch
)
41 localdata
->marker
= nextnickmarker();
44 parseError
= "kill: invalid search type";
49 struct searchNode
*reasonstr
;
51 if (!(reasonstr
=argtoconststr("kill", ctx
, argv
[0], &p
))) {
56 strlcpy(localdata
->reason
, p
, sizeof(localdata
->reason
));
57 reasonstr
->free(ctx
, reasonstr
);
59 strlcpy(localdata
->reason
, defaultreason
, sizeof(localdata
->reason
));
62 if (!(thenode
=(struct searchNode
*)malloc(sizeof (struct searchNode
)))) {
63 /* couldn't malloc() memory for thenode, so free localdata to avoid leakage */
64 parseError
= "malloc: could not allocate memory for this search.";
69 thenode
->returntype
= RETURNTYPE_BOOL
;
70 thenode
->localdata
= localdata
;
71 thenode
->exe
= kill_exe
;
72 thenode
->free
= kill_free
;
77 void *kill_exe(searchCtx
*ctx
, struct searchNode
*thenode
, void *theinput
) {
78 struct kill_localdata
*localdata
;
82 localdata
= thenode
->localdata
;
84 if (ctx
->searchcmd
== reg_chansearch
) {
85 cip
= (chanindex
*)theinput
;
86 cip
->marker
= localdata
->marker
;
87 localdata
->count
+= cip
->channel
->users
->totalusers
;
89 np
= (nick
*)theinput
;
90 np
->marker
= localdata
->marker
;
97 void kill_free(searchCtx
*ctx
, struct searchNode
*thenode
) {
98 struct kill_localdata
*localdata
;
102 unsigned int nickmarker
;
105 localdata
= thenode
->localdata
;
107 if (localdata
->count
> NSMAX_KILL_LIMIT
) {
108 /* need to warn the user that they have just tried to twat half the network ... */
109 ctx
->reply(senderNSExtern
, "Warning: your pattern matches too many users (%d) - nothing done.", localdata
->count
);
115 /* For channel searches, mark up all the nicks in the relevant channels first */
116 if (ctx
->searchcmd
== reg_chansearch
) {
117 nickmarker
=nextnickmarker();
118 for (i
=0;i
<CHANNELHASHSIZE
;i
++) {
119 for (cip
=chantable
[i
];cip
;cip
=cip
->next
) {
120 /* Skip empty and non-matching channels */
121 if (!cip
->channel
|| cip
->marker
!= localdata
->marker
)
124 for (j
=0;j
<cip
->channel
->users
->hashsize
;j
++) {
125 if (cip
->channel
->users
->content
[j
]==nouser
)
128 if ((np
=getnickbynumeric(cip
->channel
->users
->content
[j
])))
129 np
->marker
=nickmarker
;
134 /* For nick searches they're already marked, pick up the saved value */
135 nickmarker
=localdata
->marker
;
138 /* Now do the actual kills */
139 for (i
=0;i
<NICKHASHSIZE
;i
++) {
140 for (np
=nicktable
[i
];np
;np
=nnp
) {
143 if (np
->marker
!= nickmarker
)
146 if (IsOper(np
) || IsService(np
) || IsXOper(np
)) {
151 nssnprintf(msgbuf
, sizeof(msgbuf
), localdata
->reason
, np
);
152 killuser(NULL
, np
, "%s", msgbuf
);
157 ctx
->reply(senderNSExtern
, "Warning: your pattern matched privileged users (%d in total) - these have not been touched.", safe
);
158 /* notify opers of the action */
159 ctx
->wall(NL_KICKKILLS
, "%s/%s killed %d %s via %s [%d untouched].", senderNSExtern
->nick
, senderNSExtern
->authname
, (localdata
->count
- safe
),
160 (localdata
->count
- safe
) != 1 ? "users" : "user", (ctx
->searchcmd
== reg_chansearch
) ? "chansearch" : "nicksearch", safe
);