152 lines
4.6 KiB
C
152 lines
4.6 KiB
C
/*
|
|
* IRC - Internet Relay Chat, ircd/destruct_event.c
|
|
* Copyright (C) 2002 Carlo Wood <carlo@alinoe.com>
|
|
*
|
|
* 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: destruct_event.c 1271 2004-12-11 05:14:07Z klmitch $
|
|
*/
|
|
#include "config.h"
|
|
|
|
#include "channel.h" /* destruct_channel */
|
|
#include "destruct_event.h"
|
|
#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 <assert.h> -- Now using assert in ircd_log.h */
|
|
#include <stdlib.h>
|
|
|
|
/** 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);
|
|
}
|
|
}
|
|
}
|
|
|