2 * IRC - Internet Relay Chat, ircd/m_destruct.c
3 * Copyright (C) 1997 Carlo Wood.
5 * See file AUTHORS in IRC package for additional names of
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)
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.
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.
30 #include "ircd_reply.h"
31 #include "ircd_string.h"
37 #include "destruct_event.h"
43 * ms_destruct - server message handler
45 * Added 1997 by Run, actually coded and used since 2002.
47 * parv[0] = sender prefix
48 * parv[1] = channel channelname
49 * parv[2] = channel time stamp
51 * This message is intended to destruct _empty_ channels.
53 * The reason it is needed is to somehow add the notion
54 * "I destructed information" to the networks state
55 * (also messages that are still propagating are part
56 * of the global state). Without it the network could
57 * easily be desynced as a result of destructing a channel
58 * on only a part of the network while keeping the modes
59 * and creation time on others.
60 * There are three possible ways a DESTRUCT message is
61 * handled by remote servers:
62 * 1) The channel is empty and has the same timestamp
63 * as on the message. Conclusion: The channel has
64 * not been destructed and recreated in the meantime,
65 * this means that the normal synchronization rules
66 * account and we react as if we decided to destruct
67 * the channel ourselfs: we destruct the channel and
68 * send a DESTRUCT in all directions.
69 * 2) The channel is not empty. In case we cannot remove
70 * it and do not propagate the DESTRUCT message. Instead
71 * a resynchronizing BURST message is sent upstream
72 * in order to restore the channel on that side (which
73 * will have a TS younger than the current channel if
74 * it was recreated and will thus be fully synced, just
75 * like in the case of a real net-junction).
76 * 3) The channel is empty, but the creation time of the
77 * channel is older than the timestamp on the message.
78 * This can happen when there is more than one minute
79 * lag and remotely a channel was created slightly
80 * after we created the channel, being abandoned again
81 * and staying empty for a minute without that our
82 * CREATE reached that remote server. The remote server
83 * then could have generated the DESTRUCT. In the meantime
84 * our user also left the channel. We can ignore the
85 * destruct because it comes from an 'area' that will
86 * be overriden by our own CREATE: the state that generated
87 * this DESTRUCT is 'history'.
89 int ms_destruct(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
91 time_t chanTS; /* Creation time of the channel */
92 struct Channel* chptr;
96 assert(IsServer(cptr));
98 if (parc < 3 || EmptyString(parv[2]))
99 return need_more_params(sptr,"DESTRUCT");
101 chanTS = atoi(parv[2]);
103 /* Ignore DESTRUCT messages for non-existing channels. */
104 if (!(chptr = FindChannel(parv[1])))
107 /* Ignore DESTRUCT when the channel is older than the
108 timestamp on the message. */
109 if (chanTS > chptr->creationtime)
112 /* Don't pass on DESTRUCT messages for channels that
113 are not empty, but instead send a BURST msg upstream. */
114 if (chptr->users > 0) {
115 send_channel_modes(cptr, chptr);
119 /* Pass on DESTRUCT message and ALSO bounce it back! */
120 sendcmdto_serv_butone(&me, CMD_DESTRUCT, 0, "%s %Tu", parv[1], chanTS);
122 /* Remove the empty channel. */
123 remove_destruct_event(chptr);
124 destruct_channel(chptr);