]> jfr.im git - irc/quakenet/newserv.git/blame - newsearch/ns-gline.c
LUA: port luadb to dbapi2 to drop postgres dependency
[irc/quakenet/newserv.git] / newsearch / ns-gline.c
CommitLineData
4278cc14
IB
1/*
2 * GLINE functionality
3 */
4
5#include "newsearch.h"
6
7#include <stdio.h>
8#include <stdlib.h>
96429168 9#include <string.h>
8bab42e7 10#include <stdint.h>
4278cc14 11
0da2a4ae 12#include "../control/control.h"
4278cc14 13#include "../irc/irc.h" /* irc_send() */
f16cabe4 14#include "../lib/irc_string.h" /* IPtostr(), longtoduration(), durationtolong() */
2ba836f2 15#include "../lib/strlfunc.h"
324b4e11 16#include "../glines/glines.h"
4278cc14
IB
17
18/* used for *_free functions that need to warn users of certain things
19 i.e. hitting too many users in a (kill) or (gline) - declared in newsearch.c */
219d27f1 20extern nick *senderNSExtern;
2ba836f2 21static const char *defaultreason = "You (%u) have been g-lined for violating our terms of service";
4278cc14 22
c8be5183
CP
23void *gline_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
24void gline_free(searchCtx *ctx, struct searchNode *thenode);
4278cc14
IB
25
26struct gline_localdata {
27 unsigned int marker;
f16cabe4 28 unsigned int duration;
4278cc14 29 int count;
96429168 30 char reason[NSMAX_REASON_LEN];
4278cc14
IB
31};
32
f33f3f52 33struct searchNode *gline_parse(searchCtx *ctx, int argc, char **argv) {
4278cc14
IB
34 struct gline_localdata *localdata;
35 struct searchNode *thenode;
36
9ce4f0be
IB
37 if (!(localdata = (struct gline_localdata *) malloc(sizeof(struct gline_localdata)))) {
38 parseError = "malloc: could not allocate memory for this search.";
39 return NULL;
40 }
4278cc14 41 localdata->count = 0;
a92bb8e1 42 if (ctx->searchcmd == reg_chansearch)
8e257015 43 localdata->marker = nextchanmarker();
a92bb8e1 44 else if (ctx->searchcmd == reg_nicksearch)
8e257015 45 localdata->marker = nextnickmarker();
0eb4cbd3
GB
46 else if (ctx->searchcmd == reg_whowassearch)
47 localdata->marker = nextwhowasmarker();
a92bb8e1 48 else {
31686847 49 free(localdata);
a92bb8e1
P
50 parseError = "gline: invalid search type";
51 return NULL;
52 }
4278cc14 53
31686847
CP
54 /* default duration, default reason */
55 if(argc == 0) {
f16cabe4 56 localdata->duration = NSGLINE_DURATION;
2ba836f2 57 strlcpy(localdata->reason, defaultreason, sizeof(localdata->reason));
31686847
CP
58 } else if(argc > 2) {
59 free(localdata);
60 parseError = "gline: invalid number of arguments";
61 return NULL;
62 } else {
63 char *argzerop, *reasonp, *durationp;
64 struct searchNode *durationsn, *reasonsn, *argzerosn;
65
66 if (!(argzerosn=argtoconststr("gline", ctx, argv[0], &argzerop))) {
67 free(localdata);
68 return NULL;
69 }
96429168 70
31686847
CP
71 if(argc == 1) {
72 durationp = reasonp = NULL;
73 durationsn = reasonsn = NULL;
74
75 /* if we have a space it's a reason */
76 if(strchr(argzerop, ' ')) {
77 reasonsn = argzerosn;
78 reasonp = argzerop;
79 } else {
80 durationsn = argzerosn;
81 durationp = argzerop;
90323e03 82 }
31686847
CP
83 } else {
84 durationsn = argzerosn;
85 durationp = argzerop;
90323e03 86
31686847
CP
87 if (!(reasonsn=argtoconststr("gline", ctx, argv[1], &reasonp))) {
88 durationsn->free(ctx, durationsn);
89 free(localdata);
90 return NULL;
91 }
96429168 92 }
31686847
CP
93
94 if(!reasonp) {
95 strlcpy(localdata->reason, defaultreason, sizeof(localdata->reason));
96 } else {
97 strlcpy(localdata->reason, reasonp, sizeof(localdata->reason));
98 reasonsn->free(ctx, reasonsn);
96429168 99 }
96429168 100
31686847
CP
101 if(!durationp) {
102 localdata->duration = NSGLINE_DURATION;
103 } else {
104 localdata->duration = durationtolong(durationp);
105 durationsn->free(ctx, durationsn);
106
107 if (localdata->duration == 0) {
108 parseError = "gline duration invalid.";
109 free(localdata);
110 return NULL;
111 }
2ba836f2 112 }
f16cabe4
IB
113 }
114
9ce4f0be
IB
115 if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
116 /* couldn't malloc() memory for thenode, so free localdata to avoid leakage */
117 parseError = "malloc: could not allocate memory for this search.";
118 free(localdata);
119 return NULL;
120 }
4278cc14
IB
121
122 thenode->returntype = RETURNTYPE_BOOL;
123 thenode->localdata = localdata;
124 thenode->exe = gline_exe;
125 thenode->free = gline_free;
126
127 return thenode;
128}
129
c8be5183 130void *gline_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
4278cc14 131 struct gline_localdata *localdata;
8e257015
IB
132 nick *np;
133 chanindex *cip;
0eb4cbd3 134 whowas *ww;
4278cc14
IB
135
136 localdata = thenode->localdata;
137
a92bb8e1 138 if (ctx->searchcmd == reg_chansearch) {
8e257015
IB
139 cip = (chanindex *)theinput;
140 cip->marker = localdata->marker;
0371d169
GB
141 if (cip->channel != NULL)
142 localdata->count += cip->channel->users->totalusers;
8e257015
IB
143 }
144 else {
145 np = (nick *)theinput;
0eb4cbd3
GB
146 if (ctx->searchcmd == reg_nicksearch)
147 np->marker = localdata->marker;
148 else {
0495c1d1 149 ww = (whowas *)np->next;
0eb4cbd3
GB
150 ww->marker = localdata->marker;
151 }
8e257015
IB
152 localdata->count++;
153 }
4278cc14 154
c7f7a584 155 return (void *)1;
4278cc14
IB
156}
157
324b4e11 158static int glineuser(glinebuf *gbuf, nick *np, struct gline_localdata *localdata, time_t ti) {
90323e03
CP
159 char msgbuf[512];
160 if (!IsOper(np) && !IsService(np) && !IsXOper(np)) {
161 nssnprintf(msgbuf, sizeof(msgbuf), localdata->reason, np);
324b4e11 162 glinebufaddbynick(gbuf, np, 0, "newsearch", msgbuf, getnettime() + localdata->duration, getnettime(), getnettime() + localdata->duration);
90323e03
CP
163 return 1;
164 }
165
166 return 0;
167}
168
c8be5183 169void gline_free(searchCtx *ctx, struct searchNode *thenode) {
4278cc14
IB
170 struct gline_localdata *localdata;
171 nick *np, *nnp;
8e257015 172 chanindex *cip, *ncip;
0eb4cbd3 173 whowas *ww;
324b4e11 174 int i, j, hits, safe=0;
aace33dc 175 time_t ti = time(NULL);
324b4e11 176 glinebuf gbuf;
4278cc14
IB
177
178 localdata = thenode->localdata;
179
180 if (localdata->count > NSMAX_GLINE_LIMIT) {
181 /* need to warn the user that they have just tried to twat half the network ... */
0da2a4ae 182 ctx->reply(senderNSExtern, "Warning: your pattern matches too many users (%d) - nothing done.", localdata->count);
4278cc14
IB
183 free(localdata);
184 free(thenode);
185 return;
186 }
187
324b4e11
GB
188 glinebufinit(&gbuf, 0);
189
a92bb8e1 190 if (ctx->searchcmd == reg_chansearch) {
8e257015
IB
191 for (i=0;i<CHANNELHASHSIZE;i++) {
192 for (cip=chantable[i];cip;cip=ncip) {
193 ncip = cip->next;
194 if (cip != NULL && cip->channel != NULL && cip->marker == localdata->marker) {
195 for (j=0;j<cip->channel->users->hashsize;j++) {
196 if (cip->channel->users->content[j]==nouser)
197 continue;
198
199 if ((np=getnickbynumeric(cip->channel->users->content[j]))) {
324b4e11 200 if(!glineuser(&gbuf, np, localdata, ti))
2ba836f2 201 safe++;
8e257015
IB
202 }
203 }
204 }
205 }
206 }
0eb4cbd3 207 } else if (ctx->searchcmd == reg_nicksearch) {
8e257015
IB
208 for (i=0;i<NICKHASHSIZE;i++) {
209 for (np=nicktable[i];np;np=nnp) {
210 nnp = np->next;
211 if (np->marker == localdata->marker) {
324b4e11 212 if(!glineuser(&gbuf, np, localdata, ti))
90323e03 213 safe++;
4278cc14 214 }
4278cc14
IB
215 }
216 }
0eb4cbd3 217 } else {
291fdf5f
CP
218 for (i = whowasoffset; i < whowasoffset + whowasmax; i++) {
219 ww = &whowasrecs[i % whowasmax];
0495c1d1
GB
220
221 if (ww->type == WHOWAS_UNUSED)
222 continue;
223
0eb4cbd3 224 if (ww->marker == localdata->marker) {
0495c1d1 225 if(!glineuser(&gbuf, &ww->nick, localdata, ti))
0eb4cbd3
GB
226 safe++;
227 }
228 }
4278cc14 229 }
324b4e11 230
33e09c2c 231 glinebufcounthits(&gbuf, &hits, NULL);
324b4e11
GB
232 glinebufcommit(&gbuf, 1);
233
4278cc14 234 if (safe)
0da2a4ae 235 ctx->reply(senderNSExtern, "Warning: your pattern matched privileged users (%d in total) - these have not been touched.", safe);
f16cabe4 236 /* notify opers of the action */
0da2a4ae 237 ctx->wall(NL_GLINES, "%s/%s glined %d %s via %s for %s [%d untouched].", senderNSExtern->nick, senderNSExtern->authname, (localdata->count - safe),
a92bb8e1 238 (localdata->count - safe) != 1 ? "users" : "user", (ctx->searchcmd == reg_chansearch) ? "chansearch" : "nicksearch", longtoduration(localdata->duration, 1), safe);
4278cc14
IB
239 free(localdata);
240 free(thenode);
241}