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