]>
jfr.im git - irc/quakenet/newserv.git/blob - newsearch/ns-gline.c
12 #include "../control/control.h"
13 #include "../irc/irc.h" /* irc_send() */
14 #include "../lib/irc_string.h" /* IPtostr(), longtoduration(), durationtolong() */
15 #include "../lib/strlfunc.h"
16 #include "../glines/glines.h"
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 */
20 extern nick
*senderNSExtern
;
21 static const char *defaultreason
= "You (%u) have been g-lined for violating our terms of service";
23 void *gline_exe(searchCtx
*ctx
, struct searchNode
*thenode
, void *theinput
);
24 void gline_free(searchCtx
*ctx
, struct searchNode
*thenode
);
26 struct gline_localdata
{
28 unsigned int duration
;
30 char reason
[NSMAX_REASON_LEN
];
33 struct searchNode
*gline_parse(searchCtx
*ctx
, int argc
, char **argv
) {
34 struct gline_localdata
*localdata
;
35 struct searchNode
*thenode
;
37 if (!(localdata
= (struct gline_localdata
*) malloc(sizeof(struct gline_localdata
)))) {
38 parseError
= "malloc: could not allocate memory for this search.";
42 if (ctx
->searchcmd
== reg_chansearch
)
43 localdata
->marker
= nextchanmarker();
44 else if (ctx
->searchcmd
== reg_nicksearch
)
45 localdata
->marker
= nextnickmarker();
46 else if (ctx
->searchcmd
== reg_whowassearch
)
47 localdata
->marker
= nextwhowasmarker();
50 parseError
= "gline: invalid search type";
54 /* default duration, default reason */
56 localdata
->duration
= NSGLINE_DURATION
;
57 strlcpy(localdata
->reason
, defaultreason
, sizeof(localdata
->reason
));
60 parseError
= "gline: invalid number of arguments";
63 char *argzerop
, *reasonp
, *durationp
;
64 struct searchNode
*durationsn
, *reasonsn
, *argzerosn
;
66 if (!(argzerosn
=argtoconststr("gline", ctx
, argv
[0], &argzerop
))) {
72 durationp
= reasonp
= NULL
;
73 durationsn
= reasonsn
= NULL
;
75 /* if we have a space it's a reason */
76 if(strchr(argzerop
, ' ')) {
80 durationsn
= argzerosn
;
84 durationsn
= argzerosn
;
87 if (!(reasonsn
=argtoconststr("gline", ctx
, argv
[1], &reasonp
))) {
88 durationsn
->free(ctx
, durationsn
);
95 strlcpy(localdata
->reason
, defaultreason
, sizeof(localdata
->reason
));
97 strlcpy(localdata
->reason
, reasonp
, sizeof(localdata
->reason
));
98 reasonsn
->free(ctx
, reasonsn
);
102 localdata
->duration
= NSGLINE_DURATION
;
104 localdata
->duration
= durationtolong(durationp
);
105 durationsn
->free(ctx
, durationsn
);
107 if (localdata
->duration
== 0) {
108 parseError
= "gline duration invalid.";
115 if (!(thenode
=(struct searchNode
*)malloc(sizeof (struct searchNode
)))) {
116 /* couldn't malloc() memory for thenode, so free localdata to avoid leakage */
117 parseError
= "malloc: could not allocate memory for this search.";
122 thenode
->returntype
= RETURNTYPE_BOOL
;
123 thenode
->localdata
= localdata
;
124 thenode
->exe
= gline_exe
;
125 thenode
->free
= gline_free
;
130 void *gline_exe(searchCtx
*ctx
, struct searchNode
*thenode
, void *theinput
) {
131 struct gline_localdata
*localdata
;
136 localdata
= thenode
->localdata
;
138 if (ctx
->searchcmd
== reg_chansearch
) {
139 cip
= (chanindex
*)theinput
;
140 cip
->marker
= localdata
->marker
;
141 if (cip
->channel
!= NULL
)
142 localdata
->count
+= cip
->channel
->users
->totalusers
;
145 np
= (nick
*)theinput
;
146 if (ctx
->searchcmd
== reg_nicksearch
)
147 np
->marker
= localdata
->marker
;
150 ww
->marker
= localdata
->marker
;
158 static int glineuser(glinebuf
*gbuf
, nick
*np
, struct gline_localdata
*localdata
, time_t ti
) {
160 if (!IsOper(np
) && !IsService(np
) && !IsXOper(np
)) {
161 nssnprintf(msgbuf
, sizeof(msgbuf
), localdata
->reason
, np
);
162 glinebufaddbynick(gbuf
, np
, 0, "newsearch", msgbuf
, getnettime() + localdata
->duration
, getnettime(), getnettime() + localdata
->duration
);
169 void gline_free(searchCtx
*ctx
, struct searchNode
*thenode
) {
170 struct gline_localdata
*localdata
;
172 chanindex
*cip
, *ncip
;
174 int i
, j
, hits
, safe
=0;
175 time_t ti
= time(NULL
);
178 localdata
= thenode
->localdata
;
180 if (localdata
->count
> NSMAX_GLINE_LIMIT
) {
181 /* need to warn the user that they have just tried to twat half the network ... */
182 ctx
->reply(senderNSExtern
, "Warning: your pattern matches too many users (%d) - nothing done.", localdata
->count
);
188 glinebufinit(&gbuf
, 0);
190 if (ctx
->searchcmd
== reg_chansearch
) {
191 for (i
=0;i
<CHANNELHASHSIZE
;i
++) {
192 for (cip
=chantable
[i
];cip
;cip
=ncip
) {
194 if (cip
!= NULL
&& cip
->channel
!= NULL
&& cip
->marker
== localdata
->marker
) {
195 for (j
=0;j
<cip
->channel
->users
->hashsize
;j
++) {
196 if (cip
->channel
->users
->content
[j
]==nouser
)
199 if ((np
=getnickbynumeric(cip
->channel
->users
->content
[j
]))) {
200 if(!glineuser(&gbuf
, np
, localdata
, ti
))
207 } else if (ctx
->searchcmd
== reg_nicksearch
) {
208 for (i
=0;i
<NICKHASHSIZE
;i
++) {
209 for (np
=nicktable
[i
];np
;np
=nnp
) {
211 if (np
->marker
== localdata
->marker
) {
212 if(!glineuser(&gbuf
, np
, localdata
, ti
))
218 for (ww
= whowas_head
; ww
; ww
= ww
->next
) {
219 if (ww
->marker
== localdata
->marker
) {
220 if(!glineuser(&gbuf
, ww
->nick
, localdata
, ti
))
226 glinebufcounthits(&gbuf
, &hits
, NULL
);
227 glinebufcommit(&gbuf
, 1);
230 ctx
->reply(senderNSExtern
, "Warning: your pattern matched privileged users (%d in total) - these have not been touched.", safe
);
231 /* notify opers of the action */
232 ctx
->wall(NL_GLINES
, "%s/%s glined %d %s via %s for %s [%d untouched].", senderNSExtern
->nick
, senderNSExtern
->authname
, (localdata
->count
- safe
),
233 (localdata
->count
- safe
) != 1 ? "users" : "user", (ctx
->searchcmd
== reg_chansearch
) ? "chansearch" : "nicksearch", longtoduration(localdata
->duration
, 1), safe
);