]>
Commit | Line | Data |
---|---|---|
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 | 20 | extern nick *senderNSExtern; |
2ba836f2 | 21 | static const char *defaultreason = "You (%u) have been g-lined for violating our terms of service"; |
4278cc14 | 22 | |
c8be5183 CP |
23 | void *gline_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput); |
24 | void gline_free(searchCtx *ctx, struct searchNode *thenode); | |
4278cc14 IB |
25 | |
26 | struct 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 | 33 | struct 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 | 128 | void *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 | 150 | static 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 | 161 | void 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 | } |