X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=ircd%2Fjupe.c;h=243ae626df4fd5072160ef12934b922c15575e6e;hb=refs%2Fheads%2Fupstream;hp=bde16cbf9665a3decccb4e8b19721032f5dc39dd;hpb=aaa7ba6e9b842215aff8289b03629a3e9c608f4b;p=ircu2.10.12-pk.git diff --git a/ircd/jupe.c b/ircd/jupe.c index bde16cb..243ae62 100644 --- a/ircd/jupe.c +++ b/ircd/jupe.c @@ -17,14 +17,21 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id$ */ +/** @file + * @brief Implementation of juped server handling functions. + * @version $Id$ + */ +#include "config.h" + #include "jupe.h" #include "client.h" #include "hash.h" #include "ircd.h" #include "ircd_alloc.h" +#include "ircd_features.h" +#include "ircd_log.h" +#include "ircd_reply.h" #include "ircd_string.h" #include "match.h" #include "msg.h" @@ -34,13 +41,21 @@ #include "s_misc.h" #include "send.h" #include "struct.h" -#include "support.h" #include "sys.h" /* FALSE bleah */ -#include +/* #include -- Now using assert in ircd_log.h */ +#include -static struct Jupe* GlobalJupeList = 0; +/** List of jupes. */ +static struct Jupe *GlobalJupeList = 0; +/** Allocate a new jupe with the given parameters. + * @param[in] server Server name to jupe. + * @param[in] reason Reason for jupe. + * @param[in] expire Expiration time for jupe. + * @param[in] lastmod Last modification time for jupe. + * @param[in] flags Flags to set for the jupe. + */ static struct Jupe * make_jupe(char *server, char *reason, time_t expire, time_t lastmod, unsigned int flags) @@ -50,13 +65,14 @@ make_jupe(char *server, char *reason, time_t expire, time_t lastmod, ajupe = (struct Jupe*) MyMalloc(sizeof(struct Jupe)); /* alloc memory */ assert(0 != ajupe); - DupString(ajupe->ju_server, server); /* copy vital information */ + memset(ajupe, 0, sizeof(*ajupe)); + DupString(ajupe->ju_server, server); /* copy vital information */ DupString(ajupe->ju_reason, reason); ajupe->ju_expire = expire; ajupe->ju_lastmod = lastmod; - ajupe->ju_flags = flags; /* set jupe flags */ + ajupe->ju_flags = flags & JUPE_MASK; /* set jupe flags */ - ajupe->ju_next = GlobalJupeList; /* link it into the list */ + ajupe->ju_next = GlobalJupeList; /* link it into the list */ ajupe->ju_prev_p = &GlobalJupeList; if (GlobalJupeList) GlobalJupeList->ju_prev_p = &ajupe->ju_next; @@ -65,6 +81,11 @@ make_jupe(char *server, char *reason, time_t expire, time_t lastmod, return ajupe; } +/** Apply a jupe. + * @param[in] cptr Local client that sent us the jupe. + * @param[in] sptr Originator of the jupe. + * @param[in] jupe Jupe to check. + */ static int do_jupe(struct Client *cptr, struct Client *sptr, struct Jupe *jupe) { @@ -82,32 +103,39 @@ do_jupe(struct Client *cptr, struct Client *sptr, struct Jupe *jupe) return exit_client_msg(cptr, acptr, &me, "Juped: %s", jupe->ju_reason); } +/** Forward a jupe to another server. + * @param[in] cptr Local client that sent us the jupe. + * @param[in] sptr Originator of the jupe. + * @param[in] jupe Jupe to forward. + */ static void propagate_jupe(struct Client *cptr, struct Client *sptr, struct Jupe *jupe) { if (JupeIsLocal(jupe)) /* don't propagate local jupes */ return; - if (IsUser(sptr)) /* select correct prefix */ - sendto_serv_butone(cptr, "%s%s " TOK_JUPE " * %c%s " TIME_T_FMT " " - TIME_T_FMT " :%s", NumNick(sptr), - JupeIsActive(jupe) ? '+' : '-', jupe->ju_server, - jupe->ju_expire - TStime(), jupe->ju_lastmod, - jupe->ju_reason); - else - sendto_serv_butone(cptr, "%s " TOK_JUPE " * %c%s " TIME_T_FMT " " - TIME_T_FMT " :%s", NumServ(sptr), - JupeIsActive(jupe) ? '+' : '-', jupe->ju_server, - jupe->ju_expire - TStime(), jupe->ju_lastmod, - jupe->ju_reason); + sendcmdto_serv_butone(sptr, CMD_JUPE, cptr, "* %c%s %Tu %Tu :%s", + JupeIsRemActive(jupe) ? '+' : '-', jupe->ju_server, + jupe->ju_expire - CurrentTime, jupe->ju_lastmod, + jupe->ju_reason); } +/** Add a new server jupe. + * @param[in] cptr Local client that sent us the jupe. + * @param[in] sptr Originator of the jupe. + * @param[in] server Server name to jupe. + * @param[in] reason Reason for the jupe. + * @param[in] expire Jupe duration in seconds. + * @param[in] lastmod Last modification timestamp (or NULL). + * @param[in] flags Flags to set on jupe. + * @return Zero, unless the jupe causes \a cptr to be SQUIT, in which + * case CPTR_KILLED. + */ int jupe_add(struct Client *cptr, struct Client *sptr, char *server, char *reason, - time_t expire, time_t lastmod, int local, int active) + time_t expire, time_t lastmod, unsigned int flags) { struct Jupe *ajupe; - unsigned int flags = 0; assert(0 != server); assert(0 != reason); @@ -118,38 +146,25 @@ jupe_add(struct Client *cptr, struct Client *sptr, char *server, char *reason, */ if (expire <= 0 || expire > JUPE_MAX_EXPIRE) { if (!IsServer(cptr) && MyConnect(cptr)) - sendto_one(cptr, err_str(ERR_BADEXPIRE), me.name, cptr->name, expire); + send_reply(cptr, ERR_BADEXPIRE, expire); return 0; } - expire += TStime(); /* convert from lifetime to timestamp */ + expire += CurrentTime; /* convert from lifetime to timestamp */ /* Inform ops and log it */ - if (IsServer(sptr)) { - sendto_op_mask(SNO_NETWORK, "%s adding %sJUPE for %s, expiring at " - TIME_T_FMT ": %s", sptr->name, local ? "local " : "", - server, expire, reason); -#ifdef JPATH - write_log(JPATH, TIME_T_FMT " %s adding %sJUPE for %s, expiring at " - TIME_T_FMT ": %s\n", TStime(), sptr->name, - local ? "local " : "", server, expire, reason); -#endif /* JPATH */ - } else { - sendto_op_mask(SNO_NETWORK, "%s adding %sJUPE for %s, expiring at " - TIME_T_FMT ": %s", sptr->user->server->name, - local ? "local " : "", server, expire, - reason); -#ifdef JPATH - write_log(JPATH, TIME_T_FMT, " %s!%s@%s adding %sJUPE for %s, expiring at " - TIME_T_FMT ": %s\n", TStime(), sptr->name, sptr->user->username, - sptr->user->host, local ? "local " : "", server, expire, reason); -#endif /* JPATH */ - } - - if (active) /* compute initial flags */ - flags |= JUPE_ACTIVE; - if (local) - flags |= JUPE_LOCAL; + sendto_opmask_butone(0, SNO_NETWORK, "%s adding %sJUPE for %s, expiring at " + "%Tu: %s", + (feature_bool(FEAT_HIS_SNOTICES) || IsServer(sptr)) ? + cli_name(sptr) : + cli_name((cli_user(sptr))->server), + flags & JUPE_LOCAL ? "local " : "", server, + expire + TSoffset, reason); + + log_write(LS_JUPE, L_INFO, LOG_NOSNOTICE, + "%#C adding %sJUPE for %s, expiring at %Tu: %s", sptr, + flags & JUPE_LOCAL ? "local " : "", server, expire + TSoffset, + reason); /* make the jupe */ ajupe = make_jupe(server, reason, expire, lastmod, flags); @@ -159,86 +174,119 @@ jupe_add(struct Client *cptr, struct Client *sptr, char *server, char *reason, return do_jupe(cptr, sptr, ajupe); /* remove server if necessary */ } +/** Activate a jupe, optionally changing its lastmod and flags. + * @param[in] cptr Local client that sent us the jupe. + * @param[in] sptr Originator of the jupe. + * @param[in] jupe Jupe to activate. + * @param[in] lastmod New timestamp for last modification of the jupe. + * @param[in] flags Flags to set on the jupe. + * @return Zero, unless the jupe causes \a cptr to be SQUIT, in which + * case CPTR_KILLED. + */ int jupe_activate(struct Client *cptr, struct Client *sptr, struct Jupe *jupe, - time_t lastmod) + time_t lastmod, unsigned int flags) { + unsigned int saveflags = 0; + assert(0 != jupe); - jupe->ju_flags |= JUPE_ACTIVE; - jupe->ju_lastmod = lastmod; + saveflags = jupe->ju_flags; - /* Inform ops and log it */ - if (IsServer(sptr)) { - sendto_op_mask(SNO_NETWORK, "%s activating %sJUPE for %s, expiring at " - TIME_T_FMT ": %s", sptr->name, JupeIsLocal(jupe) ? - "local " : "", jupe->ju_server, jupe->ju_expire, - jupe->ju_reason); -#ifdef JPATH - write_log(JPATH, TIME_T_FMT " %s activating %sJUPE for %s, expiring at " - TIME_T_FMT ": %s\n", TStime(), sptr->name, JupeIsLocal(jupe) ? - "local " : "", jupe->ju_server, jupe->ju_expire, - jupe->ju_reason); -#endif /* JPATH */ - } else { - sendto_op_mask(SNO_NETWORK, "%s activating %sJUPE for %s, expiring at " - TIME_T_FMT ": %s", sptr->user->server->name, - JupeIsLocal(jupe) ? "local " : "", jupe->ju_server, - jupe->ju_expire, jupe->ju_reason); -#ifdef JPATH - write_log(JPATH, TIME_T_FMT, " %s!%s@%s activating %sJUPE for %s, " - "expiring at " TIME_T_FMT ": %s\n", TStime(), sptr->name, - sptr->user->username, sptr->user->host, JupeIsLocal(jupe) ? - "local " : "", jupe->ju_server, jupe->ju_expire, - jupe->ju_reason); -#endif /* JPATH */ + if (flags & JUPE_LOCAL) + jupe->ju_flags &= ~JUPE_LDEACT; + else { + jupe->ju_flags |= JUPE_ACTIVE; + + if (jupe->ju_lastmod >= lastmod) /* force lastmod to increase */ + jupe->ju_lastmod++; + else + jupe->ju_lastmod = lastmod; } - propagate_jupe(cptr, sptr, jupe); + if ((saveflags & JUPE_ACTMASK) == JUPE_ACTIVE) + return 0; /* was active to begin with */ + + /* Inform ops and log it */ + sendto_opmask_butone(0, SNO_NETWORK, "%s activating JUPE for %s, expiring " + "at %Tu: %s", + (feature_bool(FEAT_HIS_SNOTICES) || IsServer(sptr)) ? + cli_name(sptr) : + cli_name((cli_user(sptr))->server), + jupe->ju_server, jupe->ju_expire + TSoffset, + jupe->ju_reason); + + log_write(LS_JUPE, L_INFO, LOG_NOSNOTICE, + "%#C activating JUPE for %s, expiring at %Tu: %s",sptr, + jupe->ju_server, jupe->ju_expire + TSoffset, jupe->ju_reason); + + if (!(flags & JUPE_LOCAL)) /* don't propagate local changes */ + propagate_jupe(cptr, sptr, jupe); return do_jupe(cptr, sptr, jupe); } +/** Deactivate a jupe. + * @param[in] cptr Local client that sent us the jupe. + * @param[in] sptr Originator of the jupe. + * @param[in] jupe Jupe to deactivate. + * @param[in] lastmod New timestamp for last modification of the jupe. + * @param[in] flags Flags to set on the jupe. + * @return Zero. + */ int jupe_deactivate(struct Client *cptr, struct Client *sptr, struct Jupe *jupe, - time_t lastmod) + time_t lastmod, unsigned int flags) { + unsigned int saveflags = 0; + assert(0 != jupe); - jupe->ju_flags &= ~JUPE_ACTIVE; - jupe->ju_lastmod = lastmod; + saveflags = jupe->ju_flags; - /* Inform ops and log it */ - if (IsServer(sptr)) { - sendto_op_mask(SNO_NETWORK, "%s deactivating %sJUPE for %s, expiring at " - TIME_T_FMT ": %s", sptr->name, JupeIsLocal(jupe) ? - "local " : "", jupe->ju_server, jupe->ju_expire, - jupe->ju_reason); -#ifdef JPATH - write_log(JPATH, TIME_T_FMT " %s deactivating %sJUPE for %s, expiring at " - TIME_T_FMT ": %s\n", TStime(), sptr->name, JupeIsLocal(jupe) ? - "local " : "", jupe->ju_server, jupe->ju_expire, - jupe->ju_reason); -#endif /* JPATH */ - } else { - sendto_op_mask(SNO_NETWORK, "%s deactivating %sJUPE for %s, expiring at " - TIME_T_FMT ": %s", sptr->user->server->name, - JupeIsLocal(jupe) ? "local " : "", jupe->ju_server, - jupe->ju_expire, jupe->ju_reason); -#ifdef JPATH - write_log(JPATH, TIME_T_FMT, " %s!%s@%s deactivating %sJUPE for %s, " - "expiring at " TIME_T_FMT ": %s\n", TStime(), sptr->name, - sptr->user->username, sptr->user->host, JupeIsLocal(jupe) ? - "local " : "", jupe->ju_server, jupe->ju_expire, - jupe->ju_reason); -#endif /* JPATH */ + if (!JupeIsLocal(jupe)) { + if (flags & JUPE_LOCAL) + jupe->ju_flags |= JUPE_LDEACT; + else { + jupe->ju_flags &= ~JUPE_ACTIVE; + + if (jupe->ju_lastmod >= lastmod) /* force lastmod to increase */ + jupe->ju_lastmod++; + else + jupe->ju_lastmod = lastmod; + } + + if ((saveflags & JUPE_ACTMASK) != JUPE_ACTIVE) + return 0; /* was inactive to begin with */ } - propagate_jupe(cptr, sptr, jupe); + /* Inform ops and log it */ + sendto_opmask_butone(0, SNO_NETWORK, "%s %s JUPE for %s, expiring at %Tu: " + "%s", + (feature_bool(FEAT_HIS_SNOTICES) || IsServer(sptr)) ? + cli_name(sptr) : + cli_name((cli_user(sptr))->server), + JupeIsLocal(jupe) ? "removing local" : "deactivating", + jupe->ju_server, jupe->ju_expire + TSoffset, + jupe->ju_reason); + + log_write(LS_JUPE, L_INFO, LOG_NOSNOTICE, + "%#C %s JUPE for %s, expiring at %Tu: %s", sptr, + JupeIsLocal(jupe) ? "removing local" : "deactivating", + jupe->ju_server, jupe->ju_expire + TSoffset, jupe->ju_reason); + + if (JupeIsLocal(jupe)) + jupe_free(jupe); + else if (!(flags & JUPE_LOCAL)) /* don't propagate local changes */ + propagate_jupe(cptr, sptr, jupe); return 0; } +/** Find a jupe by name. + * @param[in] server %Jupe name to search for. + * @return Matching jupe (or NULL if none match). + */ struct Jupe * jupe_find(char *server) { @@ -248,7 +296,7 @@ jupe_find(char *server) for (jupe = GlobalJupeList; jupe; jupe = sjupe) { /* go through jupes */ sjupe = jupe->ju_next; - if (jupe->ju_expire <= TStime()) /* expire any that need expiring */ + if (jupe->ju_expire <= CurrentTime) /* expire any that need expiring */ jupe_free(jupe); else if (0 == ircd_strcmp(server, jupe->ju_server)) /* found it yet? */ return jupe; @@ -257,6 +305,9 @@ jupe_find(char *server) return 0; } +/** Unlink and free an unused jupe. + * @param[in] jupe Server jupe to free. + */ void jupe_free(struct Jupe* jupe) { @@ -271,6 +322,9 @@ jupe_free(struct Jupe* jupe) MyFree(jupe); } +/** Send the full list of active global jupes to \a cptr. + * @param[in] cptr Local server to send jupes to. + */ void jupe_burst(struct Client *cptr) { @@ -280,29 +334,39 @@ jupe_burst(struct Client *cptr) for (jupe = GlobalJupeList; jupe; jupe = sjupe) { /* go through jupes */ sjupe = jupe->ju_next; - if (jupe->ju_expire <= TStime()) /* expire any that need expiring */ + if (jupe->ju_expire <= CurrentTime) /* expire any that need expiring */ jupe_free(jupe); else if (!JupeIsLocal(jupe)) /* forward global jupes */ - sendto_one(cptr, "%s " TOK_JUPE " * %c%s "TIME_T_FMT" "TIME_T_FMT" :%s", - NumServ(&me), JupeIsActive(jupe) ? '+' : '-', - jupe->ju_server, jupe->ju_expire - TStime(), - jupe->ju_lastmod, jupe->ju_reason); + sendcmdto_one(&me, CMD_JUPE, cptr, "* %c%s %Tu %Tu :%s", + JupeIsRemActive(jupe) ? '+' : '-', jupe->ju_server, + jupe->ju_expire - CurrentTime, jupe->ju_lastmod, + jupe->ju_reason); } } +/** Forward a jupe to another server. + * @param[in] cptr %Server to send jupe to. + * @param[in] jupe Jupe to forward. + */ int jupe_resend(struct Client *cptr, struct Jupe *jupe) { if (JupeIsLocal(jupe)) /* don't propagate local jupes */ return 0; - sendto_one(cptr, "%s " TOK_JUPE " * %c%s " TIME_T_FMT " " TIME_T_FMT " :%s", - NumServ(&me), JupeIsActive(jupe) ? '+' : '-', jupe->ju_server, - jupe->ju_expire - TStime(), jupe->ju_lastmod, jupe->ju_reason); + sendcmdto_one(&me, CMD_JUPE, cptr, "* %c%s %Tu %Tu :%s", + JupeIsRemActive(jupe) ? '+' : '-', jupe->ju_server, + jupe->ju_expire - CurrentTime, jupe->ju_lastmod, + jupe->ju_reason); return 0; } +/** Send a jupe (or a list of jupes) to a server. + * @param[in] sptr Client searching for jupes. + * @param[in] server Name of jupe to search for (if NULL, list all). + * @return Zero. + */ int jupe_list(struct Client *sptr, char *server) { @@ -310,30 +374,47 @@ jupe_list(struct Client *sptr, char *server) struct Jupe *sjupe; if (server) { - if (!(jupe = jupe_find(server))) { /* no such jupe */ - sendto_one(sptr, err_str(ERR_NOSUCHJUPE), me.name, sptr->name, server); - return 0; - } + if (!(jupe = jupe_find(server))) /* no such jupe */ + return send_reply(sptr, ERR_NOSUCHJUPE, server); /* send jupe information along */ - sendto_one(sptr, rpl_str(RPL_JUPELIST), me.name, sptr->name, - jupe->ju_server, jupe->ju_expire, JupeIsLocal(jupe) ? - me.name : "*", JupeIsActive(jupe) ? '+' : '-', jupe->ju_reason); + send_reply(sptr, RPL_JUPELIST, jupe->ju_server, jupe->ju_expire + TSoffset, + JupeIsLocal(jupe) ? cli_name(&me) : "*", + JupeIsActive(jupe) ? '+' : '-', jupe->ju_reason); } else { for (jupe = GlobalJupeList; jupe; jupe = sjupe) { /* go through jupes */ sjupe = jupe->ju_next; - if (jupe->ju_expire <= TStime()) /* expire any that need expiring */ + if (jupe->ju_expire <= CurrentTime) /* expire any that need expiring */ jupe_free(jupe); else /* send jupe information along */ - sendto_one(sptr, rpl_str(RPL_JUPELIST), me.name, sptr->name, - jupe->ju_server, jupe->ju_expire, JupeIsLocal(jupe) ? - me.name : "*", JupeIsActive(jupe) ? '+' : '-', - jupe->ju_reason); + send_reply(sptr, RPL_JUPELIST, jupe->ju_server, + jupe->ju_expire + TSoffset, + JupeIsLocal(jupe) ? cli_name(&me) : "*", + JupeIsActive(jupe) ? '+' : '-', jupe->ju_reason); } } /* end of jupe information */ - sendto_one(sptr, rpl_str(RPL_ENDOFJUPELIST), me.name, sptr->name); - return 0; + return send_reply(sptr, RPL_ENDOFJUPELIST); +} + +/** Count jupes and memory used by them. + * @param[out] ju_size Receives total number of bytes allocated for jupes. + * @return Number of jupes currently allocated. + */ +int +jupe_memory_count(size_t *ju_size) +{ + struct Jupe *jupe; + unsigned int ju = 0; + + for (jupe = GlobalJupeList; jupe; jupe = jupe->ju_next) + { + ju++; + *ju_size += sizeof(struct Jupe); + *ju_size += jupe->ju_server ? (strlen(jupe->ju_server) + 1) : 0; + *ju_size += jupe->ju_reason ? (strlen(jupe->ju_reason) + 1) : 0; + } + return ju; }