ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/vendor/ircservices-5.1.24/docs/tech/5.html
Revision: 3389
Committed: Fri Apr 25 14:12:15 2014 UTC (9 years, 11 months ago) by michael
Content type: text/html
File size: 82975 byte(s)
Log Message:
- Imported ircservices-5.1.24

File Contents

# Content
1 <?xml version="1.0" encoding="ISO-8859-1"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11-strict.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
4 <head>
5 <meta http-equiv="Content-Style-Type" content="text/css"/>
6 <style type="text/css">@import "style.css";</style>
7 <title>IRC Services Technical Reference Manual - 5. IRC server interface</title>
8 </head>
9
10 <body>
11 <h1 class="title" id="top">IRC Services Technical Reference Manual</h1>
12
13 <h2 class="section-title">5. IRC server interface</h2>
14
15 <p class="section-toc">
16 5-1. <a href="#s1">Protocol modules: the IRC protocol bridge</a>
17 <br/>5-2. <a href="#s2">Specifying protocol features</a>
18 <br/>5-3. <a href="#s3">Sending messages to the network</a>
19 <br/>&nbsp;&nbsp;&nbsp;&nbsp;5-3-1. <a href="#s3-1">Required functionality</a>
20 <br/>&nbsp;&nbsp;&nbsp;&nbsp;5-3-2. <a href="#s3-2">Optional functionality</a>
21 <br/>5-4. <a href="#s4">Receiving messages from the network</a>
22 <br/>&nbsp;&nbsp;&nbsp;&nbsp;5-4-1. <a href="#s4-1">Required functionality</a>
23 <br/>&nbsp;&nbsp;&nbsp;&nbsp;5-4-2. <a href="#s4-2">Optional functionality</a>
24 <br/>5-5. <a href="#s5">Other functions of protocol modules</a>
25 <br/>5-6. <a href="#s6">Specific protocol module details</a>
26 <br/>&nbsp;&nbsp;&nbsp;&nbsp;5-6-1. <a href="#s6-1"><tt>protocol/rfc1459</tt></a>
27 <br/>&nbsp;&nbsp;&nbsp;&nbsp;5-6-2. <a href="#s6-2"><tt>protocol/ts8</tt></a>
28 <br/>&nbsp;&nbsp;&nbsp;&nbsp;5-6-3. <a href="#s6-3"><tt>protocol/dalnet</tt></a>
29 <br/>&nbsp;&nbsp;&nbsp;&nbsp;5-6-4. <a href="#s6-4"><tt>protocol/dreamforge</tt></a>
30 <br/>&nbsp;&nbsp;&nbsp;&nbsp;5-6-5. <a href="#s6-5"><tt>protocol/bahamut</tt></a>
31 <br/>&nbsp;&nbsp;&nbsp;&nbsp;5-6-6. <a href="#s6-6"><tt>protocol/hybrid</tt></a>
32 <br/>&nbsp;&nbsp;&nbsp;&nbsp;5-6-7. <a href="#s6-7"><tt>protocol/inspircd</tt></a>
33 <br/>&nbsp;&nbsp;&nbsp;&nbsp;5-6-8. <a href="#s6-8"><tt>protocol/monkey</tt></a>
34 <br/>&nbsp;&nbsp;&nbsp;&nbsp;5-6-9. <a href="#s6-9"><tt>protocol/ptlink</tt></a>
35 <br/>&nbsp;&nbsp;&nbsp;&nbsp;5-6-10. <a href="#s6-10"><tt>protocol/ratbox</tt></a>
36 <br/>&nbsp;&nbsp;&nbsp;&nbsp;5-6-11. <a href="#s6-11"><tt>protocol/solidircd</tt></a>
37 <br/>&nbsp;&nbsp;&nbsp;&nbsp;5-6-12. <a href="#s6-12"><tt>protocol/trircd</tt></a>
38 <br/>&nbsp;&nbsp;&nbsp;&nbsp;5-6-13. <a href="#s6-13"><tt>protocol/undernet-p9</tt></a>
39 <br/>&nbsp;&nbsp;&nbsp;&nbsp;5-6-14. <a href="#s6-14"><tt>protocol/unreal</tt></a>
40 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5-6-14-1. <a href="#s6-14-1">Module prologue</a>
41 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5-6-14-2. <a href="#s6-14-2">Message receiving</a>
42 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5-6-14-3. <a href="#s6-14-3">Message sending</a>
43 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5-6-14-4. <a href="#s6-14-4">Module initialization and cleanup</a>
44 <br/>5-7. <a href="#s7">Auxiliary source file details</a>
45 <br/>&nbsp;&nbsp;&nbsp;&nbsp;5-7-1. <a href="#s7-1"><tt>banexcept.c</tt>, <tt>banexcept.h</tt></a>
46 <br/>&nbsp;&nbsp;&nbsp;&nbsp;5-7-2. <a href="#s7-2"><tt>chanprot.c</tt>, <tt>chanprot.h</tt></a>
47 <br/>&nbsp;&nbsp;&nbsp;&nbsp;5-7-3. <a href="#s7-3"><tt>halfop.c</tt>, <tt>halfop.h</tt></a>
48 <br/>&nbsp;&nbsp;&nbsp;&nbsp;5-7-4. <a href="#s7-4"><tt>invitemask.c</tt>, <tt>invitemask.h</tt></a>
49 <br/>&nbsp;&nbsp;&nbsp;&nbsp;5-7-5. <a href="#s7-5"><tt>sjoin.c</tt>, <tt>sjoin.h</tt></a>
50 <br/>&nbsp;&nbsp;&nbsp;&nbsp;5-7-6. <a href="#s7-6"><tt>svsnick.c</tt>, <tt>svsnick.h</tt></a>
51 <br/>&nbsp;&nbsp;&nbsp;&nbsp;5-7-7. <a href="#s7-7"><tt>token.c</tt>, <tt>token.h</tt></a>
52 </p>
53
54 <p class="backlink"><a href="4.html">Previous section: The module system</a> |
55 <a href="index.html">Table of Contents</a> |
56 <a href="6.html">Next section: Database handling</a></p>
57
58 <!------------------------------------------------------------------------>
59 <hr/>
60
61 <h3 class="subsection-title" id="s1">5-1. Protocol modules: the IRC protocol bridge</h3>
62
63 <p>While the "official" IRC protocol is defined in the document
64 <a href="http://www.ietf.org/rfc/rfc1459.txt">RFC 1459</a>
65 <span class="remotehost">[www.ietf.org]</span>, modern IRC servers have
66 added many extensions to this base protocol over the years, and the current
67 state of IRC software is such that it is rare to find an IRC server
68 implementation that can communicate with a different implementation. This
69 makes the job of Services considerably more difficult, as it must
70 communicate with servers in order to perform its job, and there is no
71 telling what implementation a particular network administrator will choose.</p>
72
73 <p>In order to overcome these differences in protocol, Services makes use
74 of <i>protocol modules</i>, a class of modules which interface between the
75 generic IRC server implemented by the Services core and the specific
76 protocols used by different IRC server implementations. While there are
77 some basic assumptions made by the core code about the protocol&mdash;for
78 example, that the protocol uses lines of text terminated by a CR/LF
79 pair&mdash;most differences seen in current IRC servers can be handled by
80 protocol modules.</p>
81
82 <p>The standard protocol modules distributed in Services are located in the
83 <tt>modules/protocol</tt> directory, along with auxiliary source and header
84 files that implement functionality common to multiple protocols. This
85 location is not a requirement, however; third-party modules can be located
86 in different directories, provided that they implement the required
87 functionality described in this section.</p>
88
89 <p>Note that, in order to simplify the module initialization process,
90 Services requires that a protocol module be loaded before any other
91 modules; this requirement is enforced by the <tt>load_module()</tt>
92 routine, as discussed in <a href="4.html#s3-1">section 4-3-1</a>. A number
93 of pseudoclient modules alter their behavior depending on features of the
94 IRC protocol in use, such as maximum nickname length or support of certain
95 nonstandard IRC messages, and this requirement allows such modules to
96 simply check the protocol information without having to ensure that a
97 protocol module has been loaded (and subsequently watch for protocol module
98 loads and unloads). <i>Implementation note: Although <tt>load_module()</tt>
99 ensures that a protocol module is loaded first, <tt>unload_module()</tt>
100 does <b>not</b> prevent protocol modules from being unloaded! Protocol
101 modules should therefore use an <tt>exit_module()</tt> routine that returns
102 zero on any unload attempt, except during shutdown. The modules included
103 with Services all exhibit this behavior.</i></p>
104
105 <p class="backlink"><a href="#top">Back to top</a></p>
106
107 <!------------------------------------------------------------------------>
108 <hr/>
109
110 <h3 class="subsection-title" id="s2">5-2. Specifying protocol features</h3>
111
112 <p>In addition to providing the functionality listed in subsequent
113 sections, protocol modules must inform Services of certain information
114 about the protocol in use. This is done by setting the following global
115 variables (defined in <tt>send.c</tt>) in the module's <tt>module_init()</tt>
116 routine:</p>
117
118 <dl>
119 <dt><tt>const char *protocol_name</tt></dt>
120 <dd>Specifies the name of the protocol supported by the module. This
121 variable is provided for informational purposes only. (The current
122 core code does not make any use of the variable.)</dd>
123
124 <dt><tt>const char *protocol_version</tt></dt>
125 <dd>Specifies the version(s) of the protocol supported by the module,
126 if applicable (the variable may be left unset if there is only one
127 version of the protocol). This variable is provided for
128 informational purposes only.</dd>
129
130 <dt><tt>int32 protocol_features</tt></dt>
131 <dd>Specifies particular features supported by the protocol. The value
132 should be a combination (bitwise OR) of zero or more of the
133 following flags:
134 <ul>
135 <li><b><tt>PF_HALFOP</tt>:</b> Supports a "half-op" channel
136 user mode (such as <tt>+h</tt> as used with the Unreal
137 protocol).</li>
138 <li><b><tt>PF_CHANPROT</tt>:</b> Supports a "protected" channel
139 user mode (such as <tt>+a</tt> as used with the Unreal
140 protocol).</li>
141 <li><b><tt>PF_BANEXCEPT</tt>:</b> Supports channel ban
142 exceptions.</li>
143 <li><b><tt>PF_SZLINE</tt>:</b> Supports an <tt>SZLINE</tt> or
144 similar server-to-server command to ban an IP address from
145 connecting to any server on the network.</li>
146 <li><b><tt>PF_NOQUIT</tt>:</b> Uses "NOQUIT" mode, in which
147 servers do not send <tt>QUIT</tt> messages for affected
148 clients when a netsplit occurs (see, for example,
149 <a href="#s6-5">section 5-6-5</a>).</li>
150 <li><b><tt>PF_SVSJOIN</tt>:</b> Supports an <tt>SVSJOIN</tt> or
151 similar server-to-server command to force a client to join a
152 channel.</li>
153 <li><b><tt>PF_CHANGENICK</tt>:</b> Supports a method through
154 which a server can forcibly change a client's nickname.</li>
155 <li><b><tt>PF_AKILL_EXCL</tt>:</b> Supports autokill exclusions
156 (exceptions to network-wide bans as set by the OperServ
157 <tt>AKILL</tt> command).</li>
158 <li><b><tt>PF_MODETS_FIRST</tt>:</b> Sends the timestamp in a
159 channel <tt>MODE</tt> message immediately after the channel
160 name, rather than at the end of the message.</li>
161 <li><b><tt>PF_INVITEMASK</tt>:</b> Supports channel invite
162 masks (masks allowing users who match to join an
163 invite-only channel without being invited, such as the
164 <tt>+i</tt> channel mode as used with the Unreal
165 protocol).</li>
166 </ul>
167 Note that <tt>protocol_features</tt> is initialized to a value of
168 <tt>PF_UNSET</tt> to detect whether its value has been changed, so
169 the protocol module should use a direct assignment (rather than an
170 OR-assignment) to set the value.</dd>
171
172 <dt><tt>int protocol_nickmax</tt></dt>
173 <dd>Specifies the maximum number of characters (bytes) allowed in a
174 nickname.</dd>
175 </dl>
176
177 <p><tt>send.c</tt> hooks into the "<tt>load module</tt>" callback to check
178 that these variables, as well as the functions listed in
179 <a href="#s3-1">section 5-3-1</a>, are appropriately set when a protocol
180 module is loaded, generating a fatal error if not. <i>Implementation note:
181 As mentioned in <a href="2.html#s5-1">section 2-5-1</a>, there is nothing
182 to mark a protocol module as being such, so the callback function simply
183 assumes that the first module loaded is a protocol module.</i></p>
184
185 <p>There are also three variables which can be optionally set as needed:</p>
186
187 <dl>
188 <dt><tt>const char *pseudoclient_modes</tt></dt>
189 <dd>Specifies the user modes, if any, that should be set on any newly
190 introduced pseudoclient; a leading "<tt>+</tt>" should <i>not</i>
191 be added. For example, if a protocol includes a user mode
192 specifically for pseudoclients, that mode should be set here.
193 Defaults to the empty string (no modes). Note that mode
194 <tt>o</tt> (operator privilege) should <i>not</i> be specified even
195 if some pseudoclients need operator privileges to perform their
196 functions; use <tt>pseudoclient_oper</tt> for that instead (see
197 below).</dd>
198
199 <dt><tt>const char *enforcer_modes</tt></dt>
200 <dd>Specifies the user modes, if any, that should be set on
201 pseudoclients used as nickname enforcers. Defaults to the empty
202 string (no modes).</dd>
203
204 <dt><tt>int pseudoclient_oper</tt></dt>
205 <dd>Indicates whether pseudoclients which perform actions restricted to
206 IRC operators need the IRC operator user mode (<tt>+o</tt>) set.
207 Defaults to 1, causing this mode to be set (0 disables
208 <tt>+o</tt>).</dd>
209 </dl>
210
211 <p class="backlink"><a href="#top">Back to top</a></p>
212
213 <!------------------------------------------------------------------------>
214 <hr/>
215
216 <h3 class="subsection-title" id="s3">5-3. Sending messages to the network</h3>
217
218 <p>The bulk of a protocol module consists of routines to send messages to
219 and process messages from the network, handling any peculiarites of the
220 particular protocol in use.</p>
221
222 <p class="backlink"><a href="#top">Back to top</a></p>
223
224
225 <h4 class="subsubsection-title" id="s3-1">5-3-1. Required functionality</h4>
226
227 <p>A number of the common message sending operations defined in
228 <tt>send.c</tt> are defined as function pointers, which the protocol
229 module must set to point to appropriate functions (by default, they point
230 to a placeholder function which generates a fatal error). These function
231 pointers (see <a href="2.html#s5-1">section 2-5-1</a> for descriptions of
232 the functions) are:</p>
233
234 <ul>
235 <li><tt>void (*<b>send_nick</b>)(const char *<i>nick</i>,
236 const char *<i>user</i>, const char *<i>host</i>,
237 const char *<i>server</i>, const cahr *<i>name</i>,
238 const char *<i>modes</i>)</tt></li>
239 <li><tt>void (*<b>send_nickchange</b>)(const char *<i>nick</i>, const char *<i>newnick</i>)</tt></li>
240 <li><tt>void (*<b>send_namechange</b>)(const char *<i>name</i>, const char *<i>newname</i>)</tt></li>
241 <li><tt>void (*<b>send_server</b>)()</tt></li>
242 <li><tt>void (*<b>send_server_remote</b>)(const char *<i>server</i>, const char *<i>desc</i>)</tt></li>
243 <li><tt>void (*<b>wallops</b>)(const char *<i>source</i>, const char *<i>fmt</i>, ...)</tt></li>
244 <li><tt>void (*<b>notice_all</b>)(const char *<i>source</i>, const char *<i>fmt</i>, ...)</tt></li>
245 <li><tt>void (*<b>send_channel_cmd</b>)(const char *<i>source</i>, const char *<i>fmt</i>, ...)</tt></li>
246 </ul>
247
248 <p>Protocol modules must also provide a handler for the "<tt>set
249 topic</tt>" callback. The callback function should have the following
250 signature:</p>
251
252 <div class="code">int set_topic_handler(const char *<i>source</i>,
253 Channel *<i>c</i>,
254 const char *<i>topic</i>,
255 const char *<i>setter</i>,
256 time_t <i>t</i>)</div>
257
258 <p>This callback is called twice for each time the topic is set. The first
259 call is made before the <tt>Channel</tt> structure is changed, and
260 <tt><i>topic</i></tt>, <tt><i>setter</i></tt>, and <tt><i>t</i></tt> are
261 filled in with the new topic text, the nickname to be used as the topic
262 setter, and the timestamp for the topic. The second call is made after
263 the <tt>topic</tt> and <tt>topic_setter</tt> fields of the <tt>Channel</tt>
264 structure have been set to the new values, and the corresponding parameters
265 to the callback (<tt><i>topic</i></tt> and <tt><i>setter</i></tt>) are
266 <tt>NULL</tt> for this call. Note that the <tt>topic_time</tt> field is
267 <i>not</i> set by the core, and must be set appropriately by the callback
268 function; this is because some protocols require that the timestamp of a
269 channel topic must be newer or older than the current topic's timestamp for
270 the new topic to be accepted.</p>
271
272 <p class="backlink"><a href="#top">Back to top</a></p>
273
274
275 <h4 class="subsubsection-title" id="s3-2">5-3-2. Optional functionality</h4>
276
277 <p>In addition to the functions listed above, the OperServ modules
278 implementing the autokill and S-line functionality (see sections
279 <a href="7.html#s2-2-2">7-2-2-2</a> and <a href="7.html#s2-2-3">7-2-2-3</a>)
280 register message-sending callbacks which they expect the protocol module to
281 hook into if it supports the relevant messages. These callbacks (see
282 <a href="c.html#s3">Appendix C</a> for details) are:</p>
283
284 <ul>
285 <li><tt><b>send_akill</b></tt>: Sends an autokill to the network.</li>
286 <li><tt><b>cancel_akill</b></tt>: Clears an autokill from the network.</li>
287 <li><tt><b>send_exclude</b></tt>: Sends an autokill exclusion to the network.</li>
288 <li><tt><b>cancel_exclude</b></tt>: Clears an autokill exclusion from the network.</li>
289 <li><tt><b>send_sgline</b></tt>: Sends an SGline to the network.</li>
290 <li><tt><b>cancel_sgline</b></tt>: Clears an SGline from the network.</li>
291 <li><tt><b>send_sqline</b></tt>: Sends an SQline to the network.</li>
292 <li><tt><b>cancel_sqline</b></tt>: Clears an SQline from the network.</li>
293 <li><tt><b>send_szline</b></tt>: Sends an SZline to the network.</li>
294 <li><tt><b>cancel_szline</b></tt>: Clears an SZline from the network.</li>
295 </ul>
296
297 <p>If any of the callbacks are left unsupported, Services will simply send
298 a <tt>KILL</tt> or other appropriate message each time the autokill or
299 S-line is triggered. (However, hooking into a "send" callback but not the
300 corresponding "cancel" callback can have undesirable consequences!)</p>
301
302 <p class="backlink"><a href="#top">Back to top</a></p>
303
304 <!------------------------------------------------------------------------>
305 <hr/>
306
307 <h3 class="subsection-title" id="s4">5-4. Receiving messages from the network</h3>
308
309 <p>While basic message parsing and processing is handled by the Services
310 core, it is up to protocol modules to handle details of the particular
311 protocol as well as additional messages used by the protocol.</p>
312
313 <p>In Services, processing of received messages is handled using tables of
314 message names and corresponding processing routines, as described in
315 <a href="2.html#s5-3">section 2-5-3</a>. Protocol modules will typically
316 define a message table for messages handled by the module, and call
317 <tt>register_messages()</tt> to register the message table during module
318 initialization.</p>
319
320 <p class="backlink"><a href="#top">Back to top</a></p>
321
322
323 <h4 class="subsubsection-title" id="s4-1">5-4-1. Required functionality</h4>
324
325 <p>The only functionality required in protocol modules is the ability to
326 recognize new clients connecting to the network and clients changing
327 nicknames. As described in <a href="2.html#s5-3">section 2-5-3</a>, the
328 <tt>NICK</tt> and <tt>USER</tt> messages are not supported by the Services
329 core because of the differences between protocols in handling them; thus,
330 the protocol module must supply its own handler routines for these
331 messages, or whatever other messages may be used in their place.</p>
332
333 <p>However, in many protocols there are other messages which must be
334 handled properly to maintain the network state. These, of course, must be
335 processed accordingly as well.</p>
336
337 <p class="backlink"><a href="#top">Back to top</a></p>
338
339
340 <h4 class="subsubsection-title" id="s4-2">5-4-2. Optional functionality</h4>
341
342 <p>As described above, modules can add support for additional messages
343 through a message table; the default processing for core-handled messages
344 can be changed the same way, if (for example) a message takes a different
345 set of parameters than the "standard" server assumed by the core code.</p>
346
347 <p>There are some types of functionality shared among several servers, such
348 as the <tt>SJOIN</tt> message used in protocols such as Bahamut and Unreal
349 to update a channel's state with one message, or the "token" systems used
350 by some protocols to reduce the bandwidth and processing required for
351 inter-server messages. These are implemented by separate source files,
352 which can be included in the module's source to implement the particular
353 functionality. These are described in <a href="#s7">section 5-7</a>.</p>
354
355 <p class="backlink"><a href="#top">Back to top</a></p>
356
357 <!------------------------------------------------------------------------>
358 <hr/>
359
360 <h3 class="subsection-title" id="s5">5-5. Other functions of protocol modules</h3>
361
362 <p>Aside from handling the sending and receiving of messages particular to
363 the protocol, protocol modules must handle any other aspect of
364 server-to-server communication that is not done in the core. Chief among
365 these is the handling of protocol-specific modes.</p>
366
367 <p>Many IRC server implementations add new modes to the basic set; the
368 module must be able to recognize and process these modes appropriately.
369 This can be done using the core mode-handling facility (see
370 <a href="2.html#s6-4">section 2-6-4</a>), or by hooking into the
371 <tt>MODE</tt> message callbacks "<tt>user MODE</tt>" and
372 "<tt>channel MODE</tt>" (in the case of modes that take parameters, it is
373 usually necessary to use the latter method in order to store the parameter
374 values in the channel structure). The module may also need to hook into
375 various pseudoclient callbacks; see the relevant parts of
376 <a href="7.html">section 7</a>, or see the description of the Unreal
377 protocol module, which uses most of these callbacks, in
378 <a href="#s6-14">section 5-6-14</a> below.</p>
379
380 <p class="backlink"><a href="#top">Back to top</a></p>
381
382 <!------------------------------------------------------------------------>
383 <hr/>
384
385 <h3 class="subsection-title" id="s6">5-6. Specific protocol module details</h3>
386 <p>This section describes each of the protocol modules supplied with
387 Services. In addition to the source file for the module itself, some
388 protocol modules make use of auxiliary source files in the same directory;
389 these files are described in detail in <a href="#s7">section 5-7</a>. For
390 the most part, each subsection only covers details unique to that
391 particular module, but the <tt>protocol/unreal</tt> module
392 (<a href="#s6-14">section 5-6-14</a>), which makes use of almost all
393 protocol-related functionality, is discussed in more detail.</p>
394
395 <p class="backlink"><a href="#top">Back to top</a></p>
396
397
398 <h4 class="subsubsection-title" id="s6-1">5-6-1. <tt>protocol/rfc1459</tt></h4>
399
400 <p>The <tt>protocol/rfc1459</tt> module provides an interface for servers
401 which strictly follow the standard IRC protocol, as defined in RFC 1459.
402 While few if any such servers still remain in operation, this module serves
403 as a reference implementation for Services.</p>
404
405 <p>Since the generic IRC server implemented by Services is very similar to
406 the RFC 1459 standard, this module is rather straightforward. In a format
407 shared by the other standard protocol modules as well, the module is
408 divided into four major parts: routines to process received IRC messages,
409 routines to send IRC messages, callback functions, and module-related
410 functions and variables.</p>
411
412 <p>The only received messages which need special processing are the
413 <tt>NICK</tt> and <tt>USER</tt> messages used for introducing clients.
414 The module ignores the <tt>NICK</tt> message, assuming that the remote
415 server will take care of checking for collisions with the nicknames of any
416 pseudoclients introduced by Services, and uses the parameters to the
417 <tt>USER</tt> message to initialize the client's data record. Before
418 calling <tt>do_nick()</tt> to perform this action, the handler for the
419 <tt>USER</tt> message, <tt>m_user()</tt>, sets up a new parameter list
420 with the parameters in the order <tt>do_nick()</tt> expects them, filling
421 in default values for parameters unavailable in the RFC 1459 protocol.
422 (Technically, the hop count parameter is available from the <tt>NICK</tt>
423 message, but since it would take considerable extra effort to save this
424 value until the <tt>USER</tt> message arrived, and since the hop count is
425 not used by Services anyway, this field is simply discarded and a default
426 value of 0 used.)</p>
427
428 <p>The message-sending routines are likewise simple, for the most part.
429 The only routine that deserves special mention is the
430 <tt>do_notice_all()</tt> routine, which implements the <tt>notice_all()</tt>
431 function of <tt>send.c</tt>. Since the RFC 1459 protocol does not permit a
432 wildcard target of a <tt>NOTICE</tt> (or <tt>PRIVMSG</tt>) to be a simple
433 "<tt>*</tt>", which would target all clients on the network, the module
434 uses the <tt>NetworkDomain</tt> configuration setting, if available, to
435 create a more-specific server wildcard mask which will still target all
436 clients on the network. If this setting is not available, the routine
437 iterates through some common top-level domains (<tt>.com</tt>,
438 <tt>.net</tt>, <tt>.org</tt>, and <tt>.edu</tt>) in an attempt to reach as
439 many clients as possible.</p>
440
441 <p>There is only one callback function defined by the module; it hooks into
442 the "<tt>set&nbsp;topic</tt>" callback, used for setting channel topics
443 (see <a href="2.html#s6-5">section 2-6-5</a>). Since RFC 1459 places no
444 restrictions on topic-changing messages from servers, the callback simply
445 sends out a <tt>TOPIC</tt> message on the first call, ignoring the second.</p>
446
447 <p>The module initialization routine sets the protocol-specific variables
448 (<tt>protocol_name</tt>, <tt>protocol_version</tt>, and so on&mdash;since
449 there are no "versions" associated with RFC 1459, the version string is
450 left empty), installs the handlers for the <tt>NICK</tt> and <tt>USER</tt>
451 messages, adds the topic-setting routine to the "<tt>set&nbsp;topic</tt>"
452 callback, and installs the function pointers for the various message
453 sending operations. Of these, the module cleanup routine removes the
454 callback function and message handlers, but it leaves the protocol
455 variables and message sending function pointers alone; this is a shortcut
456 based on the assumption that the module will never be unloaded at runtime
457 (this assumption is enforced by returning zero to refuse unloading if the
458 <tt><i>shutdown</i></tt> parameter to the cleanup function is false).</p>
459
460 <p class="backlink"><a href="#top">Back to top</a></p>
461
462
463 <h4 class="subsubsection-title" id="s6-2">5-6-2. <tt>protocol/ts8</tt></h4>
464
465 <p>TS8 was one of the earliest additions made to the IRC protocol, and
466 includes timestamp (often called TS) values with many messages to indicate
467 the time at which certain actions took place. The addition of timestamps
468 allowed, among other things, less disruption of the network during
469 netjoins; in the case of a nickname collision, for example, timestamps made
470 it possible to determine which user was the first claimant on a nickname
471 and kill only the second user, rather than killing both of them as the
472 original protocol called for.</p>
473
474 <p>Other than the addition of timestamps into some IRC messages, the
475 <tt>protocol/ts8</tt> module, which supports TS8 as used in the
476 <tt>ircd-2.8</tt> series of IRC servers (specifically tested with
477 <tt>ircd-2.8.21+TS8</tt>), is very similar to the <tt>protocol/rfc1459</tt>
478 module. The one difference worth noting is in the operation of the
479 "<tt>set&nbsp;topic</tt>" callback. Under TS8, a server receiving a
480 <tt>TOPIC</tt> message from another server will give preference to the
481 topic with the older timestamp, ignoring the <tt>TOPIC</tt> message if it
482 specifies a timestamp newer than that of the topic currently set on the
483 channel; thus, in order to ensure that the topic gets set correctly, the
484 callback function modifies the caller's topic timestamp to be one second
485 earlier than the timestamp of the channel's current topic if a topic is
486 set. This same approach is used in other protocol modules as well to
487 ensure that changes made by Services are given priority over the current
488 network state regardless of timestamps.</p>
489
490 <p class="backlink"><a href="#top">Back to top</a></p>
491
492
493 <h4 class="subsubsection-title" id="s6-3">5-6-3. <tt>protocol/dalnet</tt></h4>
494
495 <p>The <tt>protocol/dalnet</tt> module supports the IRC server released by
496 (and used on) the DALnet IRC network, <tt>ircd.dal</tt>, through version
497 4.4.13. This server is, incidentally, the server for which Services was
498 originally designed, and as such, the module is nearly as concise as those
499 for the simpler RFC 1459 and TS8 protocols.</p>
500
501 <p>The DALnet IRC server introduced several additions to the standard IRC
502 protocol. Most notable, from the point of view of the protocol module, is
503 the addition of the <tt>AKILL</tt> and <tt>RAKILL</tt> messages for adding
504 and removing network-wide client bans, and the OperServ <tt>AKILL</tt>
505 command derives its name from these messages. The module includes callback
506 functions for OperServ's "<tt>send_akill</tt>" and "<tt>cancel_akill</tt>"
507 callbacks; it also includes entries in the message table for these
508 messages, but since there is no need to process <tt>AKILL</tt> messages
509 from the network, the handlers for these are <tt>NULL</tt>, along with
510 several other messages not recognized by the core message processing code.
511 (These messages are included simply to avoid warnings in the log file when
512 such messages are received.)</p>
513
514 <p>Other changes made to the server-to-server protocol in the DALnet server
515 are the unification of the <tt>NICK</tt> and <tt>USER</tt> messages into a
516 single <tt>NICK</tt> message, and the addition of the <tt>GLOBOPS</tt>
517 message, a <tt>WALLOPS</tt>-like message that cannot be seen by
518 non-operators (and which is used for the implementation of the
519 <tt>wallops()</tt> routine in preference to <tt>WALLOPS</tt>).</p>
520
521 <p>In order to ensure that the <tt>AKILL</tt>-related callbacks mentioned
522 above are added when the appropriate OperServ module
523 (<tt>operserv/akill</tt>) is loaded, this module also hooks into the
524 <tt>"load&nbsp;module"</tt> callback. An "<tt>unload&nbsp;module</tt>"
525 callback is also included for completeness, though it does nothing in this
526 module.</p>
527
528 <p>A close look at the module initialization routine,
529 <tt>module_init()</tt>, will show another difference in the DALnet
530 protocol. The RFC 1459 standard specifies that the three characters
531 <tt>[&nbsp;\&nbsp;]</tt> are to be interepreted as equivalent to
532 <tt>{&nbsp;|&nbsp;}</tt> in nicknames and channel names; this is a holdover
533 from the Scandinavian character set which was used by the creators of the
534 IRC protocol. DALnet does away with this holdover, and treats
535 <tt>[&nbsp;\&nbsp;]</tt> as distinct from <tt>{&nbsp;|&nbsp;}</tt> when
536 doing such string comparisons. By default, however, Services uses the RFC
537 1459 rules for comparing nicknames and channel names, so in order to change
538 this behavior, the <tt>module_init()</tt> routine modifies the global
539 <tt>irc_lowertable[]</tt> array. There are also two changes made to the
540 <tt>valid_chan_table[]</tt> array, to accommodate the fact that the DALnet
541 protocol allows channel names to begin with "<tt>+</tt>" and does not allow
542 colons in channel names.</p>
543
544 <p>There is also a <tt>mapstring()</tt> call in the initialization routine
545 to change the <tt>OPER_BOUNCY_MODES</tt> message to
546 <tt>OPER_BOUNCY_MODES_U_LINE</tt>; this latter message includes a specific
547 reference to "U: lines", a type of entry in the DALnet server configuration
548 file that indicates servers (like Services) that are allowed to change
549 channel modes arbitrarily. Failure to set this correctly on all servers
550 can result in the "bouncy modes" phenomenon, where a server reverses mode
551 changes made by Services, causing Services to resubmit those changes in an
552 infinite loop (see <a href="2.html#s6-3">section 2-6-3</a> for details).</p>
553
554 <p>One other piece of code not present in the <tt>rfc1459</tt> or
555 <tt>ts8</tt> modules is the mode initialization code. The DALnet protocol
556 adds two user modes to the standard mode set: <tt>+g</tt>, indicating
557 whether the client wants to receive <tt>GLOBOPS</tt> messages, and
558 <tt>+h</tt>, indicating whether the user is identified as a "help-op".
559 Neither of these have any effect on the operation of Services, but for
560 completeness, they are added to the global mode tables as described in
561 <a href="2.html#s6-4">section 2-6-4</a>. The method used for adding the
562 modes (the three arrays <tt>new_usermodes[]</tt>, <tt>new_chanmodes[]</tt>,
563 and <tt>new_chanusermodes[]</tt>, and the local initialization function
564 <tt>init_modes()</tt>, called from <tt>init_module()</tt>) is shared by
565 other protocol modules are well.</p>
566
567 <p class="backlink"><a href="#top">Back to top</a></p>
568
569
570 <h4 class="subsubsection-title" id="s6-4">5-6-4. <tt>protocol/dreamforge</tt></h4>
571
572 <p>The <tt>protocol/dreamforge</tt> module supports the Dreamforge server
573 protocol. Dreamforge is the name given to versions 4.4.15 and later of the
574 DALnet IRC server, and as such, this protocol is a direct successor to the
575 <tt>dalnet</tt> protocol.</p>
576
577 <p>The major difference between the classic DALnet protocol and the
578 Dreamforge protocol is the addition of features designed to improve the
579 integration of Services-like programs with the network. Chief among these
580 is the "Services timestamp" or "servicestamp", a timestamp-like value
581 associated with each client which is set by Services and retained by all
582 servers as long as the client is connected. This value, or 0 if it has not
583 been set, is sent as part of the <tt>NICK</tt> message when announcing a
584 new client to the network. Services can set the servicestamp to a unique
585 value, and use that value to distinguish clients with certainty, avoiding
586 problems arising from servers with out-of-sync clocks or clients that
587 connect to the network at the same time. There are also new user and
588 channel modes added to identify registered nicknames and channels, and to
589 prevent clients with unregistered nicknames from joining a channel.</p>
590
591 <p>Most of these changes are handled in the <tt>NICK</tt> message handler,
592 <tt>m_nick()</tt>, and the callback functions
593 <tt>do_user_servicestamp_change()</tt>, <tt>do_user_mode()</tt>, and
594 <tt>do_nick_identified()</tt>. The <tt>do_user_mode()</tt> callback
595 function ensures that no other server on the network attempts to change a
596 user's servicestamp (note that this can cause mode floods if two copies of
597 Services are run on the same network!) or registered-nickname status. The
598 function also sets the "Services administrator" (<tt>+a</tt>) user mode if
599 the user is known to be a Services administrator, and clears the mode
600 otherwise.</p>
601
602 <p>In order to check whether a user is a Services administrator, the module
603 has to call the <tt>is_services_admin()</tt> function in the
604 <tt>operserv/main</tt> module; however, this module may not be loaded. To
605 avoid having to check for the module and symbol at every location in the
606 code where the function is called, a local helper function,
607 <tt>local_is_services_admin()</tt>, is defined at the top of the source
608 file, and <tt>is_services_admin()</tt> is redefined (via <tt>#define</tt>)
609 to point to this local function. The function itself only checks a cache
610 variable to determine whether <tt>is_services_admin()</tt> is available;
611 this cache variable is set by the "<tt>load&nbsp;module</tt>" callback
612 function when the <tt>operserv/main</tt> module is loaded (and cleared
613 again by the "<tt>unload&nbsp;module</tt>" if <tt>operserv/main</tt> is
614 unloaded).</p>
615
616 <p>The final new aspect to this module's source code is the use of the
617 <tt>svsnick.c</tt> auxiliary source file (see <a href="#s7-6">section
618 5-7-6</a> for details on this particular file), to support the
619 <tt>SVSNICK</tt> message used to forcibly change a client's nickname. In
620 order to avoid complexities resulting from compiling the source file
621 separately and linking it into the module (in particular, identifier
622 collisions during static linking), the <tt>svsnick.c</tt> source file is
623 included directly into the module's main source file, <tt>dreamforge.c</tt>.
624 <tt>svsnick.c</tt> includes its own initialization and cleanup routines,
625 <tt>init_svsnick()</tt> and <tt>exit_svsnick()</tt>, which are called by
626 <tt>init_module()</tt> and <tt>exit_module()</tt> respectively.</p>
627
628 <p>With respect to server registration, Dreamforge includes a new
629 <tt>PROTOCTL</tt> message type, used to inform the remote server about the
630 sending server's capabilities; this allows changes and additions to be made
631 to the protocol that can be enabled or disabled depending on whether the
632 remote server supports them. Services does not make use of any such
633 optional features in Dreamforge, however, so the <tt>PROTOCOL</tt> message
634 is given a <tt>NULL</tt> handler.</p>
635
636 <p class="backlink"><a href="#top">Back to top</a></p>
637
638
639 <h4 class="subsubsection-title" id="s6-5">5-6-5. <tt>protocol/bahamut</tt></h4>
640
641 <p>Bahamut is the successor to the Dreamforge IRC server, and is the server
642 currently (2006/8) used on the DALnet IRC network. The
643 <tt>protocol/bahamut</tt> module handles versions of Bahamut from 1.8.0
644 onward.</p>
645
646 <p>In addition to the <tt>SVSNICK</tt> feature introduced in Dreamforge,
647 Bahamut includes <i>ban exceptions</i> for channels (clients matching a ban
648 exception mask can join the channel even if they also match a ban mask),
649 supported by the auxiliary source file <tt>banexcept.c</tt>; <i>invite
650 masks</i> for channels (clients matching an invite mask can join an
651 invite-only channel without having to be explicitly invited), supported by
652 <tt>invitemask.c</tt>; and a channel-join message for server-to-server
653 communications, <tt>SJOIN</tt> (which reduces bandwidth use by allowing
654 multiple users and channel modes to be sent in a single message), supported
655 by <tt>sjoin.c</tt>. With respect to the latter file, <tt>bahamut.c</tt>
656 defines the <tt>BAHAMUT_HACK</tt> symbol before including the file; this is
657 to select the Bahamut mode of operation for <tt>SJOIN</tt>, as described in
658 <a href="#s7-5">section 5-7-5</a>.</p>
659
660 <p>Bahamut includes a <tt>CAPAB</tt> message that functions like
661 Dreamforge's <tt>PROTOCTL</tt> to inform the remote server about supported
662 protocol features. Services checks for one token in the <tt>CAPAB</tt>
663 message: "<tt>NOQUIT</tt>", an extension suppressing (on server-to-server
664 links) the client <tt>QUIT</tt> messages generated when a netsplit occurs.
665 Services always advertises the <tt>NOQUIT</tt> capability, and sets the
666 <tt>PF_NOQUIT</tt> protocol flag if the remote server also supports
667 <tt>NOQUIT</tt>.</p>
668
669 <p>One difficulty that can arise when using the Bahamut server is that the
670 server to which Services connects is configured as a "Services hub" (the
671 configuration option "<tt>servtype&nbsp;serviceshub</tt>"). While this
672 seems logical from the name, this option is intended only for the custom
673 Services program that DALnet uses, and is not compatible with this program,
674 Services for IRC Networks. The DALnet Services program is customized to
675 work specifically with the Bahamut server and the DALnet network, and as
676 such takes certain shortcuts; the "Services hub" option causes the Bahamut
677 server to take advantage of these shortcuts, reducing network bandwidth.
678 In particular, activating this option causes messages to pseudoclients such
679 as NickServ to be sent in an abbreviated form (the <tt>NS</tt>, <tt>CS</tt>
680 and similar commands defined under the dummy
681 <tt>#ifdef&nbsp;ALLOW_BAHAMUT_SERVICESHUB</tt>, referring to a macro not
682 defined anywhere). As Services for IRC Networks cannot assume that these
683 clients have particular nicknames, or even that they exist, the
684 <tt>protocol/bahamut</tt> module reports an error and aborts the program if
685 any of these abbreviated messages are seen. <i>Implementation note: It
686 might be feasible to support these if the module exported a
687 <tt>register_pseudoclient()</tt> routine, which took a constant indicating
688 the pseudoclient, like <tt>BAHAMUT_NS</tt>, and the pseudoclient's nickname
689 and stored the nickname locally for processing the given message.</i> The
690 "Services hub" option also prevents channel topics and client <tt>AWAY</tt>
691 messages from reaching Services, causing channel topic retention and
692 MemoServ unaway checking to break.</p>
693
694 <p>The Bahamut-specific channel mode <tt>+j</tt> is used to limit the rate
695 at which clients can join a channel. It takes the form
696 <tt>+j&nbsp;<i>num1</i>:<i>num2</i></tt>, where <tt><i>num1</i></tt> and
697 <tt><i>num2</i></tt> are positive integers that set the exact limits on
698 joining. Internally, these are stored in the <tt><i>joinrate1</i></tt> and
699 <tt><i>joinrate2</i></tt> fields of the <tt>Channel</tt> structure as well
700 as the locked-mode set of a registered channel (see
701 <a href="7.html#s4-1-1">section 7-4-1-1</a>), and values of 0 in these
702 fields indicate that the mode is not set; values of -1 in the locked-mode
703 structure indicate that the mode is locked off.</p>
704
705 <p>Unlike RFC 1459, Bahamut does not allow control characters in a channel
706 name. It also does not allow ASCII 160 (0xA0), presumably because this
707 corresponds to an "unbreakable space" in the ISO 8859-1 character set and
708 could be confused with an ordinary space by users. The initialization
709 routine adjusts the <tt>valid_chan_table[]</tt> array to account for this.</p>
710
711 <p class="backlink"><a href="#top">Back to top</a></p>
712
713
714 <h4 class="subsubsection-title" id="s6-6">5-6-6. <tt>protocol/hybrid</tt></h4>
715
716 <p>The <tt>protocol/hybrid</tt> module supports versions 7.0 and later of
717 the ircd-hybrid IRC server. Hybrid has a fairly simple design compared to
718 other servers, and only supports a few features above the standard set.</p>
719
720 <p>The Hybrid server does not ordinarily send channel topics during the
721 initial net burst when a server connects, and only allows the channel topic
722 to be set by a <tt>TOPIC</tt> message from a client currently in the
723 channel. This prevents the ChanServ topic-related functions from working,
724 since ChanServ does not join the channel when setting a topic. There is,
725 however, a module available for Hybrid which restores the synchronization
726 of channel topics on a server link as well as the ability of a server to
727 set topics arbitrarily: the "topic burst" module, <tt>m_tburst.so</tt>. To
728 simplify processing, the <tt>protocol/hybrid</tt> module requires that its
729 uplink server support this topic bursting, and will abort the program if
730 that support is missing (as determined by the <tt>CAPAB</tt> message
731 received on connection).</p>
732
733 <p class="backlink"><a href="#top">Back to top</a></p>
734
735
736 <h4 class="subsubsection-title" id="s6-7">5-6-7. <tt>protocol/inspircd</tt></h4>
737
738 <p>The <tt>protocol/inspircd</tt> supports the InspIRCd IRC server. This
739 server shares a number of features with the Unreal server (see
740 <a href="#s6-14">section 5-6-14</a>, but was created from scratch, rather
741 than by modifying the source code of an existing IRC server as in the case
742 of most other servers.</p>
743
744 <p>The <tt>inspircd</tt> module uses the <tt>banexcept.c</tt>,
745 <tt>invitemask.c</tt>, and <tt>svsnick.c</tt> auxiliary source files
746 mentioned above, as well as the <tt>chanprot.c</tt> and <tt>halfop.c</tt>
747 files, which are used to implement two additional channel user modes
748 supported by InspIRCd: <tt>+a</tt> (protection) and <tt>+h</tt> (half-op).
749 A user with <tt>+a</tt> set cannot be kicked by a channel operator unless
750 that operator also has <tt>+a</tt> set. Half-op privilege is an extra
751 privilege level between <tt>+v</tt> (voiced) and <tt>+o</tt> (channel
752 operator); half-ops can set the channel topic and give <tt>+v</tt> to other
753 users, but cannot change channel modes or perform other actions that
754 ordinary channel operators can do. InspIRCd also has a condensed channel
755 join message (<tt>FJOIN</tt>) similar to Bahamut's <tt>SJOIN</tt>, but its
756 syntax is different enough that a message handler is included in the module
757 itself rather than using the handler in <tt>sjoin.c</tt>.</p>
758
759 <p>In addition to autokills and S-lines, InspIRCd supports autokill
760 exclusions, similar to channels' ban exceptions but applying to
761 network-wide autokill masks. As described in detail in
762 <a href="7.html#s2-2-2">section 7-2-2-2</a>, the <tt>operserv/akill</tt>
763 module can take advantage of this to implement autokill exclusions without
764 having to send <tt>KILL</tt> messages for all autokilled users manually.</p>
765
766 <p>Another feature of the InspIRCd protocol is the removal of the
767 restriction on sending network-wide messages; as such, the
768 <tt>protocol/inspircd</tt> module does not require a <tt>NetworkDomain</tt>
769 configuration setting for global messages to be correctly sent.</p>
770
771 <p class="backlink"><a href="#top">Back to top</a></p>
772
773
774 <h4 class="subsubsection-title" id="s6-8">5-6-8. <tt>protocol/monkey</tt></h4>
775
776 <p>The <tt>protocol/monkey</tt> module supports the Chunky Monkey IRCD
777 server. This server is based on an earlier version of Bahamut; the primary
778 Services-visible change is the addition of the half-op (<tt>+h</tt>)
779 channel user mode. Features like ban exceptions and invite masks, added to
780 Bahamut in later versions, are not present. Other than these differences,
781 this module is essentially the same as the <tt>bahamut</tt> module.</p>
782
783 <p class="backlink"><a href="#top">Back to top</a></p>
784
785
786 <h4 class="subsubsection-title" id="s6-9">5-6-9. <tt>protocol/ptlink</tt></h4>
787
788 <p>The <tt>protocol/ptlink</tt> module supports the PTlink IRCd server,
789 version 6.10.0 and later. This server is based on ircd-hybrid-6, and was
790 originally developed for the PTlink IRC network, from which it takes its
791 name.</p>
792
793 <p>In PTlink, autokills are set and removed using the <tt>GLINE</tt>
794 message. Since this can also be used by IRC operators to set and remove
795 autokills, Services uses a constant string (defined as <tt>GLINE_WHO</tt>
796 at the top of the source file) as the "nickname" associated with the entry.
797 Services can then check this value when receiving a <tt>GLINE</tt> message
798 from the network, in order to avoid removing entries set by IRC operators.
799 (However, nicknames are not stored with <tt>SGLINE</tt> and <tt>SQLINE</tt>
800 entries, so operator-set entries will be deleted if they do not match a
801 record in Services' databases.) See under the <tt>TKL</tt> message
802 handler in <a href="#s6-14">section 5-6-14</a>, which discusses the Unreal
803 server, for an explanation of why these entries need to be cleared when
804 received from the network.</p>
805
806 <p class="backlink"><a href="#top">Back to top</a></p>
807
808
809 <h4 class="subsubsection-title" id="s6-10">5-6-10. <tt>protocol/ratbox</tt></h4>
810
811 <p>The <tt>protocol/ratbox</tt> module supports the ircd-ratbox server.
812 This server is derived from ircd-hybrid, and the <tt>ratbox</tt> module is
813 likewise very similar to the <tt>hybrid</tt> module.</p>
814
815 <p>Like Hybrid, ircd-ratbox does not normally allow servers like Services
816 to arbitrarily change channel topics, but this behavior can be changed with
817 a similar "topic burst" function. In the case of ircd-ratbox, this
818 functionality is built into the server (rather than being a separate
819 module), and need only be enabled through the appropriate flag
820 ("<tt>topicburst</tt>" in the connect block for Services). If this flag is
821 not enabled, Services will abort at connection time, as for Hybrid.</p>
822
823 <p class="backlink"><a href="#top">Back to top</a></p>
824
825
826 <h4 class="subsubsection-title" id="s6-11">5-6-11. <tt>protocol/solidircd</tt></h4>
827
828 <p>The <tt>protocol/solidircd</tt> module supports the solid-ircd server.
829 This server is based on an earlier version of the Bahamut server, with
830 several additions and changes.</p>
831
832 <p>One new feature supported by solid-ircd is encrypted connections. If a
833 client connects to the server via SSL, the client is given user mode
834 <tt>+z</tt>; a new channel mode, <tt>+S</tt>, is also available to prevent
835 clients without <tt>+z</tt> from entering the channel. This presents a
836 problem when <tt>+S</tt> is mode-locked on: since the channel does not
837 exist when it is empty, the IRC server will not know to stop a <tt>-z</tt>
838 user from entering the channel, and even if Services then sets <tt>+S</tt>
839 on the channel, the non-secure user will already be in the channel. In
840 order to work around this, Services hooks into the ChanServ
841 "<tt>check_kick</tt>" callback, and if a non-secure user tries to join an
842 empty channel that is registered and mode-locked <tt>+S</tt>, the user is
843 kicked out just as if on the autokick list.</p>
844
845 <p class="backlink"><a href="#top">Back to top</a></p>
846
847
848 <h4 class="subsubsection-title" id="s6-12">5-6-12. <tt>protocol/trircd</tt></h4>
849
850 <p>The <tt>protocol/trircd</tt> module supports the tr-ircd server,
851 version 5.5 and later. tr-ircd was originally based on the Bahamut server,
852 but has been rewritten from scratch since version 5.0.</p>
853
854 <p>One feature unique to tr-ircd is the availability of a user mode
855 (<tt>+L</tt>)bindicating the language in which the client desires to
856 receive server messages. For users with registered nicknames, Services
857 sets this to the language selected by the user for their nickname (if
858 that language is also supported by tr-ircd) when the user identifies.
859 <i>Implementation node: It would also be theoretically possible to use the
860 mode's value as a default for sending messages unregistered nicknames, as
861 well as the initial language setting of a newly-registered nickname, but
862 this is difficult to accomplish without adding the concept of a language
863 mode for clients to the Services core.</i> The list of languages supported
864 by tr-ircd, taken from the tr-ircd source code, can be found at the top of
865 the <tt>trircd.c</tt> module source file (<tt>langhash_init[]</tt>); the
866 actual values used in the user mode are hashes created from the language
867 name strings, and these hashes are computed and stored in the
868 <tt>langhash[]</tt> array by the <tt>init_langhash()</tt> function, called
869 at module initialization time.</p>
870
871 <p>tr-ircd also supports "channel linking"; this is the ability to make one
872 channel into an "alias" for another. When this mode (coincidentally also
873 <tt>+L</tt>) is set for a channel <tt>#A</tt> with a parameter of
874 <tt>#B</tt>, for example, a user who attempts to join channel <tt>#A</tt>
875 will be sent to channel <tt>#B</tt> instead. As a side effect of this, the
876 IRC server keeps track of channels which have <tt>+L</tt> set, and does not
877 delete them even after the last client leaves. Since Services treats a
878 channel with no users as nonexistent, the <tt>trircd</tt> module must hook
879 into the low-level "<tt>receive&nbsp;message</tt>" callback to watch for
880 <tt>+L</tt> or <tt>-L</tt> messages for empty channels and process them
881 accordingly.</p>
882
883 <p>At the server-to-server communication level, tr-ircd has the ability to
884 send message names as one- or two-character tokens rather than the full
885 message names; for example, "<tt>PRIVMSG</tt>" becomes simply "<tt>P</tt>",
886 both reducing bandwidth (albeit minimally) and enabling faster lookup of
887 commands. These tokens are defined in the <tt>trircd_tokens[]</tt> array,
888 and processing is handled by the <tt>token.c</tt> auxiliary source file,
889 discussed in <a href="#s7-7">section 5-7-7</a>.</p>
890
891 <p class="backlink"><a href="#top">Back to top</a></p>
892
893
894 <h4 class="subsubsection-title" id="s6-13">5-6-13. <tt>protocol/undernet-p9</tt></h4>
895
896 <p>The <tt>protocol/undernet-p9</tt> supports version 2.9 of the Undernet
897 IRC server (ircu). This is a fairly old server, derived from the original
898 ircd-2.8 server with TS8 additions; the only additional features it
899 includes are autokills (set using the <tt>GLINE</tt> message, and not
900 propogated in the connection burst) and the merging of the <tt>USER</tt>
901 and <tt>NICK</tt> messages into a single <tt>NICK</tt> message.</p>
902
903 <p class="backlink"><a href="#top">Back to top</a></p>
904
905
906 <h4 class="subsubsection-title" id="s6-14">5-6-14. <tt>protocol/unreal</tt></h4>
907
908 <p>The <tt>protocol/unreal</tt> module supports version 3.1.1 and later of
909 the UnrealIRCd server. Unreal is originally derived from Dreamforge,
910 but has made numerous additions, and is one of the most feature-rich IRC
911 servers currently in use. This of course means that the protocol module
912 is similarly complex; Unreal makes use of nearly all protocol-related
913 routines, as well as all seven auxiliary source files. For this reason, the
914 <tt>unreal</tt> module's source code is the most heavily commented of the
915 protocol modules, and can be seen as a model for how the various parts of
916 protocol modules work.</p>
917
918 <p class="backlink"><a href="#top">Back to top</a></p>
919
920
921 <h5 class="subsubsubsection-title" id="s6-14-1">5-6-14-1. Module prologue</h5>
922
923 <p>After including appropriate header files and the auxiliary source files
924 that implement certain protocol-related functions, the module defines a
925 number of local variables:</p>
926 <ul>
927 <li class="spaced"><tt>module_chanserv</tt>, <tt>module_operserv</tt>:
928 Module handles used for accessing external symbols (see below).</li>
929 <li class="spaced"><tt>ServerNumeric</tt>, <tt>SetServerTimes</tt>,
930 <tt>SVSTIMEFrequency</tt>: Variables to hold values set in the
931 configuration file.</li>
932 <li class="spaced"><tt>to_svstime</tt>: The timeout (see
933 <a href="2.html#s7">section 2-7</a>) used to send <tt>SVSTIME</tt>
934 messages at periodic intervals.</li>
935 <li class="spaced"><tt>usermode_admin</tt>, <tt>usermode_secure</tt>,
936 <tt>usermode_hiding</tt>, <tt>chanmode_admins_only</tt>,
937 <tt>chanmode_secure_only</tt>, <tt>chanmode_no_hiding</tt>:
938 Bitmasks corresponding to certain sets of modes, used to determine
939 whether a client is allowed to enter a particular empty
940 channel.</li>
941 <li class="spaced"><tt>unreal_version</tt>: Set to the protocol version
942 number sent by the remote server at connection registration time,
943 and used to determine whether certain protocol features are
944 available.</li>
945 <li class="spaced"><tt>has_nickip</tt>: Set to nonzero if the remote server
946 supports the <tt>NICKIP</tt> feature, used to implement
947 SZlines.</li>
948 </ul>
949
950 <p>These are followed by <tt>#define</tt>s and local variables used to
951 access the <tt>s_ChanServ</tt> variable in the ChanServ module, containing
952 the nickname of the ChanServ pseudoclient, and the
953 <tt>is_services_admin()</tt> function in the OperServ module, returning
954 whether the given user is a Services administrator. As described in the
955 comments, <tt>#define</tt> macros are used to substitute an access to the
956 symbol pointer every time the symbol is used, in order to simplify the
957 code.</p>
958
959 <p>The next section of the file contains a list of user, channel, and
960 channel user modes supported by the Unreal server. In order to register
961 these with the core mode processing facility (see
962 <a href="2.html#s6-4">section 2-6-4</a>), <tt>unreal.c</tt> defines three
963 arrays, one for each mode type, containing the mode characters to be added
964 and the corresponding <tt>ModeInfo</tt> structure for each mode. The
965 module also defines six local mode flags, corresponding to the mode bitmask
966 variables listed above; these flags are ignored by the mode processing
967 facility, but the mode setup code uses them to set the bitmask
968 variables.</p>
969
970 <p>The setup code itself is located in the <tt>init_modes()</tt> routine,
971 called during module initialization. This routine iterates through each of
972 the arrays, storing the mode data in the arrays exported by the mode
973 processing facility. For the user and channel modes, it also checks for
974 the locally-defined <tt>ModeInfo</tt> flags, and if a given mode has a flag
975 set, the mode's bitmask is added to the appropriate bitmask variable.</p>
976
977 <p class="backlink"><a href="#top">Back to top</a></p>
978
979
980 <h5 class="subsubsubsection-title" id="s6-14-2">5-6-14-2. Message receiving</h5>
981
982 <p>After this comes the first major portion of the actual processing code,
983 the message handlers. Aside from the mandatory client registration
984 handler (the <tt>NICK</tt> message in Unreal), Unreal includes several
985 additional messages not supported by the core processing code. The
986 messages handled are as follows (each message is handled by a routine
987 named <tt>m_<i>message-name</i></tt>, for example the <tt>NICK</tt>
988 message is handled by <tt>m_nick()</tt>):</p>
989
990 <dl>
991 <dt><b><tt>NICK</tt></b></dt>
992 <dd>This is the standard client registration message (Unreal merges
993 the dual <tt>NICK</tt> and <tt>USER</tt> of RFC 1459 into a single
994 <tt>NICK</tt> message at the server level, as most other server
995 protocols do). The message is also used for existing clients
996 changing nicknames; in that case (where the message has a prefix
997 indicating that it came from an existing client), control is
998 simply handed off to the <tt>do_nick()</tt> routine from the
999 core's client handling code. In the case of a new client,
1000 however, <tt>do_nick()</tt> expects the parameters in a slightly
1001 different order than Unreal sends them in, so this rearrangement is
1002 performed before calling <tt>do_nick()</tt>. Additionally, on
1003 servers supporting <tt>NICKIP</tt> (the sending of IP addresses in
1004 the <tt>NICK</tt> message), the message will include an extra
1005 parameter containing the binary representation of the client's IP
1006 address, encoded using base64 encoding; this is decoded, checked
1007 for consistency, and passed to <tt>do_nick()</tt> as well. (If
1008 <tt>NICKIP</tt> is not supported, a <tt>NULL</tt> parameter is
1009 passed, indicating that the IP address is not available.)</dd>
1010
1011 <dt><b><tt>PROTOCTL</tt></b></dt>
1012 <dd>Unreal uses this message to send information about features
1013 supported by the server. Services checks the list of parameters
1014 for recognized keywords, and sets appropriate variables to reflect
1015 their presence or absence. The recognized feature tokens are:
1016 <ul>
1017 <li><b><tt>NICKv2</tt>:</b> A new format for the <tt>NICK</tt>
1018 message, compared to earlier versions of Unreal. The local
1019 variable <tt>got_nickv2</tt> is set when this token is
1020 found; if the variable is not set at the end of the
1021 function, a fatal error is generated. <i>Implementation
1022 note: The variable is declared <tt>static</tt> because
1023 Unreal can send more than one <tt>PROTOCTL</tt> message
1024 when registering (such as when the parameter list is too
1025 long). It would be more robust to use a file-global
1026 variable that is checked at the first <tt>NICK</tt>
1027 message, but current versions of Unreal always send
1028 <tt>NICKv2</tt> in the first message, so this is not
1029 currently a problem.</i></li>
1030 <li><b><tt>NOQUIT</tt>:</b> The <tt>NOQUIT</tt> feature found in
1031 other servers such as Bahamut, in which servers generate
1032 client <tt>QUIT</tt> messages for netsplits on their own
1033 rather than relaying them through the network.</li>
1034 <li><b><tt>NICKIP</tt>:</b> Indicates that IP addresses are sent
1035 with client registration messages.</li>
1036 <li><b><tt>NICKCHARS</tt>:</b> Specifies additional characters
1037 allowed to be used in nicknames. The specification is
1038 done by language code; the current version of the module
1039 uses the language codes and character sets defined in
1040 Unreal 3.2.3.</li>
1041 </ul></dd>
1042
1043 <dt><b><tt>UMODE2</tt></b></dt>
1044 <dd>This is equivalent to the <tt>MODE</tt> message for clients, but
1045 omits the nickname parameter (so, for example, "<tt>:<i>nickname</i>
1046 MODE <i>nickname</i> -o</tt>" becomes "<tt>:<i>nickname</i> UMODE2
1047 -o</tt>").</dd>
1048
1049 <dt><b><tt>SETHOST</tt>, <tt>CHGHOST</tt></b></dt>
1050 <dd>These allow setting changing the "fake hostname", the hostname
1051 seen in a <tt>WHO</tt> or <tt>WHOIS</tt> reply by non-operators,
1052 for a client. <tt>SETHOST</tt> is used by a client to change its
1053 own hostname, while <tt>CHGHOST</tt> is used by operators (or
1054 servers, such as Services, though Services does not use this at
1055 present) to change another client's hostname.</dd>
1056
1057 <dt><b><tt>SETIDENT</tt>, <tt>CHGIDENT</tt></b></dt>
1058 <dd>These are like <tt>SETHOST</tt> and <tt>CHGHOST</tt> above, but
1059 change the client's username (the part of the
1060 <tt><i>user</i>@<i>host</i></tt> mask before the <tt>@</tt>).</dd>
1061
1062 <dt><b><tt>SETNAME</tt>, <tt>CHGNAME</tt></b></dt>
1063 <dd>These are like <tt>SETHOST</tt> and <tt>CHGHOST</tt> above, but
1064 change the client's "real name" (also called "gecos").</dd>
1065
1066 <dt><b><tt>SJOIN</tt></b></dt>
1067 <dd>This is a server-to-server message used both to add a user to a
1068 channel and to send a channel's state to the network. The message
1069 takes a channel name, timestamp, mode string, optional mode
1070 parameters, and a space-separated list of nicknames of clients
1071 joining the channel. Nicknames in the nickname list are prefixed
1072 with the prefix character(s) for the channel user mode of the
1073 client, if any (for example, a channel operator would be listed
1074 as <tt>@<i>nickname</i></tt>. Recent versions of Unreal also add
1075 channel bans and ban exceptions to the nickname list as well, with
1076 prefix characters of <tt>&</tt> and <tt>"</tt> respectively.</dd>
1077
1078 <dt><b><tt>SVSMODE</tt>, <tt>SVS2MODE</tt></b></dt>
1079 <dd>These messages are used to remotely change a client's modes or
1080 to remove all bans on a channel which match a client. In the
1081 former case, the messages operate identically to the <tt>MODE</tt>
1082 message, except that the source and target client may be different.
1083 In the latter case, each server checks the channel's ban list and
1084 removes all bans corresponding to that user; Services does this by
1085 calling <tt>clear_channel()</tt>, which sends out explicit
1086 <tt>MODE</tt> messages to remove the bans, but this is mostly
1087 harmless (other than taking up a small amount of bandwidth). The
1088 only difference between SVSMODE and SVS2MODE is that, when used to
1089 set client modes, the latter sends a <tt>MODE</tt> message to the
1090 target client, while the former does not.</dd>
1091
1092 <dt><b><tt>SVSNLINE</tt></b></dt>
1093 <dd>This message is used for managing what Services refers to as the
1094 SGline list, and takes one of two formats:
1095 <ul>
1096 <li><tt>SVSNLINE + <i>reason</i> :<i>mask</i></tt></li>
1097 <li><tt>SVSNLINE - :<i>mask</i></tt></li>
1098 </ul>
1099 Unlike other access control lists, which are handled by the
1100 <tt>TKL</tt> message (discussed below), masks for <tt>SVSNLINE</tt>
1101 messages may contain spaces, and thus must be the last parameter of
1102 the message. As a corollary, the <tt><i>reason</i></tt> parameter
1103 cannot contain spaces. In Services, any spaces in the reason are
1104 converted to underscores when an <tt>SVSNLINE +</tt> message is
1105 sent.</dd>
1106
1107 <dt><b><tt>TKL</tt></b></dt>
1108 <dd>This message is used for managing network-wide global connection
1109 control lists (autokills and S-lines). The message takes as
1110 parameters:
1111 <ul>
1112 <li>A <tt>+</tt> or <tt>-</tt> indicating whether the mask is being
1113 added or removed.</li>
1114 <li>The type of the mask (a single character, such as <tt>Z</tt>
1115 for SZlines).</li>
1116 <li>The username part of the mask.</li>
1117 <li>The hostname part of the mask.</li>
1118 <li>The entity (client or server) responsible for the action.</li>
1119 <li><i>(add only)</i> Timestamp (in Unix <tt>time()</tt> style)
1120 for when the mask expires, or 0 if it should not expire.</li>
1121 <li><i>(add only)</i> Timestamp at which the mask was added.</li>
1122 <li><i>(add only)</i> Reason string associated with the mask.</li>
1123 </ul>
1124 When a new server connects to the network, all active <tt>TKL</tt>
1125 masks are forwarded to the server. This can cause problems if a
1126 mask is removed while a server is split from the network; when the
1127 split server reconnects, it will send the mask back to the network,
1128 causing it to reappear. While there is nothing that Services can
1129 do about this in the general case, it does watch for new masks
1130 added that give Services itself as the adder (Services uses its own
1131 server name as the entity adding the mask, and this is preserved
1132 when other servers forward the mask). When it sees such a mask
1133 sent from the network, it checks whether that mask actually exists
1134 in the current databases, and if not, it sends a <tt>TKL&nbsp;-</tt>
1135 message to remove the mask, assuming that a split server has
1136 rejoined the network and reintroduced an old mask.</dd>
1137 </dl>
1138
1139 <p>The extra messages in Unreal along with their handlers are listed in the
1140 <tt>unreal_messages[]</tt> table, which is registered at initialization
1141 time using <tt>register_messages()</tt> (see <a href="2.html#s5-3">section
1142 2-5-3</a>). Some additional messages are also listed with <tt>NULL</tt>
1143 handlers in order to prevent warning messages from being written to the log
1144 when those messages are received.</p>
1145
1146 <p>Unreal also supports the concept of <i>tokens</i>, short names for
1147 messages used in server-to-server communication. These slightly reduce the
1148 bandwidth needed for messages, but more importantly speed up message
1149 lookups, since only one or two characters need to be checked rather than a
1150 longer text string. The list of tokens used by Unreal is in the
1151 <tt>tokens[]</tt> array; this array is passed to <tt>init_tokens()</tt>,
1152 the initialization routine defined in the <tt>tokens.c</tt> auxiliary
1153 source file (see <a href="#s7-7">section 5-7-7</a>).</p>
1154
1155 <p class="backlink"><a href="#top">Back to top</a></p>
1156
1157
1158 <h5 class="subsubsubsection-title" id="s6-14-3">5-6-14-3. Message sending</h5>
1159
1160 <p>Most of the remainder of the source file consists of various routines
1161 which send messages to the network. These include the required
1162 functionality listed in <a href="#s3-1">section 5-3-1</a>, as well as a
1163 number of callback functions which send messages to the network in response
1164 to certain events. The routines are as follows:</p>
1165
1166 <dl>
1167 <dt><tt><b>do_send_svstime()</b></tt></dt>
1168 <dd>Sends a <tt>TSCTL SVSTIME</tt> message to the network to
1169 synchronize servers' clocks. Used for periodic time
1170 synchronization when requested via the <tt>SetServerTimes</tt>
1171 configuration directive.</dd>
1172
1173 <dt><tt><b>do_send_nick()</b></tt>
1174 <br/><tt><b>do_send_nickchange()</b></tt>
1175 <br/><tt><b>do_send_namechange()</b></tt>
1176 <br/><tt><b>do_send_server()</b></tt>
1177 <br/><tt><b>do_send_server_remote()</b></tt>
1178 <br/><tt><b>do_wallops()</b></tt>
1179 <br/><tt><b>do_notice_all()</b></tt>
1180 <br/><tt><b>do_send_channel_cmd()</b></tt></dt>
1181 <dd>Implement the corresponding required message routines.</dd>
1182
1183 <dt><tt><b>do_receive_message()</b></tt></dt>
1184 <dd>Performs special actions on received messages. This callback
1185 function has two purposes; one is to watch for and reverse
1186 improper servicestamp changes, and the other is to parse the
1187 protocol version embedded in the remote server's <tt>SERVER</tt>
1188 message at connection registration time. In both of these
1189 cases, we do not want to override the standard behavior for the
1190 messages, but the current message framework does not allow for
1191 this, so we watch for the messages at this lowest level and
1192 perform the necessary processing there. With respect to the
1193 former case specifically, it would in theory be possible to
1194 handle servicestamp changes in <tt>do_user_mode()</tt>,
1195 described below, but poor design in Unreal resulted in Services
1196 stamps sharing a mode letter (<tt>+d</tt>) with "deaf" mode, so
1197 "+d&nbsp;<i>stamp</i>" needs to be treated separately from other
1198 mode changes.</dd>
1199
1200 <dt><tt><b>do_user_create()</b></tt></dt>
1201 <dd>Called when a new <tt>User</tt> structure is created in response
1202 to a <tt>NICK</tt> message, this routine stores the "fake hostname"
1203 parameter (not handled by <tt>do_nick()</tt>) in the corresponding
1204 field in the <tt>User</tt> structure.</dd>
1205
1206 <dt><tt><b>do_user_servicestamp_change()</b></tt></dt>
1207 <dd>Called when a client is assigned a servicestamp to send the new
1208 stamp out to the network.</dd>
1209
1210 <dt><tt><b>do_user_mode()</b></tt></dt>
1211 <dd>Called when a client's user modes are being changed. Services
1212 handles two user modes exclusively: <tt>+r</tt>, indicating that
1213 the client's nickname is registered (and the client is in fact the
1214 owner of the nickname), and <tt>+a</tt>, indicating that the client
1215 is a Services administrator. If another server tries to change
1216 either of these modes, Services reverses the change. This routine
1217 also watches for users with Services administrator privilege who
1218 newly gain IRC operator status, and sets <tt>+a</tt> on them.</dd>
1219
1220 <dt><tt><b>do_channel_mode()</b></tt></dt>
1221 <dd>Called when a channel's modes are being changed. This routine
1222 takes care of storing the <tt>+L</tt> (channel link), <tt>+f</tt>
1223 (flood protection), and <tt>+j</tt> (join rate limiting) parameters
1224 in the <tt>Channel</tt> structure.</dd>
1225
1226 <dt><tt><b>do_clear_channel()</b></tt></dt>
1227 <dd>Handles requests to clear bans and exceptions from a channel.
1228 Ordinarily, <tt>clear_channel()</tt> will handle bans itself and
1229 ban exceptions are handled by the <tt>banexcept.c</tt> auxiliary
1230 source file, but Unreal has a feature called "extended ban types",
1231 in which a prefix like <tt>~r:</tt> changes the meaning of the ban
1232 or exception mask. In order to process these bans correctly,
1233 the <tt>protocol/unreal</tt> module has to intervene via the
1234 "<tt>clear_channel</tt>" callback and process ban and exception
1235 clear requests itself. The actual work is done by
1236 <tt>unreal_clear_bans_excepts()</tt>, which calls
1237 <tt>unreal_match_ban()</tt> to determine whether a particular mask
1238 matches a given client.</dd>
1239
1240 <dt><tt><b>do_nick_identified()</b></tt></dt>
1241 <dd>Called when a client identifies for its nickname, and sets the
1242 <tt>+a</tt> user mode on the client if it has Services
1243 administrator (and IRC operator) privileges.</dd>
1244
1245 <dt><tt><b>do_set_topic()</b></tt></dt>
1246 <dd>Called when setting a topic on a channel (see
1247 <a href="#s3-1">section 5-3-1</a>). Unreal ignores topic changes
1248 if the topic timestamp is earlier than that of the channel's
1249 current topic, so if necessary, the supplied timestamp is advanced
1250 to force the topic to be changed.</dd>
1251
1252 <dt><tt><b>do_check_modes()</b></tt></dt>
1253 <dd>Called when checking the validity of a mode change on a registered
1254 channel; ensures that the <tt>+L</tt>, <tt>+f</tt>, and <tt>+j</tt>
1255 modes are set properly according to the mode lock data. (The "off"
1256 versions, <tt>-L</tt> and so on, do not require parameters and thus
1257 can be handled by the standard ChanServ code.)</dd>
1258
1259 <dt><tt><b>do_check_chan_user_modes()</b></tt></dt>
1260 <dd>Called when checking whether to modify a client's channel user
1261 modes. This routine watches for and excludes from the check two
1262 classes of clients: other service-type pseudoclients (with user
1263 mode <tt>+S</tt> set), since they generally should not be subject
1264 to the same restrictions as ordinary clients, and "hiding" users
1265 (<tt>+I</tt>), whose presence would be revealed by a mode change.</dd>
1266
1267 <dt><tt><b>do_check_kick()</b></tt></dt>
1268 <dd>Called when checking whether to allow a user to join a channel.
1269 This routine watches for users entering administrator-only,
1270 secure-only, or no-hiding channels, and kicks them out if their
1271 user modes are incompatible with the channel. (Normally the IRC
1272 server will take care of this and Services will never see the join
1273 attempt, but when joining a registered channel which is empty, the
1274 server will not know anything about the channel's locked modes, so
1275 Services must perform the check.)</dd>
1276
1277 <dt><tt><b>do_set_mlock()</b></tt></dt>
1278 <dd>Called when setting a new mode lock on a registered channel.
1279 This routine takes care of setting the aforementioned <tt>+L</tt>,
1280 <tt>+f</tt>, and <tt>+j</tt> mode parameters in the mode lock
1281 structure, and also ensures that the new mode lock is consistent
1282 (<tt>+K</tt> requires <tt>+i</tt> to be set, and <tt>+L</tt>
1283 requires <tt>+l</tt>).</dd>
1284
1285 <dt><tt><b>do_send_svsjoin()</b></tt></dt>
1286 <dd>Called to send a message which forces a user to join a channel.
1287 In Unreal, the message is called <tt>SVSJOIN</tt>.</dd>
1288
1289 <dt><tt><b>do_send_akill()</b></tt>
1290 <br/><tt><b>do_cancel_akill()</b></tt>
1291 <br/><tt><b>do_send_exclude()</b></tt>
1292 <br/><tt><b>do_cancel_exclude()</b></tt>
1293 <br/><tt><b>do_send_sgline()</b></tt>
1294 <br/><tt><b>do_send_sqline()</b></tt>
1295 <br/><tt><b>do_send_szline()</b></tt>
1296 <br/><tt><b>do_cancel_sgline()</b></tt>
1297 <br/><tt><b>do_cancel_sqline()</b></tt>
1298 <br/><tt><b>do_cancel_szline()</b></tt>
1299 </dt>
1300 <dd>Called to add or remove autokill, autokill exclusion, or S-line
1301 masks.</dd>
1302 </dl>
1303
1304 <p class="backlink"><a href="#top">Back to top</a></p>
1305
1306
1307 <h5 class="subsubsubsection-title" id="s6-14-4">5-6-14-4. Module initialization and cleanup</h5>
1308
1309 <p>The final part of the module source file is the module framework, used
1310 by the core module subsystem when loading and unloading the module, along
1311 with callback functions to monitor loading and unloading of relevant
1312 modules and set appropriate callbacks and local variables.</p>
1313
1314 <p>The module's configuration data is stored in the exported array
1315 <tt>module_config[]</tt>. The <tt>protocol/unreal</tt> module includes two
1316 Unreal-specific configuration options: <tt>ServerNumeric</tt>, to assign
1317 Services a "numeric" value to be used with Unreal servers, and
1318 <tt>SetServerTimes</tt>, which sets whether and how often Services should
1319 synchronize other servers' clocks. The array also includes configuration
1320 data from the <tt>SJOIN</tt> handler (defined in <tt>sjoin.h</tt>).</p>
1321
1322 <p>The <tt>do_load_module()</tt> and <tt>do_unload_module()</tt> routines
1323 watch for various pseudoclient-related modules to be loaded or unloaded.
1324 For modules that provide callbacks which the <tt>protocol/unreal</tt>
1325 module hooks into, the appropriate callback functions are added here.
1326 Additionally, the handles for the <tt>operserv/main</tt> and
1327 <tt>chanserv/main</tt> modules, as well as the values (addresses) of the
1328 symbols <tt>is_services_admin</tt> and <tt>s_ChanServ</tt>, are saved when
1329 the relevant module is loaded and cleared when it is unloaded (see
1330 <a href="#s6-14-1">section 5-6-14-1</a>).</p>
1331
1332 <p>Finally, the initialization and cleanup functions call the appropriate
1333 subroutines in a fairly arbitrary order (except that cleanup is performed
1334 in the opposite order of initialization). The initialization and cleanup
1335 for the auxiliary source files is also handled here.</p>
1336
1337 <p class="backlink"><a href="#top">Back to top</a></p>
1338
1339 <!------------------------------------------------------------------------>
1340 <hr/>
1341
1342 <h3 class="subsection-title" id="s7">5-7. Auxiliary source file details</h3>
1343
1344 <p>In addition to the main protocol files described in
1345 <a href="#s6">section 5-6</a>, there are several auxiliary source files
1346 which implement functions common to two or more protocols. These are
1347 listed below. The source files are all designed to be included directly
1348 into the modules which use them; this is to avoid symbol clashes caused by
1349 linking the same object file into two or more modules when compiling
1350 modules statically. (Each source file also has a corresponding header
1351 file, but as this is included by the source file, modules do not need to
1352 include the header files separately.)</p>
1353
1354 <p class="backlink"><a href="#top">Back to top</a></p>
1355
1356
1357 <h4 class="subsubsection-title" id="s7-1">5-7-1. <tt>banexcept.c</tt>, <tt>banexcept.h</tt></h4>
1358
1359 <p>The <tt>banexcept.c</tt> source file implements support for <i>ban
1360 exceptions</i>, masks specifying clients which are not subject to channel
1361 bans. The channel mode for exceptions is assumed to be <tt>+e</tt>.</p>
1362
1363 <p>In addition to handling the actual setting and clearing of ban
1364 exceptions (adding or removing masks on the channel's ban exception array),
1365 the file also implements a handler for clearing ban exceptions using the
1366 <tt>CLEAR_EXCEPTS</tt> flag to <tt>clear_channel()</tt>, as well as a
1367 callback function for the ChanServ <tt>CLEAR</tt> command allowing
1368 <tt>CLEAR EXCEPTIONS</tt> to be used. Since the latter function is part
1369 of the <tt>chanserv/main</tt> module rather than the core, this
1370 necessitates the use of "<tt>load&nbsp;module</tt>" and
1371 "<tt>unload&nbsp;module</tt>" callbacks to watch for that module being
1372 loaded and unloaded.</p>
1373
1374 <p class="backlink"><a href="#top">Back to top</a></p>
1375
1376
1377 <h4 class="subsubsection-title" id="s7-2">5-7-2. <tt>chanprot.c</tt>, <tt>chanprot.h</tt></h4>
1378
1379 <p>The <tt>chanprot.c</tt> source file implements support for a "protected"
1380 channel user mode, preventing ordinary channel operators from kicking a
1381 user with that mode. However, the only "support" required is the
1382 modification of one language string, which is modified by the
1383 initialization routine and restored to its original value by the cleanup
1384 routine.</p>
1385
1386 <p class="backlink"><a href="#top">Back to top</a></p>
1387
1388
1389 <h4 class="subsubsection-title" id="s7-3">5-7-3. <tt>halfop.c</tt>, <tt>halfop.h</tt></h4>
1390
1391 <p>The <tt>halfop.c</tt> source file implements support for a "half-op"
1392 channel user mode, assumed to be <tt>+h</tt>. Half-ops occupy a privilege
1393 level between voiced users (<tt>+v</tt>) and channel operators
1394 (<tt>+o</tt>); typically, they can set <tt>+v</tt> on users and change the
1395 channel topic, but cannot change channel modes or kick channel operators.
1396 In addition to updating several language strings, the source file adds a
1397 callback function for the ChanServ <tt>CLEAR</tt> command allowing
1398 <tt>CLEAR HALFOPS</tt> to be used. As with <tt>banexcept.c</tt>, this
1399 necessitates the use of load/unload-module callback functions to watch for
1400 the ChanServ module being loaded or unloaded.</p>
1401
1402 <p class="backlink"><a href="#top">Back to top</a></p>
1403
1404
1405 <h4 class="subsubsection-title" id="s7-4">5-7-4. <tt>invitemask.c</tt>, <tt>invitemask.h</tt></h4>
1406
1407 <p>The <tt>invitemask.c</tt> source file implements support for <i>invite
1408 masks</i>, masks specifying clients which are allowed to join a <tt>+i</tt>
1409 channel without being explicitly invited into the channel. The channel
1410 mode for exceptions is assumed to be <tt>+I</tt>. Except for the actual
1411 mode character used and structure fields modified, this source file is
1412 identical to <tt>banexcept.c</tt>.</p>
1413
1414 <p class="backlink"><a href="#top">Back to top</a></p>
1415
1416
1417 <h4 class="subsubsection-title" id="s7-5">5-7-5. <tt>sjoin.c</tt>, <tt>sjoin.h</tt></h4>
1418
1419 <p>The <tt>sjoin.c</tt> source file implements support for the
1420 <tt>SJOIN</tt> message used in IRC servers such as Bahamut and Unreal.
1421 This is easily the most complex of the auxiliary source files.</p>
1422
1423 <p>The basic idea of the <tt>SJOIN</tt> message is to condense several
1424 types of channel information&mdash;channel creation time, channel modes,
1425 and users on the channel&mdash;into a single message, reducing the
1426 bandwidth required to send channel state across the network and reducing
1427 the potential for race conditions. There are a few slightly different
1428 message formats used, as noted in the source code comments, but in general
1429 the message takes the channel name, channel creation time, mode string,
1430 (optional) mode parameters, and finally (in a colon-prefixed parameter) the
1431 list of clients (nicknames) on the channel. In this last parameter, each
1432 client's nickname is prefixed with characters indicating the client's
1433 channel user modes; for example, if <tt><i>Nickname</i></tt> is a channel
1434 operator on the channel, the client will be listed as
1435 <tt>@<i>NickName</i></tt> in the message.</p>
1436
1437 <p>Processing of the <tt>SJOIN</tt> message is handled by the
1438 <tt>do_sjoin()</tt> routine; the module should call this routine when in
1439 receives an <tt>SJOIN</tt> message. <tt>do_sjoin()</tt> looks at the
1440 parameters to determine the message's format, then walks through the list
1441 of nicknames (and possibly bans and exceptions), adding each one to the
1442 channel. If any users actually joined the channel, then the channel modes
1443 and timestamp are set afterwards.</p>
1444
1445 <p>The <tt>SJOIN</tt> message can also be used as a shortcut to remove all
1446 users from a channel with one command. By sending an <tt>SJOIN</tt> with
1447 a channel timestamp older than the channel's current timestamp, the remote
1448 server will treat Services' <tt>SJOIN</tt> as authoritative. If that
1449 message indicates that no users are in the channel (an empty last
1450 parameter), then the IRC server will automatically kick all the users
1451 currently on the channel, saving Services the trouble of having to send
1452 <tt>KICK</tt> messages for all users.</p>
1453
1454 <p>Additionally, since <tt>SJOIN</tt> includes the channel's creation time
1455 as a parameter, it is possible to use a dummy <tt>SJOIN</tt> message to
1456 deliberately set the creation timestamp of a registered channel to the time
1457 the channel was registered, ensuring that the channel will always be
1458 considered the "canonical" one even if the same channel is created on a
1459 split server.. The configuration option <tt>CSSetChannelTime</tt>
1460 activates this behavior. (This configuration option is defined in a macro,
1461 <tt>SJOIN_CONFIG</tt>, in <tt>sjoin.h</tt>; the module should include this
1462 macro as part of its <tt>module_config[]</tt> array.) The actual setting
1463 of the channel creation time is done using the "<tt>channel&nbsp;create</tt>"
1464 callback; when a user first enters an empty channel, Services sends an
1465 <tt>SJOIN</tt> message to the network with the altered channel creation
1466 time, including the newly-joining user in the user list; this results in
1467 the channel creation time being updated without any other changes being
1468 made to the channel.</p>
1469
1470 <p>Unfortunately, both of the major IRC servers using <tt>SJOIN</tt>,
1471 Bahamut and Unreal, have idiosyncrasies that prevent this behavior from
1472 working exactly as designed; Bahamut ignores any channel user modes set on
1473 clients who are not behind the sending server, causing the client to lose
1474 channel operator privileges, while Unreal interprets an empty mode string
1475 (a single "<tt>+</tt>") to mean "clear all channel modes". To work around
1476 this, if the module defines the preprocessor symbol <tt>BAHAMUT_HACK</tt>
1477 before including this source file, this processing will be modified to set
1478 <tt>+o</tt> again on the newly-joining client if it was <tt>+o</tt> before
1479 the Services <tt>SJOIN</tt> was sent; this restores the original channel
1480 state, at the cost of having an unsightly <tt>MODE&nbsp;-o</tt> and
1481 <tt>MODE&nbsp;+o</tt> in quick succession when a user first enters a
1482 registered channel. Likewise, defining <tt>UNREAL_HACK</tt> will work
1483 around the Unreal problem by using the channel mode parameter to set
1484 <tt>+o</tt> on the user rather than listing the user in the final
1485 parameter.</p>
1486
1487 <p class="backlink"><a href="#top">Back to top</a></p>
1488
1489
1490 <h4 class="subsubsection-title" id="s7-6">5-7-6. <tt>svsnick.c</tt>, <tt>svsnick.h</tt></h4>
1491
1492 <p>The <tt>svsnick.c</tt> source file implements support for forced
1493 changing of clients' nicknames; this is used, for example, by NickServ to
1494 change a client's nickname to a "guest" nickname rather than disconnecting
1495 the client outright. The implementation itself simply consists of setting
1496 the <tt>PF_CHANGENICK</tt> protocol feature flag and assigning a function
1497 to the <tt>send_nickchange_remote()</tt> function pointer. However, unlike
1498 most other auxiliary source files, the initialization function
1499 <tt>init_svsnick()</tt> takes a parameter; this is so that the protocol
1500 module can specify the name of the message used, in case it is not
1501 <tt>SVSNICK</tt>.</p>
1502
1503 <p class="backlink"><a href="#top">Back to top</a></p>
1504
1505
1506 <h4 class="subsubsection-title" id="s7-7">5-7-7. <tt>token.c</tt>, <tt>token.h</tt></h4>
1507
1508 <p>The <tt>token.c</tt> source file implements the use of one- or
1509 two-character <i>tokens</i> to substitute for full message names in
1510 server-to-server communications. The mapping of tokens to message names
1511 is given by a <tt>TokenInfo</tt> array passed to <tt>init_tokens()</tt>,
1512 terminated by an entry with the <tt>token</tt> field of the structure set
1513 to <tt>NULL</tt>. The initialization routine uses this mapping array to
1514 generate a 65,536-entry lookup table, indexed by the two characters of the
1515 token taken as a 16-bit value with the first character in the high eight
1516 bits (a value of zero is used for the second character in the case of a
1517 one-character token). The values in the lookup table point directly to
1518 the handler functions; this eliminates the necessity to search through
1519 the message table, but also means that any later changes to the message
1520 table will not be seen.</p>
1521
1522 <p>The actual processing of the tokens is done by a callback function added
1523 to the "<tt>receive&nbsp;message</tt>" callback. The function checks
1524 whether the message name is two characters long or less and whether there
1525 is a function in the table corresponding to the one- or two-character
1526 message name; if so, that function is called, and the ordinary message
1527 processing is skipped.</p>
1528
1529
1530 <p class="backlink"><a href="#top">Back to top</a></p>
1531
1532 <!------------------------------------------------------------------------>
1533 <hr/>
1534
1535 <p class="backlink"><a href="4.html">Previous section: The module system</a> |
1536 <a href="index.html">Table of Contents</a> |
1537 <a href="6.html">Next section: Database handling</a></p>
1538
1539 </body>
1540 </html>