]>
jfr.im git - irc/quakenet/snircd.git/blob - ircd/jupe.c
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.
22 * @brief Implementation of juped server handling functions.
23 * @version $Id: jupe.c,v 1.20.2.1 2006/03/25 03:46:56 entrope Exp $
31 #include "ircd_alloc.h"
32 #include "ircd_features.h"
34 #include "ircd_reply.h"
35 #include "ircd_string.h"
44 #include "sys.h" /* FALSE bleah */
46 /* #include <assert.h> -- Now using assert in ircd_log.h */
50 static struct Jupe
*GlobalJupeList
= 0;
52 /** Allocate a new jupe with the given parameters.
53 * @param[in] server Server name to jupe.
54 * @param[in] reason Reason for jupe.
55 * @param[in] expire Expiration time for jupe.
56 * @param[in] lastmod Last modification time for jupe.
57 * @param[in] flags Flags to set for the jupe.
60 make_jupe(char *server
, char *reason
, time_t expire
, time_t lastmod
,
65 ajupe
= (struct Jupe
*) MyMalloc(sizeof(struct Jupe
)); /* alloc memory */
68 memset(ajupe
, 0, sizeof(*ajupe
));
69 DupString(ajupe
->ju_server
, server
); /* copy vital information */
70 DupString(ajupe
->ju_reason
, reason
);
71 ajupe
->ju_expire
= expire
;
72 ajupe
->ju_lastmod
= lastmod
;
73 ajupe
->ju_flags
= flags
& JUPE_MASK
; /* set jupe flags */
75 ajupe
->ju_next
= GlobalJupeList
; /* link it into the list */
76 ajupe
->ju_prev_p
= &GlobalJupeList
;
78 GlobalJupeList
->ju_prev_p
= &ajupe
->ju_next
;
79 GlobalJupeList
= ajupe
;
85 * @param[in] cptr Local client that sent us the jupe.
86 * @param[in] sptr Originator of the jupe.
87 * @param[in] jupe Jupe to check.
90 do_jupe(struct Client
*cptr
, struct Client
*sptr
, struct Jupe
*jupe
)
94 if (!JupeIsActive(jupe
)) /* no action to be taken on inactive jupes */
97 acptr
= FindServer(jupe
->ju_server
);
99 /* server isn't online or isn't local or is me */
100 if (!acptr
|| !MyConnect(acptr
) || IsMe(acptr
))
103 return exit_client_msg(cptr
, acptr
, &me
, "Juped: %s", jupe
->ju_reason
);
106 /** Forward a jupe to another server.
107 * @param[in] cptr Local client that sent us the jupe.
108 * @param[in] sptr Originator of the jupe.
109 * @param[in] jupe Jupe to forward.
112 propagate_jupe(struct Client
*cptr
, struct Client
*sptr
, struct Jupe
*jupe
)
114 if (JupeIsLocal(jupe
)) /* don't propagate local jupes */
117 sendcmdto_serv_butone(sptr
, CMD_JUPE
, cptr
, "* %c%s %Tu %Tu :%s",
118 JupeIsRemActive(jupe
) ? '+' : '-', jupe
->ju_server
,
119 jupe
->ju_expire
- CurrentTime
, jupe
->ju_lastmod
,
123 /** Add a new server jupe.
124 * @param[in] cptr Local client that sent us the jupe.
125 * @param[in] sptr Originator of the jupe.
126 * @param[in] server Server name to jupe.
127 * @param[in] reason Reason for the jupe.
128 * @param[in] expire Jupe duration in seconds.
129 * @param[in] lastmod Last modification timestamp (or NULL).
130 * @param[in] flags Flags to set on jupe.
131 * @return Zero, unless the jupe causes \a cptr to be SQUIT, in which
135 jupe_add(struct Client
*cptr
, struct Client
*sptr
, char *server
, char *reason
,
136 time_t expire
, time_t lastmod
, unsigned int flags
)
144 * You cannot set a negative (or zero) expire time, nor can you set an
145 * expiration time for greater than JUPE_MAX_EXPIRE.
147 if (expire
<= 0 || expire
> JUPE_MAX_EXPIRE
) {
148 if (!IsServer(cptr
) && MyConnect(cptr
))
149 send_reply(cptr
, ERR_BADEXPIRE
, expire
);
153 expire
+= CurrentTime
; /* convert from lifetime to timestamp */
155 /* Inform ops and log it */
156 sendto_opmask_butone(0, SNO_NETWORK
, "%s adding %sJUPE for %s, expiring at "
158 (feature_bool(FEAT_HIS_SNOTICES
) || IsServer(sptr
)) ?
160 cli_name((cli_user(sptr
))->server
),
161 flags
& JUPE_LOCAL
? "local " : "", server
,
162 expire
+ TSoffset
, reason
);
164 log_write(LS_JUPE
, L_INFO
, LOG_NOSNOTICE
,
165 "%#C adding %sJUPE for %s, expiring at %Tu: %s", sptr
,
166 flags
& JUPE_LOCAL
? "local " : "", server
, expire
+ TSoffset
,
170 ajupe
= make_jupe(server
, reason
, expire
, lastmod
, flags
);
172 propagate_jupe(cptr
, sptr
, ajupe
);
174 return do_jupe(cptr
, sptr
, ajupe
); /* remove server if necessary */
177 /** Activate a jupe, optionally changing its lastmod and flags.
178 * @param[in] cptr Local client that sent us the jupe.
179 * @param[in] sptr Originator of the jupe.
180 * @param[in] jupe Jupe to activate.
181 * @param[in] lastmod New timestamp for last modification of the jupe.
182 * @param[in] flags Flags to set on the jupe.
183 * @return Zero, unless the jupe causes \a cptr to be SQUIT, in which
187 jupe_activate(struct Client
*cptr
, struct Client
*sptr
, struct Jupe
*jupe
,
188 time_t lastmod
, unsigned int flags
)
190 unsigned int saveflags
= 0;
194 saveflags
= jupe
->ju_flags
;
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 active to begin with */
210 /* Inform ops and log it */
211 sendto_opmask_butone(0, SNO_NETWORK
, "%s activating JUPE for %s, expiring "
213 (feature_bool(FEAT_HIS_SNOTICES
) || IsServer(sptr
)) ?
215 cli_name((cli_user(sptr
))->server
),
216 jupe
->ju_server
, jupe
->ju_expire
+ TSoffset
,
219 log_write(LS_JUPE
, L_INFO
, LOG_NOSNOTICE
,
220 "%#C activating JUPE for %s, expiring at %Tu: %s",sptr
,
221 jupe
->ju_server
, jupe
->ju_expire
+ TSoffset
, jupe
->ju_reason
);
223 if (!(flags
& JUPE_LOCAL
)) /* don't propagate local changes */
224 propagate_jupe(cptr
, sptr
, jupe
);
226 return do_jupe(cptr
, sptr
, jupe
);
229 /** Deactivate a jupe.
230 * @param[in] cptr Local client that sent us the jupe.
231 * @param[in] sptr Originator of the jupe.
232 * @param[in] jupe Jupe to deactivate.
233 * @param[in] lastmod New timestamp for last modification of the jupe.
234 * @param[in] flags Flags to set on the jupe.
238 jupe_deactivate(struct Client
*cptr
, struct Client
*sptr
, struct Jupe
*jupe
,
239 time_t lastmod
, unsigned int flags
)
241 unsigned int saveflags
= 0;
245 saveflags
= jupe
->ju_flags
;
247 if (!JupeIsLocal(jupe
)) {
248 if (flags
& JUPE_LOCAL
)
249 jupe
->ju_flags
|= JUPE_LDEACT
;
251 jupe
->ju_flags
&= ~JUPE_ACTIVE
;
253 if (jupe
->ju_lastmod
>= lastmod
) /* force lastmod to increase */
256 jupe
->ju_lastmod
= lastmod
;
259 if ((saveflags
& JUPE_ACTMASK
) != JUPE_ACTIVE
)
260 return 0; /* was inactive to begin with */
263 /* Inform ops and log it */
264 sendto_opmask_butone(0, SNO_NETWORK
, "%s %s JUPE for %s, expiring at %Tu: "
266 (feature_bool(FEAT_HIS_SNOTICES
) || IsServer(sptr
)) ?
268 cli_name((cli_user(sptr
))->server
),
269 JupeIsLocal(jupe
) ? "removing local" : "deactivating",
270 jupe
->ju_server
, jupe
->ju_expire
+ TSoffset
,
273 log_write(LS_JUPE
, L_INFO
, LOG_NOSNOTICE
,
274 "%#C %s JUPE for %s, expiring at %Tu: %s", sptr
,
275 JupeIsLocal(jupe
) ? "removing local" : "deactivating",
276 jupe
->ju_server
, jupe
->ju_expire
+ TSoffset
, jupe
->ju_reason
);
278 if (JupeIsLocal(jupe
))
280 else if (!(flags
& JUPE_LOCAL
)) /* don't propagate local changes */
281 propagate_jupe(cptr
, sptr
, jupe
);
286 /** Find a jupe by name.
287 * @param[in] server %Jupe name to search for.
288 * @return Matching jupe (or NULL if none match).
291 jupe_find(char *server
)
296 for (jupe
= GlobalJupeList
; jupe
; jupe
= sjupe
) { /* go through jupes */
297 sjupe
= jupe
->ju_next
;
299 if (jupe
->ju_expire
<= CurrentTime
) /* expire any that need expiring */
301 else if (0 == ircd_strcmp(server
, jupe
->ju_server
)) /* found it yet? */
308 /** Unlink and free an unused jupe.
309 * @param[in] jupe Server jupe to free.
312 jupe_free(struct Jupe
* jupe
)
316 *jupe
->ju_prev_p
= jupe
->ju_next
; /* squeeze this jupe out */
318 jupe
->ju_next
->ju_prev_p
= jupe
->ju_prev_p
;
320 MyFree(jupe
->ju_server
); /* and free up the memory */
321 MyFree(jupe
->ju_reason
);
325 /** Send the full list of active global jupes to \a cptr.
326 * @param[in] cptr Local server to send jupes to.
329 jupe_burst(struct Client
*cptr
)
334 for (jupe
= GlobalJupeList
; jupe
; jupe
= sjupe
) { /* go through jupes */
335 sjupe
= jupe
->ju_next
;
337 if (jupe
->ju_expire
<= CurrentTime
) /* expire any that need expiring */
339 else if (!JupeIsLocal(jupe
)) /* forward global jupes */
340 sendcmdto_one(&me
, CMD_JUPE
, cptr
, "* %c%s %Tu %Tu :%s",
341 JupeIsRemActive(jupe
) ? '+' : '-', jupe
->ju_server
,
342 jupe
->ju_expire
- CurrentTime
, jupe
->ju_lastmod
,
347 /** Forward a jupe to another server.
348 * @param[in] cptr %Server to send jupe to.
349 * @param[in] jupe Jupe to forward.
352 jupe_resend(struct Client
*cptr
, struct Jupe
*jupe
)
354 if (JupeIsLocal(jupe
)) /* don't propagate local jupes */
357 sendcmdto_one(&me
, CMD_JUPE
, cptr
, "* %c%s %Tu %Tu :%s",
358 JupeIsRemActive(jupe
) ? '+' : '-', jupe
->ju_server
,
359 jupe
->ju_expire
- CurrentTime
, jupe
->ju_lastmod
,
365 /** Send a jupe (or a list of jupes) to a server.
366 * @param[in] sptr Client searching for jupes.
367 * @param[in] server Name of jupe to search for (if NULL, list all).
371 jupe_list(struct Client
*sptr
, char *server
)
377 if (!(jupe
= jupe_find(server
))) /* no such jupe */
378 return send_reply(sptr
, ERR_NOSUCHJUPE
, server
);
380 /* send jupe information along */
381 send_reply(sptr
, RPL_JUPELIST
, jupe
->ju_server
, jupe
->ju_expire
+ TSoffset
,
382 JupeIsLocal(jupe
) ? cli_name(&me
) : "*",
383 JupeIsActive(jupe
) ? '+' : '-', jupe
->ju_reason
);
385 for (jupe
= GlobalJupeList
; jupe
; jupe
= sjupe
) { /* go through jupes */
386 sjupe
= jupe
->ju_next
;
388 if (jupe
->ju_expire
<= CurrentTime
) /* expire any that need expiring */
390 else /* send jupe information along */
391 send_reply(sptr
, RPL_JUPELIST
, jupe
->ju_server
,
392 jupe
->ju_expire
+ TSoffset
,
393 JupeIsLocal(jupe
) ? cli_name(&me
) : "*",
394 JupeIsActive(jupe
) ? '+' : '-', jupe
->ju_reason
);
398 /* end of jupe information */
399 return send_reply(sptr
, RPL_ENDOFJUPELIST
);
402 /** Count jupes and memory used by them.
403 * @param[out] ju_size Receives total number of bytes allocated for jupes.
404 * @return Number of jupes currently allocated.
407 jupe_memory_count(size_t *ju_size
)
412 for (jupe
= GlobalJupeList
; jupe
; jupe
= jupe
->ju_next
)
415 *ju_size
+= sizeof(struct Jupe
);
416 *ju_size
+= jupe
->ju_server
? (strlen(jupe
->ju_server
) + 1) : 0;
417 *ju_size
+= jupe
->ju_reason
? (strlen(jupe
->ju_reason
) + 1) : 0;