]>
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();
48 parseError
= "gline: invalid search type";
52 /* default duration, default reason */
54 localdata
->duration
= NSGLINE_DURATION
;
55 strlcpy(localdata
->reason
, defaultreason
, sizeof(localdata
->reason
));
58 parseError
= "gline: invalid number of arguments";
61 char *argzerop
, *reasonp
, *durationp
;
62 struct searchNode
*durationsn
, *reasonsn
, *argzerosn
;
64 if (!(argzerosn
=argtoconststr("gline", ctx
, argv
[0], &argzerop
))) {
70 durationp
= reasonp
= NULL
;
71 durationsn
= reasonsn
= NULL
;
73 /* if we have a space it's a reason */
74 if(strchr(argzerop
, ' ')) {
78 durationsn
= argzerosn
;
82 durationsn
= argzerosn
;
85 if (!(reasonsn
=argtoconststr("gline", ctx
, argv
[1], &reasonp
))) {
86 durationsn
->free(ctx
, durationsn
);
93 strlcpy(localdata
->reason
, defaultreason
, sizeof(localdata
->reason
));
95 strlcpy(localdata
->reason
, reasonp
, sizeof(localdata
->reason
));
96 reasonsn
->free(ctx
, reasonsn
);
100 localdata
->duration
= NSGLINE_DURATION
;
102 localdata
->duration
= durationtolong(durationp
);
103 durationsn
->free(ctx
, durationsn
);
105 if (localdata
->duration
== 0) {
106 parseError
= "gline duration invalid.";
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.";
120 thenode
->returntype
= RETURNTYPE_BOOL
;
121 thenode
->localdata
= localdata
;
122 thenode
->exe
= gline_exe
;
123 thenode
->free
= gline_free
;
128 void *gline_exe(searchCtx
*ctx
, struct searchNode
*thenode
, void *theinput
) {
129 struct gline_localdata
*localdata
;
133 localdata
= thenode
->localdata
;
135 if (ctx
->searchcmd
== reg_chansearch
) {
136 cip
= (chanindex
*)theinput
;
137 cip
->marker
= localdata
->marker
;
138 if (cip
->channel
!= NULL
)
139 localdata
->count
+= cip
->channel
->users
->totalusers
;
142 np
= (nick
*)theinput
;
143 np
->marker
= localdata
->marker
;
150 static int glineuser(glinebuf
*gbuf
, nick
*np
, struct gline_localdata
*localdata
, time_t ti
) {
152 if (!IsOper(np
) && !IsService(np
) && !IsXOper(np
)) {
153 nssnprintf(msgbuf
, sizeof(msgbuf
), localdata
->reason
, np
);
154 glinebufaddbynick(gbuf
, np
, 0, "newsearch", msgbuf
, getnettime() + localdata
->duration
, getnettime(), getnettime() + localdata
->duration
);
161 void gline_free(searchCtx
*ctx
, struct searchNode
*thenode
) {
162 struct gline_localdata
*localdata
;
164 chanindex
*cip
, *ncip
;
165 int i
, j
, hits
, safe
=0;
166 time_t ti
= time(NULL
);
169 localdata
= thenode
->localdata
;
171 if (localdata
->count
> NSMAX_GLINE_LIMIT
) {
172 /* need to warn the user that they have just tried to twat half the network ... */
173 ctx
->reply(senderNSExtern
, "Warning: your pattern matches too many users (%d) - nothing done.", localdata
->count
);
179 glinebufinit(&gbuf
, 0);
181 if (ctx
->searchcmd
== reg_chansearch
) {
182 for (i
=0;i
<CHANNELHASHSIZE
;i
++) {
183 for (cip
=chantable
[i
];cip
;cip
=ncip
) {
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
)
190 if ((np
=getnickbynumeric(cip
->channel
->users
->content
[j
]))) {
191 if(!glineuser(&gbuf
, np
, localdata
, ti
))
200 for (i
=0;i
<NICKHASHSIZE
;i
++) {
201 for (np
=nicktable
[i
];np
;np
=nnp
) {
203 if (np
->marker
== localdata
->marker
) {
204 if(!glineuser(&gbuf
, np
, localdata
, ti
))
211 glinebufcounthits(&gbuf
, &hits
, NULL
);
212 glinebufcommit(&gbuf
, 1);
215 ctx
->reply(senderNSExtern
, "Warning: your pattern matched privileged users (%d in total) - these have not been touched.", safe
);
216 /* notify opers of the action */
217 ctx
->wall(NL_GLINES
, "%s/%s glined %d %s via %s for %s [%d untouched].", senderNSExtern
->nick
, senderNSExtern
->authname
, (localdata
->count
- safe
),
218 (localdata
->count
- safe
) != 1 ? "users" : "user", (ctx
->searchcmd
== reg_chansearch
) ? "chansearch" : "nicksearch", longtoduration(localdata
->duration
, 1), safe
);