]> jfr.im git - irc/quakenet/newserv.git/blame - newsearch/ns-gline.c
trust search ast
[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"
4278cc14
IB
16
17/* used for *_free functions that need to warn users of certain things
18 i.e. hitting too many users in a (kill) or (gline) - declared in newsearch.c */
219d27f1 19extern nick *senderNSExtern;
2ba836f2 20static const char *defaultreason = "You (%u) have been g-lined for violating our terms of service";
4278cc14 21
c8be5183
CP
22void *gline_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
23void gline_free(searchCtx *ctx, struct searchNode *thenode);
4278cc14
IB
24
25struct gline_localdata {
26 unsigned int marker;
f16cabe4 27 unsigned int duration;
4278cc14 28 int count;
96429168 29 char reason[NSMAX_REASON_LEN];
4278cc14
IB
30};
31
f33f3f52 32struct searchNode *gline_parse(searchCtx *ctx, int argc, char **argv) {
4278cc14
IB
33 struct gline_localdata *localdata;
34 struct searchNode *thenode;
35
9ce4f0be
IB
36 if (!(localdata = (struct gline_localdata *) malloc(sizeof(struct gline_localdata)))) {
37 parseError = "malloc: could not allocate memory for this search.";
38 return NULL;
39 }
4278cc14 40 localdata->count = 0;
a92bb8e1 41 if (ctx->searchcmd == reg_chansearch)
8e257015 42 localdata->marker = nextchanmarker();
a92bb8e1 43 else if (ctx->searchcmd == reg_nicksearch)
8e257015 44 localdata->marker = nextnickmarker();
a92bb8e1 45 else {
31686847 46 free(localdata);
a92bb8e1
P
47 parseError = "gline: invalid search type";
48 return NULL;
49 }
4278cc14 50
31686847
CP
51 /* default duration, default reason */
52 if(argc == 0) {
f16cabe4 53 localdata->duration = NSGLINE_DURATION;
2ba836f2 54 strlcpy(localdata->reason, defaultreason, sizeof(localdata->reason));
31686847
CP
55 } else if(argc > 2) {
56 free(localdata);
57 parseError = "gline: invalid number of arguments";
58 return NULL;
59 } else {
60 char *argzerop, *reasonp, *durationp;
61 struct searchNode *durationsn, *reasonsn, *argzerosn;
62
63 if (!(argzerosn=argtoconststr("gline", ctx, argv[0], &argzerop))) {
64 free(localdata);
65 return NULL;
66 }
96429168 67
31686847
CP
68 if(argc == 1) {
69 durationp = reasonp = NULL;
70 durationsn = reasonsn = NULL;
71
72 /* if we have a space it's a reason */
73 if(strchr(argzerop, ' ')) {
74 reasonsn = argzerosn;
75 reasonp = argzerop;
76 } else {
77 durationsn = argzerosn;
78 durationp = argzerop;
90323e03 79 }
31686847
CP
80 } else {
81 durationsn = argzerosn;
82 durationp = argzerop;
90323e03 83
31686847
CP
84 if (!(reasonsn=argtoconststr("gline", ctx, argv[1], &reasonp))) {
85 durationsn->free(ctx, durationsn);
86 free(localdata);
87 return NULL;
88 }
96429168 89 }
31686847
CP
90
91 if(!reasonp) {
92 strlcpy(localdata->reason, defaultreason, sizeof(localdata->reason));
93 } else {
94 strlcpy(localdata->reason, reasonp, sizeof(localdata->reason));
95 reasonsn->free(ctx, reasonsn);
96429168 96 }
96429168 97
31686847
CP
98 if(!durationp) {
99 localdata->duration = NSGLINE_DURATION;
100 } else {
101 localdata->duration = durationtolong(durationp);
102 durationsn->free(ctx, durationsn);
103
104 if (localdata->duration == 0) {
105 parseError = "gline duration invalid.";
106 free(localdata);
107 return NULL;
108 }
2ba836f2 109 }
f16cabe4
IB
110 }
111
9ce4f0be
IB
112 if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
113 /* couldn't malloc() memory for thenode, so free localdata to avoid leakage */
114 parseError = "malloc: could not allocate memory for this search.";
115 free(localdata);
116 return NULL;
117 }
4278cc14
IB
118
119 thenode->returntype = RETURNTYPE_BOOL;
120 thenode->localdata = localdata;
121 thenode->exe = gline_exe;
122 thenode->free = gline_free;
123
124 return thenode;
125}
126
c8be5183 127void *gline_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
4278cc14 128 struct gline_localdata *localdata;
8e257015
IB
129 nick *np;
130 chanindex *cip;
4278cc14
IB
131
132 localdata = thenode->localdata;
133
a92bb8e1 134 if (ctx->searchcmd == reg_chansearch) {
8e257015
IB
135 cip = (chanindex *)theinput;
136 cip->marker = localdata->marker;
1545f345 137 localdata->count += cip->channel->users->totalusers;
8e257015
IB
138 }
139 else {
140 np = (nick *)theinput;
141 np->marker = localdata->marker;
142 localdata->count++;
143 }
4278cc14 144
c7f7a584 145 return (void *)1;
4278cc14
IB
146}
147
90323e03
CP
148static int glineuser(nick *np, struct gline_localdata *localdata, time_t ti) {
149 char msgbuf[512];
150 if (!IsOper(np) && !IsService(np) && !IsXOper(np)) {
151 nssnprintf(msgbuf, sizeof(msgbuf), localdata->reason, np);
152 if (np->host->clonecount <= NSMAX_GLINE_CLONES)
153 irc_send("%s GL * +*@%s %u %jd :%s", mynumeric->content, IPtostr(np->p_ipaddr), localdata->duration, (intmax_t)ti, msgbuf);
154 else
155 irc_send("%s GL * +%s@%s %u %jd :%s", mynumeric->content, np->ident, IPtostr(np->p_ipaddr), localdata->duration, (intmax_t)ti, msgbuf);
156 return 1;
157 }
158
159 return 0;
160}
161
c8be5183 162void gline_free(searchCtx *ctx, struct searchNode *thenode) {
4278cc14
IB
163 struct gline_localdata *localdata;
164 nick *np, *nnp;
8e257015
IB
165 chanindex *cip, *ncip;
166 int i, j, safe=0;
aace33dc 167 time_t ti = time(NULL);
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
a92bb8e1 179 if (ctx->searchcmd == reg_chansearch) {
8e257015
IB
180 for (i=0;i<CHANNELHASHSIZE;i++) {
181 for (cip=chantable[i];cip;cip=ncip) {
182 ncip = cip->next;
183 if (cip != NULL && cip->channel != NULL && cip->marker == localdata->marker) {
184 for (j=0;j<cip->channel->users->hashsize;j++) {
185 if (cip->channel->users->content[j]==nouser)
186 continue;
187
188 if ((np=getnickbynumeric(cip->channel->users->content[j]))) {
90323e03 189 if(!glineuser(np, localdata, ti))
2ba836f2 190 safe++;
8e257015
IB
191 }
192 }
193 }
194 }
195 }
196 }
197 else {
198 for (i=0;i<NICKHASHSIZE;i++) {
199 for (np=nicktable[i];np;np=nnp) {
200 nnp = np->next;
201 if (np->marker == localdata->marker) {
90323e03
CP
202 if(!glineuser(np, localdata, ti))
203 safe++;
4278cc14 204 }
4278cc14
IB
205 }
206 }
207 }
208 if (safe)
0da2a4ae 209 ctx->reply(senderNSExtern, "Warning: your pattern matched privileged users (%d in total) - these have not been touched.", safe);
f16cabe4 210 /* notify opers of the action */
0da2a4ae 211 ctx->wall(NL_GLINES, "%s/%s glined %d %s via %s for %s [%d untouched].", senderNSExtern->nick, senderNSExtern->authname, (localdata->count - safe),
a92bb8e1 212 (localdata->count - safe) != 1 ? "users" : "user", (ctx->searchcmd == reg_chansearch) ? "chansearch" : "nicksearch", longtoduration(localdata->duration, 1), safe);
4278cc14
IB
213 free(localdata);
214 free(thenode);
215}