]> jfr.im git - irc/quakenet/newserv.git/blame - newsearch/ns-kill.c
Don't duplicate work for +k chanmode - cs_banuser already checks if a user is banned...
[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
10#include "../control/control.h" /* controlreply() */
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
c7f7a584 19void *kill_exe(struct searchNode *thenode, void *theinput);
4278cc14 20void kill_free(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;
8e257015 26 int type;
96429168 27 char reason[NSMAX_REASON_LEN];
4278cc14
IB
28};
29
30struct searchNode *kill_parse(int type, int argc, char **argv) {
31 struct kill_localdata *localdata;
32 struct searchNode *thenode;
96429168 33 int len;
4278cc14 34
9ce4f0be
IB
35 if (!(localdata = (struct kill_localdata *) malloc(sizeof(struct kill_localdata)))) {
36 parseError = "malloc: could not allocate memory for this search.";
37 return NULL;
38 }
4278cc14 39 localdata->count = 0;
8e257015
IB
40 localdata->type = type;
41 if (type == SEARCHTYPE_CHANNEL)
42 localdata->marker = nextchanmarker();
43 else
44 localdata->marker = nextnickmarker();
4278cc14 45
96429168 46 if (argc==1) {
2ba836f2
CP
47 char *p = argv[0];
48 if(*p == '\"')
7759d816 49 p++;
2ba836f2
CP
50 len = strlcpy(localdata->reason, p, sizeof(localdata->reason));
51 if(len >= sizeof(localdata->reason)) {
52 localdata->reason[sizeof(localdata->reason)-1] = '\0';
53 } else {
54 localdata->reason[len-1] = '\0';
55 }
96429168
IB
56 }
57 else
2ba836f2 58 strlcpy(localdata->reason, defaultreason, sizeof(localdata->reason));
96429168 59
9ce4f0be
IB
60 if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
61 /* couldn't malloc() memory for thenode, so free localdata to avoid leakage */
62 parseError = "malloc: could not allocate memory for this search.";
63 free(localdata);
64 return NULL;
65 }
4278cc14
IB
66
67 thenode->returntype = RETURNTYPE_BOOL;
68 thenode->localdata = localdata;
69 thenode->exe = kill_exe;
70 thenode->free = kill_free;
71
72 return thenode;
73}
74
c7f7a584 75void *kill_exe(struct searchNode *thenode, void *theinput) {
4278cc14 76 struct kill_localdata *localdata;
8e257015
IB
77 nick *np;
78 chanindex *cip;
4278cc14
IB
79
80 localdata = thenode->localdata;
81
8e257015
IB
82 if (localdata->type == SEARCHTYPE_CHANNEL) {
83 cip = (chanindex *)theinput;
84 cip->marker = localdata->marker;
1545f345 85 localdata->count += cip->channel->users->totalusers;
8e257015
IB
86 }
87 else {
88 np = (nick *)theinput;
89 np->marker = localdata->marker;
90 localdata->count++;
91 }
4278cc14 92
c7f7a584 93 return (void *)1;
4278cc14
IB
94}
95
96void kill_free(struct searchNode *thenode) {
97 struct kill_localdata *localdata;
98 nick *np, *nnp;
8e257015
IB
99 chanindex *cip, *ncip;
100 int i, j, safe=0;
42458fa5 101 unsigned int nickmarker;
2ba836f2 102 char msgbuf[512];
4278cc14
IB
103
104 localdata = thenode->localdata;
105
106 if (localdata->count > NSMAX_KILL_LIMIT) {
107 /* need to warn the user that they have just tried to twat half the network ... */
108 controlreply(senderNSExtern, "Warning: your pattern matches too many users (%d) - nothing done.", localdata->count);
4278cc14
IB
109 free(localdata);
110 free(thenode);
111 return;
112 }
113
8e257015 114 if (localdata->type == SEARCHTYPE_CHANNEL) {
42458fa5 115 nickmarker=nextnickmarker();
8e257015
IB
116 for (i=0;i<CHANNELHASHSIZE;i++) {
117 for (cip=chantable[i];cip;cip=ncip) {
118 ncip = cip->next;
119 if (cip != NULL && cip->channel != NULL && cip->marker == localdata->marker) {
120 for (j=0;j<cip->channel->users->hashsize;j++) {
121 if (cip->channel->users->content[j]==nouser)
122 continue;
123
124 if ((np=getnickbynumeric(cip->channel->users->content[j]))) {
125 if (!IsOper(np) && !IsService(np) && !IsXOper(np)) {
42458fa5 126 np->marker=nickmarker;
8e257015
IB
127 }
128 else
129 safe++;
130 }
131 }
132 }
133 }
134 }
42458fa5
P
135 for (i=0;i<NICKHASHSIZE;i++) {
136 for(np=nicktable[i];np;np=nnp) {
137 nnp = np->next;
2ba836f2
CP
138 if (np->marker == nickmarker) {
139 nssnprintf(msgbuf, sizeof(msgbuf), localdata->reason, np);
140 killuser(NULL, np, "%s", msgbuf);
141 }
42458fa5
P
142 }
143 }
8e257015
IB
144 }
145 else {
146 for (i=0;i<NICKHASHSIZE;i++) {
147 for (np=nicktable[i];np;np=nnp) {
148 nnp = np->next;
149 if (np->marker == localdata->marker) {
150 if (!IsOper(np) && !IsService(np) && !IsXOper(np)) {
2ba836f2
CP
151 nssnprintf(msgbuf, sizeof(msgbuf), localdata->reason, np);
152 killuser(NULL, np, "%s", msgbuf);
8e257015
IB
153 }
154 else
155 safe++;
4278cc14 156 }
4278cc14
IB
157 }
158 }
159 }
160 if (safe)
161 controlreply(senderNSExtern, "Warning: your pattern matched privileged users (%d in total) - these have not been touched.", safe);
f16cabe4 162 /* notify opers of the action */
8e257015
IB
163 controlwall(NO_OPER, NL_KICKKILLS, "%s/%s killed %d %s via %s [%d untouched].", senderNSExtern->nick, senderNSExtern->authname, (localdata->count - safe),
164 (localdata->count - safe) != 1 ? "users" : "user", (localdata->type == SEARCHTYPE_CHANNEL) ? "chansearch" : "nicksearch", safe);
4278cc14
IB
165 free(localdata);
166 free(thenode);
167}