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.
29 #include "ircd_alloc.h"
30 #include "ircd_features.h"
32 #include "ircd_reply.h"
33 #include "ircd_string.h"
42 #include "sys.h" /* FALSE bleah */
47 static struct Jupe *GlobalJupeList = 0;
50 make_jupe(char *server, char *reason, time_t expire, time_t lastmod,
55 ajupe = (struct Jupe*) MyMalloc(sizeof(struct Jupe)); /* alloc memory */
58 DupString(ajupe->ju_server, server); /* copy vital information */
59 DupString(ajupe->ju_reason, reason);
60 ajupe->ju_expire = expire;
61 ajupe->ju_lastmod = lastmod;
62 ajupe->ju_flags = flags & JUPE_MASK; /* set jupe flags */
64 ajupe->ju_next = GlobalJupeList; /* link it into the list */
65 ajupe->ju_prev_p = &GlobalJupeList;
67 GlobalJupeList->ju_prev_p = &ajupe->ju_next;
68 GlobalJupeList = ajupe;
74 do_jupe(struct Client *cptr, struct Client *sptr, struct Jupe *jupe)
78 if (!JupeIsActive(jupe)) /* no action to be taken on inactive jupes */
81 acptr = FindServer(jupe->ju_server);
83 /* server isn't online or isn't local or is me */
84 if (!acptr || !MyConnect(acptr) || IsMe(acptr))
87 return exit_client_msg(cptr, acptr, &me, "Juped: %s", jupe->ju_reason);
91 propagate_jupe(struct Client *cptr, struct Client *sptr, struct Jupe *jupe)
93 if (JupeIsLocal(jupe)) /* don't propagate local jupes */
96 sendcmdto_serv_butone(sptr, CMD_JUPE, cptr, "* %c%s %Tu %Tu :%s",
97 JupeIsRemActive(jupe) ? '+' : '-', jupe->ju_server,
98 jupe->ju_expire - CurrentTime, jupe->ju_lastmod,
103 jupe_add(struct Client *cptr, struct Client *sptr, char *server, char *reason,
104 time_t expire, time_t lastmod, unsigned int flags)
112 * You cannot set a negative (or zero) expire time, nor can you set an
113 * expiration time for greater than JUPE_MAX_EXPIRE.
115 if (expire <= 0 || expire > JUPE_MAX_EXPIRE) {
116 if (!IsServer(cptr) && MyConnect(cptr))
117 send_reply(cptr, ERR_BADEXPIRE, expire);
121 expire += CurrentTime; /* convert from lifetime to timestamp */
123 /* Inform ops and log it */
124 sendto_opmask_butone(0, SNO_NETWORK, "%s adding %sJUPE for %s, expiring at "
126 (feature_bool(FEAT_HIS_SNOTICES) || IsServer(sptr)) ?
128 cli_name((cli_user(sptr))->server),
129 flags & JUPE_LOCAL ? "local " : "", server,
130 expire + TSoffset, reason);
132 log_write(LS_JUPE, L_INFO, LOG_NOSNOTICE,
133 "%#C adding %sJUPE for %s, expiring at %Tu: %s", sptr,
134 flags & JUPE_LOCAL ? "local " : "", server, expire + TSoffset,
138 ajupe = make_jupe(server, reason, expire, lastmod, flags);
140 propagate_jupe(cptr, sptr, ajupe);
142 return do_jupe(cptr, sptr, ajupe); /* remove server if necessary */
146 jupe_activate(struct Client *cptr, struct Client *sptr, struct Jupe *jupe,
147 time_t lastmod, unsigned int flags)
149 unsigned int saveflags = 0;
153 saveflags = jupe->ju_flags;
155 if (flags & JUPE_LOCAL)
156 jupe->ju_flags &= ~JUPE_LDEACT;
158 jupe->ju_flags |= JUPE_ACTIVE;
160 if (jupe->ju_lastmod >= lastmod) /* force lastmod to increase */
163 jupe->ju_lastmod = lastmod;
166 if ((saveflags & JUPE_ACTMASK) == JUPE_ACTIVE)
167 return 0; /* was active to begin with */
169 /* Inform ops and log it */
170 sendto_opmask_butone(0, SNO_NETWORK, "%s activating JUPE for %s, expiring "
172 (feature_bool(FEAT_HIS_SNOTICES) || IsServer(sptr)) ?
174 cli_name((cli_user(sptr))->server),
175 jupe->ju_server, jupe->ju_expire + TSoffset,
178 log_write(LS_JUPE, L_INFO, LOG_NOSNOTICE,
179 "%#C activating JUPE for %s, expiring at %Tu: %s",sptr,
180 jupe->ju_server, jupe->ju_expire + TSoffset, jupe->ju_reason);
182 if (!(flags & JUPE_LOCAL)) /* don't propagate local changes */
183 propagate_jupe(cptr, sptr, jupe);
185 return do_jupe(cptr, sptr, jupe);
189 jupe_deactivate(struct Client *cptr, struct Client *sptr, struct Jupe *jupe,
190 time_t lastmod, unsigned int flags)
192 unsigned int saveflags = 0;
196 saveflags = jupe->ju_flags;
198 if (!JupeIsLocal(jupe)) {
199 if (flags & JUPE_LOCAL)
200 jupe->ju_flags |= JUPE_LDEACT;
202 jupe->ju_flags &= ~JUPE_ACTIVE;
204 if (jupe->ju_lastmod >= lastmod) /* force lastmod to increase */
207 jupe->ju_lastmod = lastmod;
210 if ((saveflags & JUPE_ACTMASK) != JUPE_ACTIVE)
211 return 0; /* was inactive to begin with */
214 /* Inform ops and log it */
215 sendto_opmask_butone(0, SNO_NETWORK, "%s %s JUPE for %s, expiring at %Tu: "
217 (feature_bool(FEAT_HIS_SNOTICES) || IsServer(sptr)) ?
219 cli_name((cli_user(sptr))->server),
220 JupeIsLocal(jupe) ? "removing local" : "deactivating",
221 jupe->ju_server, jupe->ju_expire + TSoffset,
224 log_write(LS_JUPE, L_INFO, LOG_NOSNOTICE,
225 "%#C %s JUPE for %s, expiring at %Tu: %s", sptr,
226 JupeIsLocal(jupe) ? "removing local" : "deactivating",
227 jupe->ju_server, jupe->ju_expire + TSoffset, jupe->ju_reason);
229 if (JupeIsLocal(jupe))
231 else if (!(flags & JUPE_LOCAL)) /* don't propagate local changes */
232 propagate_jupe(cptr, sptr, jupe);
238 jupe_find(char *server)
243 for (jupe = GlobalJupeList; jupe; jupe = sjupe) { /* go through jupes */
244 sjupe = jupe->ju_next;
246 if (jupe->ju_expire <= CurrentTime) /* expire any that need expiring */
248 else if (0 == ircd_strcmp(server, jupe->ju_server)) /* found it yet? */
256 jupe_free(struct Jupe* jupe)
260 *jupe->ju_prev_p = jupe->ju_next; /* squeeze this jupe out */
262 jupe->ju_next->ju_prev_p = jupe->ju_prev_p;
264 MyFree(jupe->ju_server); /* and free up the memory */
265 MyFree(jupe->ju_reason);
270 jupe_burst(struct Client *cptr)
275 for (jupe = GlobalJupeList; jupe; jupe = sjupe) { /* go through jupes */
276 sjupe = jupe->ju_next;
278 if (jupe->ju_expire <= CurrentTime) /* expire any that need expiring */
280 else if (!JupeIsLocal(jupe)) /* forward global jupes */
281 sendcmdto_one(&me, CMD_JUPE, cptr, "* %c%s %Tu %Tu :%s",
282 JupeIsRemActive(jupe) ? '+' : '-', jupe->ju_server,
283 jupe->ju_expire - CurrentTime, jupe->ju_lastmod,
289 jupe_resend(struct Client *cptr, struct Jupe *jupe)
291 if (JupeIsLocal(jupe)) /* don't propagate local jupes */
294 sendcmdto_one(&me, CMD_JUPE, cptr, "* %c%s %Tu %Tu :%s",
295 JupeIsRemActive(jupe) ? '+' : '-', jupe->ju_server,
296 jupe->ju_expire - CurrentTime, jupe->ju_lastmod,
303 jupe_list(struct Client *sptr, char *server)
309 if (!(jupe = jupe_find(server))) /* no such jupe */
310 return send_reply(sptr, ERR_NOSUCHJUPE, server);
312 /* send jupe information along */
313 send_reply(sptr, RPL_JUPELIST, jupe->ju_server, jupe->ju_expire + TSoffset,
314 JupeIsLocal(jupe) ? cli_name(&me) : "*",
315 JupeIsActive(jupe) ? '+' : '-', jupe->ju_reason);
317 for (jupe = GlobalJupeList; jupe; jupe = sjupe) { /* go through jupes */
318 sjupe = jupe->ju_next;
320 if (jupe->ju_expire <= CurrentTime) /* expire any that need expiring */
322 else /* send jupe information along */
323 send_reply(sptr, RPL_JUPELIST, jupe->ju_server,
324 jupe->ju_expire + TSoffset,
325 JupeIsLocal(jupe) ? cli_name(&me) : "*",
326 JupeIsActive(jupe) ? '+' : '-', jupe->ju_reason);
330 /* end of jupe information */
331 return send_reply(sptr, RPL_ENDOFJUPELIST);
335 jupe_memory_count(size_t *ju_size)
340 for (jupe = GlobalJupeList; jupe; jupe = jupe->ju_next)
343 *ju_size += sizeof(struct Jupe);
344 *ju_size += jupe->ju_server ? (strlen(jupe->ju_server) + 1) : 0;
345 *ju_size += jupe->ju_reason ? (strlen(jupe->ju_reason) + 1) : 0;