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_reply.h"
29 #include "ircd_string.h"
39 #include "sys.h" /* FALSE bleah */
43 static struct Jupe* GlobalJupeList = 0;
46 make_jupe(char *server, char *reason, time_t expire, time_t lastmod,
51 ajupe = (struct Jupe*) MyMalloc(sizeof(struct Jupe)); /* alloc memory */
54 DupString(ajupe->ju_server, server); /* copy vital information */
55 DupString(ajupe->ju_reason, reason);
56 ajupe->ju_expire = expire;
57 ajupe->ju_lastmod = lastmod;
58 ajupe->ju_flags = flags; /* set jupe flags */
60 ajupe->ju_next = GlobalJupeList; /* link it into the list */
61 ajupe->ju_prev_p = &GlobalJupeList;
63 GlobalJupeList->ju_prev_p = &ajupe->ju_next;
64 GlobalJupeList = ajupe;
70 do_jupe(struct Client *cptr, struct Client *sptr, struct Jupe *jupe)
74 if (!JupeIsActive(jupe)) /* no action to be taken on inactive jupes */
77 acptr = FindServer(jupe->ju_server);
79 /* server isn't online or isn't local or is me */
80 if (!acptr || !MyConnect(acptr) || IsMe(acptr))
83 return exit_client_msg(cptr, acptr, &me, "Juped: %s", jupe->ju_reason);
87 propagate_jupe(struct Client *cptr, struct Client *sptr, struct Jupe *jupe)
89 if (JupeIsLocal(jupe)) /* don't propagate local jupes */
92 sendcmdto_serv_butone(cptr, CMD_JUPE, sptr, "* %c%s %Tu %Tu :%s",
93 JupeIsActive(jupe) ? '+' : '-', jupe->ju_server,
94 jupe->ju_expire - TStime(), jupe->ju_lastmod,
99 jupe_add(struct Client *cptr, struct Client *sptr, char *server, char *reason,
100 time_t expire, time_t lastmod, int local, int active)
103 unsigned int flags = 0;
109 * You cannot set a negative (or zero) expire time, nor can you set an
110 * expiration time for greater than JUPE_MAX_EXPIRE.
112 if (expire <= 0 || expire > JUPE_MAX_EXPIRE) {
113 if (!IsServer(cptr) && MyConnect(cptr))
114 send_error_to_client(cptr, ERR_BADEXPIRE, expire);
118 expire += TStime(); /* convert from lifetime to timestamp */
120 /* Inform ops and log it */
121 if (IsServer(sptr)) {
122 sendto_op_mask(SNO_NETWORK, "%s adding %sJUPE for %s, expiring at "
123 TIME_T_FMT ": %s", sptr->name, local ? "local " : "",
124 server, expire, reason);
126 write_log(JPATH, TIME_T_FMT " %s adding %sJUPE for %s, expiring at "
127 TIME_T_FMT ": %s\n", TStime(), sptr->name,
128 local ? "local " : "", server, expire, reason);
131 sendto_op_mask(SNO_NETWORK, "%s adding %sJUPE for %s, expiring at "
132 TIME_T_FMT ": %s", sptr->user->server->name,
133 local ? "local " : "", server, expire,
136 write_log(JPATH, TIME_T_FMT, " %s!%s@%s adding %sJUPE for %s, expiring at "
137 TIME_T_FMT ": %s\n", TStime(), sptr->name, sptr->user->username,
138 sptr->user->host, local ? "local " : "", server, expire, reason);
142 if (active) /* compute initial flags */
143 flags |= JUPE_ACTIVE;
148 ajupe = make_jupe(server, reason, expire, lastmod, flags);
150 propagate_jupe(cptr, sptr, ajupe);
152 return do_jupe(cptr, sptr, ajupe); /* remove server if necessary */
156 jupe_activate(struct Client *cptr, struct Client *sptr, struct Jupe *jupe,
161 jupe->ju_flags |= JUPE_ACTIVE;
162 jupe->ju_lastmod = lastmod;
164 /* Inform ops and log it */
165 if (IsServer(sptr)) {
166 sendto_op_mask(SNO_NETWORK, "%s activating %sJUPE for %s, expiring at "
167 TIME_T_FMT ": %s", sptr->name, JupeIsLocal(jupe) ?
168 "local " : "", jupe->ju_server, jupe->ju_expire,
171 write_log(JPATH, TIME_T_FMT " %s activating %sJUPE for %s, expiring at "
172 TIME_T_FMT ": %s\n", TStime(), sptr->name, JupeIsLocal(jupe) ?
173 "local " : "", jupe->ju_server, jupe->ju_expire,
177 sendto_op_mask(SNO_NETWORK, "%s activating %sJUPE for %s, expiring at "
178 TIME_T_FMT ": %s", sptr->user->server->name,
179 JupeIsLocal(jupe) ? "local " : "", jupe->ju_server,
180 jupe->ju_expire, jupe->ju_reason);
182 write_log(JPATH, TIME_T_FMT, " %s!%s@%s activating %sJUPE for %s, "
183 "expiring at " TIME_T_FMT ": %s\n", TStime(), sptr->name,
184 sptr->user->username, sptr->user->host, JupeIsLocal(jupe) ?
185 "local " : "", jupe->ju_server, jupe->ju_expire,
190 propagate_jupe(cptr, sptr, jupe);
192 return do_jupe(cptr, sptr, jupe);
196 jupe_deactivate(struct Client *cptr, struct Client *sptr, struct Jupe *jupe,
201 jupe->ju_flags &= ~JUPE_ACTIVE;
202 jupe->ju_lastmod = lastmod;
204 /* Inform ops and log it */
205 if (IsServer(sptr)) {
206 sendto_op_mask(SNO_NETWORK, "%s deactivating %sJUPE for %s, expiring at "
207 TIME_T_FMT ": %s", sptr->name, JupeIsLocal(jupe) ?
208 "local " : "", jupe->ju_server, jupe->ju_expire,
211 write_log(JPATH, TIME_T_FMT " %s deactivating %sJUPE for %s, expiring at "
212 TIME_T_FMT ": %s\n", TStime(), sptr->name, JupeIsLocal(jupe) ?
213 "local " : "", jupe->ju_server, jupe->ju_expire,
217 sendto_op_mask(SNO_NETWORK, "%s deactivating %sJUPE for %s, expiring at "
218 TIME_T_FMT ": %s", sptr->user->server->name,
219 JupeIsLocal(jupe) ? "local " : "", jupe->ju_server,
220 jupe->ju_expire, jupe->ju_reason);
222 write_log(JPATH, TIME_T_FMT, " %s!%s@%s deactivating %sJUPE for %s, "
223 "expiring at " TIME_T_FMT ": %s\n", TStime(), sptr->name,
224 sptr->user->username, sptr->user->host, JupeIsLocal(jupe) ?
225 "local " : "", jupe->ju_server, jupe->ju_expire,
230 propagate_jupe(cptr, sptr, jupe);
236 jupe_find(char *server)
241 for (jupe = GlobalJupeList; jupe; jupe = sjupe) { /* go through jupes */
242 sjupe = jupe->ju_next;
244 if (jupe->ju_expire <= TStime()) /* expire any that need expiring */
246 else if (0 == ircd_strcmp(server, jupe->ju_server)) /* found it yet? */
254 jupe_free(struct Jupe* jupe)
258 *jupe->ju_prev_p = jupe->ju_next; /* squeeze this jupe out */
260 jupe->ju_next->ju_prev_p = jupe->ju_prev_p;
262 MyFree(jupe->ju_server); /* and free up the memory */
263 MyFree(jupe->ju_reason);
268 jupe_burst(struct Client *cptr)
273 for (jupe = GlobalJupeList; jupe; jupe = sjupe) { /* go through jupes */
274 sjupe = jupe->ju_next;
276 if (jupe->ju_expire <= TStime()) /* expire any that need expiring */
278 else if (!JupeIsLocal(jupe)) /* forward global jupes */
279 sendcmdto_one(cptr, CMD_JUPE, &me, "* %c%s %Tu %Tu :%s",
280 JupeIsActive(jupe) ? '+' : '-', jupe->ju_server,
281 jupe->ju_expire - TStime(), jupe->ju_lastmod,
287 jupe_resend(struct Client *cptr, struct Jupe *jupe)
289 if (JupeIsLocal(jupe)) /* don't propagate local jupes */
292 sendcmdto_one(cptr, CMD_JUPE, &me, "* %c%s %Tu %Tu :%s",
293 JupeIsActive(jupe) ? '+' : '-', jupe->ju_server,
294 jupe->ju_expire - TStime(), jupe->ju_lastmod, jupe->ju_reason);
300 jupe_list(struct Client *sptr, char *server)
306 if (!(jupe = jupe_find(server))) /* no such jupe */
307 return send_error_to_client(sptr, ERR_NOSUCHJUPE, server);
309 /* send jupe information along */
310 sendto_one(sptr, rpl_str(RPL_JUPELIST), me.name, sptr->name,
311 jupe->ju_server, jupe->ju_expire, JupeIsLocal(jupe) ?
312 me.name : "*", JupeIsActive(jupe) ? '+' : '-', jupe->ju_reason);
314 for (jupe = GlobalJupeList; jupe; jupe = sjupe) { /* go through jupes */
315 sjupe = jupe->ju_next;
317 if (jupe->ju_expire <= TStime()) /* expire any that need expiring */
319 else /* send jupe information along */
320 sendto_one(sptr, rpl_str(RPL_JUPELIST), me.name, sptr->name,
321 jupe->ju_server, jupe->ju_expire, JupeIsLocal(jupe) ?
322 me.name : "*", JupeIsActive(jupe) ? '+' : '-',
327 /* end of jupe information */
328 sendto_one(sptr, rpl_str(RPL_ENDOFJUPELIST), me.name, sptr->name);