]> jfr.im git - irc/quakenet/newserv.git/blame - newsearch/ns-gline.c
Now I realise I broke Q9's newsearch...
[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>
4278cc14
IB
10
11#include "../control/control.h" /* controlreply() */
12#include "../irc/irc.h" /* irc_send() */
f16cabe4 13#include "../lib/irc_string.h" /* IPtostr(), longtoduration(), durationtolong() */
2ba836f2 14#include "../lib/strlfunc.h"
4278cc14
IB
15
16/* used for *_free functions that need to warn users of certain things
17 i.e. hitting too many users in a (kill) or (gline) - declared in newsearch.c */
219d27f1 18extern nick *senderNSExtern;
2ba836f2 19static const char *defaultreason = "You (%u) have been g-lined for violating our terms of service";
4278cc14 20
c8be5183
CP
21void *gline_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
22void gline_free(searchCtx *ctx, struct searchNode *thenode);
4278cc14
IB
23
24struct gline_localdata {
25 unsigned int marker;
f16cabe4 26 unsigned int duration;
4278cc14 27 int count;
8e257015 28 int type;
96429168 29 char reason[NSMAX_REASON_LEN];
4278cc14
IB
30};
31
c8be5183 32struct searchNode *gline_parse(searchCtx *ctx, int type, int argc, char **argv) {
4278cc14
IB
33 struct gline_localdata *localdata;
34 struct searchNode *thenode;
96429168 35 int len;
2ba836f2 36 char *p;
4278cc14 37
9ce4f0be
IB
38 if (!(localdata = (struct gline_localdata *) malloc(sizeof(struct gline_localdata)))) {
39 parseError = "malloc: could not allocate memory for this search.";
40 return NULL;
41 }
4278cc14 42 localdata->count = 0;
8e257015
IB
43 localdata->type = type;
44 if (type == SEARCHTYPE_CHANNEL)
45 localdata->marker = nextchanmarker();
46 else
47 localdata->marker = nextnickmarker();
4278cc14 48
96429168
IB
49 switch (argc) {
50 case 0:
f16cabe4 51 localdata->duration = NSGLINE_DURATION;
2ba836f2 52 strlcpy(localdata->reason, defaultreason, sizeof(localdata->reason));
96429168
IB
53 break;
54
55 case 1:
56 if (strchr(argv[0], ' ') == NULL) { /* duration specified */
57 localdata->duration = durationtolong(argv[0]);
58 /* error checking on gline duration */
59 if (localdata->duration == 0)
60 localdata->duration = NSGLINE_DURATION;
2ba836f2 61 strlcpy(localdata->reason, defaultreason, sizeof(localdata->reason));
96429168
IB
62 }
63 else { /* reason specified */
64 localdata->duration = NSGLINE_DURATION;
2ba836f2
CP
65
66 p = argv[0];
67 if(*p == '\"')
7759d816 68 p++;
2ba836f2
CP
69 len = strlcpy(localdata->reason, p, sizeof(localdata->reason));
70 if(len >= sizeof(localdata->reason)) {
71 localdata->reason[sizeof(localdata->reason)-1] = '\0';
72 } else {
73 localdata->reason[len-1] = '\0';
74 }
96429168
IB
75 }
76 break;
77
78 case 2:
f16cabe4
IB
79 localdata->duration = durationtolong(argv[0]);
80 /* error checking on gline duration */
81 if (localdata->duration == 0)
82 localdata->duration = NSGLINE_DURATION;
96429168 83
2ba836f2
CP
84 p = argv[1];
85 if(*p == '\"')
5b417a78 86 p++;
2ba836f2
CP
87 len = strlcpy(localdata->reason, p, sizeof(localdata->reason));
88 if(len >= sizeof(localdata->reason)) {
89 localdata->reason[sizeof(localdata->reason)-1] = '\0';
90 } else {
91 localdata->reason[len-1] = '\0';
92 }
93
94 break;
96429168
IB
95 default:
96 free(localdata);
97 parseError = "gline: invalid number of arguments";
98 return NULL;
f16cabe4
IB
99 }
100
9ce4f0be
IB
101 if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
102 /* couldn't malloc() memory for thenode, so free localdata to avoid leakage */
103 parseError = "malloc: could not allocate memory for this search.";
104 free(localdata);
105 return NULL;
106 }
4278cc14
IB
107
108 thenode->returntype = RETURNTYPE_BOOL;
109 thenode->localdata = localdata;
110 thenode->exe = gline_exe;
111 thenode->free = gline_free;
112
113 return thenode;
114}
115
c8be5183 116void *gline_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
4278cc14 117 struct gline_localdata *localdata;
8e257015
IB
118 nick *np;
119 chanindex *cip;
4278cc14
IB
120
121 localdata = thenode->localdata;
122
8e257015
IB
123 if (localdata->type == SEARCHTYPE_CHANNEL) {
124 cip = (chanindex *)theinput;
125 cip->marker = localdata->marker;
1545f345 126 localdata->count += cip->channel->users->totalusers;
8e257015
IB
127 }
128 else {
129 np = (nick *)theinput;
130 np->marker = localdata->marker;
131 localdata->count++;
132 }
4278cc14 133
c7f7a584 134 return (void *)1;
4278cc14
IB
135}
136
c8be5183 137void gline_free(searchCtx *ctx, struct searchNode *thenode) {
4278cc14
IB
138 struct gline_localdata *localdata;
139 nick *np, *nnp;
8e257015
IB
140 chanindex *cip, *ncip;
141 int i, j, safe=0;
2ba836f2 142 char msgbuf[512];
4278cc14
IB
143
144 localdata = thenode->localdata;
145
146 if (localdata->count > NSMAX_GLINE_LIMIT) {
147 /* need to warn the user that they have just tried to twat half the network ... */
148 controlreply(senderNSExtern, "Warning: your pattern matches too many users (%d) - nothing done.", localdata->count);
4278cc14
IB
149 free(localdata);
150 free(thenode);
151 return;
152 }
153
8e257015
IB
154 if (localdata->type == SEARCHTYPE_CHANNEL) {
155 for (i=0;i<CHANNELHASHSIZE;i++) {
156 for (cip=chantable[i];cip;cip=ncip) {
157 ncip = cip->next;
158 if (cip != NULL && cip->channel != NULL && cip->marker == localdata->marker) {
159 for (j=0;j<cip->channel->users->hashsize;j++) {
160 if (cip->channel->users->content[j]==nouser)
161 continue;
162
163 if ((np=getnickbynumeric(cip->channel->users->content[j]))) {
164 if (!IsOper(np) && !IsService(np) && !IsXOper(np)) {
2ba836f2 165 nssnprintf(msgbuf, sizeof(msgbuf), localdata->reason, np);
8e257015 166 if (np->host->clonecount <= NSMAX_GLINE_CLONES)
2ba836f2 167 irc_send("%s GL * +*@%s %u :%s", mynumeric->content, IPtostr(np->p_ipaddr), localdata->duration, msgbuf);
8e257015 168 else
2ba836f2
CP
169 irc_send("%s GL * +%s@%s %u :%s", mynumeric->content, np->ident, IPtostr(np->p_ipaddr), localdata->duration, msgbuf);
170 }
171 else
172 safe++;
8e257015
IB
173 }
174 }
175 }
176 }
177 }
178 }
179 else {
180 for (i=0;i<NICKHASHSIZE;i++) {
181 for (np=nicktable[i];np;np=nnp) {
182 nnp = np->next;
183 if (np->marker == localdata->marker) {
184 if (!IsOper(np) && !IsService(np) && !IsXOper(np)) {
2ba836f2 185 nssnprintf(msgbuf, sizeof(msgbuf), localdata->reason, np);
8e257015 186 if (np->host->clonecount <= NSMAX_GLINE_CLONES)
2ba836f2 187 irc_send("%s GL * +*@%s %u :%s", mynumeric->content, IPtostr(np->p_ipaddr), localdata->duration, msgbuf);
8e257015 188 else
2ba836f2 189 irc_send("%s GL * +%s@%s %u :%s", mynumeric->content, np->ident, IPtostr(np->p_ipaddr), localdata->duration, msgbuf);
8e257015 190 }
4278cc14 191 else
8e257015 192 safe++;
4278cc14 193 }
4278cc14
IB
194 }
195 }
196 }
197 if (safe)
198 controlreply(senderNSExtern, "Warning: your pattern matched privileged users (%d in total) - these have not been touched.", safe);
f16cabe4 199 /* notify opers of the action */
8e257015
IB
200 controlwall(NO_OPER, NL_GLINES, "%s/%s glined %d %s via %s for %s [%d untouched].", senderNSExtern->nick, senderNSExtern->authname, (localdata->count - safe),
201 (localdata->count - safe) != 1 ? "users" : "user", (localdata->type == SEARCHTYPE_CHANNEL) ? "chansearch" : "nicksearch", longtoduration(localdata->duration, 1), safe);
4278cc14
IB
202 free(localdata);
203 free(thenode);
204}