]> jfr.im git - irc/quakenet/newserv.git/blob - newsearch/ns-kill.c
Merge.
[irc/quakenet/newserv.git] / newsearch / ns-kill.c
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() */
13
14 /* used for *_free functions that need to warn users of certain things
15 i.e. hitting too many users in a (kill) or (gline) - declared in newsearch.c */
16 extern nick *senderNSExtern;
17
18 void *kill_exe(struct searchNode *thenode, void *theinput);
19 void kill_free(struct searchNode *thenode);
20
21 struct kill_localdata {
22 unsigned int marker;
23 int count;
24 int type;
25 char reason[NSMAX_REASON_LEN];
26 };
27
28 struct searchNode *kill_parse(int type, int argc, char **argv) {
29 struct kill_localdata *localdata;
30 struct searchNode *thenode;
31 int len;
32
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 }
37 localdata->count = 0;
38 localdata->type = type;
39 if (type == SEARCHTYPE_CHANNEL)
40 localdata->marker = nextchanmarker();
41 else
42 localdata->marker = nextnickmarker();
43
44 if (argc==1) {
45 len = snprintf(localdata->reason, NSMAX_REASON_LEN, ":%s", argv[0]);
46 /* strip leading and trailing '"'s */
47 localdata->reason[1] = ' ';
48 localdata->reason[len-1] = '\0';
49 }
50 else
51 snprintf(localdata->reason, NSMAX_REASON_LEN, ".");
52
53 if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
54 /* couldn't malloc() memory for thenode, so free localdata to avoid leakage */
55 parseError = "malloc: could not allocate memory for this search.";
56 free(localdata);
57 return NULL;
58 }
59
60 thenode->returntype = RETURNTYPE_BOOL;
61 thenode->localdata = localdata;
62 thenode->exe = kill_exe;
63 thenode->free = kill_free;
64
65 return thenode;
66 }
67
68 void *kill_exe(struct searchNode *thenode, void *theinput) {
69 struct kill_localdata *localdata;
70 nick *np;
71 chanindex *cip;
72
73 localdata = thenode->localdata;
74
75 if (localdata->type == SEARCHTYPE_CHANNEL) {
76 cip = (chanindex *)theinput;
77 cip->marker = localdata->marker;
78 localdata->count += cip->channel->users->totalusers;
79 }
80 else {
81 np = (nick *)theinput;
82 np->marker = localdata->marker;
83 localdata->count++;
84 }
85
86 return (void *)1;
87 }
88
89 void kill_free(struct searchNode *thenode) {
90 struct kill_localdata *localdata;
91 nick *np, *nnp;
92 chanindex *cip, *ncip;
93 int i, j, safe=0;
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 ... */
99 controlreply(senderNSExtern, "Warning: your pattern matches too many users (%d) - nothing done.", localdata->count);
100 free(localdata);
101 free(thenode);
102 return;
103 }
104
105 if (localdata->type == SEARCHTYPE_CHANNEL) {
106 for (i=0;i<CHANNELHASHSIZE;i++) {
107 for (cip=chantable[i];cip;cip=ncip) {
108 ncip = cip->next;
109 if (cip != NULL && cip->channel != NULL && cip->marker == localdata->marker) {
110 for (j=0;j<cip->channel->users->hashsize;j++) {
111 if (cip->channel->users->content[j]==nouser)
112 continue;
113
114 if ((np=getnickbynumeric(cip->channel->users->content[j]))) {
115 if (!IsOper(np) && !IsService(np) && !IsXOper(np)) {
116 killuser(NULL, np, "You (%s!%s@%s) have been disconnected for violating our terms of service%s", np->nick,
117 np->ident, IPtostr(np->p_ipaddr), localdata->reason);
118 }
119 else
120 safe++;
121 }
122 }
123 }
124 }
125 }
126 }
127 else {
128 for (i=0;i<NICKHASHSIZE;i++) {
129 for (np=nicktable[i];np;np=nnp) {
130 nnp = np->next;
131 if (np->marker == localdata->marker) {
132 if (!IsOper(np) && !IsService(np) && !IsXOper(np)) {
133 killuser(NULL, np, "You (%s!%s@%s) have been disconnected for violating our terms of service%s", np->nick,
134 np->ident, IPtostr(np->p_ipaddr), localdata->reason);
135 }
136 else
137 safe++;
138 }
139 }
140 }
141 }
142 if (safe)
143 controlreply(senderNSExtern, "Warning: your pattern matched privileged users (%d in total) - these have not been touched.", safe);
144 /* notify opers of the action */
145 controlwall(NO_OPER, NL_KICKKILLS, "%s/%s killed %d %s via %s [%d untouched].", senderNSExtern->nick, senderNSExtern->authname, (localdata->count - safe),
146 (localdata->count - safe) != 1 ? "users" : "user", (localdata->type == SEARCHTYPE_CHANNEL) ? "chansearch" : "nicksearch", safe);
147 free(localdata);
148 free(thenode);
149 }