File: modiface.xml

package info (click to toggle)
kamailio 5.6.3-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 68,332 kB
  • sloc: ansic: 744,091; xml: 196,848; cpp: 14,471; makefile: 8,859; sh: 8,814; sql: 7,844; yacc: 3,863; perl: 2,955; python: 2,710; java: 449; javascript: 269; php: 258; ruby: 225; cs: 40; awk: 27
file content (803 lines) | stat: -rw-r--r-- 29,255 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" 
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">

<section id="module_interface" xmlns:xi="http://www.w3.org/2001/XInclude">
    <sectioninfo>
	<revhistory>
	    <revision>
		<revnumber>$Revision$</revnumber>
		<date>$Date$</date>
	    </revision>
	</revhistory>
	<abstract>
	<para>
	    SER features modular architecture which allows us to split SER's
	    functionality across several modules. This approach gives us
	    greater flexibility, only required set of functions can be loaded
	    upon startup which minimizes the server's memory footprint. Modules
	    can be also provided by 3rd party developers and distributed
	    separately from the main server. Most of the functionality that SER
	    provides is available through modules, the core itself contains
	    only minimum set of functions that is essential for proper server's
	    behavior or that is needed by all modules.
	</para>
	<para>
	    This chapter provides detailed information on module interface of
	    SER, which is used to pass information on available functions and
	    parameters from the modules to the core.
	</para>

	</abstract>
    </sectioninfo>

    <title>Module Interface</title>

    <section id="shared_objects">
	<title>Shared Objects</title>
	<abstract>
	    <para>
		First it would be good to know how SER loads and uses modules
		before we describe the module interface in detail. This section
		gives a brief overview of SER's module subsystem.
	    </para>
	</abstract>
	<para>
	    SER modules are compiled as "shared objects". A file containing a
	    shared object has usually .so suffix. All modules (shared objects)
	    will be stored in one directory after installation. For example tm
	    module, which contains code essential for stateful processing, will
	    be stored in file named <filename>tm.so</filename>. By default
	    these files are stored in
	    <filename>/usr/local/lib/ser/modules</filename> directory.
	</para>
	<para>
	    You can later load the modules using <command>loadmodule</command>
	    command in your configuration file. If you want to load previously
	    mentioned <filename>tm.so</filename> module, you can do it using
	    <command>loadmodule "/usr/local/lib/ser/modules/tm.so"</command> in
	    your configuration file. This command invokes dynamic linker
	    provided by the operating system which opens
	    <filename>tm.so</filename> file, loads it into memory and resolves
	    all symbol dependencies (a module might require symbols from the
	    core, for example functions and variables).
	</para>
	<para>
	    As the last step of the module loading the core tries to find
	    variable named <varname>exports</varname>, which describes all
	    functions and parameters provided by the module. These functions
	    and parameters are later available to the server and can be used
	    either in the configuration file or by other modules.
	</para>
    </section>
    
    <section id="exporting_functions">
	<title>Exporting Functions</title>
	<abstract>
	    <para>
		Each module can provide zero or more functions, which can be
		used in the configuration file or by other modules
		internally. This section gives a detailed description of
		structure describing exported functions and passing this
		information to the core through the module interface.
	    </para>
	</abstract>
	<para>
	    Each function exported by a module must be described by
	    <structname>cmd_export_t</structname> structure. Structures
	    describing all exported functions are arranged into an array and
	    pointer to the array is then passed to the core. The last element
	    of the array must contain 0 in all it's fields, this element serves
	    as the mark telling the core that this is the very last element and
	    it must stop scanning the array.
	</para>
	<para>
	    Each exported function is described by the following structure:
	</para>
	<programlisting>
struct cmd_export_ {
	char* name;             /* null terminated command name */
	cmd_function function;  /* pointer to the corresponding function */
	int param_no;           /* number of parameters used by the function */
	fixup_function fixup;   /* pointer to the function called to "fix" the parameters */
	int flags;              /* Function flags */
};	   

typedef struct cmd_export_ cmd_export_t;
	</programlisting>
	
	<itemizedlist>
	    <title>Meaning of the fileds:</title>
	    <listitem>
		<simpara><varname>char* name</varname></simpara> 
		<simpara>
		    This is the name under which the function will be visible
		    to the core. Usually it is the same as the name of the
		    corresponding function.
		</simpara>
	    </listitem>
	    <listitem>
		<simpara><varname>cmd_function function</varname></simpara>
		<para>cmd_function type is defined as follows: </para>
		<programlisting>
