]> jfr.im git - irc/quakenet/newserv.git/blame - request/request_fasttrack.c
A4STATS: remove E style escapes and switch to createtable for indices
[irc/quakenet/newserv.git] / request / request_fasttrack.c
CommitLineData
6fec1818
GB
1#include <stdio.h>
2#include <string.h>
3#include "../core/schedule.h"
4#include "../irc/irc.h"
5#include "../lib/irc_string.h"
6#include "request_fasttrack.h"
7
8typedef struct rq_fasttrack {
9 unsigned long userid;
10
11 unsigned int targets;
12 time_t refill_time;
13
14 struct rq_fasttrack *next;
15} rq_fasttrack;
16
17static rq_fasttrack *ftlist;
18
19/* our fast-track extension */
20int rqnext;
21
22static void rq_cleanup_fasttrack(void *arg);
23static void rqhook_account(int hook, void *arg);
24
25int rq_initfasttrack(void) {
26 rqnext = registernickext("request_fasttrack");
27 if(rqnext < 0)
28 return 0;
29
30 registerhook(HOOK_NICK_NEWNICK, &rqhook_account);
31 registerhook(HOOK_NICK_ACCOUNT, &rqhook_account);
32
33 schedulerecurring(time(NULL)+1, 0, 3600, rq_cleanup_fasttrack, NULL);
34
35 return 1;
36}
37
38void rq_finifasttrack(void) {
3bbec84c 39 rq_fasttrack *ft, *next;
6fec1818
GB
40
41 deregisterhook(HOOK_NICK_NEWNICK, &rqhook_account);
42 deregisterhook(HOOK_NICK_ACCOUNT, &rqhook_account);
43
3bbec84c
GB
44 for(ft=ftlist;ft;) {
45 next = ft->next;
6fec1818 46 free(ft);
3bbec84c
GB
47 ft = next;
48 }
6fec1818
GB
49
50 releasenickext(rqnext);
51}
52
53static void rqhook_account(int hook, void *arg) {
54 nick *np = (nick *)arg;
55 rq_fasttrack *ft;
56
1d763339
GB
57 np->exts[rqnext] = NULL;
58
6fec1818
GB
59 /* Auth might be null for the newnick hook. */
60 if(!np->auth)
61 return;
62
63 /* Try to find an existing fasttrack record for this user. */
64 for(ft=ftlist;ft;ft=ft->next) {
65 if(np->auth->userid==ft->userid) {
66 np->exts[rqnext] = ft;
67 break;
68 }
69 }
70}
71
72static void rq_cleanup_fasttrack(void *arg) {
fd1680f9 73 time_t now;
3bbec84c
GB
74 rq_fasttrack **pft, *ft;
75 int j;
76 nick *tnp;
77
78 now = getnettime();
79
4c51f2b4 80 for(pft=&ftlist;*pft;pft=&((*pft)->next)) {
3bbec84c 81 int foundnick = 0;
6fec1818 82
4c51f2b4
GB
83 ft = *pft;
84
3bbec84c
GB
85 for(j=0;j<NICKHASHSIZE && !foundnick;j++) {
86 for(tnp=nicktable[j];tnp;tnp=tnp->next) {
87 if(tnp->exts[rqnext]==ft) {
88 foundnick = 1;
89 break;
90 }
91 }
92 }
93
1543c3f8 94 if(!foundnick && ft->refill_time < now) {
3bbec84c
GB
95 *pft = ft->next;
96 free(ft);
97 }
a72ed70f
GB
98
99 if (!*pft)
100 break;
3bbec84c 101 }
6fec1818
GB
102}
103
104static rq_fasttrack *rq_getfasttrack(nick *np) {
105 rq_fasttrack *ft;
106
107 /* Use an existing fast-track record if the nick has one. */
108 if(np->exts[rqnext])
109 return np->exts[rqnext];
110
111 if(!np->auth)
112 return NULL;
113
114 ft = malloc(sizeof(rq_fasttrack));
115
116 if(!ft)
117 return NULL;
118
119 ft->userid = np->auth->userid;
120 ft->targets = 0;
121 ft->refill_time = 0;
122
3bbec84c
GB
123 ft->next = ftlist;
124 ftlist = ft;
125
6fec1818
GB
126 np->exts[rqnext] = ft;
127
128 return ft;
129}
130
131int rq_tryfasttrack(nick *np) {
132 rq_fasttrack *ft = rq_getfasttrack(np);
133
134 /* Don't fast-track if we can't find a fast-track record. */
135 if(!ft)
136 return 0;
137
138 /* Refill targets if necessary. */
139 if(getnettime() > ft->refill_time) {
140 ft->targets = RQ_FASTTRACK_TARGETS;
141 ft->refill_time = getnettime() + RQ_FASTTRACK_TIMEOUT;
142 }
143
144 /* Check if we have a free target. */
145 if(ft->targets==0)
146 return 0;
147
148 ft->targets--;
149 return 1;
150}
151