]> jfr.im git - irc/quakenet/snircd.git/blame - ircd/m_destruct.c
merge 07 in
[irc/quakenet/snircd.git] / ircd / m_destruct.c
CommitLineData
189935b1 1/*
2 * IRC - Internet Relay Chat, ircd/m_destruct.c
d8e74551 3 * Copyright (C) 1997 Carlo Wood.
189935b1 4 *
5 * See file AUTHORS in IRC package for additional names of
6 * the programmers.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 1, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
d8e74551 22 * $Id: m_destruct.c,v 1.9 2005/03/20 16:06:18 entrope Exp $
189935b1 23 */
24
25#include "config.h"
26
27#include "client.h"
28#include "hash.h"
29#include "ircd.h"
30#include "ircd_log.h"
31#include "ircd_reply.h"
32#include "ircd_string.h"
33#include "msg.h"
34#include "numeric.h"
35#include "numnicks.h"
36#include "send.h"
37#include "channel.h"
38#include "destruct_event.h"
39
40/* #include <assert.h> -- Now using assert in ircd_log.h */
41#include <stdlib.h>
42
43/*
44 * ms_destruct - server message handler
45 *
46 * Added 1997 by Run, actually coded and used since 2002.
47 *
48 * parv[0] = sender prefix
49 * parv[1] = channel channelname
50 * parv[2] = channel time stamp
51 *
52 * This message is intended to destruct _empty_ channels.
53 *
54 * The reason it is needed is to somehow add the notion
55 * "I destructed information" to the networks state
56 * (also messages that are still propagating are part
57 * of the global state). Without it the network could
58 * easily be desynced as a result of destructing a channel
59 * on only a part of the network while keeping the modes
60 * and creation time on others.
61 * There are three possible ways a DESTRUCT message is
62 * handled by remote servers:
63 * 1) The channel is empty and has the same timestamp
64 * as on the message. Conclusion: The channel has
65 * not been destructed and recreated in the meantime,
66 * this means that the normal synchronization rules
67 * account and we react as if we decided to destruct
68 * the channel ourselves: we destruct the channel and
69 * send a DESTRUCT in all directions.
70 * 2) The channel is not empty. In case we cannot remove
71 * it and do not propagate the DESTRUCT message. Instead
72 * a resynchronizing BURST message is sent upstream
73 * in order to restore the channel on that side (which
74 * will have a TS younger than the current channel if
75 * it was recreated and will thus be fully synced, just
76 * like in the case of a real net-junction).
77 * 3) The channel is empty, but the creation time of the
78 * channel is older than the timestamp on the message.
79 * This can happen when there is more than one minute
80 * lag and remotely a channel was created slightly
81 * after we created the channel, being abandoned again
82 * and staying empty for a minute without that our
83 * CREATE reached that remote server. The remote server
84 * then could have generated the DESTRUCT. In the meantime
85 * our user also left the channel. We can ignore the
86 * destruct because it comes from an 'area' that will
87 * be overridden by our own CREATE: the state that generated
88 * this DESTRUCT is 'history'.
89 */
90int ms_destruct(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
91{
92 time_t chanTS; /* Creation time of the channel */
93 struct Channel* chptr;
94
95 assert(0 != cptr);
96 assert(0 != sptr);
97 assert(IsServer(cptr));
98
99 if (parc < 3 || EmptyString(parv[2]))
100 return need_more_params(sptr,"DESTRUCT");
101
102 chanTS = atoi(parv[2]);
103
104 /* Ignore DESTRUCT messages for non-existing channels. */
105 if (!(chptr = FindChannel(parv[1])))
106 return 0;
107
108 /* Ignore DESTRUCT when the channel is older than the
109 timestamp on the message. */
110 if (chanTS > chptr->creationtime)
111 return 0;
112
113 /* Don't pass on DESTRUCT messages for channels that
114 are not empty, but instead send a BURST msg upstream. */
115 if (chptr->users > 0) {
116 send_channel_modes(cptr, chptr);
117 return 0;
118 }
119
120 /* Pass on DESTRUCT message and ALSO bounce it back! */
121 sendcmdto_serv_butone(&me, CMD_DESTRUCT, 0, "%s %Tu", parv[1], chanTS);
122
123 /* Remove the empty channel. */
d8e74551 124 remove_destruct_event(chptr);
189935b1 125 destruct_channel(chptr);
126
127 return 0;
128}