]>
Commit | Line | Data |
---|---|---|
01250ca8 | 1 | #include <stdlib.h> |
7d4c3792 | 2 | #include <stdint.h> |
01250ca8 P |
3 | #include <sys/time.h> |
4 | ||
5 | #include "../core/hooks.h" | |
6 | #include "../lib/sstring.h" | |
7 | #include "../server/server.h" | |
8 | #include "../irc/irc.h" | |
9 | #include "../core/error.h" | |
10 | #include "../lib/irc_string.h" | |
11 | #include "jupe.h" | |
12 | ||
cf1c4f02 | 13 | jupe_t *jupes = NULL; |
01250ca8 P |
14 | |
15 | int handlejupe(void *source, int cargc, char **cargv); | |
16 | void sendjupeburst(int hook, void *args); | |
17 | ||
18 | void _init() { | |
5b9636e0 P |
19 | /* If we're connected to IRC, force a disconnect. */ |
20 | if (connected) { | |
21 | irc_send("%s SQ %s 0 :Resync [adding jupe support]", mynumeric->content, myserver->content); | |
22 | irc_disconnected(); | |
23 | } | |
24 | ||
64bf1b4e | 25 | registerhook(HOOK_IRC_SENDBURSTBURSTS, &sendjupeburst); |
01250ca8 | 26 | |
64bf1b4e | 27 | registerserverhandler("JU", &handlejupe, 5); |
01250ca8 P |
28 | } |
29 | ||
30 | void _fini() { | |
64bf1b4e | 31 | jupe_t *next; |
01250ca8 | 32 | |
64bf1b4e P |
33 | while (jupes) { |
34 | /* keep a pointer to the next item */ | |
35 | next = jupes->ju_next; | |
01250ca8 | 36 | |
64bf1b4e | 37 | free(jupes); |
01250ca8 | 38 | |
64bf1b4e P |
39 | jupes = next; |
40 | } | |
01250ca8 | 41 | |
64bf1b4e | 42 | deregisterhook(HOOK_IRC_SENDBURSTBURSTS, &sendjupeburst); |
01250ca8 | 43 | |
64bf1b4e | 44 | deregisterserverhandler("JU", &handlejupe); |
01250ca8 P |
45 | } |
46 | ||
47 | int handlejupe(void *source, int cargc, char **cargv) { | |
64bf1b4e P |
48 | char *server, *expire, *modtime, *reason; |
49 | jupe_t *jupe; | |
50 | unsigned int flags; | |
01250ca8 | 51 | |
64bf1b4e P |
52 | if (cargc < 5) |
53 | return CMD_OK; /* local jupe or not a valid.. we don't care */ | |
01250ca8 | 54 | |
64bf1b4e P |
55 | server = cargv[1]; |
56 | expire = cargv[2]; | |
57 | modtime = cargv[3]; | |
58 | reason = cargv[4]; | |
01250ca8 | 59 | |
64bf1b4e P |
60 | if (atoi(expire) > JUPE_MAX_EXPIRE || atoi(expire) <= 0) |
61 | return CMD_ERROR; /* jupe's expiry date is not valid */ | |
01250ca8 | 62 | |
64bf1b4e P |
63 | if (server[0] != '+' && server[0] != '-') |
64 | return CMD_OK; /* not a valid jupe either */ | |
65 | else { | |
66 | flags = (server[0] == '+') ? JUPE_ACTIVE : 0; | |
67 | server++; | |
68 | } | |
01250ca8 | 69 | |
64bf1b4e | 70 | jupe = jupe_find(server); |
01250ca8 | 71 | |
64bf1b4e P |
72 | if (jupe != NULL && atoi(modtime) > jupe->ju_lastmod) { |
73 | jupe->ju_flags = flags; | |
74 | jupe->ju_lastmod = atoi(modtime); | |
01250ca8 | 75 | |
143e1ccd | 76 | Error("jupe", ERR_INFO, "jupe modified for %s (%s) expiring in %s," |
64bf1b4e P |
77 | " lastmod: %s, active: %s", server, reason, expire, modtime, flags ? "yes" : "no"); |
78 | return CMD_OK; | |
79 | } | |
01250ca8 | 80 | |
64bf1b4e | 81 | jupe = make_jupe(server, reason, getnettime() + atoi(expire), atoi(modtime), flags); |
01250ca8 | 82 | |
64bf1b4e P |
83 | if (jupe == NULL) |
84 | return CMD_ERROR; | |
01250ca8 | 85 | |
143e1ccd | 86 | Error("jupe", ERR_INFO, "jupe added for %s (%s) expiring in %s," |
64bf1b4e | 87 | " lastmod: %s, active: %s", server, reason, expire, modtime, flags ? "yes" : "no"); |
01250ca8 | 88 | |
64bf1b4e | 89 | return CMD_OK; |
01250ca8 P |
90 | } |
91 | ||
92 | void sendjupeburst(int hook, void *args) { | |
64bf1b4e | 93 | jupe_t *jupe = jupes; |
01250ca8 | 94 | |
64bf1b4e P |
95 | if (hook != HOOK_IRC_SENDBURSTBURSTS) |
96 | return; | |
01250ca8 | 97 | |
64bf1b4e P |
98 | while (jupe) { |
99 | jupe_propagate(jupe); | |
01250ca8 | 100 | |
64bf1b4e P |
101 | jupe = jupe->ju_next; |
102 | } | |
01250ca8 P |
103 | } |
104 | ||
105 | jupe_t *make_jupe(char *server, char *reason, time_t expirets, time_t lastmod, unsigned int flags) { | |
64bf1b4e | 106 | jupe_t *jupe; |
01250ca8 | 107 | |
64bf1b4e | 108 | jupe = (jupe_t*)malloc(sizeof(jupe_t)); |
01250ca8 | 109 | |
64bf1b4e P |
110 | if (jupe == NULL) |
111 | return NULL; | |
01250ca8 | 112 | |
64bf1b4e P |
113 | jupe->ju_server = getsstring(server, HOSTLEN); |
114 | jupe->ju_reason = getsstring(reason, TOPICLEN); | |
115 | jupe->ju_expire = expirets; | |
116 | jupe->ju_lastmod = lastmod; | |
117 | jupe->ju_flags = flags; | |
118 | jupe->ju_next = NULL; | |
01250ca8 | 119 | |
64bf1b4e P |
120 | /* add the jupe to our linked list */ |
121 | jupe->ju_next = jupes; | |
122 | jupes = jupe; | |
01250ca8 | 123 | |
64bf1b4e | 124 | return jupe; |
01250ca8 P |
125 | } |
126 | ||
127 | void jupe_propagate(jupe_t *jupe) { | |
64bf1b4e P |
128 | irc_send("%s JU * %c%s %jd %jd :%s", mynumeric->content, |
129 | JupeIsRemActive(jupe) ? '+' : '-', | |
130 | JupeServer(jupe), | |
131 | (intmax_t)(jupe->ju_expire - getnettime()), | |
132 | (intmax_t)JupeLastMod(jupe), | |
133 | JupeReason(jupe)); | |
01250ca8 P |
134 | } |
135 | ||
136 | void jupe_expire(void) { | |
64bf1b4e | 137 | jupe_find(NULL); |
01250ca8 P |
138 | } |
139 | ||
140 | jupe_t *jupe_find(char *server) { | |
64bf1b4e P |
141 | jupe_t *jupe = jupes; |
142 | ||
143 | while (jupe) { | |
144 | /* server == NULL if jupe_find() is used by jupe_expire */ | |
145 | if (server && ircd_strcmp(server, JupeServer(jupe)) == 0) | |
146 | return jupe; | |
01250ca8 | 147 | |
64bf1b4e P |
148 | if (jupe->ju_next && jupe->ju_next->ju_expire < getnettime()) |
149 | jupe_free(jupe->ju_next); | |
01250ca8 | 150 | |
64bf1b4e P |
151 | jupe = jupe->ju_next; |
152 | } | |
01250ca8 | 153 | |
64bf1b4e P |
154 | if (jupes && jupes->ju_expire < getnettime()) |
155 | jupe_free(jupes); | |
01250ca8 | 156 | |
64bf1b4e | 157 | return NULL; |
01250ca8 P |
158 | } |
159 | ||
160 | void jupe_free(jupe_t *jupe) { | |
64bf1b4e P |
161 | jupe_t *trav = jupes; |
162 | ||
163 | if (jupe == jupes) | |
164 | jupes = jupe->ju_next; | |
165 | else { | |
166 | while (trav) { | |
167 | if (trav->ju_next == jupe) { | |
168 | trav->ju_next = jupe->ju_next; | |
169 | break; | |
170 | } | |
171 | ||
172 | trav = trav->ju_next; | |
173 | } | |
174 | } | |
175 | ||
176 | freesstring(jupe->ju_server); | |
177 | freesstring(jupe->ju_reason); | |
178 | free(jupe); | |
01250ca8 P |
179 | } |
180 | ||
181 | void jupe_activate(jupe_t *jupe) { | |
64bf1b4e P |
182 | if (jupe->ju_flags & JUPE_ACTIVE) |
183 | return; | |
01250ca8 | 184 | |
64bf1b4e P |
185 | jupe->ju_flags |= JUPE_ACTIVE; |
186 | jupe->ju_lastmod = getnettime(); | |
01250ca8 | 187 | |
64bf1b4e | 188 | jupe_propagate(jupe); |
01250ca8 P |
189 | } |
190 | ||
191 | void jupe_deactivate(jupe_t *jupe) { | |
64bf1b4e P |
192 | if ((jupe->ju_flags & JUPE_ACTIVE) == 0) |
193 | return; | |
01250ca8 | 194 | |
64bf1b4e P |
195 | jupe->ju_flags &= ~JUPE_ACTIVE; |
196 | jupe->ju_lastmod = getnettime(); | |
01250ca8 | 197 | |
64bf1b4e | 198 | jupe_propagate(jupe); |
01250ca8 P |
199 | } |
200 | ||
201 | int jupe_add(char *server, char *reason, time_t duration, unsigned int flags) { | |
64bf1b4e | 202 | jupe_t *jupe; |
01250ca8 | 203 | |
64bf1b4e P |
204 | if (jupe_find(server) != NULL) |
205 | return 0; | |
206 | ||
207 | if (duration > JUPE_MAX_EXPIRE || duration <= 0) | |
208 | return 0; | |
01250ca8 | 209 | |
64bf1b4e | 210 | jupe = make_jupe(server, reason, getnettime() + duration, getnettime(), flags); |
143e1ccd | 211 | |
64bf1b4e P |
212 | if (jupe == NULL) |
213 | return 0; | |
01250ca8 | 214 | |
64bf1b4e | 215 | jupe_propagate(jupe); |
01250ca8 | 216 | |
64bf1b4e | 217 | return 1; |
01250ca8 | 218 | } |