X-Git-Url: http://git.pk910.de/?p=ircu2.10.12-pk.git;a=blobdiff_plain;f=ircd%2Fdestruct_event.c;fp=ircd%2Fdestruct_event.c;h=b16fd98319a5b1e33643137440cf34a055f8090e;hp=0000000000000000000000000000000000000000;hb=0400a5a6479398d82526785c18c0df8bc8b92dce;hpb=d17e10da972ce5776c60b4c317267c6abe0e1ead diff --git a/ircd/destruct_event.c b/ircd/destruct_event.c new file mode 100644 index 0000000..b16fd98 --- /dev/null +++ b/ircd/destruct_event.c @@ -0,0 +1,158 @@ +/* + * IRC - Internet Relay Chat, ircd/destruct_event.c + * Copyright (C) 2002 Carlo Wood + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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. + */ +/** @file + * @brief Implementation of timed channel destruction events. + * @version $Id$ + */ +#include "config.h" + +#include "channel.h" /* destruct_channel */ +#include "s_debug.h" +#include "ircd_alloc.h" +#include "ircd.h" +#include "ircd_events.h" +#include "ircd_log.h" +#include "send.h" +#include "msg.h" + +/* #include -- Now using assert in ircd_log.h */ +#include + +/** Structure describing a destruction event. */ +struct DestructEvent { + struct DestructEvent* next_event; /**< Next event in the queue. */ + struct DestructEvent* prev_event; /**< Previous event in the queue. */ + time_t expires; /**< When the destruction should happen. */ + struct Channel* chptr; /**< Channel to destroy. */ +}; + +/** Head of short-delay destruction events. */ +static struct DestructEvent* minute_list_top; +/** Tail of short-delay destruction events. */ +static struct DestructEvent* minute_list_bottom; +/** Head of long-delay destruction events. */ +static struct DestructEvent* days_list_top; +/** Tail of long-delay destruction events. */ +static struct DestructEvent* days_list_bottom; + +/** Schedule a short-delay destruction event for \a chptr. + * @param[in] chptr Channel to destroy. + */ +void schedule_destruct_event_1m(struct Channel* chptr) +{ + struct DestructEvent* new_event; + + /* Ignore request when we already have a destruct request */ + if (chptr->destruct_event) + return; + + /* Create a new destruct event and add it at the top of the list. */ + new_event = (struct DestructEvent*)MyMalloc(sizeof(struct DestructEvent)); + new_event->expires = TStime() + 60; /* 1 minute from now */ + new_event->next_event = NULL; + new_event->prev_event = minute_list_top; + new_event->chptr = chptr; + + if (minute_list_top) + minute_list_top->next_event = new_event; + minute_list_top = new_event; + if (!minute_list_bottom) + minute_list_bottom = new_event; + + chptr->destruct_event = new_event; +} + +/** Schedule a long-delay destruction event for \a chptr. + * @param[in] chptr Channel to destroy. + */ +void schedule_destruct_event_48h(struct Channel* chptr) +{ + struct DestructEvent* new_event; + + /* Ignore request when we already have a destruct request */ + if (chptr->destruct_event) + return; + + /* Create a new destruct event and add it at the top of the list. */ + new_event = (struct DestructEvent*)MyMalloc(sizeof(struct DestructEvent)); + new_event->expires = TStime() + 172800; /* 48 hours from now */ + new_event->next_event = NULL; + new_event->prev_event = days_list_top; + new_event->chptr = chptr; + + if (days_list_top) + days_list_top->next_event = new_event; + days_list_top = new_event; + if (!days_list_bottom) + days_list_bottom = new_event; + + chptr->destruct_event = new_event; +} + +/** Unlink a destruction event for a channel. + * @param[in] chptr Channel that is being destroyed early. + */ +void remove_destruct_event(struct Channel* chptr) +{ + struct DestructEvent* event = chptr->destruct_event; + + assert(event != NULL); + + /* unlink event */ + if (event->prev_event) + event->prev_event->next_event = event->next_event; + if (event->next_event) + event->next_event->prev_event = event->prev_event; + + /* correct top and bottom pointers */ + if (days_list_top == event) + days_list_top = event->prev_event; + if (minute_list_top == event) + minute_list_top = event->prev_event; + if (days_list_bottom == event) + days_list_bottom = event->next_event; + if (minute_list_bottom == event) + minute_list_bottom = event->next_event; + + /* Free memory */ + MyFree(event); + + chptr->destruct_event = NULL; +} + +/** Execute expired channel destruction events. + * @param[in] ev Expired timer event (ignored). + */ +void exec_expired_destruct_events(struct Event* ev) +{ + int i = 0; + struct DestructEvent** list_bottom; + for(list_bottom = &minute_list_bottom; i < 2; ++i, list_bottom = &days_list_bottom) + { + while (*list_bottom && TStime() >= (*list_bottom)->expires) + { + struct Channel* chptr = (*list_bottom)->chptr; + /* Send DESTRUCT message */ + sendcmdto_serv_butone(&me, CMD_DESTRUCT, 0, "%s %Tu", chptr->chname, chptr->creationtime); + remove_destruct_event(chptr); + destruct_channel(chptr); + } + } +} +