]> jfr.im git - irc/quakenet/snircd-patchqueue.git/blob - welcome.patch
cmdhelp.patch almost finished
[irc/quakenet/snircd-patchqueue.git] / welcome.patch
1 diff -r a662d02e9a76 include/handlers.h
2 --- a/include/handlers.h Sat Jan 24 21:39:56 2009 +0100
3 +++ b/include/handlers.h Sat Jan 24 22:38:10 2009 +0100
4 @@ -151,6 +151,7 @@
5 extern int m_version(struct Client*, struct Client*, int, char*[]);
6 extern int m_wallchops(struct Client*, struct Client*, int, char*[]);
7 extern int m_wallvoices(struct Client*, struct Client*, int, char*[]);
8 +extern int m_welcome(struct Client*, struct Client*, int, char*[]);
9 extern int m_who(struct Client*, struct Client*, int, char*[]);
10 extern int m_whois(struct Client*, struct Client*, int, char*[]);
11 extern int m_whowas(struct Client*, struct Client*, int, char*[]);
12 @@ -185,6 +186,7 @@
13 extern int mo_version(struct Client*, struct Client*, int, char*[]);
14 extern int mo_wallops(struct Client*, struct Client*, int, char*[]);
15 extern int mo_wallusers(struct Client*, struct Client*, int, char*[]);
16 +extern int mo_welcome(struct Client*, struct Client*, int, char*[]);
17 extern int mr_error(struct Client*, struct Client*, int, char*[]);
18 extern int mr_error(struct Client*, struct Client*, int, char*[]);
19 extern int mr_pong(struct Client*, struct Client*, int, char*[]);
20 @@ -242,6 +244,7 @@
21 extern int ms_wallops(struct Client*, struct Client*, int, char*[]);
22 extern int ms_wallusers(struct Client*, struct Client*, int, char*[]);
23 extern int ms_wallvoices(struct Client*, struct Client*, int, char*[]);
24 +extern int ms_welcome(struct Client*, struct Client*, int, char*[]);
25 extern int ms_whois(struct Client*, struct Client*, int, char*[]);
26
27 #endif /* INCLUDED_handlers_h */
28 diff -r a662d02e9a76 include/msg.h
29 --- a/include/msg.h Sat Jan 24 21:39:56 2009 +0100
30 +++ b/include/msg.h Sat Jan 24 22:38:10 2009 +0100
31 @@ -195,6 +195,10 @@
32 #define MSG_NOTICE "NOTICE" /* NOTI */
33 #define TOK_NOTICE "O"
34 #define CMD_NOTICE MSG_NOTICE, TOK_NOTICE
35 +
36 +#define MSG_WELCOME "WELCOME" /* WELC */
37 +#define TOK_WELCOME "WE"
38 +#define CMD_WELCOME MSG_WELCOME, TOK_WELCOME
39
40 #define MSG_WALLCHOPS "WALLCHOPS" /* WC */
41 #define TOK_WALLCHOPS "WC"
42 diff -r a662d02e9a76 include/welcome.h
43 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
44 +++ b/include/welcome.h Sat Jan 24 22:38:10 2009 +0100
45 @@ -0,0 +1,43 @@
46 +#ifndef INCLUDED_welcome_h
47 +#define INCLUDED_welcome_h
48 +/*
49 + * IRC - Internet Relay Chat, include/welcome.h
50 + * Copyright (C) 1990 Jarkko Oikarinen and
51 + * University of Oulu, Computing Center
52 + * Copyright (C) 2000 Kevin L. Mitchell <klmitch@mit.edu>
53 + *
54 + * This program is free software; you can redistribute it and/or modify
55 + * it under the terms of the GNU General Public License as published by
56 + * the Free Software Foundation; either version 2, or (at your option)
57 + * any later version.
58 + *
59 + * This program is distributed in the hope that it will be useful,
60 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
61 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
62 + * GNU General Public License for more details.
63 + *
64 + * You should have received a copy of the GNU General Public License
65 + * along with this program; if not, write to the Free Software
66 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
67 + */
68 +/** @file
69 + * @brief Interface and declarations for welcome server handling.
70 + * @version $Id: jupe.h 1208 2004-10-03 14:12:35Z entrope $
71 + */
72 +#ifndef INCLUDED_sys_types_h
73 +#include <sys/types.h>
74 +#define INCLUDED_sys_types_h
75 +#endif
76 +
77 +
78 +
79 +
80 +
81 +extern int welcome_set(struct Client *cptr, struct Client *sptr,
82 + char *reason, time_t lastmod);
83 +extern void welcome_burst(struct Client *cptr);
84 +extern int welcome_resend(struct Client *cptr);
85 +extern int welcome_list(struct Client *sptr);
86 +extern int welcome_memory_count(size_t *ju_size);
87 +
88 +#endif /* INCLUDED_welcome_h */
89 \ No newline at end of file
90 diff -r a662d02e9a76 ircd/m_welcome.c
91 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
92 +++ b/ircd/m_welcome.c Sat Jan 24 22:38:10 2009 +0100
93 @@ -0,0 +1,142 @@
94 +/*
95 + * IRC - Internet Relay Chat, ircd/m_welcome.c
96 + * Copyright (C) 1990 Jarkko Oikarinen and
97 + * University of Oulu, Computing Center
98 + *
99 + * See file AUTHORS in IRC package for additional names of
100 + * the programmers.
101 + *
102 + * This program is free software; you can redistribute it and/or modify
103 + * it under the terms of the GNU General Public License as published by
104 + * the Free Software Foundation; either version 1, or (at your option)
105 + * any later version.
106 + *
107 + * This program is distributed in the hope that it will be useful,
108 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
109 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
110 + * GNU General Public License for more details.
111 + *
112 + * You should have received a copy of the GNU General Public License
113 + * along with this program; if not, write to the Free Software
114 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
115 + *
116 + * $Id: m_welcome.c 1903 2009-01-13 03:54:45Z entrope $
117 + */
118 +
119 +/*
120 + * m_functions execute protocol messages on this server:
121 + *
122 + * cptr is always NON-NULL, pointing to a *LOCAL* client
123 + * structure (with an open socket connected!). This
124 + * identifies the physical socket where the message
125 + * originated (or which caused the m_function to be
126 + * executed--some m_functions may call others...).
127 + *
128 + * sptr is the source of the message, defined by the
129 + * prefix part of the message if present. If not
130 + * or prefix not found, then sptr==cptr.
131 + *
132 + * (!IsServer(cptr)) => (cptr == sptr), because
133 + * prefixes are taken *only* from servers...
134 + *
135 + * (IsServer(cptr))
136 + * (sptr == cptr) => the message didn't
137 + * have the prefix.
138 + *
139 + * (sptr != cptr && IsServer(sptr) means
140 + * the prefix specified servername. (?)
141 + *
142 + * (sptr != cptr && !IsServer(sptr) means
143 + * that message originated from a remote
144 + * user (not local).
145 + *
146 + * combining
147 + *
148 + * (!IsServer(sptr)) means that, sptr can safely
149 + * taken as defining the target structure of the
150 + * message in this server.
151 + *
152 + * *Always* true (if 'parse' and others are working correct):
153 + *
154 + * 1) sptr->from == cptr (note: cptr->from == cptr)
155 + *
156 + * 2) MyConnect(sptr) <=> sptr == cptr (e.g. sptr
157 + * *cannot* be a local connection, unless it's
158 + * actually cptr!). [MyConnect(x) should probably
159 + * be defined as (x == x->from) --msa ]
160 + *
161 + * parc number of variable parameter strings (if zero,
162 + * parv is allowed to be NULL)
163 + *
164 + * parv a NULL terminated list of parameter pointers,
165 + *
166 + * parv[0], sender (prefix string), if not present
167 + * this points to an empty string.
168 + * parv[1]...parv[parc-1]
169 + * pointers to additional parameters
170 + * parv[parc] == NULL, *always*
171 + *
172 + * note: it is guaranteed that parv[0]..parv[parc-1] are all
173 + * non-NULL pointers.
174 + */
175 +#include "config.h"
176 +
177 +#include "channel.h"
178 +#include "client.h"
179 +#include "hash.h"
180 +#include "ircd.h"
181 +#include "ircd_log.h"
182 +#include "ircd_reply.h"
183 +#include "ircd_string.h"
184 +#include "msg.h"
185 +#include "numeric.h"
186 +#include "numnicks.h"
187 +#include "s_user.h"
188 +#include "send.h"
189 +
190 +/* #include <assert.h> -- Now using assert in ircd_log.h */
191 +
192 +/*
193 + * m_welcome - local generic message handler
194 + *
195 + * parv[0] = Send prefix
196 + */
197 +int m_welcome(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
198 +{
199 + return 0;
200 +}
201 +
202 +
203 +/*
204 + * mo_welcome - oper message handler
205 + *
206 + * listing:
207 + * parv[0] = Send prefix
208 + *
209 + * remote listing:
210 + * parv[0] = Send prefix
211 + * parv[1] = Target
212 + *
213 + * set global or on remote server:
214 + * parv[0] = Send prefix
215 + * parv[1] = Target: server or * for global
216 + * parv[2] = Text
217 + */
218 +int mo_welcome(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
219 +{
220 + return 0;
221 +}
222 +
223 +
224 +/*
225 + * ms_welcome - server message handler
226 + *
227 + * parv[0] = Send prefix
228 + * parv[1] = Target: server numeric or * for global
229 + * parv[2] = Timestamp
230 + * parv[3] = Text
231 + */
232 +int ms_welcome(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
233 +{
234 + return 0;
235 +}
236 diff -r a662d02e9a76 ircd/parse.c
237 --- a/ircd/parse.c Sat Jan 24 21:39:56 2009 +0100
238 +++ b/ircd/parse.c Sat Jan 24 22:38:10 2009 +0100
239 @@ -668,6 +668,15 @@
240 /* UNREG, CLIENT, SERVER, OPER, SERVICE */
241 { m_unregistered, m_not_oper, ms_opkick, mo_opkick, m_ignore }
242 },
243 +
244 + /* add command for WELCOME */
245 + {
246 + MSG_WELCOME,
247 + TOK_WELCOME,
248 + 0, MAXPARA, MFLG_SLOW, 0, NULL,
249 + /* UNREG, CLIENT, SERVER, OPER, SERVICE */
250 + { m_unregistered, m_welcome, ms_welcome, mo_welcome, m_ignore }
251 + },
252
253 /* This command is an alias for QUIT during the unregistered part of
254 * of the server. This is because someone jumping via a broken web
255 diff -r a662d02e9a76 ircd/welcome.c
256 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
257 +++ b/ircd/welcome.c Sat Jan 24 22:38:10 2009 +0100
258 @@ -0,0 +1,430 @@
259 +/*
260 + * IRC - Internet Relay Chat, ircd/jupe.c
261 + * Copyright (C) 1990 Jarkko Oikarinen and
262 + * University of Oulu, Finland
263 + * Copyright (C) 2000 Kevin L. Mitchell <klmitch@mit.edu>
264 + *
265 + * This program is free software; you can redistribute it and/or modify
266 + * it under the terms of the GNU General Public License as published by
267 + * the Free Software Foundation; either version 1, or (at your option)
268 + * any later version.
269 + *
270 + * This program is distributed in the hope that it will be useful,
271 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
272 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
273 + * GNU General Public License for more details.
274 + *
275 + * You should have received a copy of the GNU General Public License
276 + * along with this program; if not, write to the Free Software
277 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
278 + */
279 +/** @file
280 + * @brief Implementation of juped server handling functions.
281 + * @version $Id: jupe.c 1633 2006-03-25 03:46:56Z entrope $
282 + */
283 +#include "config.h"
284 +
285 +#include "client.h"
286 +#include "hash.h"
287 +#include "ircd.h"
288 +#include "ircd_alloc.h"
289 +#include "ircd_features.h"
290 +#include "ircd_log.h"
291 +#include "ircd_reply.h"
292 +#include "ircd_string.h"
293 +#include "match.h"
294 +#include "msg.h"
295 +#include "numeric.h"
296 +#include "numnicks.h"
297 +#include "s_bsd.h"
298 +#include "s_misc.h"
299 +#include "send.h"
300 +#include "struct.h"
301 +#include "sys.h" /* FALSE bleah */
302 +#include "welcome.h"
303 +
304 +/* #include <assert.h> -- Now using assert in ircd_log.h */
305 +#include <string.h>
306 +
307 +/** List of jupes. */
308 +static struct Jupe *GlobalJupeList = 0;
309 +
310 +/** Allocate a new jupe with the given parameters.
311 + * @param[in] server Server name to jupe.
312 + * @param[in] reason Reason for jupe.
313 + * @param[in] expire Expiration time for jupe.
314 + * @param[in] lastmod Last modification time for jupe.
315 + * @param[in] flags Flags to set for the jupe.
316 + */
317 +static struct Jupe *
318 +make_jupe(char *server, char *reason, time_t expire, time_t lastmod,
319 + unsigned int flags)
320 +{
321 + struct Jupe *ajupe;
322 +
323 + ajupe = (struct Jupe*) MyMalloc(sizeof(struct Jupe)); /* alloc memory */
324 + assert(0 != ajupe);
325 +
326 + memset(ajupe, 0, sizeof(*ajupe));
327 + DupString(ajupe->ju_server, server); /* copy vital information */
328 + DupString(ajupe->ju_reason, reason);
329 + ajupe->ju_expire = expire;
330 + ajupe->ju_lastmod = lastmod;
331 + ajupe->ju_flags = flags & JUPE_MASK; /* set jupe flags */
332 +
333 + ajupe->ju_next = GlobalJupeList; /* link it into the list */
334 + ajupe->ju_prev_p = &GlobalJupeList;
335 + if (GlobalJupeList)
336 + GlobalJupeList->ju_prev_p = &ajupe->ju_next;
337 + GlobalJupeList = ajupe;
338 +
339 + return ajupe;
340 +}
341 +
342 +/** Apply a jupe.
343 + * @param[in] cptr Local client that sent us the jupe.
344 + * @param[in] sptr Originator of the jupe.
345 + * @param[in] jupe Jupe to check.
346 + */
347 +static int
348 +do_jupe(struct Client *cptr, struct Client *sptr, struct Jupe *jupe)
349 +{
350 + struct Client *acptr;
351 +
352 + if (!JupeIsActive(jupe)) /* no action to be taken on inactive jupes */
353 + return 0;
354 +
355 + acptr = FindServer(jupe->ju_server);
356 +
357 + /* server isn't online or isn't local or is me */
358 + if (!acptr || !MyConnect(acptr) || IsMe(acptr))
359 + return 0;
360 +
361 + return exit_client_msg(cptr, acptr, &me, "Juped: %s", jupe->ju_reason);
362 +}
363 +
364 +/** Forward a jupe to another server.
365 + * @param[in] cptr Local client that sent us the jupe.
366 + * @param[in] sptr Originator of the jupe.
367 + * @param[in] jupe Jupe to forward.
368 + */
369 +static void
370 +propagate_jupe(struct Client *cptr, struct Client *sptr, struct Jupe *jupe)
371 +{
372 + if (JupeIsLocal(jupe)) /* don't propagate local jupes */
373 + return;
374 +
375 + sendcmdto_serv_butone(sptr, CMD_JUPE, cptr, "* %c%s %Tu %Tu :%s",
376 + JupeIsRemActive(jupe) ? '+' : '-', jupe->ju_server,
377 + jupe->ju_expire - CurrentTime, jupe->ju_lastmod,
378 + jupe->ju_reason);
379 +}
380 +
381 +/** Add a new server jupe.
382 + * @param[in] cptr Local client that sent us the jupe.
383 + * @param[in] sptr Originator of the jupe.
384 + * @param[in] server Server name to jupe.
385 + * @param[in] reason Reason for the jupe.
386 + * @param[in] expire Jupe duration in seconds.
387 + * @param[in] lastmod Last modification timestamp (or NULL).
388 + * @param[in] flags Flags to set on jupe.
389 + * @return Zero, unless the jupe causes \a cptr to be SQUIT, in which
390 + * case CPTR_KILLED.
391 + */
392 +int
393 +jupe_add(struct Client *cptr, struct Client *sptr, char *server, char *reason,
394 + time_t expire, time_t lastmod, unsigned int flags)
395 +{
396 + struct Jupe *ajupe;
397 +
398 + assert(0 != server);
399 + assert(0 != reason);
400 +
401 + /*
402 + * You cannot set a negative (or zero) expire time, nor can you set an
403 + * expiration time for greater than JUPE_MAX_EXPIRE.
404 + */
405 + if (expire <= 0 || expire > JUPE_MAX_EXPIRE) {
406 + if (!IsServer(cptr) && MyConnect(cptr))
407 + send_reply(cptr, ERR_BADEXPIRE, expire);
408 + return 0;
409 + }
410 +
411 + expire += CurrentTime; /* convert from lifetime to timestamp */
412 +
413 + /* Inform ops and log it */
414 + sendto_opmask_butone(0, SNO_NETWORK, "%s adding %sJUPE for %s, expiring at "
415 + "%Tu: %s",
416 + (feature_bool(FEAT_HIS_SNOTICES) || IsServer(sptr)) ?
417 + get_client_name_and_opername(sptr) :
418 + cli_name((cli_user(sptr))->server),
419 + flags & JUPE_LOCAL ? "local " : "", server,
420 + expire + TSoffset, reason);
421 +
422 + log_write(LS_JUPE, L_INFO, LOG_NOSNOTICE,
423 + "%#C adding %sJUPE for %s, expiring at %Tu: %s", sptr,
424 + flags & JUPE_LOCAL ? "local " : "", server, expire + TSoffset,
425 + reason);
426 +
427 + /* local jupe set by remote user, inform oper of success */
428 + if ((flags & JUPE_LOCAL) && IsUser(sptr) && !MyUser(sptr))
429 + sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :%s adding local JUPE for %s, expiring at %Tu: %s",
430 + sptr, cli_name(sptr), server, expire + TSoffset, reason);
431 +
432 + /* make the jupe */
433 + ajupe = make_jupe(server, reason, expire, lastmod, flags);
434 +
435 + propagate_jupe(cptr, sptr, ajupe);
436 +
437 + return do_jupe(cptr, sptr, ajupe); /* remove server if necessary */
438 +}
439 +
440 +/** Activate a jupe, optionally changing its lastmod and flags.
441 + * @param[in] cptr Local client that sent us the jupe.
442 + * @param[in] sptr Originator of the jupe.
443 + * @param[in] jupe Jupe to activate.
444 + * @param[in] lastmod New timestamp for last modification of the jupe.
445 + * @param[in] flags Flags to set on the jupe.
446 + * @return Zero, unless the jupe causes \a cptr to be SQUIT, in which
447 + * case CPTR_KILLED.
448 + */
449 +int
450 +jupe_activate(struct Client *cptr, struct Client *sptr, struct Jupe *jupe,
451 + time_t lastmod, unsigned int flags)
452 +{
453 + unsigned int saveflags = 0;
454 +
455 + assert(0 != jupe);
456 +
457 + saveflags = jupe->ju_flags;
458 +
459 + if (flags & JUPE_LOCAL)
460 + jupe->ju_flags &= ~JUPE_LDEACT;
461 + else {
462 + jupe->ju_flags |= JUPE_ACTIVE;
463 +
464 + if (jupe->ju_lastmod >= lastmod) /* force lastmod to increase */
465 + jupe->ju_lastmod++;
466 + else
467 + jupe->ju_lastmod = lastmod;
468 + }
469 +
470 + if ((saveflags & JUPE_ACTMASK) == JUPE_ACTIVE)
471 + return 0; /* was active to begin with */
472 +
473 + /* Inform ops and log it */
474 + sendto_opmask_butone(0, SNO_NETWORK, "%s activating JUPE for %s, expiring "
475 + "at %Tu: %s",
476 + (feature_bool(FEAT_HIS_SNOTICES) || IsServer(sptr)) ?
477 + get_client_name_and_opername(sptr) :
478 + cli_name((cli_user(sptr))->server),
479 + jupe->ju_server, jupe->ju_expire + TSoffset,
480 + jupe->ju_reason);
481 +
482 + log_write(LS_JUPE, L_INFO, LOG_NOSNOTICE,
483 + "%#C activating JUPE for %s, expiring at %Tu: %s",sptr,
484 + jupe->ju_server, jupe->ju_expire + TSoffset, jupe->ju_reason);
485 +
486 + if (!(flags & JUPE_LOCAL)) /* don't propagate local changes */
487 + propagate_jupe(cptr, sptr, jupe);
488 +
489 + return do_jupe(cptr, sptr, jupe);
490 +}
491 +
492 +/** Deactivate a jupe.
493 + * @param[in] cptr Local client that sent us the jupe.
494 + * @param[in] sptr Originator of the jupe.
495 + * @param[in] jupe Jupe to deactivate.
496 + * @param[in] lastmod New timestamp for last modification of the jupe.
497 + * @param[in] flags Flags to set on the jupe.
498 + * @return Zero.
499 + */
500 +int
501 +jupe_deactivate(struct Client *cptr, struct Client *sptr, struct Jupe *jupe,
502 + time_t lastmod, unsigned int flags)
503 +{
504 + unsigned int saveflags = 0;
505 +
506 + assert(0 != jupe);
507 +
508 + saveflags = jupe->ju_flags;
509 +
510 + if (!JupeIsLocal(jupe)) {
511 + if (flags & JUPE_LOCAL)
512 + jupe->ju_flags |= JUPE_LDEACT;
513 + else {
514 + jupe->ju_flags &= ~JUPE_ACTIVE;
515 +
516 + if (jupe->ju_lastmod >= lastmod) /* force lastmod to increase */
517 + jupe->ju_lastmod++;
518 + else
519 + jupe->ju_lastmod = lastmod;
520 + }
521 +
522 + if ((saveflags & JUPE_ACTMASK) != JUPE_ACTIVE)
523 + return 0; /* was inactive to begin with */
524 + }
525 +
526 + /* Inform ops and log it */
527 + sendto_opmask_butone(0, SNO_NETWORK, "%s %s JUPE for %s, expiring at %Tu: "
528 + "%s",
529 + (feature_bool(FEAT_HIS_SNOTICES) || IsServer(sptr)) ?
530 + get_client_name_and_opername(sptr) :
531 + cli_name((cli_user(sptr))->server),
532 + JupeIsLocal(jupe) ? "removing local" : "deactivating",
533 + jupe->ju_server, jupe->ju_expire + TSoffset,
534 + jupe->ju_reason);
535 +
536 + log_write(LS_JUPE, L_INFO, LOG_NOSNOTICE,
537 + "%#C %s JUPE for %s, expiring at %Tu: %s", sptr,
538 + JupeIsLocal(jupe) ? "removing local" : "deactivating",
539 + jupe->ju_server, jupe->ju_expire + TSoffset, jupe->ju_reason);
540 +
541 + /* local jupe removed by remote user, inform oper of success */
542 + if ((flags & JUPE_LOCAL) && IsUser(sptr) && !MyUser(sptr))
543 + sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :%s removing local JUPE for %s, expiring at %Tu: %s",
544 + sptr, cli_name(sptr), jupe->ju_server, jupe->ju_expire + TSoffset, jupe->ju_reason);
545 +
546 + if (JupeIsLocal(jupe))
547 + jupe_free(jupe);
548 + else if (!(flags & JUPE_LOCAL)) /* don't propagate local changes */
549 + propagate_jupe(cptr, sptr, jupe);
550 +
551 + return 0;
552 +}
553 +
554 +/** Find a jupe by name.
555 + * @param[in] server %Jupe name to search for.
556 + * @return Matching jupe (or NULL if none match).
557 + */
558 +struct Jupe *
559 +jupe_find(char *server)
560 +{
561 + struct Jupe* jupe;
562 + struct Jupe* sjupe;
563 +
564 + for (jupe = GlobalJupeList; jupe; jupe = sjupe) { /* go through jupes */
565 + sjupe = jupe->ju_next;
566 +
567 + if (jupe->ju_expire <= CurrentTime) /* expire any that need expiring */
568 + jupe_free(jupe);
569 + else if (0 == ircd_strcmp(server, jupe->ju_server)) /* found it yet? */
570 + return jupe;
571 + }
572 +
573 + return 0;
574 +}
575 +
576 +/** Unlink and free an unused jupe.
577 + * @param[in] jupe Server jupe to free.
578 + */
579 +void
580 +jupe_free(struct Jupe* jupe)
581 +{
582 + assert(0 != jupe);
583 +
584 + *jupe->ju_prev_p = jupe->ju_next; /* squeeze this jupe out */
585 + if (jupe->ju_next)
586 + jupe->ju_next->ju_prev_p = jupe->ju_prev_p;
587 +
588 + MyFree(jupe->ju_server); /* and free up the memory */
589 + MyFree(jupe->ju_reason);
590 + MyFree(jupe);
591 +}
592 +
593 +/** Send the full list of active global jupes to \a cptr.
594 + * @param[in] cptr Local server to send jupes to.
595 + */
596 +void
597 +jupe_burst(struct Client *cptr)
598 +{
599 + struct Jupe *jupe;
600 + struct Jupe *sjupe;
601 +
602 + for (jupe = GlobalJupeList; jupe; jupe = sjupe) { /* go through jupes */
603 + sjupe = jupe->ju_next;
604 +
605 + if (jupe->ju_expire <= CurrentTime) /* expire any that need expiring */
606 + jupe_free(jupe);
607 + else if (!JupeIsLocal(jupe)) /* forward global jupes */
608 + sendcmdto_one(&me, CMD_JUPE, cptr, "* %c%s %Tu %Tu :%s",
609 + JupeIsRemActive(jupe) ? '+' : '-', jupe->ju_server,
610 + jupe->ju_expire - CurrentTime, jupe->ju_lastmod,
611 + jupe->ju_reason);
612 + }
613 +}
614 +
615 +/** Forward a jupe to another server.
616 + * @param[in] cptr %Server to send jupe to.
617 + * @param[in] jupe Jupe to forward.
618 + */
619 +int
620 +jupe_resend(struct Client *cptr, struct Jupe *jupe)
621 +{
622 + if (JupeIsLocal(jupe)) /* don't propagate local jupes */
623 + return 0;
624 +
625 + sendcmdto_one(&me, CMD_JUPE, cptr, "* %c%s %Tu %Tu :%s",
626 + JupeIsRemActive(jupe) ? '+' : '-', jupe->ju_server,
627 + jupe->ju_expire - CurrentTime, jupe->ju_lastmod,
628 + jupe->ju_reason);
629 +
630 + return 0;
631 +}
632 +
633 +/** Send a jupe (or a list of jupes) to a server.
634 + * @param[in] sptr Client searching for jupes.
635 + * @param[in] server Name of jupe to search for (if NULL, list all).
636 + * @return Zero.
637 + */
638 +int
639 +jupe_list(struct Client *sptr, char *server)
640 +{
641 + struct Jupe *jupe;
642 + struct Jupe *sjupe;
643 +
644 + if (server) {
645 + if (!(jupe = jupe_find(server))) /* no such jupe */
646 + return send_reply(sptr, ERR_NOSUCHJUPE, server);
647 +
648 + /* send jupe information along */
649 + send_reply(sptr, RPL_JUPELIST, jupe->ju_server, jupe->ju_expire + TSoffset,
650 + JupeIsLocal(jupe) ? cli_name(&me) : "*",
651 + JupeIsActive(jupe) ? '+' : '-', jupe->ju_reason);
652 + } else {
653 + for (jupe = GlobalJupeList; jupe; jupe = sjupe) { /* go through jupes */
654 + sjupe = jupe->ju_next;
655 +
656 + if (jupe->ju_expire <= CurrentTime) /* expire any that need expiring */
657 + jupe_free(jupe);
658 + else /* send jupe information along */
659 + send_reply(sptr, RPL_JUPELIST, jupe->ju_server,
660 + jupe->ju_expire + TSoffset,
661 + JupeIsLocal(jupe) ? cli_name(&me) : "*",
662 + JupeIsActive(jupe) ? '+' : '-', jupe->ju_reason);
663 + }
664 + }
665 +
666 + /* end of jupe information */
667 + return send_reply(sptr, RPL_ENDOFJUPELIST);
668 +}
669 +
670 +/** Count welcome and memory used by it.
671 + * @param[out] we_size Receives total number of bytes allocated for welcome.
672 + * @return Number of welcomes currently allocated.
673 + */
674 +int
675 +welcome_memory_count(size_t *we_size)
676 +{
677 + struct Jupe *jupe;
678 + unsigned int ju = 0;
679 +
680 + for (jupe = GlobalJupeList; jupe; jupe = jupe->ju_next)
681 + {
682 + ju++;
683 + *ju_size += sizeof(struct Jupe);
684 + *ju_size += jupe->ju_server ? (strlen(jupe->ju_server) + 1) : 0;
685 + *ju_size += jupe->ju_reason ? (strlen(jupe->ju_reason) + 1) : 0;
686 + }
687 + return ju;
688 +}
689 \ No newline at end of file