]> jfr.im git - irc/quakenet/newserv.git/blame - newsearch/ns-gline.c
trusts: Don't check clone limits for ::.
[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();
a92bb8e1 46 else {
31686847 47 free(localdata);
a92bb8e1
P
48 parseError = "gline: invalid search type";
49 return NULL;
50 }
4278cc14 51
31686847
CP
52 /* default duration, default reason */
53 if(argc == 0) {
f16cabe4 54 localdata->duration = NSGLINE_DURATION;
2ba836f2 55 strlcpy(localdata->reason, defaultreason, sizeof(localdata->reason));
31686847
CP
56 } else if(argc > 2) {
57 free(localdata);
58 parseError = "gline: invalid number of arguments";
59 return NULL;
60 } else {
61 char *argzerop, *reasonp, *durationp;
62 struct searchNode *durationsn, *reasonsn, *argzerosn;
63
64 if (!(argzerosn=argtoconststr("gline", ctx, argv[0], &argzerop))) {
65 free(localdata);
66 return NULL;
67 }
96429168 68
31686847
CP
69 if(argc == 1) {
70 durationp = reasonp = NULL;
71 durationsn = reasonsn = NULL;
72
73 /* if we have a space it's a reason */
74 if(strchr(argzerop, ' ')) {
75 reasonsn = argzerosn;
76 reasonp = argzerop;
77 } else {
78 durationsn = argzerosn;
79 durationp = argzerop;
90323e03 80 }
31686847
CP
81 } else {
82 durationsn = argzerosn;
83 durationp = argzerop;
90323e03 84
31686847
CP
85 if (!(reasonsn=argtoconststr("gline", ctx, argv[1], &reasonp))) {
86 durationsn->free(ctx, durationsn);
87 free(localdata);
88 return NULL;
89 }
96429168 90 }
31686847
CP
91
92 if(!reasonp) {
93 strlcpy(localdata->reason, defaultreason, sizeof(localdata->reason));
94 } else {
95 strlcpy(localdata->reason, reasonp, sizeof(localdata->reason));
96 reasonsn->free(ctx, reasonsn);
96429168 97 }
96429168 98
31686847
CP
99 if(!durationp) {
100 localdata->duration = NSGLINE_DURATION;
101 } else {
102 localdata->duration = durationtolong(durationp);
103 durationsn->free(ctx, durationsn);
104
105 if (localdata->duration == 0) {
106 parseError = "gline duration invalid.";
107 free(localdata);
108 return NULL;
109 }
2ba836f2 110 }
f16cabe4
IB
111 }
112
9ce4f0be
IB
113 if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
114 /* couldn't malloc() memory for thenode, so free localdata to avoid leakage */
115 parseError = "malloc: could not allocate memory for this search.";
116 free(localdata);
117 return NULL;
118 }
4278cc14
IB
119
120 thenode->returntype = RETURNTYPE_BOOL;
121 thenode->localdata = localdata;
122 thenode->exe = gline_exe;
123 thenode->free = gline_free;
124
125 return thenode;
126}
127
c8be5183 128void *gline_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
4278cc14 129 struct gline_localdata *localdata;
8e257015
IB
130 nick *np;
131 chanindex *cip;
4278cc14
IB
132
133 localdata = thenode->localdata;
134
a92bb8e1 135 if (ctx->searchcmd == reg_chansearch) {
8e257015
IB
136 cip = (chanindex *)theinput;
137 cip->marker = localdata->marker;
0371d169
GB
138 if (cip->channel != NULL)
139 localdata->count += cip->channel->users->totalusers;
8e257015
IB
140 }
141 else {
142 np = (nick *)theinput;
143 np->marker = localdata->marker;
144 localdata->count++;
145 }
4278cc14 146
c7f7a584 147 return (void *)1;
4278cc14
IB
148}
149
324b4e11 150static int glineuser(glinebuf *gbuf, nick *np, struct gline_localdata *localdata, time_t ti) {
90323e03
CP
151 char msgbuf[512];
152 if (!IsOper(np) && !IsService(np) && !IsXOper(np)) {
153 nssnprintf(msgbuf, sizeof(msgbuf), localdata->reason, np);
324b4e11 154 glinebufaddbynick(gbuf, np, 0, "newsearch", msgbuf, getnettime() + localdata->duration, getnettime(), getnettime() + localdata->duration);
90323e03
CP
155 return 1;
156 }
157
158 return 0;
159}
160
c8be5183 161void gline_free(searchCtx *ctx, struct searchNode *thenode) {
4278cc14
IB
162 struct gline_localdata *localdata;
163 nick *np, *nnp;
8e257015 164 chanindex *cip, *ncip;
324b4e11 165 int i, j, hits, safe=0;
aace33dc 166 time_t ti = time(NULL);
324b4e11 167 glinebuf gbuf;
4278cc14
IB
168
169 localdata = thenode->localdata;
170
171 if (localdata->count > NSMAX_GLINE_LIMIT) {
172 /* need to warn the user that they have just tried to twat half the network ... */
0da2a4ae 173 ctx->reply(senderNSExtern, "Warning: your pattern matches too many users (%d) - nothing done.", localdata->count);
4278cc14
IB
174 free(localdata);
175 free(thenode);
176 return;
177 }
178
324b4e11
GB
179 glinebufinit(&gbuf, 0);
180
a92bb8e1 181 if (ctx->searchcmd == reg_chansearch) {
8e257015
IB
182 for (i=0;i<CHANNELHASHSIZE;i++) {
183 for (cip=chantable[i];cip;cip=ncip) {
184 ncip = cip->next;
185 if (cip != NULL && cip->channel != NULL && cip->marker == localdata->marker) {
186 for (j=0;j<cip->channel->users->hashsize;j++) {
187 if (cip->channel->users->content[j]==nouser)
188 continue;
189
190 if ((np=getnickbynumeric(cip->channel->users->content[j]))) {
324b4e11 191 if(!glineuser(&gbuf, np, localdata, ti))
2ba836f2 192 safe++;
8e257015
IB
193 }
194 }
195 }
196 }
197 }
198 }
199 else {
200 for (i=0;i<NICKHASHSIZE;i++) {
201 for (np=nicktable[i];np;np=nnp) {
202 nnp = np->next;
203 if (np->marker == localdata->marker) {
324b4e11 204 if(!glineuser(&gbuf, np, localdata, ti))
90323e03 205 safe++;
4278cc14 206 }
4278cc14
IB
207 }
208 }
209 }
324b4e11 210
33e09c2c 211 glinebufcounthits(&gbuf, &hits, NULL);
324b4e11
GB
212 glinebufcommit(&gbuf, 1);
213
4278cc14 214 if (safe)
0da2a4ae 215 ctx->reply(senderNSExtern, "Warning: your pattern matched privileged users (%d in total) - these have not been touched.", safe);
f16cabe4 216 /* notify opers of the action */
0da2a4ae 217 ctx->wall(NL_GLINES, "%s/%s glined %d %s via %s for %s [%d untouched].", senderNSExtern->nick, senderNSExtern->authname, (localdata->count - safe),
a92bb8e1 218 (localdata->count - safe) != 1 ? "users" : "user", (ctx->searchcmd == reg_chansearch) ? "chansearch" : "nicksearch", longtoduration(localdata->duration, 1), safe);
4278cc14
IB
219 free(localdata);
220 free(thenode);
221}