typedef int (*cmd_function)(struct sip_msg*, char*, char*); 
		</programlisting>
		<simpara>
		    The first parameter is a SIP message
		    being processed, the other 2 parameters are given from the
		    configuration file.
		</simpara>
		<note>
		    <simpara>
			From time to time you might need to export a function
			that has different synopsis. This can happen if you
			export functions that are supposed to be called by
			other modules only and must not be called from the
			configuration script. In this case you will have to do
			type-casting otherwise the compiler will complain and
			will not compile your module.
		    </simpara>
		    <simpara>
			Simply put (cmd_function) just before the function
			name, for example
			<function>(cmd_function)my_function</function>.  Don't
			use this unless you know what are you doing ! The
			server might crash if you pass wrong parameters to the
			function later !
		    </simpara>
		</note>
	    </listitem>
	    <listitem>
		<simpara><varname>int param_no</varname></simpara>
		<simpara>
		    Number of parameters of the function. It can be 0, 1 or
		    2. The function will be not visible from the configuration
		    script if you use another value.
		</simpara>
	    </listitem>
	    <listitem>
		<simpara><varname>fixup_function fixup</varname></simpara>
		<simpara>
		    This is the function that will be used to "fixup" function
		    parameters. Set this field to 0 if you don't need this.
		</simpara>
		<simpara>
		    If you provide pointer to a fixup function in this field,
		    the fixup function will be called for each occurrence of
		    the exported function in the configuration script.
		</simpara>
		<simpara>
		    The fixup function can be used to perform some operation on
		    the function parameters. For example, if one of the
		    parameters is a regular expression, you can use the fixup
		    to compile the regular expression. The fixup functions are
		    called only once - upon the server startup and so the
		    regular expression will be compiled before the server
		    starts processing messages. When the server calls the
		    exported function to process a SIP message, the function
		    will be given the already compiled regular expression and
		    doesn't have to compile it again. This is a significant
		    performance improvement.
		</simpara>
		<simpara>
		    Fixup functions can also be used to convert string to
		    integer. As you have might noticed, the exported functions
		    accept up to 2 parameters of type char*. Because of that it
		    is not possible to pass integer parameters from the script
		    files directly. If you want to pass an integer as a
		    parameter, you must pass it as string (i.e. enclosed in
		    quotes).
		</simpara>
		<simpara>
		    Fixup function can be used to convert the string back to
		    integer. Such a conversion should happened only once because
		    the string parameter doesn't change when the server is
		    running. Fixup is therefore ideal place for the conversion,
		    it will be converted upon the server startup before the
		    server starts processing SIP messages. After the conversion
		    the function will get directly the converted value. See
		    existing modules for example of such a fixup function.
		</simpara>
	    </listitem>
	    <listitem>
		<simpara><varname>int flags</varname></simpara>
		<simpara>
		    Usage of each function can be restricted. You may want to
		    write a function that can be used by other modules but
		    cannot be called from the script. If you write a function
		    that is supposed to process SIP requests only, you may want
		    to restrict it so it will be never called for SIP replies
		    and vice versa. That's what is flags field for.
		</simpara>
		<simpara>
		    This field is OR value of different flags. Currently only
		    REQUEST_ROUTE and REPLY_ROUTE flags are defined and used by
		    the core. If you use REQUEST_ROUTE flag, then the function
		    can be called from the main route block. If you use
		    REPLY_ROUTE flag, then the function can be called from
		    reply route blocks (More on this in the SER User's
		    Guide). If this field is set to 0, then the function can be
		    called internally (i.e. from other modules) only. If you
		    want to make your function callable anywhere in the script,
		    you can use REQUEST_ROUTE | REPLY_ROUTE.
		</simpara>
	    </listitem>
	</itemizedlist>
    </section>

    <section id="exporting_parameters">
	<title>Exporting Parameters</title>
	<abstract>
	    <simpara>
		Each module can provide zero or more parameters, which can
		affect the module's behavior. This section gives a detailed
		description of structures describing exported parameters and
		passing this information to the core through the module
		interface.
	    </simpara>
	</abstract>
	<simpara>
	    Each parameter exported by a module must be described by
	    <structname>param_export_t</structname> structure. Structures
	    describing all exported parameters are arranged into an array and
	    pointer to the array is then passed to the core. The last element
	    of the array must contain 0 in all it's fields, this element serves
	    as the mark telling the core that this is the very last element and
	    it must stop scanning the array (This is same as in array of
	    exported functions).
	</simpara>
	<simpara>
	    Each exported parameter is described by the following structure:
	</simpara>
	<programlisting>
