]>
jfr.im git - irc/quakenet/snircd.git/blob - ircd/m_destruct.c
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.
22 * $Id: m_destruct.c,v 1.9 2005/03/20 16:06:18 entrope Exp $
31 #include "ircd_reply.h"
32 #include "ircd_string.h"
38 #include "destruct_event.h"
40 /* #include <assert.h> -- Now using assert in ircd_log.h */
44 * ms_destruct - server message handler
46 * Added 1997 by Run, actually coded and used since 2002.
48 * parv[0] = sender prefix
49 * parv[1] = channel channelname
50 * parv[2] = channel time stamp
52 * This message is intended to destruct _empty_ channels.
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'.
90 int ms_destruct(struct Client
* cptr
, struct Client
* sptr
, int parc
, char* parv
[])
92 time_t chanTS
; /* Creation time of the channel */
93 struct Channel
* chptr
;
97 assert(IsServer(cptr
));
99 if (parc
< 3 || EmptyString(parv
[2]))
100 return need_more_params(sptr
,"DESTRUCT");
102 chanTS
= atoi(parv
[2]);
104 /* Ignore DESTRUCT messages for non-existing channels. */
105 if (!(chptr
= FindChannel(parv
[1])))
108 /* Ignore DESTRUCT when the channel is older than the
109 timestamp on the message. */
110 if (chanTS
> chptr
->creationtime
)
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
);
120 /* Pass on DESTRUCT message and ALSO bounce it back! */
121 sendcmdto_serv_butone(&me
, CMD_DESTRUCT
, 0, "%s %Tu", parv
[1], chanTS
);
123 /* Remove the empty channel. */
124 remove_destruct_event(chptr
);
125 destruct_channel(chptr
);