There are two main points when a module can be initialized: during
daemon startup, and prior to handling an FTP session. In order to tell
the core engine that your module has code to be run at these points, you
need to use the initialization callback slots in the module
structure at the bottom of your module source file:
module geewhiz_module = { ... /* Module initialization function */ NULL, /* Session initialization function */ NULL };Rather than having
NULL
, you would have the name of your
initialization callback function there. Both initialization callback
functions have the same prototype:
int func(void);
What is the difference, then, between module initialization and session
initialization? The former is called when the proftpd
daemon
starts, prior to parsing the configuration file; the latter is called
after the daemon has fork()
ed a process to handle a client,
but before the process handles any FTP commands sent by the client.
Module initialization, if any is needed, tends to be simple: allocating
module-specific resources (e.g. memory pool
,
array_header
s), perhaps initializing any third-party code
(e.g. libraries) used by the module, etc. Most modules will
make use more of the session initialization function, which is where the
module can act on per-server/server-specific configuration settings, such
as processing any of the module's configuration directives that are in
context of the server contacted by the client.
The two above callbacks suffice for the majority of situations in which a module developer might want to have initialization code executed. However, every now and then, there arises the case where a module may need to be initialized based on configured directives, but still as part of the daemon startup process. Remember, the module initialization callback is called before the configuration file is parsed, not after. To handle this scenario, a new registration function was added in 1.2.8rc1:
void pr_register_postparse_init(int (*cb)(void));If a module wishes to have initialization code executed after the configuration file has been parsed, then, in the module's module initialization function, it will need to call
pr_register_postparse_init()
, specifying
the name of the function to be called once the daemon has parsed the
configuration.
For example:
static int geewhiz_postparse_cb(void) { /* Do some possibly-configuration-influenced stuff here */ ... return 0; } static int geewhiz_init(void) { ... /* Make sure we act on the needed directives' parameters */ pr_register_postparse_init(geewhiz_postparse_cb); return 0; } module geewhiz_module = { ... /* Module initialization function */ geewhiz_init, /* Session initialization function */ NULL };