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