/[svn]/ircd-hybrid-7.2/modules/m_tburst.c
ViewVC logotype

Annotation of /ircd-hybrid-7.2/modules/m_tburst.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 394 - (hide annotations)
Fri Feb 3 17:32:17 2006 UTC (13 years, 11 months ago) by michael
File MIME type: text/x-chdr
File size: 7426 byte(s)
- Fixed TBURST as reported by ThaPrince

1 michael 325 /* modules/m_tburst.c
2     * Copyright (C) 2002, 2003, 2004, 2005 Hybrid Development Team
3     *
4     * Redistribution and use in source and binary forms, with or without
5     * modification, are permitted provided that the following conditions are
6     * met:
7     *
8     * 1.Redistributions of source code must retain the above copyright notice,
9     * this list of conditions and the following disclaimer.
10     * 2.Redistributions in binary form must reproduce the above copyright
11     * notice, this list of conditions and the following disclaimer in the
12     * documentation and/or other materials provided with the distribution.
13     * 3.The name of the author may not be used to endorse or promote products
14     * derived from this software without specific prior written permission.
15     *
16     * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17     * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18     * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19     * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20     * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21     * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22     * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24     * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
25     * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26     * POSSIBILITY OF SUCH DAMAGE.
27     *
28 michael 335 * $Id$
29 michael 325 */
30    
31     #include "stdinc.h"
32     #include "handlers.h"
33     #include "client.h"
34     #include "common.h"
35     #include "ircd.h"
36     #include "send.h"
37     #include "msg.h"
38     #include "modules.h"
39     #include "hash.h"
40     #include "s_serv.h"
41     #include "s_conf.h"
42    
43     static void ms_tb(struct Client *, struct Client *, int, char *[]);
44     static void ms_tburst(struct Client *, struct Client *, int, char *[]);
45 michael 335 static void set_topic(struct Client *, struct Channel *, time_t,
46     const char *, const char *);
47 michael 325
48     struct Message tburst_msgtab = {
49 michael 394 "TBURST", 0, 0, 5, 0, MFLG_SLOW, 0,
50 michael 335 { m_ignore, m_ignore, ms_tburst, m_ignore, m_ignore, m_ignore }
51 michael 325 };
52    
53     struct Message tb_msgtab = {
54 michael 338 "TB", 0, 0, 4, 0, MFLG_SLOW, 0,
55 michael 335 { m_ignore, m_ignore, ms_tb, m_ignore, m_ignore, m_ignore }
56 michael 325 };
57    
58     #ifndef STATIC_MODULES
59    
60     void
61     _modinit(void)
62     {
63     mod_add_cmd(&tb_msgtab);
64     add_capability("TB", CAP_TB, 1);
65    
66     mod_add_cmd(&tburst_msgtab);
67     add_capability("TBURST", CAP_TBURST, 1);
68     }
69    
70     void
71     _moddeinit(void)
72     {
73     mod_del_cmd(&tb_msgtab);
74     delete_capability("TB");
75    
76     mod_del_cmd(&tburst_msgtab);
77     delete_capability("TBURST");
78     }
79    
80     const char *_version = "$Revision: 122 $";
81    
82     #endif /* !STATIC_MODULES */
83    
84     /* ms_tburst()
85     *
86     * parv[0] = sender prefix
87     * parv[1] = channel timestamp
88     * parv[2] = channel
89     * parv[3] = topic timestamp
90     * parv[4] = topic setter
91     * parv[5] = topic
92     */
93     static void
94     ms_tburst(struct Client *client_p, struct Client *source_p,
95     int parc, char *parv[])
96     {
97     struct Channel *chptr = NULL;
98 michael 336 int accept_remote = 0;
99     time_t remote_channel_ts = atol(parv[1]);
100     time_t remote_topic_ts = atol(parv[3]);
101 michael 394 const char *topic = "";
102     const char *setby = "";
103 michael 325
104 michael 336 /*
105     * Do NOT test parv[5] for an empty string and return if true!
106     * parv[5] CAN be an empty string, i.e. if the other side wants
107     * to unset our topic. Don't forget: an empty topic is also a
108     * valid topic.
109     */
110    
111    
112 michael 325 if ((chptr = hash_find_channel(parv[2])) == NULL)
113     return;
114    
115 michael 394 if (parc == 6)
116     {
117     topic = parv[5];
118     setby = parv[4];
119     }
120    
121 michael 336 /*
122     * The logic for accepting and rejecting channel topics was
123     * always a bit hairy, so now we got exactly 2 cases where
124     * we would accept a bursted topic
125     *
126     * Case 1:
127     * The TS of the remote channel is older than ours
128     * Case 2:
129     * The TS of the remote channel is equal to ours AND
130     * the TS of the remote topic is newer than ours
131 michael 325 */
132 michael 336 if (remote_channel_ts < chptr->channelts)
133     accept_remote = 1;
134     else if (remote_channel_ts == chptr->channelts)
135     if (remote_topic_ts > chptr->topic_time)
136     accept_remote = 1;
137    
138     if (accept_remote)
139     {
140 michael 394 int topic_differs = strcmp(chptr->topic ? chptr->topic : "", topic);
141 michael 336
142 michael 394 set_channel_topic(chptr, topic, setby, remote_topic_ts);
143 michael 336
144     if (topic_differs)
145     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s TOPIC %s :%s",
146     ConfigServerHide.hide_servers ? me.name : source_p->name,
147     chptr->chname, chptr->topic == NULL ? "" : chptr->topic);
148     }
149    
150     /*
151     * Always propagate what we have received, not only if we accept the topic.
152     * This will keep other servers in sync.
153     */
154     sendto_server(source_p, NULL, chptr, CAP_TBURST, NOCAPS, NOFLAGS,
155     ":%s TBURST %s %s %s %s :%s",
156 michael 394 source_p->name, parv[1], parv[2], parv[3], setby, topic);
157     if (parc > 6 && *topic != '\0') /* unsetting a topic is not supported by TB */
158     sendto_server(source_p, NULL, chptr, CAP_TB, CAP_TBURST, NOFLAGS,
159     ":%s TB %s %s %s :%s",
160     source_p->name, parv[1], parv[2], setby, topic);
161 michael 325 }
162    
163     /* ms_tb()
164     *
165     * parv[0] = sender prefix
166     * parv[1] = channel name
167     * parv[2] = topic timestamp
168     * parv[3] = topic setter OR topic itself if parc == 4
169     * parv[4] = topic itself if parc == 5
170     */
171     #define tb_channel parv[1]
172     #define tb_topicts_str parv[2]
173    
174     static void
175     ms_tb(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
176     {
177     struct Channel *chptr;
178     time_t tb_topicts = atol(tb_topicts_str);
179     char *tb_whoset = NULL;
180     char *tb_topic = NULL;
181    
182     if ((chptr = hash_find_channel(tb_channel)) == NULL)
183     return;
184    
185     if (parc == 5)
186     {
187     tb_whoset = parv[3];
188     tb_topic = parv[4];
189     }
190     else
191     {
192     tb_whoset = source_p->name;
193     tb_topic = parv[3];
194     }
195    
196     set_topic(source_p, chptr, tb_topicts, tb_whoset, tb_topic);
197     }
198    
199     /*
200     * set_topic
201     *
202     * inputs - source_p pointer
203     * - channel pointer
204     * - topicts to set
205     * - who to set as who doing the topic
206     * - topic
207     * output - none
208     * Side effects - simply propagates topic as needed
209     * little helper function, could be removed
210     */
211     static void
212 michael 335 set_topic(struct Client *source_p, struct Channel *chptr, time_t topicts,
213     const char *topicwho, const char *topic)
214 michael 325 {
215 michael 335 int new_topic = strcmp(chptr->topic ? chptr->topic : "", topic);
216    
217 michael 325 set_channel_topic(chptr, topic, topicwho, topicts);
218    
219 michael 335 /* Only send TOPIC to channel if it's different */
220     if (new_topic)
221 michael 325 sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s TOPIC %s :%s",
222     ConfigServerHide.hide_servers ? me.name : source_p->name,
223     chptr->chname, chptr->topic == NULL ? "" : chptr->topic);
224    
225     sendto_server(source_p, NULL, chptr, CAP_TBURST, NOCAPS, NOFLAGS,
226     ":%s TBURST %lu %s %lu %s :%s",
227     me.name, (unsigned long)chptr->channelts, chptr->chname,
228     (unsigned long)chptr->topic_time,
229     chptr->topic_info == NULL ? "" : chptr->topic_info,
230     chptr->topic == NULL ? "" : chptr->topic);
231     sendto_server(source_p, NULL, chptr, CAP_TB, CAP_TBURST, NOFLAGS,
232     ":%s TB %s %lu %s :%s",
233     me.name, chptr->chname,
234     (unsigned long)chptr->topic_time,
235     chptr->topic_info == NULL ? "" : chptr->topic_info,
236     chptr->topic == NULL ? "" : chptr->topic);
237     }

Properties

Name Value
svn:eol-style native
svn:keywords Id

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.26