ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/vendor/ircservices-5.1.24/docs/tech/6.html
Revision: 3389
Committed: Fri Apr 25 14:12:15 2014 UTC (11 years, 4 months ago) by michael
Content type: text/html
File size: 58608 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 - 6. Database handling</title>
8 </head>
9
10 <body>
11 <h1 class="title" id="top">IRC Services Technical Reference Manual</h1>
12
13 <h2 class="section-title">6. Database handling</h2>
14
15 <p class="section-toc">
16 6-1. <a href="#s1">Databases in Services</a>
17 <br/>6-2. <a href="#s2">The database subsystem interface</a>
18 <br/>&nbsp;&nbsp;&nbsp;&nbsp;6-2-1. <a href="#s2-1">Tables, records, and fields</a>
19 <br/>&nbsp;&nbsp;&nbsp;&nbsp;6-2-2. <a href="#s2-2">Registering and unregistering tables</a>
20 <br/>&nbsp;&nbsp;&nbsp;&nbsp;6-2-3. <a href="#s2-3">Loading and saving data</a>
21 <br/>6-3. <a href="#s3">Database modules</a>
22 <br/>6-4. <a href="#s4">Specific module details</a>
23 <br/>&nbsp;&nbsp;&nbsp;&nbsp;6-4-1. <a href="#s4-1"><tt>database/standard</tt></a>
24 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6-4-1-1. <a href="#s4-1-1">Data format</a>
25 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6-4-1-2. <a href="#s4-1-2">Module structure</a>
26 <br/>&nbsp;&nbsp;&nbsp;&nbsp;6-4-2. <a href="#s4-2"><tt>database/version4</tt></a>
27 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6-4-2-1. <a href="#s4-2-1">Data format</a>
28 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6-4-2-2. <a href="#s4-2-2">Module structure</a>
29 <br/>6-5. <a href="#s5">Auxiliary source files</a>
30 <br/>&nbsp;&nbsp;&nbsp;&nbsp;6-5-1. <a href="#s5-1"><tt>fileutil.c</tt>, <tt>fileutil.h</tt></a>
31 <br/>&nbsp;&nbsp;&nbsp;&nbsp;6-5-2. <a href="#s5-2"><tt>extsyms.c</tt>, <tt>extsyms.h</tt></a>
32 </p>
33
34 <p class="backlink"><a href="5.html">Previous section: IRC server interface</a> |
35 <a href="index.html">Table of Contents</a> |
36 <a href="7.html">Next section: Services pseudoclients</a></p>
37
38 <!------------------------------------------------------------------------>
39 <hr/>
40
41 <h3 class="subsection-title" id="s1">6-1. Databases in Services</h3>
42
43 <p>As with any program that handles large amounts of data, Services needs
44 a place to store nickname, channel, and other data. In Services, the
45 primary data storage method is in-memory lists and tables; however, since
46 these disappear when Services terminates, a more persistent method of
47 recording the data is required. This is implemented through the
48 <i>database subsystem</i>, briefly touched on in
49 <a href="2.html#s9-2">section 2-9-2</a>.</p>
50
51 <p>The primary reason for the use of such a two-layer structure is because
52 of the history of Services; as it was originally designed only for use on a
53 small network, the effort required to implement Services using a true
54 database management system was seen as excessive compared to the simplicity
55 of accessing data structures already in memory. As a result, little
56 thought was given to the structure or accessibility of the persistent data
57 files, which were seen as only an adjunct to the in-memory structures.
58 While this served well enough for a time, the system's inflexibility proved
59 cumbersome as more data was stored, and the file format's opaqueness caused
60 trouble for other programs attempting to access the data.</p>
61
62 <p>The latter problem of opaqueness was mostly resolved with the addition
63 of XML-based data import and export modules (<tt>misc/xml-import</tt> and
64 <tt>misc/xml-export</tt>, described in <a href="8.html#s4">section 8-4</a>).
65 The database system itself remained an issue through version 5.0, but has
66 been redesigned for version 5.1 to allow significantly more flexibility in
67 storing data, as described below. (The two-layer style has been retained,
68 however, primarily due to the difficulty of changing it&mdash;a complete
69 rewrite of Services would be required.)</p>
70
71 <p class="backlink"><a href="#top">Back to top</a></p>
72
73 <!------------------------------------------------------------------------>
74 <hr/>
75
76 <h3 class="subsection-title" id="s2">6-2. The database subsystem interface</h3>
77
78 <p>In Services (as in any typical database system), data to be stored in
79 databases is organized into <i>tables</i>, <i>records</i>, and
80 <i>fields</i>. However, this organization is separate from the in-memory
81 representation of the data: rather than storing the actual data itself,
82 the "tables" handled by the database system hold information on <i>how to
83 access the data</i>. The actual operations of reading data from and
84 writing data to persistent storage are then performed using this
85 information, along with utility routines provided by the table's owner.</p>
86
87 <p>The core part of the database subsystem is in the source files
88 <tt>databases.c</tt> and <tt>databases.h</tt>.</p>
89
90 <p class="backlink"><a href="#top">Back to top</a></p>
91
92
93 <h4 class="subsubsection-title" id="s2-1">6-2-1. Tables, records, and fields</h4>
94
95 <p>A table, as used by the database subsystem, is defined by a
96 <tt>DBTable</tt> structure, which contains information about the fields
97 used in the table and utility routines used to create, delete, and access
98 records in the table. The structure is defined (in <tt>databases.h</tt>,
99 along with all other database-related structures and declarations) as
100 follows:</p>
101
102 <dl>
103 <dt><tt>const char *<b>name</b></tt></dt>
104 <dd>The name for the table. This is used to identify the table to
105 the database system, and is generally used as a filename or other
106 identifier for the copy of the table in persistent storage. The
107 name must be unique among all registered tables.</dd>
108
109 <dt><tt>DBField *<b>fields</b></tt></dt>
110 <dd>A pointer to an array of <tt>DBField</tt> structures describing the
111 fields in the table, terminated by an entry with
112 <tt>DBField.name</tt> set to <tt>NULL</tt>.</dd>
113
114 <dt><tt>void *(*<b>newrec</b>)()</tt></dt>
115 <dd>Returns a newly allocated record to place data in. This function
116 is guaranteed to never be called for more than one record
117 simultaneously (in other words, a call to <tt>newrec()</tt> is
118 guaranteed to be followed by a call to either <tt>insert()</tt> or
119 <tt>freerec()</tt>), so this routine may return a pointer to a
120 static buffer instead than actually allocating memory if doing so
121 is more convenient (see the description of the
122 <tt>nickserv/access</tt> module in <a href="7.html#s3-2">section
123 7-3-2</a> for an example of such usage).</dd>
124
125 <dt><tt>void (*<b>insert</b>)(void *<i>record</i>)</tt></dt>
126 <dd>Inserts a record into the table. This function is called by the
127 database subsystem to insert a new record into the table after it
128 has been successfully loaded. The record passed in is no longer
129 valid after the function returns.</dd>
130
131 <dt><tt>void (*<b>freerec</b>)(void *<i>record</i>)</tt></dt>
132 <dd>Frees resources used by a record. This function is called by the
133 database subsystem if an error occurs while loading a record,
134 before the record has been inserted into the table.</dd>
135
136 <dt><tt>void *(*<b>first</b>)()</tt></dt>
137 <dd>Returns a pointer to the first record in the table.</dd>
138
139 <dt><tt>void *(*<b>next</b>)()</tt></dt>
140 <dd>Returns a pointer to the next record in the table after the last
141 one returned by <tt>first()</tt> or <tt>next()</tt>.</dd>
142
143 <dt><tt>int (*<b>postload</b>)()</tt></dt>
144 <dd>Called by the database subsystem after all records have been loaded.
145 This can be used to, <i>e.g.,</i> implement data integrity checks
146 which can only be performed after all data has been loaded. If the
147 routine returns zero, the load operation is treated as a failure.
148 This field may be <tt>NULL</tt> if no post-load routine is
149 required.</dd>
150 </dl>
151
152 <p>As can be seen from this structure, the actual records themselves are
153 not stored in the <tt>DBTable</tt> structure, but are rather left to the
154 table's owner to store as appropriate. For example, the ChanServ
155 pseudoclient module stores the data for each record in a
156 <tt>ChannelInfo</tt> structure.</p>
157
158 <p>The field data, stored in <tt>DBField</tt> structures, likewise does
159 not hold actual data, only instructions on how to access it. The
160 <tt>DBField</tt> structure contains:</p>
161
162 <dl>
163 <dt><tt>const char *<b>name</b></tt></dt>
164 <dd>The name for the field. Typically the same as the field identifier
165 used in the program.</dd>
166
167 <dt><tt>DBType <b>type</b></tt></dt>
168 <dd>The type of the field. Valid types are defined in
169 <tt>databases.h</tt>:
170 <ul><li><tt><b>DBTYPE_INT<i>n</i></b></tt>,
171 <tt><b>DBTYPE_UINT<i>n</i></b></tt>:
172 Signed and unsigned integer values of different bit lengths
173 (8, 16, or 32).</li>
174 <li><tt><b>DBTYPE_TIME</b></tt>: A <tt>time_t</tt> value.</li>
175 <li><tt><b>DBTYPE_STRING</b></tt>: A string (<tt>char&nbsp;*</tt>)
176 value, which can be <tt>NULL</tt>.</li>
177 <li><tt><b>DBTYPE_BUFFER</b></tt>: A fixed-length buffer. The
178 buffer size is given in <tt>DBField.length</tt>.</li>
179 <li><tt><b>DBTYPE_PASSWORD</b></tt>: A <tt>Password</tt> value,
180 as defined in <tt>encrypt.h</tt>.</li>
181 </ul></dd>
182
183 <dt><tt>int <b>offset</b></tt></dt>
184 <dd>The offset in bytes from the start of the record to the location
185 where the field's value is stored. For records stored in a
186 <tt>struct</tt>, this can be obtained using the standard
187 <tt>offsetof()</tt> macro; for example, the offset of this member
188 in a <tt>DBField</tt> structure is given by:
189 <div class="code">offsetof(DBField, offset)</div></dd>
190
191 <dt><tt>int <b>length</b></tt></dt>
192 <dd>For <tt>DBTYPE_BUFFER</tt> fields, this gives the length of the
193 buffer, in bytes. This value is ignored for other field types.</dd>
194
195 <dt><tt>int <b>load_only</b></tt></dt>
196 <dd>If nonzero, the field is not saved to persistent storage. This is
197 intended to facilitate changes in table format, as described
198 below.</dd>
199
200 <dt><tt>void <b>get</b>(const void *<i>record</i>, void **<i>value_ret</i>)</tt></dt>
201 <dd>If not <tt>NULL</tt>, provides a function to retrieve the field's
202 value; the database subsystem will call this function instead of
203 simply accessing the data stored in the field.
204 <tt><i>record</i></tt> is a pointer to the record structure, and
205 <tt><i>value_ret</i></tt> points to a buffer to receive the value;
206 the buffer will be large enough to hold the data type specified by
207 <tt>DBField.type</tt>. (For strings, store a <tt>char&nbsp;*</tt>
208 value in <tt>*<i>value_ret</i></tt>; the string will <i>not</i> be
209 freed after use, so a static buffer or other method is needed to
210 avoid memory leaks if the string is generated dynamically.)</dd>
211
212 <dt><tt>void <b>put</b>(void *<i>record</i>, const void *<i>value</i>)</tt></dt>
213 <dd>If not <tt>NULL</tt>, provides a function to set the field's value;
214 the database system will call this function instead of simply
215 storing the loaded data into the field. <tt><i>record</i></tt> is
216 a pointer to the record structure which is to receive the data, and
217 <tt><i>value</i></tt> points to the data itself, in the format
218 given by <tt>DBField.type</tt>. (For strings, this is a
219 <tt>char&nbsp;*</tt> value which may be <tt>NULL</tt>; if not
220 <tt>NULL</tt>, the string has been allocated with <tt>malloc()</tt>
221 and will not be freed by the database subsystem, so you will need
222 to free it if you do not store the pointer directly into the
223 record.)</dd>
224 </dl>
225
226 <p>This structure is designed with the assumption that data will be stored
227 in some structured type in memory; if no <tt>get()</tt> or <tt>put()</tt>
228 routine is provided, the database subsystem will simply access the memory
229 location derived by adding the field's offset to the record pointer
230 returned by the table's record access functions (<tt>newrec()</tt>,
231 <tt>first()</tt>, or <tt>next()</tt>). If this is not sufficient, however,
232 the table owner can define <tt>get()</tt> and/or <tt>put()</tt> functions
233 for accessing the data.</p>
234
235 <p>One member of the <tt>DBField</tt> structure that deserves particular
236 mention is the <tt>load_only</tt> member. If a field's <tt>load_only</tt>
237 value is nonzero, then the field will be ignored when the database is saved
238 to persistent storage. This can be used to handle changes in the format of
239 a table; if the old field is left defined with <tt>load_only</tt> nonzero
240 and a <tt>put()</tt> routine provided, that routine will be called whenever
241 a record with the old field is loaded, allowing the old field's value to be
242 processed as necessary to fit the new table format. Alternatively, the old
243 field can be left in the in-memory structure, and code added to the table's
244 <tt>insert()</tt> routine to handle the data translation.</p>
245
246 <p class="backlink"><a href="#top">Back to top</a></p>
247
248
249 <h4 class="subsubsection-title" id="s2-2">6-2-2. Registering and unregistering tables</h4>
250
251 <p>In order for a database table to be loaded from and saved to persistent
252 storage, it must first be registered with the database subsystem by calling
253 the <tt>register_dbtable()</tt> routine; the complementary
254 <tt>unregister_dbtable()</tt> routine must be called when the table is no
255 longer needed (for example, when the module owning the table exits). The
256 routines' prototypes are as follows:</p>
257
258 <div class="code">int <b>register_dbtable</b>(DBTable *<i>table</i>)
259 void <b>unregister_dbtable</b>(DBTable *<i>table</i>)</div>
260
261 <p>Both routines take a pointer to the <tt>DBTable</tt> structure
262 describing the table to be registered or unregistered. The
263 <tt>register_dbtable()</tt> routine returns nonzero on success, zero on
264 failure.</p>
265
266 <p>Note that <tt>register_dbtable()</tt> assumes that the in-memory table
267 is empty, and has no facility to signal the database owner to clear the
268 table before data is loaded. The database owner must ensure that the table
269 is empty or take whatever other precautions are appropriate before
270 registering the table.</p>
271
272 <p class="backlink"><a href="#top">Back to top</a></p>
273
274
275 <h4 class="subsubsection-title" id="s2-3">6-2-3. Loading and saving data</h4>
276
277 <p>Data loading and saving is performed on a per-table basis when the table
278 is registered or unregistered, respectively; thus data is immediately
279 available for use when <tt>register_dbtable()</tt> returns successfully,
280 and any changes made to the data after <tt>unregister_dbtable()</tt> is
281 called will not be reflected in persistent storage. There is also an
282 auxiliary routine, <tt>save_all_dbtables()</tt>, which causes all
283 registered tables to be saved (synced) to persistent storage immediately:</p>
284
285 <div class="code">int <b>save_all_dbtables</b>()</div>
286
287 <p>This routine returns one of the following values:</p>
288
289 <ul>
290 <li><b>1</b> if all database tables were saved with no errors, or if no
291 tables are registered.</li>
292 <li><b>0</b> if some tables were saved successfully, but errors occured on
293 at least one table.</li>
294 <li><b>-1</b> if no tables were saved successfully.</li>
295 </ul>
296
297 <p>This routine is called by the main loop (via the <tt>save_data_now()</tt>
298 helper routine) at periodic intervals or when explicitly requested, as
299 described in <a href="2.html#s3-3">section 2-3-3</a>.</p>
300
301 <p class="backlink"><a href="#top">Back to top</a></p>
302
303 <!------------------------------------------------------------------------>
304 <hr/>
305
306 <h3 class="subsection-title" id="s3">6-3. Database modules</h3>
307
308 <p>The core portion of the database subsystem only provides the interface
309 for persistent storage of databases; the actual work of transferring data
310 to and front persistent storage is performed by <i>database modules</i>.
311 The standard database modules are located in the <tt>modules/database</tt>
312 directory.</p>
313
314 <p>A database module registers itself with the core part of the subsystem
315 by calling <tt>register_dbmodule()</tt>; as with tables, the module must
316 unregister itself with the complementary <tt>unregister_dbmodule()</tt>
317 when exiting:</p>
318
319 <div class="code">int <b>register_dbmodule</b>(DBModule *<i>module</i>)
320 void <b>unregister_dbmodule</b>(DBModule *<i>module</i>)</div>
321
322 <p>Only one database module may be registered; if a second module tries to
323 register itself, <tt>register_dbmodule()</tt> will return an error (zero).</p>
324
325 <p>The <tt>DBModule</tt> structure passed to these functions contains two
326 function pointers:</p>
327
328 <div class="code">int (*<b>load_table</b>)(DBTable *<i>table</i>)
329 int (*<b>save_table</b>)(DBTable *<i>table</i>)</div>
330
331 <p>As the names suggest, <tt>load_table()</tt> is called to load a table
332 from persistent storage, and <tt>save_table()</tt> is called to save a
333 table to persistent storage. Both routines should return nonzero on
334 success, zero on failure.</p>
335
336 <p>Since the <tt>DBTable</tt> structures representing registered database
337 tables are passed directly to these two routines, the module must take care
338 to observe the restrictions and requirements on calling the table's
339 function pointers documented in <a href="#s2">section 6-2</a> above, such
340 as not calling <tt>newrec()</tt> twice without an intervening
341 <tt>insert()</tt> or <tt>freerec()</tt> and ensuring that <tt>postload()</tt>
342 is called when a table has been loaded. <i>Implementation note: A better
343 implementation might hide the DBTable structure from database modules,
344 providing an interface that ensures the rules are followed.</i></p>
345
346 <p>To simplify data access logic and avoid bugs caused by misuse of data
347 fields, database modules should use the <tt>get_dbfield()</tt> and
348 <tt>put_dbfield()</tt> routines to read and write fields in database
349 records. These routines are declared as:</p>
350
351 <div class="code">void <b>get_dbfield</b>(const void *<i>record</i>, const DBField *<i>field</i>, void *<i>buffer</i>)
352 void <b>put_dbfield</b>(void *<i>record</i>, const DBField *<i>field</i>, const void *<i>value</i>)</div>
353
354 <p>The routines will automatically call the field's <tt>get()</tt> or
355 <tt>put()</tt> routine if one is supplied, or else copy the field's value
356 to or from the supplied buffer.</p>
357
358 <p class="backlink"><a href="#top">Back to top</a></p>
359
360 <!------------------------------------------------------------------------>
361 <hr/>
362
363 <h3 class="subsection-title" id="s4">6-4. Specific module details</h3>
364
365 <p>Services includes two standard database modules. The first,
366 <tt>database/standard</tt>, is (as the name implies) intended to be the
367 standard module for use with version 5.1; it stores each table in a binary
368 data file. The second module, <tt>database/version4</tt>, uses the same
369 file format as was used in Services versions 4.x and 5.0, and is intended
370 for compatibility when testing Services 5.1 or converting databases to the
371 new format. (It is not possible to have one module handle loading and a
372 different module handle saving, so data must first be exported to XML using
373 the <tt>version4</tt> module and then imported using the <tt>standard</tt>
374 module in the latter case.)</p>
375
376 <p class="backlink"><a href="#top">Back to top</a></p>
377
378
379 <h4 class="subsubsection-title" id="s4-1">6-4-1. <tt>database/standard</tt></h4>
380
381 <h5 class="subsubsubsection-title" id="s4-1-1">6-4-1-1. Data format</h5>
382
383 <p>This module stores each table in a file whose name is constructed by
384 replacing all non-alphanumeric characters (except hyphens and underscores)
385 by underscores and appending "<tt>.sdb</tt>". The file format consists of
386 three main sections, described below. In all cases, numeric data is
387 written in big-endian format (with the most-significant byte first);
388 strings are stored as a 16-bit length in bytes followed by the specified
389 number of bytes of string data (including a terminating null byte), with a
390 <tt>NULL</tt> string indicated by a length value of zero.
391 <i>Implementation note: This obviously limits the length of a string to
392 65,534 bytes. This is the result of reusing the string reading and writing
393 routines used for the old file format; while it has not proved to be a
394 problem to date, it is nonetheless an unnecessary artificial
395 limitation.</i></p>
396
397 <dl>
398
399 <dt><b>The file header</b></dt>
400
401 <dd><p>The file header contains basic information about the file, in the
402 following four fields:</p>
403 <ul>
404 <li class="spaced"><b>File format version:</b> <i>(32-bit integer)</i>
405 A value which identifies the file format in use. This is
406 always the constant <tt>NEWDB_VERSION</tt>; the upper 24
407 bits of this value contain the ASCII string "<tt>ISD</tt>",
408 identifying the file as an <b>I</b>RC <b>S</b>ervices
409 <b>D</b>atabase, and the lower 8 bits contain a format
410 version number, currently 1.</li>
411 <li class="spaced"><b>Header size:</b> <i>(32-bit integer)</i>
412 The total size of the header, in bytes. Currently 16.</li>
413 <li class="spaced"><b>Field list offset:</b> <i>(32-bit integer)</i>
414 The offset in bytes from the start of the file to the field
415 list, described below.</li>
416 <li class="spaced"><b>Record data offset:</b> <i>(32-bit integer)</i>
417 The offset in bytes from the start of the file to the
418 record data, described below.</li>
419 </ul>
420 </dd>
421
422 <dt><b>The field list</b></dt>
423
424 <dd><p>The field list contains information about the fields in the data
425 table and how they are stored in the file. The field list can be
426 stored anywhere in the file, but the current implementation writes
427 it immediately after the file header. The field list consists of a
428 header followed by a variable number of field entries. The header
429 contains the following three values:</p>
430 <ul>
431 <li class="spaced"><b>Field list size:</b> <i>(32-bit integer)</i>
432 The total size of the field list, in bytes.</li>
433 <li class="spaced"><b>Number of fields:</b> <i>(32-bit integer)</i>
434 The number of fields in the field list.</li>
435 <li class="spaced"><b>Record data size:</b> <i>(32-bit integer)</i>
436 The size in bytes of the fixed part of a single record's
437 data. This is the portion of the record data which is
438 always stored in the same format, excluding variable-length
439 data such as strings.</li>
440 </ul>
441 <p>For each field, the following data is recorded:</p>
442 <ul>
443 <li class="spaced"><b>Field data size:</b> <i>(32-bit integer)</i>
444 The size in bytes of the data as stored in the fixed part
445 of the record data. All fields are stored consecutively in
446 the order they appear in the field list, with no padding;
447 thus the offset of a field's data is equal to the sum of
448 the sizes of all previous fields.</li>
449 <li class="spaced"><b>Field type:</b> <i>(16-bit integer)</i>
450 The type of the field. The value is one of the
451 <tt>DBTYPE_*</tt> constants defined in <tt>databaess.h</tt>.
452 <i>Implementation note: This is a bad idea; it would be
453 better to explicitly define constants in <tt>standard.c</tt>
454 to avoid problems arising from changes in the values of the
455 constants.</i></li>
456 <li class="spaced"><b>Field name:</b> <i>(string)</i>
457 The name of the field.</li>
458 </ul>
459 </dd>
460
461 <dt><b>The record data</b></dt>
462
463 <dd><p>The last section of the file contains the actual data for each
464 record in the table. To avoid the potential for a corrupt record
465 to render all following records unreadable (if, for example, the
466 length of a string is incorrect), the actual record data is
467 preceded by a <i>record descriptor table</i>, which contains a
468 file offset pointer and total length for each record's data.</p>
469
470 <p>In order to simplify the writing of database files, the record
471 descriptor table is allowed to be fragmented into multiple parts.
472 Each partial table consists of an 8-byte header containing:</p>
473 <ul>
474 <li class="spaced"><b>Next table pointer:</b> <i>(32-bit integer)</i>
475 The absolute file offset (in bytes) of the next record
476 descriptor table. Set to zero for the last table in the
477 file.</li>
478 <li class="spaced"><b>Table length:</b> <i>(32-bit integer)</i>
479 The length of this record descriptor table in bytes,
480 including the header.</li>
481 </ul>
482 <p>The remainder of the table is filled with 8-byte record
483 descriptors, each containing:</p>
484 <ul>
485 <li class="spaced"><b>Record data pointer:</b> <i>(32-bit integer)</i>
486 The absolute file offset of the record's data.</li>
487 <li class="spaced"><b>Record data length:</b> <i>(32-bit integer)</i>
488 The length of the record's data in bytes.</li>
489 </ul>
490 <p>Note that the header has the same format as a record descriptor,
491 so the entire descriptor table can be treated as an array of
492 descriptors in which the first entry points to the next table
493 rather than a particular record.</p>
494
495 <p>The record data pointed to by each descriptor consists, in turn,
496 of a fixed-length part and a variable-length part. The
497 fixed-length part (also referred to in the field list description
498 above) contains all data which is of a fixed length for every
499 record; this includes all numeric data, as well as a 32-bit data
500 offset pointer for strings (see below). Variable-length data is
501 stored immediately after the fixed-length part of the data, in
502 arbitrary order.</p>
503
504 <p>The various field types are stored as follows (where not
505 explicitly mentioned, the value is stored entirely in the
506 fixed-length part of the record data):</p>
507 <ul>
508 <li class="spaced"><b><tt>DBTYPE_INT<i>n</i></tt>,
509 <tt>DBTYPE_UINT<i>n</i></tt>:</b> The value is stored
510 using the requisite number of bytes (1, 2, or 4, depending
511 on the data type size).</li>
512 <li class="spaced"><b><tt>DBTYPE_TIME</tt>:</b>
513 The value is stored as a 64-bit integer.</li>
514 <li class="spaced"><b><tt>DBTYPE_STRING</tt>:</b>
515 A 32-bit data offset is stored in the fixed-length part;
516 this is a byte offset relative to the start of the record
517 data, and points to the location of the actual string data
518 (a16-bit length followed by character data), stored in the
519 variable-length part of the record.</li>
520 <li class="spaced"><b><tt>DBTYPE_BUFFER</tt>:</b>
521 The value is stored using the number of bytes specified by
522 <tt>DBField.length</tt>.</li>
523 <li class="spaced"><b><tt>DBTYPE_PASSWORD</tt>:</b>
524 The value is stored as a data offset pointing to the string
525 giving the cipher name (<tt>Password.cipher</tt>) followed
526 by a fixed buffer of <tt>PASSMAX</tt> bytes. The cipher
527 name itself is stored in the variable-length part, like
528 other strings.</li>
529 </ul>
530 </dd>
531
532 </dl>
533
534 <p class="backlink"><a href="#top">Back to top</a></p>
535
536
537 <h5 class="subsubsubsection-title" id="s4-1-2">6-4-1-2. Module structure</h5>
538
539 <p>Database loading and saving are handled by the routines
540 <tt>standard_load_table()</tt> and <tt>standard_save_table()</tt>,
541 respectively. (The <tt>standard_</tt> prefix comes from the module name,
542 and is included to avoid potential name clashes with other database
543 modules, which would complicate debugging.) Each of these routines calls
544 three subroutines to handle each of the three parts of a database file
545 described in <a href="#s4-1-1">section 6-4-1-1</a> above.</p>
546
547 <p>The <tt>SAFE()</tt> preprocessor macro defined at the top of the file is
548 used in read and write operations to check for a premature end-of-file (on
549 read) or a write error (on write) and abort the routine in these cases.</p>
550
551 <p>Three helper functions used in loading and saving are defined first:</p>
552
553 <dl>
554 <dt><tt>TableInfo *<b>create_tableinfo</b>(const DBTable *<i>table</i>)</tt></dt>
555 <dd>Generates a <tt>TableInfo</tt> structure corresponding to the given
556 database table. The <tt>TableInfo</tt> structure is defined at the
557 top of the file, and includes the size of each field as stored in
558 memory and on disk, as well as the location of each field within
559 the record's data as written to disk. (This latter value,
560 <tt>offset</tt>, is set to -1 by this routine, since it is
561 initialized differently when loading than when saving.)</dd>
562
563 <dt><tt>void <b>free_tableinfo</b>(TableInfo *<i>ti</i>)</tt></dt>
564 <dd>Frees a <tt>TableInfo</tt> structure created by
565 <tt>create_tableinfo()</tt>.</dd>
566
567 <dt><tt>const char *<b>make_filename</b>(const DBTable *<i>table</i>)</tt></dt>
568 <dd>Generates the filename corresponding to the table name for the
569 given table. The returned filename string is stored in a static
570 buffer, which will be overwritten by subsequent calls.</dd>
571 </dl>
572
573 <p>Following these routines is <tt>standard_load_table()</tt>, along with
574 its helper routines <tt>read_file_header()</tt>, <tt>read_field_list()</tt>,
575 and <tt>read_records()</tt>. When called, <tt>standard_load_table()</tt>
576 takes the following actions:</p>
577
578 <ul>
579 <li class="spaced">Generates a <tt>TableInfo</tt> structure for the
580 database table.</li>
581
582 <li class="spaced">Opens the file corresponding to the table, using
583 <tt>open_db()</tt> from <tt>fileutil.c</tt>(see
584 <a href="#s5-1">section 6-5-1</a>).</li>
585
586 <li class="spaced">Calls <tt>read_file_header()</tt> to read in the file
587 header.</li>
588
589 <li class="spaced">Seeks to the beginning of the field list, and calls
590 <tt>read_field_list()</tt> to read it in.</li>
591
592 <li class="spaced">Seeks to the beginning of the record data, and calls
593 <tt>read_records()</tt> to read it in.</li>
594 </ul>
595
596 <p><tt>read_file_header()</tt> is fairly straightforward; it simply reads
597 in the four header fields, checks the version number and header size to
598 ensure that they have appropriate values, and returns the field list and
599 record data offsets in the variable references passed in.</p>
600
601 <p><tt>read_field_list()</tt> is slightly more complex; since there is no
602 guarantee that the record structure stored in the file will match that
603 given by the <tt>DBTable</tt> structure, the routine must match fields in
604 the file to those in the structure. <tt>read_field_list()</tt> iterates
605 through the fields in the loaded table, searching the <tt>TableInfo</tt>
606 structure for a matching field (the name, type, and field size must all
607 match); if found, the record data offset is recorded in the
608 <tt>TableInfo</tt> structure, while unknown fields are simply ignored.
609 <i>Implementation note: As a side effect of this handling, fields like
610 nicknames, channel names, and passwords will cease to be recognized if the
611 relevant buffer sizes are changed, thus the note in <tt>defs.h</tt> about
612 backing up the data before changing the constants.</i></p>
613
614 <p><tt>read_records()</tt> reads in and loops through the record descriptor
615 tables, continuing until an empty descriptor, signifying the end of the
616 table, is found. In order to avoid duplication of code, the descriptor
617 table is loaded (when necessary) at the beginning of the loop; however,
618 since the descriptor table must be loaded before the end-of-data check can
619 be made, the loop termination check is performed in the middle of the loop,
620 immediately after the descriptor table loading. The <tt>recnum</tt> loop
621 variable indicates the current index in the descriptor table, with 1
622 meaning the first record descriptor (after the header) and 0 meaning that a
623 new table has to be loaded; the modulo arithmetic in the loop variable
624 update expression ensures that when the index reaches the end of the table,
625 it will be reset to zero, causing the next table to be loaded.</p>
626
627 <p>The table-saving routine <tt>standard_save_table()</tt> and its
628 subroutines <tt>write_file_header()</tt>, <tt>write_field_list()</tt>, and
629 <tt>write_records()</tt> operate in essentially the same way, although they
630 are slightly simpler because there is no need to check for invalid data, as
631 must be done while reading. The other point worth mentioning is that
632 <tt>open_db()</tt> automatically writes the version number given as the
633 third parameter into the file, so there is no need for
634 <tt>write_file_header()</tt> to do so. <i>Implementation note: Yes, this
635 is ugly; see <a href="#s5-1">section 6-5-1</a> for an explanation.</i></p>
636
637 <p>Finally, the source file concludes with the standard module variables
638 and routines, along with the <tt>DBModule</tt> structure required for
639 registering the database module. However, for this module they are
640 enclosed by <tt>#ifndef&nbsp;INCLUDE_IN_VERSION4</tt> and <tt>#endif</tt>;
641 this is so that the source file can be directly included in the
642 <tt>database/version4</tt> module (see <a href="#s4-2-2">section
643 6-4-2-2</a> below) without causing identifier conflicts or other
644 problems.</p>
645
646 <p class="backlink"><a href="#top">Back to top</a></p>
647
648
649 <h4 class="subsubsection-title" id="s4-2">6-4-2. <tt>database/version4</tt></h4>
650
651 <p>This module is intended as a compatibility/transition module, and (as
652 the name implies) supports database files in the format used by 4.x
653 versions of Services, as well as the extended form of that format used in
654 version 5.0. These versions did not support generic database tables, so
655 any such tables which do not correspond to tables used in version 4/5
656 format files are simply written out in the same format used with the
657 <tt>database/standard</tt> module.</p>
658
659 <p class="backlink"><a href="#top">Back to top</a></p>
660
661
662 <h5 class="subsubsubsection-title" id="s4-2-1">6-4-2-1. Data format</h5>
663
664 <p>The pre-5.1 data file format is a rather complex beast, an extended form
665 of the original database files which were simply binary dumps of the
666 structures used in memory. The format is not documented outside of the
667 code that implements it, and even I (the developer) often have to refer to
668 the code when analyzing a database file from these versions.</p>
669
670 <p>The database files used encompass all of the data handled by the
671 standard pseudoclients, but the files are generally split by pseudoclient
672 name rather than individual table: for example, the nickname, nickname
673 group, and memo data are all stored in the same database. This, again,
674 derives from the fact that such data was at one time all stored as part of
675 the same structure (even now, memos are stored in the nickname group
676 structure rather than having their own separate table in memory). The list
677 of files and the tables they encompass follows:</p>
678
679 <ul>
680 <li class="spaced"><b><tt>nick.db</tt></b> contains the <tt>nick</tt>,
681 <tt>nickgroup</tt>, <tt>nick-access</tt>, <tt>nick-autojoin</tt>,
682 <tt>memo</tt>, and <tt>memo-ignore</tt> tables.</li>
683 <li class="spaced"><b><tt>chan.db</tt></b> contains the <tt>chan</tt>,
684 <tt>chan-access</tt>, and <tt>chan-akick</tt> tables.</li>
685 <li class="spaced"><b><tt>oper.db</tt></b> contains the <tt>oper</tt>
686 table.</li>
687 <li class="spaced"><b><tt>news.db</tt></b> contains the <tt>news</tt>
688 table.</li>
689 <li class="spaced"><b><tt>akill.db</tt></b> contains the <tt>akill</tt> and
690 <tt>exclude</tt> tables.</li>
691 <li class="spaced"><b><tt>exception.db</tt></b> contains the
692 <tt>exception</tt> table.</li>
693 <li class="spaced"><b><tt>sline.db</tt></b> contains the <tt>sgline</tt>,
694 <tt>sqline</tt>, and <tt>szline</tt> tables.</li>
695 <li class="spaced"><b><tt>stats.db</tt></b> contains the
696 <tt>stat-servers</tt> table.</li>
697 </ul>
698
699 <p>In general, the contents of each database file can be divided into three
700 parts: the base data, the 5.0 extension data, and the 5.1 extension
701 data, all concatenated together. This division of data was introduced in
702 version 5.0 to allow databases written by version 5.0 to be read by version
703 4.5 (minus the 5.0-specific features, of course); version 5.0 wrote the
704 data in the format used by version 4.5, then appended the 5.0-specific data
705 to the end of the file, so that the 4.5 code would simply ignore it,
706 believing that it had reached the end of the data, while the 5.0 code would
707 know to look for the extension data to supplement the (possibly inaccurate)
708 data in the base part. Version 5.1 takes the same approach with respect to
709 version 5.0, resulting in database files which are very convoluted but
710 which can be used in any of versions 4.5, 5.0, or 5.1.</p>
711
712 <p>Each part begins with a 32-bit version number identifying the format of
713 the data (like the 5.1 standard format, all values are stored in big-endian
714 byte order); this value is fixed at 11 for the base data and 27 for the 5.0
715 extension data, the file version numbers used in the final releases of
716 these versions of Services. The file version is followed immediately by
717 the data itself, whose format varies depending on the particular data being
718 stored. Simple arrays like news and autokill data typically use a 16-bit
719 count followed by the appropriate number of repetitions of the data
720 structure, a format which is also used for sub-arrays such as access lists
721 within nickname and channel data. Nicknames and channels, on the other
722 hand, do not have a count field, and instead simply consist of a byte with
723 value 1 followed by the nickname or channel data structure for as many
724 structures as necessary, followed by 256 zero bytes indicating the end of
725 the table. (The reason for 256 zero bytes instead of just one is that very
726 old versions of Services, earlier than version 4.0, wrote out each
727 collision list of the 256-element hash arrays separately, terminating each
728 list with a zero; when this was changed, the fiction of 256 collision lists
729 was kept in order to simplify the database reading logic.)</p>
730
731 <p>For cases where there is a difference in data format or content between
732 the base, 5.0, and 5.1 data, the data is written so that if loaded by the
733 corresponding version of Services, it will be interpreted as closely as
734 possible to the true value. For example, the 32-bit nickname group ID is
735 written into 16 bits of the nickname flags and the 16-bit registered
736 channel limit in the base data, since 4.5 does not interpret these bits;
737 however, since 5.0 does make use of them, the correct values of those two
738 fields are then re-recorded in the 5.0 extension data. Similarly, channel
739 access levels are recorded in the base data using the 4.5 access level
740 system (a range from -9999 to 9999 with standard levels clustered from -2
741 to 10), and again in the 5.0 extension data using the current system.</p>
742
743 <p class="backlink"><a href="#top">Back to top</a></p>
744
745
746 <h5 class="subsubsubsection-title" id="s4-2-2">6-4-2-2. Module structure</h5>
747
748 <p>The source file, <tt>version4.c</tt>, starts with a workaround for a
749 limitation of static module compilation. As with the
750 <tt>database/standard</tt> module, this module makes use of the utility
751 routines in <tt>fileutil.c</tt>; however, if <tt>fileutil.c</tt> is simply
752 linked into the module, as is done with the <tt>database/standard</tt>
753 module, an error would occur at link time due to the symbols being defined
754 in both modules. While it is possible to adjust the compilation process to
755 avoid this problem, the <tt>database/version4</tt> module instead simply
756 uses <tt>#define</tt> to rename all of the exported functions in
757 <tt>fileutil.c</tt>, then includes that source file directly.</p>
758
759 <p>The four version number defines indicate the file version numbers to be
760 used with various parts of the data:</p>
761 <ul>
762 <li><b><tt>FILE_VERSION</tt>:</b> The file version used for the base data.
763 Always 11 (the last value used in Services 4.5).</li>
764 <li><b><tt>LOCAL_VERSION</tt>:</b> The file version used for the 5.1
765 extension data. Incremented when the 5.1 extension data format
766 changes.</li>
767 <li><b><tt>FIRST_VERSION_51</tt>:</b> The first file version used in
768 Services 5.1. Used to ensure that the 5.1 extension data is
769 valid.</li>
770 <li><b><tt>LOCAL_VERSION_50</tt>:</b> The file version used for the 5.0
771 extension data. Always 27 (the last value used in Services 5.0).</li>
772 </ul>
773
774 <p>The <tt>CA_SIZE_4_5</tt>, <tt>ACCESS_INVALID_4_5</tt>, and
775 <tt>def_levels_4_5[]</tt> constants and array are used when processing
776 channel privilege level data as stored in the base data section. Since
777 Services 4.5 always stored the privilege level array, even if all values
778 were set to the defaults, this array is used to detect such a case when
779 loading data and to supply data for channels using the default settings
780 when saving. (The channel access levels themselves use a different scale
781 in 4.5; this is handled by the <tt>convert_old_level()</tt> and
782 <tt>convert_new_level()</tt> helper functions, defined later.)</p>
783
784 <p>The last set of compatibility constants and variables,
785 <tt>MAX_SERVADMINS</tt>, <tt>services_admins[]</tt> and so on, is used to
786 handle loading and saving of the Services administrator and operator lists
787 in <tt>oper.db</tt>. (Version 4.5 kept these separate from the nickname
788 data, as opposed to the current method which stores the OperServ status
789 level in the nickname group data.)</p>
790
791 <p>Following these preliminary declarations are the main load and save
792 routines, <tt>version4_load_table()</tt> and <tt>version4_save_table()</tt>,
793 preceded by forward declarations of the individual table handling routines.
794 For the most part, these consist of checking the name of the table to be
795 loaded or saved and calling the appropriate routine; however, since most
796 database files encompass two or more tables, the table pointers must be
797 saved in local variables until all relevant tables are available. Also,
798 several tables are simply ignored this is because the load/save routines
799 access the corresponding data directly through the parent structures (for
800 example, channel access and autokick lists are accessed via the
801 <tt>ChannelInfo</tt> structures in the <tt>chan</tt> table). One other
802 workaround required when loading data is the temporary setting of the
803 global <tt>noexpire</tt> flag; as the comments in the code indicate, this
804 is because the databases are loaded in several steps, and records'
805 expiration timestamps may not be correct until the final step, so leaving
806 expiration enabled could cause records to be improperly expired during the
807 loading process (since expiration occurs when a record is accessed via the
808 various pseudoclients' <tt>get()</tt>, <tt>first()</tt>, and <tt>next()</tt>
809 functions).</p>
810
811 <p>Next are three short utility functions. The first,
812 <tt>my_open_db_r()</tt>, calls <tt>open_db()</tt> from <tt>fileutil.c</tt>
813 (see <a href="#s5-1">section 6-5-1</a>) to open the given database file for
814 reading, then reads in the file version number and checks that it is within
815 range for the base data section; the version number is then returned in
816 <tt>*<i>ver_ret</i></tt>. (File versions below 5, corresponding to
817 Services 3.0, are not supported because they stored numeric values in a
818 machine-dependent format.) The other two utility routines,
819 <tt>read_maskdata()</tt> and <tt>write_maskdata</tt>, are used to read and
820 write lists of <tt>MaskData</tt> structures, used (for example) in
821 autokills and S-lines.</p>
822
823 <p>The bulk of the module is taken up by the routines to load particular
824 tables. Since each database file has its own particular format, the table
825 load/save routines must be tailored for each file; the load routines, in
826 particular, must be able to handle multiple versions of files, and as such
827 are especially complex (for the nickname and channel tables, the load
828 routine is broken up into several subroutines). For the sake of simplicity
829 and speed, the routines access the relevant structures directly rather than
830 going through the <tt>DBField</tt> entries of the table; this means that
831 the module must be updated whenever the structures' formats or meanings
832 change, but as the module is only intended as a transitional one, this is
833 not seen to be a significant problem.</p>
834
835 <p>The load/save routines also call some routines defined in the various
836 pseudoclient modules, such as <tt>get()</tt>, <tt>first()</tt>, and
837 <tt>next()</tt> routines for the various data structures. Since the
838 database may be (and generally is) loaded before the pseudoclient modules,
839 the symbols must be imported appropriately; this is handled by the
840 <tt>extsyms.c</tt> and <tt>extsyms.h</tt> auxiliary files, though the
841 handling is rather machine-dependent. See <a href="#s5-2">section
842 6-5-2</a> for details.</p>
843
844 <p>The routines used for loading and saving tables which do not correspond
845 to any of the files listed above, <tt>load_generic_table()</tt> and
846 <tt>save_generic_table()</tt>, are actually renamed versions of the
847 <tt>standard_load_table()</tt> and <tt>standard_save_table()</tt> routines
848 defined in the <tt>database/standard</tt> module. To avoid the
849 difficulties involved in trying to load two database modules at once, this
850 module simply includes the <tt>standard.c</tt> source file directly, after
851 setting up <tt>#define</tt> directives to rename the load and save
852 routines; a <tt>#ifndef INCLUDED_IN_VERSION4</tt> protects the parts of the
853 <tt>database/standard</tt> module not related to loading and saving,
854 avoiding multiple definitions of module-related symbols.</p>
855
856 <p class="backlink"><a href="#top">Back to top</a></p>
857
858 <!------------------------------------------------------------------------>
859 <hr/>
860
861 <h3 class="subsection-title" id="s5">6-5. Auxiliary source files</h3>
862
863 <h4 class="subsubsection-title" id="s5-1">6-5-1. <tt>fileutil.c</tt>, <tt>fileutil.h</tt></h4>
864
865 <p><tt>fileutil.c</tt> (and its corresponding header, <tt>fileutil.h</tt>)
866 provide utility functions used by both the <tt>database/standard</tt> and
867 <tt>database/version4</tt> modules for reading and writing binary data
868 files. The functions use a <tt>dbFILE</tt> structure to indicate the file
869 to be read from or written to; this is analagous to the <tt>FILE</tt>
870 structure used by stdio-style functions, but includes extra fields used by
871 the open and close functions to ensure that a valid copy of the file is
872 retained even if a write error occurs (see the function descriptions below
873 for details). The actual file pointer is also available in the structure's
874 <tt>fp</tt> field for direct use with the stdio functions.</p>
875
876 <p>There are several preprocessor conditionals on <tt>CONVERT_DB</tt>
877 scattered throughout the code. These are used to prevent unneeded portions
878 of code, particularly log- and module-related functions, from being seen
879 when the source file is compiled for the <tt>convert-db</tt> tool.</p>
880
881 <p>The following functions are available. Note that all of the read/write
882 functions (except <tt>get_file_version()</tt> and the raw read/write
883 functions <tt>read_db()</tt>, <tt>write_db()</tt>, and <tt>getc_db()</tt>)
884 share the property that they return 0 on success and -1 on error.</p>
885
886 <dl>
887 <dt><tt>int32 <b>get_file_version</b>(dbFILE *<i>f</i>)</tt></dt>
888 <dd>Retrieves the file version number from the given file. Returns -1
889 if the file version could not be read.</dd>
890
891 <dt><tt>int <b>write_file_version</b>(dbFILE *<i>f</i>, int32 <i>filever</i>)</tt></dt>
892 <dd>Writes the specified file version number to the file. Returns 0
893 on success, -1 on failure.</dd>
894
895 <dt><tt>dbFILE *<b>open_db</b>(const char *<i>filename</i>, const char *<i>mode</i>, int32 <i>version</i>)</tt></dt>
896 <dd>Opens the given file for reading (<tt><i>mode</i>=="r"</tt>) or
897 writing (<tt><i>mode</i>=="w"</tt>), returning the <tt>dbFILE</tt>
898 structure pointer on success, <tt>NULL</tt> on failure. When
899 opening a file for writing, the actual file created is a temporary
900 file whose name is the given filename with "<tt>.new</tt>"
901 appended; when <tt>close_db()</tt> is called, the <tt>rename()</tt>
902 system call is used to overwrite any existing file with this
903 temporary file. This ensures that a valid copy of the file will
904 remain on disk even if the writing process is interrupted for some
905 reason. The <tt><i>version</i></tt> parameter is used only when
906 opening a file for writing, and is automatically written to the
907 file using <tt><i>write_file_version()</i></tt>.</dd>
908
909 <dt><tt>int <b>close_db</b>(dbFILE *<i>f</i>)</tt></dt>
910 <dd>Closes the given file. If the file was open for writing, the
911 temporary file is renamed over the original (if any exists),
912 generating an error if the rename operation fails. Returns 0 on
913 success, -1 on failure.</dd>
914
915 <dt><tt>void <b>restore_db</b>(dbFILE *<i>f</i>)</tt></dt>
916 <dd>Closes the given file. If the file was open for writing, removes
917 the temporary file, leaving the original file unchanged. This
918 function never generates an error (errors returned from
919 <tt>fclose()</tt> are ignored), and preserves the value of
920 <tt>errno</tt>.</dd>
921
922 <dt><tt>int <b>read_db</b>(dbFILE *<i>f</i>, void *<i>buf</i>, size_t <i>len</i>)</tt></dt>
923 <dd>Reads the specified number of bytes from the file into
924 <tt><i>buf</i></tt>, returning the number of bytes successfully
925 read or -1 on error. Implemented as a macro in <tt>fileutil.h</tt>.</dd>
926
927 <dt><tt>int <b>write_db</b>(dbFILE *<i>f</i>, const void *<i>buf</i>, size_t <i>len</i>)</tt></dt>
928 <dd>Writes the specified number of bytes from <tt><i>buf</i></tt> into
929 the file, returning the number of bytes successfully written or -1
930 on error. Implemented as a macro in <tt>fileutil.h</tt>.</dd>
931
932 <dt><tt>int <b>getc_db</b>(dbFILE *<i>f</i>)</tt></dt>
933 <dd>Reads a single byte from the file, returning the byte's value on
934 success, -1 on error. Implemented as a macro in
935 <tt>fileutil.h</tt>.</dd>
936
937 <dt><tt>int <b>read_int8</b>(int8 *ret, dbFILE *<i>f</i>)</tt></dt>
938 <dd>Reads an 8-bit integer from the file, storing it in the location
939 pointed to by <tt><i>ret</i></tt>. Returns 0 on success, -1 on
940 failure.</dd>
941
942 <dt><tt>int <b>read_uint8</b>(uint8 *ret, dbFILE *<i>f</i>)</tt></dt>
943 <dd>Reads an unsigned 8-bit integer from the file. Identical in
944 behavior to <tt>read_int8()</tt>; this function is provided to
945 avoid signed/unsigned type conversion warnings when compiling.</dd>
946
947 <dt><tt>int <b>write_int8</b>(int8 val, dbFILE *<i>f</i>)</tt></dt>
948 <dd>Writes the given 8-bit integer to the file. Returns 0 on success,
949 -1 on failure.</dd>
950
951 <dt><tt>int <b>read_int16</b>(int16 *ret, dbFILE *<i>f</i>)</tt></dt>
952 <dd>Reads a 16-bit integer from the file, storing it in the location
953 pointed to by <tt><i>ret</i></tt>. Returns 0 on success, -1 on
954 failure.</dd>
955
956 <dt><tt>int <b>read_uint16</b>(uint16 *ret, dbFILE *<i>f</i>)</tt></dt>
957 <dd>Reads an unsigned 16-bit integer from the file. Identical in
958 behavior to <tt>read_int16()</tt>.</dd>
959
960 <dt><tt>int <b>write_int16</b>(int16 val, dbFILE *<i>f</i>)</tt></dt>
961 <dd>Writes the given 16-bit integer to the file. Returns 0 on success,
962 -1 on failure.</dd>
963
964 <dt><tt>int <b>read_int32</b>(int32 *ret, dbFILE *<i>f</i>)</tt></dt>
965 <dd>Reads a 32-bit integer from the file, storing it in the location
966 pointed to by <tt><i>ret</i></tt>. Returns 0 on success, -1 on
967 failure.</dd>
968
969 <dt><tt>int <b>read_uint32</b>(uint32 *ret, dbFILE *<i>f</i>)</tt></dt>
970 <dd>Reads an unsigned 32-bit integer from the file. Identical in
971 behavior to <tt>read_int32()</tt>.</dd>
972
973 <dt><tt>int <b>write_int32</b>(int32 val, dbFILE *<i>f</i>)</tt></dt>
974 <dd>Writes the given 32-bit integer to the file. Returns 0 on success,
975 -1 on failure.</dd>
976
977 <dt><tt>int <b>read_time</b>(time_t *ret, dbFILE *<i>f</i>)</tt></dt>
978 <dd>Reads a timestamp value from the file, storing it in the location
979 pointed to by <tt><i>ret</i></tt>. Returns 0 on success, -1 on
980 failure. Timestamp values are always stored using 64 bits,
981 regardless of the size of the <tt>time_t</tt> type.</dd>
982
983 <dt><tt>int <b>write_time</b>(time_t val, dbFILE *<i>f</i>)</tt></dt>
984 <dd>Writes the given timestamp value to the file. Returns 0 on
985 success, -1 on failure.</dd>
986
987 <dt><tt>int <b>read_ptr</b>(void **ret, dbFILE *<i>f</i>)</tt></dt>
988 <dd>Reads a pointer value from the file, storing it in the location
989 pointed to by <tt><i>ret</i></tt>. The value will be either
990 <tt>NULL</tt> or an arbitrary non-<tt>NULL</tt> value. Returns 0
991 on success, -1 on failure. <i>Implementation note: This function
992 and its complement, <tt>write_ptr()</tt>, are included only for use
993 by the <tt>database/version4</tt> module and the <tt>convert-db</tt>
994 tool, which actually do have to deal with pointers written in this
995 way.</i></dd>
996
997 <dt><tt>int <b>write_ptr</b>(const void *ptr, dbFILE *<i>f</i>)</tt></dt>
998 <dd>Writes the given pointer value to the file. The actual pointer
999 itself is not stored, only a flag indicating whether the pointer is
1000 <tt>NULL</tt> or not. Returns 0 on success, -1 on failure.</dd>
1001
1002 <dt><tt>int <b>read_string</b>(char **ret, dbFILE *<i>f</i>)</tt></dt>
1003 <dd>Reads a string from the file, allocating memory for the string
1004 using <tt>malloc()</tt> and storing a pointer to the string in the
1005 location pointed to by <tt><i>ret</i></tt>. Note that the value
1006 stored may be <tt>NULL</tt>. Returns 0 on success, -1 on
1007 failure.</dd>
1008
1009 <dt><tt>int <b>write_string</b>(const char *s, dbFILE *<i>f</i>)</tt></dt>
1010 <dd>Writes the given string (which may be <tt>NULL</tt>) to the file.
1011 The string must be no longer than 65,534 bytes (if longer, the
1012 value written will be silently truncated). Returns 0 on success,
1013 -1 on failure.</dd>
1014
1015 <dt><tt>int <b>read_buffer</b>(<i>buf</i>, dbFILE *<i>f</i>)</tt></dt>
1016 <dd>Reads the given buffer (assumed to be declared as, <i>e.g.</i>,
1017 a <tt>char</tt> array) from the file. Returns 0 on success, -1 on
1018 failure. Implemented as a macro in <tt>fileutil.h</tt>.</dd>
1019
1020 <dt><tt>int <b>write_buffer</b>(<i>buf</i>, dbFILE *<i>f</i>)</tt></dt>
1021 <dd>Writes the given buffer (assumed to be declared as, <i>e.g.</i>,
1022 a <tt>char</tt> array) to the file. Returns 0 on success, -1 on
1023 failure. Implemented as a macro in <tt>fileutil.h</tt>.</dd>
1024 </dl>
1025
1026 <p class="backlink"><a href="#top">Back to top</a></p>
1027
1028
1029 <h4 class="subsubsection-title" id="s5-2">6-5-2. <tt>extsyms.c</tt>, <tt>extsyms.h</tt></h4>
1030
1031 <p><tt>extsyms.c</tt> and <tt>extsyms.h</tt> are used by the
1032 <tt>database/version4</tt> module to import external symbols from other
1033 modules which may not be loaded when the <tt>version4</tt> module is
1034 initialized. The <tt>version4</tt> module makes use of a number of
1035 functions and variables from the various pseudoclient modules, and adding
1036 code at every use to check whether the appropriate module is loaded and
1037 look up the symbol would only further complicate already complex code. For
1038 this reason, the actual work of looking up the symbols is done in
1039 <tt>extsyms.c</tt>, and <tt>extsyms.h</tt> provides redefinition macros to
1040 allow the <tt>version4</tt> module to be written as if the functions and
1041 variables were already present.</p>
1042
1043 <p>The actual work of looking up and accessing (for values) or calling (for
1044 functions) the external symbols is implemented by the <tt>IMPORT_FUNC()</tt>,
1045 <tt>IMPORT_VAR()</tt>, and <tt>IMPORT_VAR_MAYBE()</tt> macros defined in
1046 <tt>extsyms.c</tt>. These macros all have the same basic format: they
1047 define a variable of the form <tt>__dblocal_<i>symbol</i>_ptr</tt> to hold
1048 the value of the symbol (the address of the function or variable), followed
1049 by a function which looks up the symbol's value if it is not yet known,
1050 then accesses or calls it. (Module pointers are likewise cached in
1051 file-local variables, declared separately.) If the symbol or its module
1052 cannot be found, the local routine <tt>fatal_no_symbol()</tt> is called to
1053 abort the program, except for <tt>IMPORT_VAR_MAYBE()</tt>, in which case a
1054 default value is returned from the accessing function if the symbol is not
1055 available.</p>
1056
1057 <p>The logic for accessing an external variable is simple; a reference to
1058 the variable is translated by macros in <tt>extsyms.h</tt> into a call to
1059 the function defined by <tt>IMPORT_VAR()</tt> or <tt>IMPORT_VAR_MAYBE()</tt>
1060 (whose name has the format <tt>__dblocal_get_<i>variable</i>()</tt>), which
1061 accesses the variable's value through the pointer obtained from looking up
1062 the symbol and returns it. The function's declaration uses the GCC
1063 <tt>typeof()</tt> built-in operator to give the function's return value, as
1064 well as the cache variable for the symbol value, the same type as the
1065 variable itself.</p>
1066
1067 <p>Calling an external function is a more complex task, due to the fact
1068 that functions can take parameters or not and can return or not return a
1069 value. Rather than explicitly writing out the symbol access functions for
1070 each external function accessed, <tt>extsyms.c</tt> makes use of a GCC
1071 feature which allows a function to call another function, passing along
1072 the same parameters passed to the parent function, and return its return
1073 value without knowing anything about either the parameters or the type of
1074 return value. This feature is the builtin apply/return code, which takes
1075 the general form:</p>
1076
1077 <div class="code">__builtin_return(__builtin_apply(
1078 <i>function_pointer</i>,
1079 __builtin_apply_args(),
1080 <i>parameter_buffer_size</i>))</div>
1081
1082 <p>where <tt><i>function_pointer</i></tt> is a pointer to the function to
1083 be called, and <tt><i>parameter_buffer_size</i></tt> is the maximum amount
1084 of stack space expected to be used by the parameters to the function, if
1085 any. If this feature is not available, for example because a compiler
1086 other than GCC is in use, then the code tries to use another
1087 (assembly-based) algorithm to accomplish the same thing if possible, or
1088 generates a compilation error if no such substitute algorithm is
1089 available.</p>
1090
1091 <p>However, the use of the <tt>__builtin_apply()</tt> GCC feature in
1092 Services has, over the course of Services' development, revealed a few bugs
1093 in the implementation of that feature; as such, Services must sometimes
1094 resort to an assembly-based algorithm even when using GCC. The necessity
1095 of this is indicated by the preprocessor macro <tt>NEED_GCC3_HACK</tt>,
1096 which is set by the <tt>configure</tt> script if it detects that this
1097 workaround is required. The bugs which have been discovered are:</p>
1098
1099 <ul>
1100 <li class="spaced">The generated code can access the wrong area of memory
1101 when setting up the stack for the called function
1102 (<a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=8028">GCC
1103 Bugzilla bug 8028</a>
1104 <span class="remotehost">[gcc.gnu.org]</span>).</li>
1105 <li class="spaced">The generated code can fail to pass through the called
1106 function's return value
1107 (<a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11151">GCC
1108 Bugzilla bug 11151</a>
1109 <span class="remotehost">[gcc.gnu.org]</span>).</li>
1110 <li class="spaced">A function calling <tt>__builtin_apply()</tt> can
1111 behave incorrectly if inlined in another function.
1112 (<a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20076">GCC
1113 Bugzilla bug 20076</a>
1114 <span class="remotehost">[gcc.gnu.org]</span>). This is not
1115 directly relevant to <tt>extsyms.c</tt>, but caused problems at
1116 one time in the <tt>configure</tt> script.</li>
1117 </ul>
1118
1119 <p>Finally, in order to avoid cached pointers going stale when a module is
1120 unloaded, <tt>extsyms.c</tt> includes a callback function for the
1121 "<tt>unload&nbsp;module</tt>" callback, which clears out all cached
1122 pointers for a module when the module is unloaded.</p>
1123
1124 <p class="backlink"><a href="#top">Back to top</a></p>
1125
1126 <!------------------------------------------------------------------------>
1127 <hr/>
1128
1129 <p class="backlink"><a href="5.html">Previous section: IRC server interface</a> |
1130 <a href="index.html">Table of Contents</a> |
1131 <a href="7.html">Next section: Services pseudoclients</a></p>
1132
1133 </body>
1134 </html>