struct param_export_ {
	char* name;             /* null terminated param. name */
	modparam_t type;        /* param. type */
	void* param_pointer;    /* pointer to the param. memory location */
};

typedef struct param_export_ param_export_t;
	</programlisting>
	<itemizedlist>
	    <title>Meaning of the fields:</title>
	    <listitem>
		<simpara><varname>char* name</varname></simpara>
		<simpara>
		    This is null-terminated name of the parameters as it will
		    be used in the scripts. Usually this is the same as the
		    name of the variable holding the value.
		</simpara>
	    </listitem>
	    <listitem>
		<simpara><varname>modparam_t type</varname></simpara>
		<simpara>
		    Type of the parameter. Currently only two types are
		    defined. PARAM_INT for integer parameters (corresponding
		    variable must be of type int), PARAM_STR for str parameters
		    (corresponding variable must be of type char*)  and PARAM_STRING 
		    for string parameters (corresponding variable must be of type char*).
		</simpara>
	    </listitem>
	    <listitem>
		<simpara><varname>void* param_pointer</varname></simpara>
		<simpara>
		    Pointer to the corresponding variable (stored as void*
		    pointer, make sure that the variable has appropriate type
		    depending on the type of the parameter !).
		</simpara>
	    </listitem>
	</itemizedlist>
    </section>

    <section id="module_initialization">
	<title>Module Initialization</title>
	<simpara>
	    If you need to initialize your module before the server starts
	    processing SIP messages, you should provide
	    initialization function. Each module can provide two initialization
	    functions, main initialization function and child-specific
	    initialization function.  Fields holding pointers to both
	    initialization functions are in main export structure (will be
	    described later). Simply pass 0 instead of function pointer if you
	    don't need one or both initialization functions.
	</simpara>
	<simpara>
	    The main initialization function will be called before any other
	    function exported by the module. The function will be called only
	    once, before the main process forks. This function is good for
	    initialization that is common for all the children (processes). The
	    function should return 0 if everything went OK and a negative error
	    code otherwise. Server will abort if the function returns a
	    negative value.
	</simpara>
	<simpara>
	    Per-child initialization function will be called
	    <emphasis>after</emphasis> the main process forks. The function
	    will be called for each child separately. The function should
	    perform initialization that is specific for each child. For example
	    each child process might open it's own database connection to avoid
	    locking of a single connection shared by many processes. Such
	    connections can be opened in the per-child initialization
	    function. The function accepts one parameter which is rank
	    (integer) of child for which the function is being executed. This
	    allows developers to distinguish different children and perform
	    different initialization for each child. The meaning of return
	    value is same as in the main initialization function.
	</simpara>
    </section>

    <section id="module_cleanup">
	<title>Module Clean-up</title>
	<simpara>
	    A module can also export a clean-up function that will be called by
	    the main process when the server shuts down. The function accepts
	    no parameters and return no value.
	</simpara>
    </section>

    <section id="module_callbacks">
	<title>Module Callbacks</title>
	<para>
	    TBD.
	</para>
    </section>

    <section id="exports_structure">
	<title><structname>exports</structname> Structure - Assembling the Pieces Together</title>
	<simpara>
	    We have already described how a module can export functions and
	    parameters, but we haven't yet described how to pass this
	    information to the core. Each module must have variable named
	    <varname>exports</varname> which is structure module_exports. The
	    variable will be looked up by the core immediately after it loads
	    the module. The structure contains pointers to both arrays
	    (functions, parameters), pointers to both initialization functions,
	    destroy function and the callbacks. So the structure contains
	    everything the core will need.
	</simpara>
	<simpara>The structure looks like the follows:</simpara>
	<programlisting>
