2 * IRC - Internet Relay Chat, ircd/jupe.c
3 * Copyright (C) 1990 Jarkko Oikarinen and
4 * University of Oulu, Finland
5 * Copyright (C) 2000 Kevin L. Mitchell <klmitch@mit.edu>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 1, or (at your option)
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include "ircd_alloc.h"
28 #include "ircd_string.h"
38 #include "sys.h" /* FALSE bleah */
42 static struct Jupe* GlobalJupeList = 0;
45 make_jupe(char *server, char *reason, time_t expire, time_t lastmod,
50 ajupe = (struct Jupe*) MyMalloc(sizeof(struct Jupe)); /* alloc memory */
53 DupString(ajupe->ju_server, server); /* copy vital information */
54 DupString(ajupe->ju_reason, reason);
55 ajupe->ju_expire = expire;
56 ajupe->ju_lastmod = lastmod;
57 ajupe->ju_flags = flags; /* set jupe flags */
59 ajupe->ju_next = GlobalJupeList; /* link it into the list */
60 ajupe->ju_prev_p = &GlobalJupeList;
62 GlobalJupeList->ju_prev_p = &ajupe->ju_next;
63 GlobalJupeList = ajupe;
69 do_jupe(struct Client *cptr, struct Client *sptr, struct Jupe *jupe)
73 if (!JupeIsActive(jupe)) /* no action to be taken on inactive jupes */
76 acptr = FindServer(jupe->ju_server);
78 /* server isn't online or isn't local or is me */
79 if (!acptr || !MyConnect(acptr) || IsMe(acptr))
82 return exit_client_msg(cptr, acptr, &me, "Juped: %s", jupe->ju_reason);
86 propagate_jupe(struct Client *cptr, struct Client *sptr, struct Jupe *jupe)
88 if (JupeIsLocal(jupe)) /* don't propagate local jupes */
91 if (IsUser(sptr)) /* select correct prefix */
92 sendto_serv_butone(cptr, "%s%s " TOK_JUPE " * %c%s " TIME_T_FMT " "
93 TIME_T_FMT " :%s", NumNick(sptr),
94 JupeIsActive(jupe) ? '+' : '-', jupe->ju_server,
95 jupe->ju_expire - TStime(), jupe->ju_lastmod,
98 sendto_serv_butone(cptr, "%s " TOK_JUPE " * %c%s " TIME_T_FMT " "
99 TIME_T_FMT " :%s", NumServ(sptr),
100 JupeIsActive(jupe) ? '+' : '-', jupe->ju_server,
101 jupe->ju_expire - TStime(), jupe->ju_lastmod,
106 jupe_add(struct Client *cptr, struct Client *sptr, char *server, char *reason,
107 time_t expire, time_t lastmod, int local, int active)
110 unsigned int flags = 0;
116 * You cannot set a negative (or zero) expire time, nor can you set an
117 * expiration time for greater than JUPE_MAX_EXPIRE.
119 if (expire <= 0 || expire > JUPE_MAX_EXPIRE) {
120 if (!IsServer(cptr) && MyConnect(cptr))
121 sendto_one(cptr, err_str(ERR_BADEXPIRE), me.name, cptr->name, expire);
125 expire += TStime(); /* convert from lifetime to timestamp */
127 /* Inform ops and log it */
128 if (IsServer(sptr)) {
129 sendto_op_mask(SNO_NETWORK, "%s adding %sJUPE for %s, expiring at "
130 TIME_T_FMT ": %s", sptr->name, local ? "local " : "",
131 server, expire, reason);
133 write_log(JPATH, TIME_T_FMT " %s adding %sJUPE for %s, expiring at "
134 TIME_T_FMT ": %s\n", TStime(), sptr->name,
135 local ? "local " : "", server, expire, reason);
138 sendto_op_mask(SNO_NETWORK, "%s adding %sJUPE for %s, expiring at "
139 TIME_T_FMT ": %s", sptr->user->server->name,
140 local ? "local " : "", server, expire,
143 write_log(JPATH, TIME_T_FMT, " %s!%s@%s adding %sJUPE for %s, expiring at "
144 TIME_T_FMT ": %s\n", TStime(), sptr->name, sptr->user->username,
145 sptr->user->host, local ? "local " : "", server, expire, reason);
149 if (active) /* compute initial flags */
150 flags |= JUPE_ACTIVE;
155 ajupe = make_jupe(server, reason, expire, lastmod, flags);
157 propagate_jupe(cptr, sptr, ajupe);
159 return do_jupe(cptr, sptr, ajupe); /* remove server if necessary */
163 jupe_activate(struct Client *cptr, struct Client *sptr, struct Jupe *jupe,
168 jupe->ju_flags |= JUPE_ACTIVE;
169 jupe->ju_lastmod = lastmod;
171 /* Inform ops and log it */
172 if (IsServer(sptr)) {
173 sendto_op_mask(SNO_NETWORK, "%s activating %sJUPE for %s, expiring at "
174 TIME_T_FMT ": %s", sptr->name, JupeIsLocal(jupe) ?
175 "local " : "", jupe->ju_server, jupe->ju_expire,
178 write_log(JPATH, TIME_T_FMT " %s activating %sJUPE for %s, expiring at "
179 TIME_T_FMT ": %s\n", TStime(), sptr->name, JupeIsLocal(jupe) ?
180 "local " : "", jupe->ju_server, jupe->ju_expire,
184 sendto_op_mask(SNO_NETWORK, "%s activating %sJUPE for %s, expiring at "
185 TIME_T_FMT ": %s", sptr->user->server->name,
186 JupeIsLocal(jupe) ? "local " : "", jupe->ju_server,
187 jupe->ju_expire, jupe->ju_reason);
189 write_log(JPATH, TIME_T_FMT, " %s!%s@%s activating %sJUPE for %s, "
190 "expiring at " TIME_T_FMT ": %s\n", TStime(), sptr->name,
191 sptr->user->username, sptr->user->host, JupeIsLocal(jupe) ?
192 "local " : "", jupe->ju_server, jupe->ju_expire,
197 propagate_jupe(cptr, sptr, jupe);
199 return do_jupe(cptr, sptr, jupe);
203 jupe_deactivate(struct Client *cptr, struct Client *sptr, struct Jupe *jupe,
208 jupe->ju_flags &= ~JUPE_ACTIVE;
209 jupe->ju_lastmod = lastmod;
211 /* Inform ops and log it */
212 if (IsServer(sptr)) {
213 sendto_op_mask(SNO_NETWORK, "%s deactivating %sJUPE for %s, expiring at "
214 TIME_T_FMT ": %s", sptr->name, JupeIsLocal(jupe) ?
215 "local " : "", jupe->ju_server, jupe->ju_expire,
218 write_log(JPATH, TIME_T_FMT " %s deactivating %sJUPE for %s, expiring at "
219 TIME_T_FMT ": %s\n", TStime(), sptr->name, JupeIsLocal(jupe) ?
220 "local " : "", jupe->ju_server, jupe->ju_expire,
224 sendto_op_mask(SNO_NETWORK, "%s deactivating %sJUPE for %s, expiring at "
225 TIME_T_FMT ": %s", sptr->user->server->name,
226 JupeIsLocal(jupe) ? "local " : "", jupe->ju_server,
227 jupe->ju_expire, jupe->ju_reason);
229 write_log(JPATH, TIME_T_FMT, " %s!%s@%s deactivating %sJUPE for %s, "
230 "expiring at " TIME_T_FMT ": %s\n", TStime(), sptr->name,
231 sptr->user->username, sptr->user->host, JupeIsLocal(jupe) ?
232 "local " : "", jupe->ju_server, jupe->ju_expire,
237 propagate_jupe(cptr, sptr, jupe);
243 jupe_find(char *server)
248 for (jupe = GlobalJupeList; jupe; jupe = sjupe) { /* go through jupes */
249 sjupe = jupe->ju_next;
251 if (jupe->ju_expire <= TStime()) /* expire any that need expiring */
253 else if (0 == ircd_strcmp(server, jupe->ju_server)) /* found it yet? */
261 jupe_free(struct Jupe* jupe)
265 *jupe->ju_prev_p = jupe->ju_next; /* squeeze this jupe out */
267 jupe->ju_next->ju_prev_p = jupe->ju_prev_p;
269 MyFree(jupe->ju_server); /* and free up the memory */
270 MyFree(jupe->ju_reason);
275 jupe_burst(struct Client *cptr)
280 for (jupe = GlobalJupeList; jupe; jupe = sjupe) { /* go through jupes */
281 sjupe = jupe->ju_next;
283 if (jupe->ju_expire <= TStime()) /* expire any that need expiring */
285 else if (!JupeIsLocal(jupe)) /* forward global jupes */
286 sendto_one(cptr, "%s " TOK_JUPE " * %c%s "TIME_T_FMT" "TIME_T_FMT" :%s",
287 NumServ(&me), JupeIsActive(jupe) ? '+' : '-',
288 jupe->ju_server, jupe->ju_expire - TStime(),
289 jupe->ju_lastmod, jupe->ju_reason);
294 jupe_resend(struct Client *cptr, struct Jupe *jupe)
296 if (JupeIsLocal(jupe)) /* don't propagate local jupes */
299 sendto_one(cptr, "%s " TOK_JUPE " * %c%s " TIME_T_FMT " " TIME_T_FMT " :%s",
300 NumServ(&me), JupeIsActive(jupe) ? '+' : '-', jupe->ju_server,
301 jupe->ju_expire - TStime(), jupe->ju_lastmod, jupe->ju_reason);
307 jupe_list(struct Client *sptr, char *server)
313 if (!(jupe = jupe_find(server))) { /* no such jupe */
314 sendto_one(sptr, err_str(ERR_NOSUCHJUPE), me.name, sptr->name, server);
318 /* send jupe information along */
319 sendto_one(sptr, rpl_str(RPL_JUPELIST), me.name, sptr->name,
320 jupe->ju_server, jupe->ju_expire, JupeIsLocal(jupe) ?
321 me.name : "*", JupeIsActive(jupe) ? '+' : '-', jupe->ju_reason);
323 for (jupe = GlobalJupeList; jupe; jupe = sjupe) { /* go through jupes */
324 sjupe = jupe->ju_next;
326 if (jupe->ju_expire <= TStime()) /* expire any that need expiring */
328 else /* send jupe information along */
329 sendto_one(sptr, rpl_str(RPL_JUPELIST), me.name, sptr->name,
330 jupe->ju_server, jupe->ju_expire, JupeIsLocal(jupe) ?
331 me.name : "*", JupeIsActive(jupe) ? '+' : '-',
336 /* end of jupe information */
337 sendto_one(sptr, rpl_str(RPL_ENDOFJUPELIST), me.name, sptr->name);