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"
43 #include "sys.h" /* FALSE bleah */
48 static struct Jupe *GlobalJupeList = 0;
51 make_jupe(char *server, char *reason, time_t expire, time_t lastmod,
56 ajupe = (struct Jupe*) MyMalloc(sizeof(struct Jupe)); /* alloc memory */
59 DupString(ajupe->ju_server, server); /* copy vital information */
60 DupString(ajupe->ju_reason, reason);
61 ajupe->ju_expire = expire;
62 ajupe->ju_lastmod = lastmod;
63 ajupe->ju_flags = flags & JUPE_MASK; /* set jupe flags */
65 ajupe->ju_next = GlobalJupeList; /* link it into the list */
66 ajupe->ju_prev_p = &GlobalJupeList;
68 GlobalJupeList->ju_prev_p = &ajupe->ju_next;
69 GlobalJupeList = ajupe;
75 do_jupe(struct Client *cptr, struct Client *sptr, struct Jupe *jupe)
79 if (!JupeIsActive(jupe)) /* no action to be taken on inactive jupes */
82 acptr = FindServer(jupe->ju_server);
84 /* server isn't online or isn't local or is me */
85 if (!acptr || !MyConnect(acptr) || IsMe(acptr))
88 return exit_client_msg(cptr, acptr, &me, "Juped: %s", jupe->ju_reason);
92 propagate_jupe(struct Client *cptr, struct Client *sptr, struct Jupe *jupe)
94 if (JupeIsLocal(jupe)) /* don't propagate local jupes */
97 sendcmdto_serv_butone(sptr, CMD_JUPE, cptr, "* %c%s %Tu %Tu :%s",
98 JupeIsRemActive(jupe) ? '+' : '-', jupe->ju_server,
99 jupe->ju_expire - CurrentTime, jupe->ju_lastmod,
104 jupe_add(struct Client *cptr, struct Client *sptr, char *server, char *reason,
105 time_t expire, time_t lastmod, unsigned int flags)
113 * You cannot set a negative (or zero) expire time, nor can you set an
114 * expiration time for greater than JUPE_MAX_EXPIRE.
116 if (expire <= 0 || expire > JUPE_MAX_EXPIRE) {
117 if (!IsServer(cptr) && MyConnect(cptr))
118 send_reply(cptr, ERR_BADEXPIRE, expire);
122 expire += CurrentTime; /* convert from lifetime to timestamp */
124 /* Inform ops and log it */
125 sendto_opmask_butone(0, SNO_NETWORK, "%s adding %sJUPE for %s, expiring at "
127 (feature_bool(FEAT_HIS_SNOTICES) || IsServer(sptr)) ?
129 cli_name((cli_user(sptr))->server),
130 flags & JUPE_LOCAL ? "local " : "", server,
131 expire + TSoffset, reason);
133 log_write(LS_JUPE, L_INFO, LOG_NOSNOTICE,
134 "%#C adding %sJUPE for %s, expiring at %Tu: %s", sptr,
135 flags & JUPE_LOCAL ? "local " : "", server, expire + TSoffset,
139 ajupe = make_jupe(server, reason, expire, lastmod, flags);
141 propagate_jupe(cptr, sptr, ajupe);
143 return do_jupe(cptr, sptr, ajupe); /* remove server if necessary */
147 jupe_activate(struct Client *cptr, struct Client *sptr, struct Jupe *jupe,
148 time_t lastmod, unsigned int flags)
150 unsigned int saveflags = 0;
154 saveflags = jupe->ju_flags;
156 if (flags & JUPE_LOCAL)
157 jupe->ju_flags &= ~JUPE_LDEACT;
159 jupe->ju_flags |= JUPE_ACTIVE;
161 if (jupe->ju_lastmod >= lastmod) /* force lastmod to increase */
164 jupe->ju_lastmod = lastmod;
167 if ((saveflags & JUPE_ACTMASK) == JUPE_ACTIVE)
168 return 0; /* was active to begin with */
170 /* Inform ops and log it */
171 sendto_opmask_butone(0, SNO_NETWORK, "%s activating JUPE for %s, expiring "
173 (feature_bool(FEAT_HIS_SNOTICES) || IsServer(sptr)) ?
175 cli_name((cli_user(sptr))->server),
176 jupe->ju_server, jupe->ju_expire + TSoffset,
179 log_write(LS_JUPE, L_INFO, LOG_NOSNOTICE,
180 "%#C activating JUPE for %s, expiring at %Tu: %s",sptr,
181 jupe->ju_server, jupe->ju_expire + TSoffset, jupe->ju_reason);
183 if (!(flags & JUPE_LOCAL)) /* don't propagate local changes */
184 propagate_jupe(cptr, sptr, jupe);
186 return do_jupe(cptr, sptr, jupe);
190 jupe_deactivate(struct Client *cptr, struct Client *sptr, struct Jupe *jupe,
191 time_t lastmod, unsigned int flags)
193 unsigned int saveflags = 0;
197 saveflags = jupe->ju_flags;
199 if (!JupeIsLocal(jupe)) {
200 if (flags & JUPE_LOCAL)
201 jupe->ju_flags |= JUPE_LDEACT;
203 jupe->ju_flags &= ~JUPE_ACTIVE;
205 if (jupe->ju_lastmod >= lastmod) /* force lastmod to increase */
208 jupe->ju_lastmod = lastmod;
211 if ((saveflags & JUPE_ACTMASK) != JUPE_ACTIVE)
212 return 0; /* was inactive to begin with */
215 /* Inform ops and log it */
216 sendto_opmask_butone(0, SNO_NETWORK, "%s %s JUPE for %s, expiring at %Tu: "
218 (feature_bool(FEAT_HIS_SNOTICES) || IsServer(sptr)) ?
220 cli_name((cli_user(sptr))->server),
221 JupeIsLocal(jupe) ? "removing local" : "deactivating",
222 jupe->ju_server, jupe->ju_expire + TSoffset,
225 log_write(LS_JUPE, L_INFO, LOG_NOSNOTICE,
226 "%#C %s JUPE for %s, expiring at %Tu: %s", sptr,
227 JupeIsLocal(jupe) ? "removing local" : "deactivating",
228 jupe->ju_server, jupe->ju_expire + TSoffset, jupe->ju_reason);
230 if (JupeIsLocal(jupe))
232 else if (!(flags & JUPE_LOCAL)) /* don't propagate local changes */
233 propagate_jupe(cptr, sptr, jupe);
239 jupe_find(char *server)
244 for (jupe = GlobalJupeList; jupe; jupe = sjupe) { /* go through jupes */
245 sjupe = jupe->ju_next;
247 if (jupe->ju_expire <= CurrentTime) /* expire any that need expiring */
249 else if (0 == ircd_strcmp(server, jupe->ju_server)) /* found it yet? */
257 jupe_free(struct Jupe* jupe)
261 *jupe->ju_prev_p = jupe->ju_next; /* squeeze this jupe out */
263 jupe->ju_next->ju_prev_p = jupe->ju_prev_p;
265 MyFree(jupe->ju_server); /* and free up the memory */
266 MyFree(jupe->ju_reason);
271 jupe_burst(struct Client *cptr)
276 for (jupe = GlobalJupeList; jupe; jupe = sjupe) { /* go through jupes */
277 sjupe = jupe->ju_next;
279 if (jupe->ju_expire <= CurrentTime) /* expire any that need expiring */
281 else if (!JupeIsLocal(jupe)) /* forward global jupes */
282 sendcmdto_one(&me, CMD_JUPE, cptr, "* %c%s %Tu %Tu :%s",
283 JupeIsRemActive(jupe) ? '+' : '-', jupe->ju_server,
284 jupe->ju_expire - CurrentTime, jupe->ju_lastmod,
290 jupe_resend(struct Client *cptr, struct Jupe *jupe)
292 if (JupeIsLocal(jupe)) /* don't propagate local jupes */
295 sendcmdto_one(&me, CMD_JUPE, cptr, "* %c%s %Tu %Tu :%s",
296 JupeIsRemActive(jupe) ? '+' : '-', jupe->ju_server,
297 jupe->ju_expire - CurrentTime, jupe->ju_lastmod,
304 jupe_list(struct Client *sptr, char *server)
310 if (!(jupe = jupe_find(server))) /* no such jupe */
311 return send_reply(sptr, ERR_NOSUCHJUPE, server);
313 /* send jupe information along */
314 send_reply(sptr, RPL_JUPELIST, jupe->ju_server, jupe->ju_expire + TSoffset,
315 JupeIsLocal(jupe) ? cli_name(&me) : "*",
316 JupeIsActive(jupe) ? '+' : '-', jupe->ju_reason);
318 for (jupe = GlobalJupeList; jupe; jupe = sjupe) { /* go through jupes */
319 sjupe = jupe->ju_next;
321 if (jupe->ju_expire <= CurrentTime) /* expire any that need expiring */
323 else /* send jupe information along */
324 send_reply(sptr, RPL_JUPELIST, jupe->ju_server,
325 jupe->ju_expire + TSoffset,
326 JupeIsLocal(jupe) ? cli_name(&me) : "*",
327 JupeIsActive(jupe) ? '+' : '-', jupe->ju_reason);
331 /* end of jupe information */
332 return send_reply(sptr, RPL_ENDOFJUPELIST);
336 jupe_memory_count(size_t *ju_size)
341 for (jupe = GlobalJupeList; jupe; jupe = jupe->ju_next)
344 ju_size += sizeof(struct Jupe);
345 ju_size += jupe->ju_server ? (strlen(jupe->ju_server) + 1) : 0;
346 ju_size += jupe->ju_reason ? (strlen(jupe->ju_reason) + 1) : 0;