ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_tburst.c
Revision: 1309
Committed: Sun Mar 25 11:24:18 2012 UTC (14 years, 4 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-8/modules/m_tburst.c
File size: 7055 byte(s)
Log Message:
- renaming files:

  ircd_parser.y -> conf_parser.y
  ircd_lexer.l  -> conf_lexer.l
  s_conf.c      -> conf.c
  s_conf.h      -> conf.h
  s_log.c       -> log.c
  s_log.h       -> log.h

File Contents

# User Rev Content
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 "client.h"
33     #include "ircd.h"
34     #include "send.h"
35     #include "modules.h"
36     #include "hash.h"
37     #include "s_serv.h"
38 michael 1309 #include "conf.h"
39 michael 1243 #include "parse.h"
40 michael 325
41    
42 michael 1230 /*
43     * set_topic
44     *
45     * inputs - source_p pointer
46     * - channel pointer
47     * - topicts to set
48     * - who to set as who doing the topic
49     * - topic
50     * output - none
51     * Side effects - simply propagates topic as needed
52     * little helper function, could be removed
53     */
54     static void
55     set_topic(struct Client *source_p, struct Channel *chptr, time_t topicts,
56     const char *topicwho, const char *topic)
57 michael 325 {
58 michael 1230 int new_topic = strcmp(chptr->topic, topic);
59 michael 325
60 michael 1230 set_channel_topic(chptr, topic, topicwho, topicts);
61 michael 325
62 michael 1230 /* Only send TOPIC to channel if it's different */
63     if (new_topic)
64 michael 1243 sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s TOPIC %s :%s",
65 michael 1230 ConfigServerHide.hide_servers ? me.name : source_p->name,
66     chptr->chname, chptr->topic);
67 michael 325
68 michael 1230 sendto_server(source_p, chptr, CAP_TBURST, NOCAPS,
69     ":%s TBURST %lu %s %lu %s :%s",
70     me.name, (unsigned long)chptr->channelts, chptr->chname,
71     (unsigned long)chptr->topic_time,
72     chptr->topic_info,
73     chptr->topic);
74     sendto_server(source_p, chptr, CAP_TB, CAP_TBURST,
75     ":%s TB %s %lu %s :%s",
76     me.name, chptr->chname,
77     (unsigned long)chptr->topic_time,
78     chptr->topic_info,
79     chptr->topic);
80 michael 325 }
81    
82     /* ms_tburst()
83     *
84     * parv[0] = sender prefix
85     * parv[1] = channel timestamp
86     * parv[2] = channel
87     * parv[3] = topic timestamp
88     * parv[4] = topic setter
89     * parv[5] = topic
90     */
91     static void
92     ms_tburst(struct Client *client_p, struct Client *source_p,
93     int parc, char *parv[])
94     {
95     struct Channel *chptr = NULL;
96 michael 336 int accept_remote = 0;
97     time_t remote_channel_ts = atol(parv[1]);
98     time_t remote_topic_ts = atol(parv[3]);
99 michael 394 const char *topic = "";
100     const char *setby = "";
101 michael 325
102 michael 336 /*
103     * Do NOT test parv[5] for an empty string and return if true!
104     * parv[5] CAN be an empty string, i.e. if the other side wants
105     * to unset our topic. Don't forget: an empty topic is also a
106     * valid topic.
107     */
108    
109    
110 michael 325 if ((chptr = hash_find_channel(parv[2])) == NULL)
111     return;
112    
113 michael 394 if (parc == 6)
114     {
115     topic = parv[5];
116     setby = parv[4];
117     }
118    
119 michael 336 /*
120     * The logic for accepting and rejecting channel topics was
121     * always a bit hairy, so now we got exactly 2 cases where
122     * we would accept a bursted topic
123     *
124     * Case 1:
125     * The TS of the remote channel is older than ours
126     * Case 2:
127     * The TS of the remote channel is equal to ours AND
128     * the TS of the remote topic is newer than ours
129 michael 325 */
130 michael 336 if (remote_channel_ts < chptr->channelts)
131     accept_remote = 1;
132     else if (remote_channel_ts == chptr->channelts)
133     if (remote_topic_ts > chptr->topic_time)
134     accept_remote = 1;
135    
136     if (accept_remote)
137     {
138 michael 1203 int topic_differs = strcmp(chptr->topic, topic);
139 michael 336
140 michael 394 set_channel_topic(chptr, topic, setby, remote_topic_ts);
141 michael 336
142     if (topic_differs)
143 michael 1243 sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s TOPIC %s :%s",
144 michael 336 ConfigServerHide.hide_servers ? me.name : source_p->name,
145 michael 1203 chptr->chname, chptr->topic);
146 michael 336 }
147    
148     /*
149     * Always propagate what we have received, not only if we accept the topic.
150     * This will keep other servers in sync.
151     */
152 michael 885 sendto_server(source_p, chptr, CAP_TBURST, NOCAPS,
153 michael 336 ":%s TBURST %s %s %s %s :%s",
154 michael 394 source_p->name, parv[1], parv[2], parv[3], setby, topic);
155 michael 395 if (parc > 5 && *topic != '\0') /* unsetting a topic is not supported by TB */
156 michael 885 sendto_server(source_p, chptr, CAP_TB, CAP_TBURST,
157 michael 394 ":%s TB %s %s %s :%s",
158     source_p->name, parv[1], parv[2], setby, topic);
159 michael 325 }
160    
161     /* ms_tb()
162     *
163     * parv[0] = sender prefix
164     * parv[1] = channel name
165     * parv[2] = topic timestamp
166     * parv[3] = topic setter OR topic itself if parc == 4
167     * parv[4] = topic itself if parc == 5
168     */
169     #define tb_channel parv[1]
170     #define tb_topicts_str parv[2]
171    
172     static void
173     ms_tb(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
174     {
175     struct Channel *chptr;
176     time_t tb_topicts = atol(tb_topicts_str);
177     char *tb_whoset = NULL;
178     char *tb_topic = NULL;
179    
180     if ((chptr = hash_find_channel(tb_channel)) == NULL)
181     return;
182    
183     if (parc == 5)
184     {
185     tb_whoset = parv[3];
186     tb_topic = parv[4];
187     }
188     else
189     {
190     tb_whoset = source_p->name;
191     tb_topic = parv[3];
192     }
193    
194     set_topic(source_p, chptr, tb_topicts, tb_whoset, tb_topic);
195     }
196    
197 michael 1230 static struct Message tburst_msgtab = {
198     "TBURST", 0, 0, 5, MAXPARA, MFLG_SLOW, 0,
199     { m_ignore, m_ignore, ms_tburst, m_ignore, m_ignore, m_ignore }
200     };
201    
202     static struct Message tb_msgtab = {
203     "TB", 0, 0, 4, MAXPARA, MFLG_SLOW, 0,
204     { m_ignore, m_ignore, ms_tb, m_ignore, m_ignore, m_ignore }
205     };
206    
207 michael 325 static void
208 michael 1230 module_init(void)
209 michael 325 {
210 michael 1230 mod_add_cmd(&tb_msgtab);
211     add_capability("TB", CAP_TB, 1);
212 michael 335
213 michael 1230 mod_add_cmd(&tburst_msgtab);
214     add_capability("TBURST", CAP_TBURST, 1);
215     }
216 michael 325
217 michael 1230 static void
218     module_exit(void)
219     {
220     mod_del_cmd(&tb_msgtab);
221     delete_capability("TB");
222 michael 325
223 michael 1230 mod_del_cmd(&tburst_msgtab);
224     delete_capability("TBURST");
225 michael 325 }
226 michael 1230
227     struct module module_entry = {
228     .node = { NULL, NULL, NULL },
229     .name = NULL,
230     .version = "$Revision$",
231     .handle = NULL,
232     .modinit = module_init,
233     .modexit = module_exit,
234     .flags = 0
235     };

Properties

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