struct module_exports{
    char* name;                     /* null terminated module name */
    cmd_export_t* cmds;             /* null terminated array of the exported commands */
    param_export_t* params;         /* null terminated array of the exported module parameters */
    init_function init_f;           /* Initialization function */
    response_function response_f;   /* function used for responses, returns yes or no; can be null */
    destroy_function destroy_f;     /* function called when the module should be "destroyed", e.g: on ser exit; can be null */
    onbreak_function onbreak_f;
    child_init_function init_child_f;  /* function called by all processes after the fork */
};
	</programlisting>
	<itemizedlist>
	    <title>Field description:</title>
	    <listitem>
		<simpara><varname>char* name</varname></simpara>
		<simpara>Null terminated name of the module</simpara>
	    </listitem>
	    <listitem>
		<simpara><varname>cmd_exports* cmds</varname></simpara>
		<simpara>
		    Pointer to the array of exported functions
		</simpara>
	    </listitem>
	    <listitem>
		<simpara><varname>param_export_t* params</varname></simpara>
		<simpara>
		    Pointer to the array of exported parameters
		</simpara>
	    </listitem>
	    <listitem>
		<simpara><varname>init_function init_f</varname></simpara>
		<simpara>Pointer to the module initialization function</simpara>
	    </listitem>
	    <listitem>
		<simpara><varname>response_function response_f</varname></simpara>
		<simpara>Pointer to function processing responses</simpara>
	    </listitem>
	    <listitem>
		<simpara><varname>destroy_function destroy_f</varname></simpara>
		<simpara>Pointer to the module clean-up function</simpara>
	    </listitem>
	    <listitem>
		<simpara><varname>onbreak_function onbreak_f</varname></simpara>
		<simpara>TBD</simpara>
	    </listitem>
	    <listitem>
		<simpara><varname>child_init_function init_child_f</varname></simpara>
		<simpara>Pointer to the per-child initialization function</simpara>
	    </listitem>
	</itemizedlist>
    </section>

    <section id="simple_interface">
	    <title>Example - Simple Module Interface</title>
	<para>
	    Let's suppose that we are going to write a simple module. The
	    module will export two functions - <function>foo_req</function>
	    which will be processing <acronym>SIP</acronym> requests and
	    <function>foo_int</function> which is an internal function that can
	    be called by other modules only.  Both functions will take 2
	    parameters.
	</para>
	<programlisting>
/* Prototypes */
int foo_req(struct sip_msg* msg, char* param1, char* param2);
int foo_res(struct sip_msg* msg, char* param1, char* param2);

static cmd_export cmds[] = {
    {"foo_req", foo_req, 2, 0, ROUTE_REQUEST},
    {"foo_int", foo_int, 2, 0, 0            },
    {0, 0, 0, 0}
};
	</programlisting>
	<para>
	    The module will also have two parameters, foo_bar of type integer
	    and bar_foo of type string.
	</para>
	<programlisting>
int foo_bar = 0;
char* bar_foo = "default value";
str bar_bar = STR_STATIC_INIT("default");

static param_export params[] = {
    {"foo_bar", PARAM_INT, &amp;foo_bar},
    {"bar_foo", PARAM_STRING, &amp;bar_foo},
    {"bar_bar", PARAM_STR, &amp;ar_bar.s},
    {0, 0, 0}
}; 
	</programlisting>
	<para>
	    We will also create both initialization functions and a clean-up function:
	</para>
	<programlisting>
static int mod_init(void)
{
    printf("foo module initializing\n");
}

static int child_init(int rank)
{
    printf("child nr. %d initializing\n", rank);
    return 0;
}

static void destroy(void)
{
    printf("foo module cleaning up\n");
}
	</programlisting>
	<para>
	    And finally we put everything into the exports structure:
	</para>
	<programlisting>
