]> jfr.im git - irc/quakenet/newserv.git/blame - newsearch/ns-kill.c
merge
[irc/quakenet/newserv.git] / newsearch / ns-kill.c
CommitLineData
4278cc14
IB
1/*
2 * KILL functionality
3 */
4
5#include "newsearch.h"
6
7#include <stdio.h>
8#include <stdlib.h>
9
0da2a4ae 10#include "../control/control.h"
4278cc14
IB
11#include "../localuser/localuser.h" /* killuser() */
12#include "../lib/irc_string.h" /* IPtostr() */
2ba836f2 13#include "../lib/strlfunc.h"
4278cc14
IB
14
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 */
219d27f1 17extern nick *senderNSExtern;
4278cc14 18
c8be5183
CP
19void *kill_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
20void kill_free(searchCtx *ctx, struct searchNode *thenode);
a2646788 21static const char *defaultreason = "You (%n) have been disconnected for violating our terms of service";
4278cc14
IB
22
23struct kill_localdata {
24 unsigned int marker;
25 int count;
96429168 26 char reason[NSMAX_REASON_LEN];
4278cc14
IB
27};
28
f33f3f52 29struct searchNode *kill_parse(searchCtx *ctx, int argc, char **argv) {
4278cc14
IB
30 struct kill_localdata *localdata;
31 struct searchNode *thenode;
32
9ce4f0be
IB
33 if (!(localdata = (struct kill_localdata *) malloc(sizeof(struct kill_localdata)))) {
34 parseError = "malloc: could not allocate memory for this search.";
35 return NULL;
36 }
4278cc14 37 localdata->count = 0;
a92bb8e1 38 if (ctx->searchcmd == reg_chansearch)
8e257015 39 localdata->marker = nextchanmarker();
a92bb8e1 40 else if (ctx->searchcmd == reg_nicksearch)
8e257015 41 localdata->marker = nextnickmarker();
a92bb8e1
P
42 else {
43 parseError = "kill: invalid search type";
44 return NULL;
45 }
4278cc14 46
90323e03
CP
47 if (argc==1)
48 strlcpy(localdata->reason, argv[0], sizeof(localdata->reason));
96429168 49 else
2ba836f2 50 strlcpy(localdata->reason, defaultreason, sizeof(localdata->reason));
96429168 51
9ce4f0be
IB
52 if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
53 /* couldn't malloc() memory for thenode, so free localdata to avoid leakage */
54 parseError = "malloc: could not allocate memory for this search.";
55 free(localdata);
56 return NULL;
57 }
4278cc14
IB
58
59 thenode->returntype = RETURNTYPE_BOOL;
60 thenode->localdata = localdata;
61 thenode->exe = kill_exe;
62 thenode->free = kill_free;
63
64 return thenode;
65}
66
c8be5183 67void *kill_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
4278cc14 68 struct kill_localdata *localdata;
8e257015
IB
69 nick *np;
70 chanindex *cip;
4278cc14
IB
71
72 localdata = thenode->localdata;
73
a92bb8e1 74 if (ctx->searchcmd == reg_chansearch) {
8e257015
IB
75 cip = (chanindex *)theinput;
76 cip->marker = localdata->marker;
1545f345 77 localdata->count += cip->channel->users->totalusers;
a92bb8e1 78 } else {
8e257015
IB
79 np = (nick *)theinput;
80 np->marker = localdata->marker;
81 localdata->count++;
82 }
4278cc14 83
c7f7a584 84 return (void *)1;
4278cc14
IB
85}
86
c8be5183 87void kill_free(searchCtx *ctx, struct searchNode *thenode) {
4278cc14
IB
88 struct kill_localdata *localdata;
89 nick *np, *nnp;
82b7019b 90 chanindex *cip;
8e257015 91 int i, j, safe=0;
42458fa5 92 unsigned int nickmarker;
2ba836f2 93 char msgbuf[512];
4278cc14
IB
94
95 localdata = thenode->localdata;
96
97 if (localdata->count > NSMAX_KILL_LIMIT) {
98 /* need to warn the user that they have just tried to twat half the network ... */
0da2a4ae 99 ctx->reply(senderNSExtern, "Warning: your pattern matches too many users (%d) - nothing done.", localdata->count);
4278cc14
IB
100 free(localdata);
101 free(thenode);
102 return;
103 }
104
82b7019b 105 /* For channel searches, mark up all the nicks in the relevant channels first */
a92bb8e1 106 if (ctx->searchcmd == reg_chansearch) {
42458fa5 107 nickmarker=nextnickmarker();
8e257015 108 for (i=0;i<CHANNELHASHSIZE;i++) {
82b7019b 109 for (cip=chantable[i];cip;cip=cip->next) {
110 /* Skip empty and non-matching channels */
111 if (!cip->channel || cip->marker != localdata->marker)
112 continue;
113
114 for (j=0;j<cip->channel->users->hashsize;j++) {
115 if (cip->channel->users->content[j]==nouser)
116 continue;
117
118 if ((np=getnickbynumeric(cip->channel->users->content[j])))
119 np->marker=nickmarker;
2ba836f2 120 }
42458fa5
P
121 }
122 }
82b7019b 123 } else {
124 /* For nick searches they're already marked, pick up the saved value */
125 nickmarker=localdata->marker;
8e257015 126 }
82b7019b 127
128 /* Now do the actual kills */
129 for (i=0;i<NICKHASHSIZE;i++) {
130 for (np=nicktable[i];np;np=nnp) {
131 nnp = np->next;
132
133 if (np->marker != nickmarker)
134 continue;
135
136 if (IsOper(np) || IsService(np) || IsXOper(np)) {
137 safe++;
138 continue;
4278cc14 139 }
82b7019b 140
141 nssnprintf(msgbuf, sizeof(msgbuf), localdata->reason, np);
142 killuser(NULL, np, "%s", msgbuf);
4278cc14
IB
143 }
144 }
82b7019b 145
4278cc14 146 if (safe)
0da2a4ae 147 ctx->reply(senderNSExtern, "Warning: your pattern matched privileged users (%d in total) - these have not been touched.", safe);
f16cabe4 148 /* notify opers of the action */
0da2a4ae 149 ctx->wall(NL_KICKKILLS, "%s/%s killed %d %s via %s [%d untouched].", senderNSExtern->nick, senderNSExtern->authname, (localdata->count - safe),
a92bb8e1 150 (localdata->count - safe) != 1 ? "users" : "user", (ctx->searchcmd == reg_chansearch) ? "chansearch" : "nicksearch", safe);
4278cc14
IB
151 free(localdata);
152 free(thenode);
153}