]>
jfr.im git - irc/quakenet/newserv.git/blob - request/request_block.c
3 #include "../irc/irc.h"
4 #include "../lib/irc_string.h"
5 #include "request_block.h"
10 /* our anti-flood nick extension */
13 /* are we currently loading blocks? */
16 void rqhook_lostnick(int hook
, void *arg
);
18 int rq_initblocks(void) {
19 rqnext
= registernickext("request");
23 array_init(&rqblocks
, sizeof(rq_block
));
24 array_setlim1(&rqblocks
, 5);
25 array_setlim2(&rqblocks
, 20);
31 rq_addblock("#qnet*", "Reserved for QuakeNet use only.", "request", 0, 0);
32 rq_addblock("#help*", "Reserved for QuakeNet use only.", "request", 0, 0);
34 registerhook(HOOK_NICK_LOSTNICK
, &rqhook_lostnick
);
39 void rq_finiblocks(void) {
44 for (i
= 0; i
< rqblocks
.cursi
; i
++) {
45 block
= ((rq_block
*)rqblocks
.content
)[i
];
47 freesstring(block
.pattern
);
48 freesstring(block
.reason
);
49 freesstring(block
.creator
);
52 array_free(&rqblocks
);
54 for (i
=0; i
<NICKHASHSIZE
; i
++)
55 for (nip
=nicktable
[i
]; nip
; nip
=nip
->next
)
56 free(nip
->exts
[rqnext
]);
58 deregisterhook(HOOK_NICK_LOSTNICK
, &rqhook_lostnick
);
60 releasenickext(rqnext
);
63 void rqhook_lostnick(int hook
, void *arg
) {
64 nick
*np
= (nick
*)arg
;
66 free(np
->exts
[rqnext
]);
69 int rq_isspam(nick
*np
) {
72 if (np
->exts
[rqnext
] == NULL
) {
73 np
->exts
[rqnext
] = lf
= (rq_flood
*)malloc(sizeof(rq_flood
));
76 lf
->created
= getnettime();
81 lf
= np
->exts
[rqnext
];
83 lf
->count
-= (getnettime() - lf
->created
) / (RQ_SPAMBLOCK
/ RQ_SPAMCOUNT
);
88 if (lf
->count
> RQ_SPAMCOUNT
&& lf
->expire
> getnettime()) {
93 if (lf
->count
> RQ_SPAMCOUNT
) {
94 lf
->expire
= getnettime() + RQ_SPAMBLOCK
;
96 rq_addblock(np
->authname
, "Flooding the request system.", "request", 0, getnettime() + 3600);
106 time_t rq_blocktime(nick
*np
) {
107 if (np
->exts
[rqnext
] == NULL
)
110 return ((rq_flood
*)np
->exts
[rqnext
])->expire
- getnettime();
113 rq_block
*rq_findblock(const char *pattern
) {
117 for (i
= rqblocks
.cursi
- 1; i
>= 0; i
--) {
118 block
= ((rq_block
*)rqblocks
.content
)[i
];
120 if (match2strings(block
.pattern
->content
, pattern
)) {
121 if (block
.expires
!= 0 && block
.expires
< getnettime())
122 rq_removeblock(block
.pattern
->content
);
124 return &(((rq_block
*)rqblocks
.content
)[i
]);
131 void rq_addblock(const char *pattern
, const char *reason
, const char *creator
, time_t created
, time_t expires
) {
135 if (rq_findblock(pattern
) != NULL
)
138 slot
= array_getfreeslot(&rqblocks
);
140 block
= &(((rq_block
*)rqblocks
.content
)[slot
]);
142 block
->pattern
= getsstring(pattern
, CHANNELLEN
);
143 block
->reason
= getsstring(reason
, RQ_BLOCKLEN
);
144 block
->creator
= getsstring(creator
, ACCOUNTLEN
);
145 block
->created
= created
== 0 ? getnettime() : created
;
146 block
->expires
= expires
;
151 int rq_removeblock(const char *pattern
) {
155 for (i
= 0; i
< rqblocks
.cursi
; i
++) {
156 block
= ((rq_block
*)rqblocks
.content
)[i
];
158 if (ircd_strcmp(block
.pattern
->content
, pattern
) == 0) {
159 freesstring(block
.pattern
);
160 freesstring(block
.reason
);
161 freesstring(block
.creator
);
163 array_delslot(&rqblocks
, i
);
174 /* pattern reason creator created expires */
175 int rq_parseline(char *line
) {
176 char pattern
[CHANNELLEN
+1];
177 char reason
[RQ_BLOCKLEN
+1];
178 char creator
[ACCOUNTLEN
+1];
179 time_t created
, expires
;
181 if (sscanf(line
, "%s %s %lu %lu %[^\n]", pattern
, creator
, &created
, &expires
, reason
) < 2) /* \n won't be there anyway, but %s won't return the whole string */
182 return 0; /* invalid block */
184 /* tell rq_addblock that it should not save the blocks to disk this time */
186 rq_addblock(pattern
, reason
, creator
, created
, expires
);
192 int rq_loadblocks(void) {
197 rqdata
= fopen(RQ_BLOCKFILE
, "r");
204 while (!feof(rqdata
)) {
205 if (fgets(line
, sizeof(line
), rqdata
) == NULL
)
208 if (line
[strlen(line
) - 1] == '\n')
209 line
[strlen(line
) - 1] = '\0';
211 if (line
[strlen(line
) - 1] == '\r')
212 line
[strlen(line
) - 1] = '\0';
214 if (line
[0] != '\0') {
215 if (rq_parseline(line
))
225 int rq_saveblocks(void) {
229 /* don't save the blocks if we're currently loading them from the disk */
233 rqdata
= fopen(RQ_BLOCKFILE
, "w");
240 for (i
= 0; i
< rqblocks
.cursi
; i
++) {
241 block
= ((rq_block
*)rqblocks
.content
)[i
];
243 fprintf(rqdata
, "%s %s %lu %lu %s\n", block
.pattern
->content
, block
.creator
->content
, block
.created
, block
.expires
, block
.reason
->content
);