struct module_exports exports = {
    "foobar",   /* Module name */
    cmds,       /* Exported functions */
    params,     /* Exported parameters */
    mod_init,   /* Module initialization function */
    0,          /* Response function */
    destroy,    /* Clean-up function */
    0,          /* On Cancel function */
    child_init  /* Per-child init function */
};
	</programlisting>
	<simpara>And that's it.</simpara>
    </section>

    <section id="module_interface_internals">
	<title>Module Interface Internals</title>
	<para>
	    All the data structures and functions mentioned in this section can
	    be found in files <filename>sr_module.h</filename> and
	    <function>sr_module.c</function>.
	</para>

	<xi:include href="sr_module.xml"/>
	<xi:include href="module_exports.xml"/>

	<section id="module-loading">
	    <title>Module Loading</title>
	    <para>
		Modules are compiled and stored as shared objects. Shared
		objects have usually appendix ".so".  Shared objects can be
		loaded at runtime.
	    </para>
	    <para>
		When you instruct the server to load a module using
		<function>loadmodule</function> command in the config file, it
		will call function <function>load_module</function>. The
		function will do the following:
		<itemizedlist>
		    <listitem>
			<para>
			    It will try to open specified file using
			    <function>dlopen</function>. For example if you
			    write loadmodule "/usr/lib/ser/modules/auth.so" in
			    the config file, the server will try to open file
			    "/usr/lib/ser/modules/auth.so" using
			    <function>dlopen</function> function.
			</para>
			<para>
			    If <function>dlopen</function> failed, the server
			    will issue an error and abort.
			</para>
		    </listitem>
		    <listitem>
			<para>
			    As the next step, list of all previously loaded
			    modules will be searched for the same module.  If
			    such module is found, it means, that user is trying
			    to load the same module twice. In such case an
			    warning will be issued and server will abort.
			</para>
		    </listitem>
		    <listitem>
			<para>
			    The server will try to find pointer to "exports"
			    symbol using <function>dlsym</function> in the
			    module. If that fails, server will issue an error
			    and abort.
			</para>
		    </listitem>
		    <listitem>
			<para>
			    And as the last step, function
			    <function>register_module</function> will register
			    the module with the server core and loading of the
			    module is complete.
			</para>
		    </listitem>
		</itemizedlist>
	    </para>
	    <para>
		Function <function>register_module</function> registers a
		module with the server core. By registration we mean the
		following set of steps (see function
		<function>register_module</function> in file
		<filename>sr_module.c</filename> for more details):
		<itemizedlist>
		    <listitem>
			<para>
			    The function creates and initializes new instance
			    of <structname>sr_module</structname> structure.
			</para>
		    </listitem>
		    <listitem>
			<para>
			    <structfield>path</structfield> field will be set
			    to path of the module.
			</para>
		    </listitem>
		    <listitem>
			<para>
			    <structfield>handle</structfield> field will be set
			    to handle previously returned by
			    <function>dlopen</function>.
			</para>
		    </listitem>
		    <listitem>
			<para>
			    <structfield>exports</structfield> field will be
			    set to pointer to module's
			    <varname>exports</varname> structure previously
			    obtained through <function>dlsym</function> in
			    <function>load_module</function> function.
			</para>
		    </listitem>
		    <listitem>
			<para>
			    As the last step, the newly created structure will
			    be inserted into linked list of all loaded modules
			    and registration is complete.
			</para>
		    </listitem>
		</itemizedlist>
	    </para>
	</section> <!-- module-loading -->

	<section id="module_configuration">
	    <title>Module Configuration</title>
	    <para>
		In addition to set of functions each module can export set of
		configuration variables.  Value of a module's configuration
		variable can be changed in the config file using <function
		    moreinfo="none">modparam</function> function. Module
		configuration will be described in this section.
	    </para>
	    <section id="modparam">
		<title>Function <function>modparam</function></title>
		<para>
		    <function>modparam</function> function accepts three
		    parameters:
		    <itemizedlist>
			<listitem>
			    <para>
				<emphasis>module name</emphasis> - Name of
				module as exported in
				<structfield>name</structfield> field of
				<varname>exports</varname> global variable.
			    </para>
			</listitem>
			<listitem>
			    <para>
				<emphasis>variable name</emphasis> - Name of
				variable to be set - it must be one of names
				specified in
				<structfield>param_names</structfield> field of
				<varname>exports</varname> variable of the
				module.
			    </para>
			</listitem>
			<listitem>
			    <para>
				<emphasis>value</emphasis> - New value of the
				variable. There are two types of variables:
				string and integer. If the last parameter
				(value) of <function>modparam</function>
				function is enclosed in quotes, it is string
				parameter and server will try to find the
				corresponding variable among string parameters
				only.
			    </para>
			    <para>
				Otherwise it is integer parameter and server
				will try to find corresponding variable among
				integer parameters only.
			    </para>
			</listitem>
		    </itemizedlist>
		</para>
	    </section> <!-- modparam -->
	    
	    <section id="set_mod_param">
		<title>Function <function>set_mod_param</function></title>
		<para>
		    When the server finds <function>modparam</function>
		    function in the config file, it will call
		    <function>set_mod_param</function> function. The function
		    can be found in <filename>modparam.c</filename> file. The
		    function will do the following:
		</para>
		
		<itemizedlist>
		    <listitem>
			<para>
			    It tries to find corresponding variable using
			    <function>find_param_export</function> function.
			</para>
		    </listitem>
		    <listitem>
			<para>
			    If it is string parameter, a new copy of the string
			    will be obtained using <function>strdup</function>
			    function and pointer to the copy will be stored in
			    the variable.
			</para>
			<para>
			    If it is integer parameter, its value will be
			    simply copied in the variable.
			</para>
		    </listitem>
		</itemizedlist>
	    </section> <!-- set_mod_param -->

	    <section id="find_param_export">
		<title>Function <function>find_param_export</function></title>
		<para>
		    This function accepts 3 parameters:
		    <itemizedlist>
			<listitem>
			    <para>
				<emphasis>module</emphasis> - Name of module.
			    </para>
			</listitem>
			<listitem>
			    <para>
				<emphasis>parameter</emphasis> - Name of parameter to be found.
			    </para>
			</listitem>
			<listitem>
			    <para>
				<emphasis>type</emphasis> - Type of the parameter.
			    </para>
			</listitem>
		    </itemizedlist>
		</para>
		<para>
		    The function will search list of all modules until it finds
		    module with given name.  Then it will search through all
		    module's exported parameters until it finds parameter with
		    corresponding name and type. If such parameter was found,
		    pointer to variable holding the parameter's value will be
		    returned. If the function failed to find either module or
		    parameter with given name and type then zero will be
		    returned.
		</para>
	    </section> <!-- find_param_export -->
	</section> <!-- module_config -->
	
	<section id="lookingup_exported_function">
	    <title>Looking Up an Exported Function</title> 
	    <para>
		If you need to find exported function with given name and
		number of parameters, <function>find_export</function> function
		is what you need. The function is defined in
		<filename>sr_module.c</filename> file.  The function accepts
		two parameters:
		<itemizedlist>
		    <listitem>
			<para>
			    <emphasis>name</emphasis> - Name of function to be
			    found.
			</para>
		    </listitem>
		    <listitem>
			<para>
			    <emphasis>param_no</emphasis> - Number of
			    parameters of the function.
			</para>
		    </listitem>
		</itemizedlist>
	    </para>
	    <para>
		The function will search through list of all loaded modules and
		in each module through array of all exported functions until it
		finds function with given name and number of parameters. If
		such exported function was found,
		<function>find_exported</function> will return pointer to the
		function, otherwise zero will be returned.
	    </para>
	</section> <!-- lookingup_exported_function -->
	
	<section id="additional_functions">
	    <title>Additional Functions</title>
	    <para>
		There are several additional functions defined in file
		<filename>sr_module.c</filename>.  There functions are mostly
		internal and shouldn't be used directly by user. We will
		shortly describe them here.
	    </para>
	    <itemizedlist>
		<listitem>
		    <para>
			<function>register_builtin_modules</function> - Some
			modules might be linked statically with main
			executable, this is handy for debugging. This function
			will register all such modules upon server startup.
		    </para>
		</listitem>
		<listitem>
		    <para>
			<function>init_child</function> - This function will
			call child-initialization function of all loaded
			modules. The function will be called by the server core
			immediately after the fork.
		    </para>
		</listitem>
		<listitem>
		    <para>
			<function>find_module</function> - The function accepts
			pointer to an exported function and number of
			parameters as parameters and returns pointer to
			corresponding module that exported the function.
		    </para>
		</listitem>
		<listitem>
		    <para>
			<function>destroy_modules</function> - The function
			will call destroy function of all loaded modules. This
			function will be called by the server core upon shut
			down.
		    </para>
		</listitem>
		<listitem>
		    <para>
			<function>init_modules</function> - The function will
			call initialization function of all loaded modules. The
			function will be called by the server before the fork.
		    </para>
		</listitem>
	    </itemizedlist>
	</section>
    </section>
</section>