/* * node.C: Data structure management. * Rights to this code are documented in doc/pod/license.pod. * * Copyright © 2005-2007 Atheme Project (http://www.atheme.org) */ static char const rcsid[] = "$Id: node.C,v 1.5 2007/09/09 20:05:52 pippijn Exp $"; #include "atheme.h" #include "servers.h" #include #include "uplink.h" #include "privs.h" kline_t::list_type kline_t::list; /************* * L I S T S * *************/ void init_nodes (void) { #if 0 kline_heap = BlockHeapCreate (sizeof (kline_t), 16); #endif init_uplinks (); init_servers (); init_accounts (); init_users (); init_channels (); init_privs (); } /* Mark everything illegal, to be called before a rehash -- jilles */ void mark_all_illegal () { node_t *n, *tn; uplink_t *u; soper_t *soper; operclass_t *operclass; LIST_FOREACH (n, uplinks.head) { u = (uplink_t *) n->data; u->flags |= UPF_ILLEGAL; } /* just delete these, we can survive without for a while */ LIST_FOREACH_SAFE (n, tn, soperlist.head) { soper = (soper_t *) n->data; if (soper->flags & SOPER_CONF) soper_delete (soper); } /* no sopers pointing to these anymore */ LIST_FOREACH_SAFE (n, tn, operclasslist.head) { operclass = (operclass_t *) n->data; operclass_delete (operclass); } } /* Unmark everything illegal, to be called after a failed rehash -- jilles */ void unmark_all_illegal () { node_t *n; uplink_t *u; LIST_FOREACH (n, uplinks.head) { u = (uplink_t *) n->data; u->flags &= ~UPF_ILLEGAL; } } /* Remove illegal stuff, to be called after a successful rehash -- jilles */ void remove_illegals () { node_t *n, *tn; uplink_t *u; LIST_FOREACH_SAFE (n, tn, uplinks.head) { u = (uplink_t *) n->data; if (u->flags & UPF_ILLEGAL && u != curr_uplink) uplink_delete (u); } } /************* * K L I N E * *************/ kline_t * kline_t::create (char const * const user, char const * const host, char const * const reason, long duration) { kline_t *k; static unsigned int kcnt = 0; slog (LG_DEBUG, "kline_t::create(): %s@%s -> %s (%ld)", user, host, reason, duration); k = new kline_t; k->user = sstrdup (user); k->host = sstrdup (host); k->reason = sstrdup (reason); k->duration = duration; k->settime = NOW; k->expires = NOW + duration; k->number = ++kcnt; list.push_back (k); cnt.kline++; phandler->kline_sts ("*", user, host, duration, reason); return k; } void kline_t::destroy (char const * const user, char const * const host) { kline_t *k = find (user, host); if (!k) { slog (LG_DEBUG, "kline_t::destroy(): called for nonexistant kline: %s@%s", user, host); return; } slog (LG_DEBUG, "kline_t::destroy(): %s@%s -> %s", k->user, k->host, k->reason); /* only unkline if ircd has not already removed this -- jilles */ if (k->duration == 0 || k->expires > NOW) phandler->unkline_sts ("*", k->user, k->host); k->destroy (); } kline_t * kline_t::find (char const * const user, char const * const host) { kline_t *k; list_type::iterator klit = list.begin (); list_type::iterator klet = list.end (); while (klit != klet) { k = *klit; if ((!match (k->user, user)) && (!match (k->host, host))) return k; ++klit; } return NULL; } kline_t * kline_t::find (unsigned int number) { kline_t *k; list_type::iterator klit = list.begin (); list_type::iterator klet = list.end (); while (klit != klet) { k = *klit; if (k->number == number) return k; ++klit; } return NULL; } kline_t * kline_t::find (user_t *u) { kline_t *k; list_type::iterator klit = list.begin (); list_type::iterator klet = list.end (); while (klit != klet) { k = *klit; if (k->duration != 0 && k->expires <= NOW) continue; if (!match (k->user, u->user) && (!match (k->host, u->host) || !match (k->host, u->ip) || !match_ips (k->host, u->ip))) return k; ++klit; } return NULL; } void kline_t::expire (void *arg) { kline_t *k; std::vector mortals; list_type::iterator klit = list.begin (); list_type::iterator klet = list.end (); while (klit != klet) { k = *klit; if (k->duration == 0) continue; if (k->expires <= NOW) { snoop (_("KLINE:EXPIRE: \2%s@%s\2 set \2%s\2 ago by \2%s\2"), k->user, k->host, time_ago (k->settime), k->setby); verbose_wallops (_("AKILL expired on \2%s@%s\2, set by \2%s\2"), k->user, k->host, k->setby); mortals.push_back (k); } ++klit; } // We have to do this because we cannot destroy klines while iterating while (!mortals.empty ()) { mortals.back ()->destroy (); mortals.pop_back (); } }