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 */
44 static struct Jupe *GlobalJupeList = 0;
47 make_jupe(char *server, char *reason, time_t expire, time_t lastmod,
52 ajupe = (struct Jupe*) MyMalloc(sizeof(struct Jupe)); /* alloc memory */
55 DupString(ajupe->ju_server, server); /* copy vital information */
56 DupString(ajupe->ju_reason, reason);
57 ajupe->ju_expire = expire;
58 ajupe->ju_lastmod = lastmod;
59 ajupe->ju_flags = flags & JUPE_MASK; /* set jupe flags */
61 ajupe->ju_next = GlobalJupeList; /* link it into the list */
62 ajupe->ju_prev_p = &GlobalJupeList;
64 GlobalJupeList->ju_prev_p = &ajupe->ju_next;
65 GlobalJupeList = ajupe;
71 do_jupe(struct Client *cptr, struct Client *sptr, struct Jupe *jupe)
75 if (!JupeIsActive(jupe)) /* no action to be taken on inactive jupes */
78 acptr = FindServer(jupe->ju_server);
80 /* server isn't online or isn't local or is me */
81 if (!acptr || !MyConnect(acptr) || IsMe(acptr))
84 return exit_client_msg(cptr, acptr, &me, "Juped: %s", jupe->ju_reason);
88 propagate_jupe(struct Client *cptr, struct Client *sptr, struct Jupe *jupe)
90 if (JupeIsLocal(jupe)) /* don't propagate local jupes */
93 sendcmdto_serv_butone(sptr, CMD_JUPE, cptr, "* %c%s %Tu %Tu :%s",
94 JupeIsRemActive(jupe) ? '+' : '-', jupe->ju_server,
95 jupe->ju_expire - CurrentTime, jupe->ju_lastmod,
100 jupe_add(struct Client *cptr, struct Client *sptr, char *server, char *reason,
101 time_t expire, time_t lastmod, unsigned int flags)
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_reply(cptr, ERR_BADEXPIRE, expire);
118 expire += CurrentTime; /* convert from lifetime to timestamp */
120 /* Inform ops and log it */
121 sendto_opmask_butone(0, SNO_NETWORK, "%s adding %sJUPE for %s, expiring at "
122 "%Tu: %s", IsServer(sptr) ? sptr->name :
123 sptr->user->server->name,
124 flags & JUPE_LOCAL ? "local " : "", server,
125 expire + TSoffset, reason);
128 write_log(JPATH, "%Tu %C adding %sJUPE for %s, expiring at %Tu: %s\n",
129 TStime(), sptr, flags & JUPE_LOCAL ? "local " : "", server,
130 expire + TSoffset, reason);
134 ajupe = make_jupe(server, reason, expire, lastmod, flags);
136 propagate_jupe(cptr, sptr, ajupe);
138 return do_jupe(cptr, sptr, ajupe); /* remove server if necessary */
142 jupe_activate(struct Client *cptr, struct Client *sptr, struct Jupe *jupe,
143 time_t lastmod, unsigned int flags)
145 unsigned int saveflags = 0;
148 assert(!JupeIsLocal(jupe));
150 saveflags = jupe->ju_flags;
152 if (flags & JUPE_LOCAL)
153 jupe->ju_flags &= ~JUPE_LDEACT;
155 jupe->ju_flags |= JUPE_ACTIVE;
157 if (jupe->ju_lastmod >= lastmod) /* force lastmod to increase */
160 jupe->ju_lastmod = lastmod;
163 if ((saveflags & JUPE_ACTMASK) == JUPE_ACTIVE)
164 return 0; /* was active to begin with */
166 /* Inform ops and log it */
167 sendto_opmask_butone(0, SNO_NETWORK, "%s activating JUPE for %s, expiring "
169 IsServer(sptr) ? sptr->name : sptr->user->server->name,
170 jupe->ju_server, jupe->ju_expire + TSoffset,
174 write_log(JPATH, "%Tu %C activating JUPE for %s, expiring at %Tu: %s\n",
175 TStime(), sptr, jupe->ju_server, jupe->ju_expire + TSoffset,
179 if (!(flags & JUPE_LOCAL)) /* don't propagate local changes */
180 propagate_jupe(cptr, sptr, jupe);
182 return do_jupe(cptr, sptr, jupe);
186 jupe_deactivate(struct Client *cptr, struct Client *sptr, struct Jupe *jupe,
187 time_t lastmod, unsigned int flags)
189 unsigned int saveflags = 0;
193 saveflags = jupe->ju_flags;
195 if (!JupeIsLocal(jupe)) {
196 if (flags & JUPE_LOCAL)
197 jupe->ju_flags |= JUPE_LDEACT;
199 jupe->ju_flags &= ~JUPE_ACTIVE;
201 if (jupe->ju_lastmod >= lastmod) /* force lastmod to increase */
204 jupe->ju_lastmod = lastmod;
207 if ((saveflags & JUPE_ACTMASK) != JUPE_ACTIVE)
208 return 0; /* was inactive to begin with */
211 /* Inform ops and log it */
212 sendto_opmask_butone(0, SNO_NETWORK, "%s %s JUPE for %s, expiring at %Tu: "
214 IsServer(sptr) ? sptr->name : sptr->user->server->name,
215 JupeIsLocal(jupe) ? "removing local" : "deactivating",
216 jupe->ju_server, jupe->ju_expire + TSoffset,
220 write_log(JPATH, "%Tu %s %s JUPE for %s, expiring at %Tu: %s\n", TStime(),
221 sptr, JupeIsLocal(jupe) ? "removing local" : "deactivating",
222 jupe->ju_server, jupe->ju_expire + TSoffset, jupe->ju_reason);
225 if (JupeIsLocal(jupe))
227 else if (!(flags & JUPE_LOCAL)) /* don't propagate local changes */
228 propagate_jupe(cptr, sptr, jupe);
234 jupe_find(char *server)
239 for (jupe = GlobalJupeList; jupe; jupe = sjupe) { /* go through jupes */
240 sjupe = jupe->ju_next;
242 if (jupe->ju_expire <= CurrentTime) /* expire any that need expiring */
244 else if (0 == ircd_strcmp(server, jupe->ju_server)) /* found it yet? */
252 jupe_free(struct Jupe* jupe)
256 *jupe->ju_prev_p = jupe->ju_next; /* squeeze this jupe out */
258 jupe->ju_next->ju_prev_p = jupe->ju_prev_p;
260 MyFree(jupe->ju_server); /* and free up the memory */
261 MyFree(jupe->ju_reason);
266 jupe_burst(struct Client *cptr)
271 for (jupe = GlobalJupeList; jupe; jupe = sjupe) { /* go through jupes */
272 sjupe = jupe->ju_next;
274 if (jupe->ju_expire <= CurrentTime) /* expire any that need expiring */
276 else if (!JupeIsLocal(jupe)) /* forward global jupes */
277 sendcmdto_one(&me, CMD_JUPE, cptr, "* %c%s %Tu %Tu :%s",
278 JupeIsRemActive(jupe) ? '+' : '-', jupe->ju_server,
279 jupe->ju_expire - CurrentTime, jupe->ju_lastmod,
285 jupe_resend(struct Client *cptr, struct Jupe *jupe)
287 if (JupeIsLocal(jupe)) /* don't propagate local jupes */
290 sendcmdto_one(&me, CMD_JUPE, cptr, "* %c%s %Tu %Tu :%s",
291 JupeIsRemActive(jupe) ? '+' : '-', jupe->ju_server,
292 jupe->ju_expire - CurrentTime, jupe->ju_lastmod,
299 jupe_list(struct Client *sptr, char *server)
305 if (!(jupe = jupe_find(server))) /* no such jupe */
306 return send_reply(sptr, ERR_NOSUCHJUPE, server);
308 /* send jupe information along */
309 send_reply(sptr, RPL_JUPELIST, jupe->ju_server, jupe->ju_expire + TSoffset,
310 JupeIsLocal(jupe) ? me.name : "*",
311 JupeIsActive(jupe) ? '+' : '-', jupe->ju_reason);
313 for (jupe = GlobalJupeList; jupe; jupe = sjupe) { /* go through jupes */
314 sjupe = jupe->ju_next;
316 if (jupe->ju_expire <= CurrentTime) /* expire any that need expiring */
318 else /* send jupe information along */
319 send_reply(sptr, RPL_JUPELIST, jupe->ju_server,
320 jupe->ju_expire + TSoffset,
321 JupeIsLocal(jupe) ? me.name : "*",
322 JupeIsActive(jupe) ? '+' : '-', jupe->ju_reason);
326 /* end of jupe information */
327 return send_reply(sptr, RPL_ENDOFJUPELIST);