diff --git a/smmapdfw/doc/smmapdfw.texi b/smmapdfw/doc/smmapdfw.texi index 1d5bf0e..2a47ff2 100644 --- a/smmapdfw/doc/smmapdfw.texi +++ b/smmapdfw/doc/smmapdfw.texi @@ -55,6 +55,26 @@ Plugin * Sender-address verifier:: * Cyrus mailbox checker:: +API + +* Plugin interface:: +* Obtaining configuration data:: +* More or less useful stuff:: + +Plugin interface + +* name:: +* Container setup function:: +* Container destroy function:: +* Worker setup function:: +* Worker destroy function:: +* Worker function:: + +Obtaining configuration data + +* Without default value:: +* With default value:: + @end detailmenu @end menu @@ -378,5 +398,298 @@ Port to be used for the lmtp dialog. @chapter API API documentation for plugin programmers +@menu +* Plugin interface:: +* Obtaining configuration data:: +* More or less useful stuff:: +@end menu + +@node Plugin interface, Obtaining configuration data, API, API +@section Plugin interface + +Each plugin has to defined a class descriptor of the type +@code{class_descriptor_t}. + +@verbatim +struct class_descriptor_s { + char *name; + int (*init_function)(cfgl_t *cfg, void **handle); + int (*destroy_function)(void *handle); + int (*work_setup_function)(void *handle, void **work_handle); + int (*work_function)(void *handle, void *work_handle, char *input, + char *output); + int (*work_destroy_function)(void *handle, void *work_handle); +}; + +typedef struct class_descriptor_s class_descriptor_t; + +@end verbatim + +The variable name of the class descriptor must be the same as the +configuration section name from the configuration file. As an example: +here is the descriptor of the verifier plugin: + +@verbatim +class_descriptor_t verifier = { + "verifier", + &verify_init, + &verify_destroy, + &verify_work_setup, + &verify_work, + &verify_work_destroy +}; + +@end verbatim + +@menu +* name:: +* Container setup function:: +* Container destroy function:: +* Worker setup function:: +* Worker destroy function:: +* Worker function:: +@end menu + +@node name, Container setup function, Plugin interface, Plugin interface +@subsection @code{name} + +This is the name of the plugin. It must match to the name of the +plugin descriptor and the name of the plugin's configuration section. + +@node Container setup function, Container destroy function, name, Plugin interface +@subsection Container setup function: @code{init_function} + +@code{int (*init_function)(cfgl_t *cfg, void **handle);} + +The Container setup function is called at start up time. A handle to +access the configuration is handed over and the container handle is +expected back. + +Each plugin defines its own structure for the container +handle. Certainly it will store the configuration handle within. + + +@node Container destroy function, Worker setup function, Container setup function, Plugin interface +@subsection Container destroy function: @code{destroy_function} + +@code{int (*destroy_function)(void *handle);} + +The Container destroy function is called when the plugin is +unloaded. Is happens currently never. + +However, free any resources allocated for the container within this +function. + + +@node Worker setup function, Worker destroy function, Container destroy function, Plugin interface +@subsection Worker setup function: @code{work_setup_function} + +@code{int (*work_setup_function)(void *handle, void **work_handle);} + +The worker setup function is called when the first request of one +connection is dispatched to the plugin. The container handle is +provided, the worker handle is expected back. + +Each plugin defines its own structure for the worker handle. + + +@node Worker destroy function, Worker function, Worker setup function, Plugin interface +@subsection Worker destroy function: @code{work_destroy_function} + +@code{int (*work_destroy_function)(void *handle, void *work_handle);} + +The worker destroy function is called when the connection associated +with the worker is closed. + +Free any resources allocated for this worker. Do not free resources +associated with the container. + +@node Worker function, , Worker destroy function, Plugin interface +@subsection Worker function: @code{work_function} + +@code{int (*work_function)(void *handle, void *work_handle, char *input, char *output);} + +The worker function is called for each request dispatched to this +plugin. The container handle, the worker handle and of course the +input is provided. + +The return value must be one of + +@verbatim +#define SMM_OK 1 +#define SMM_TEMP_NOK 2 +#define SMM_PERM_NOK 3 +#define SMM_NOT_FOUND_NOK 4 + +@end verbatim + +which matches to the codes sendmail expects in the response from a +socket map. + +@code{output} is the text returned with the code to +sendmail. Especially for @code{SMM_OK} this is the return value of the +map. + + +@node Obtaining configuration data, More or less useful stuff, Plugin interface, API +@section Obtaining configuration data + +Each plugin can easily obtain data from its own configuration section. + + +@menu +* Without default value:: +* With default value:: +@end menu + +@node Without default value, With default value, Obtaining configuration data, Obtaining configuration data +@subsection Without default value + +@code{char *findcfgl(config_item_t *cfg, char *name);} + +@table @samp +@item cfg +Configuration handle, handed over to the plugin through the container +setup function. + +@item name +Name of the configuration parameter. +@end table + +The value of the request configuration parameter is returned. If it +does not exist, @code{NULL} is returned. + +@node With default value, , Without default value, Obtaining configuration data +@subsection With default value + +@code{char *findcfglx(config_item_t *cfg, char *name, char *default_value);} + +@table @samp +@item cfg +Configuration handle, handed over to the plugin through the container +setup function. + +@item name +Name of the configuration parameter. + +@item default_value +Default value to be returned instead of @code{NULL} if the parameter +is not mentioned in the configuration file. +@end table + + + +@node More or less useful stuff, , Obtaining configuration data, API +@section More or less useful stuff + +The functions of the library are discussed here for each of the header files. + +@node +@subsection @code{count.h} + +This is a threadsafe counter, wrapped around an @code{int}. + +Define or allocate a handle of type @code{count_t} to use it. + +It defines the following functions of hopefully obvious meaning: + +@verbatim +void count_init(count_t *c); +void count_destroy(count_t *c); +int count_inc(count_t *c); +int count_dec(count_t *c); +int count_get(count_t *c); +@end verbatim + + +@node +@subsection @code{queue.h} + +This is a threadsafe queue. Pointers to anything (@code{void}) can be +stored in it. + +Define or allocate a handle of type @code{ht_queue_t} to use it. + +It defines the following functions of hopefully obvious meaning: + +@verbatim +void queue_init(ht_queue_t *q); +void queue_destroy(ht_queue_t *q); +int queue_put(ht_queue_t *q, void *d); +void *queue_get_wait(ht_queue_t *q); +@end verbatim + + +@node +@subsection @code{htdns.h} + +This is a wrapper around the resolver library selected at build time +(currently traditional @code{libresolv} or djbdns). + +It defines the following functions: + +@verbatim +void free_rrs(void **resp); +mx_rdata_t** get_mx_rrs(char *domain); +mx_rdata_t** get_best_mx_rrs(char *domain); +a_rdata_t** get_a_rrs(char *domain); +cname_rdata_t** get_cname_rrs(char *domain); +@end verbatim + +For details on the data types look into the header file. + +Don't forget to free anything you got using @code{free_rrs}. + +@node +@subsection @code{htmalloc.h} + +This provides variants of @code{malloc}, @code{realloc} and +@code{strdup} which either returns or in case of out-of-memory sends +the whole process into nirwana. + +@verbatim +void *htmalloc(size_t size); +void *htrealloc(void *ptr, size_t size); +char *htstrdup(const char *s); +@end verbatim + + +@node +@subsection @code{smtp.h} + +This is a simple smtp library, also useable for lmtp. + +Define or allocate a handle of type @code{smtp_t} to use it. + +@verbatim +smtp_t *smtp_init2(char *host_address, int port, int timeout); +smtp_t *smtp_init(unsigned int address, int port, int timeout); +void smtp_destroy(smtp_t *handle); + +int smtp_response(smtp_t *handle, char **response); +int smtp_command(smtp_t *handle, char *command, char *arg); + +int smtp_connect(smtp_t *handle); +int smtp_close(smtp_t *handle); + +int smtp_helo(smtp_t *handle, char *arg); +int smtp_ehlo(smtp_t *handle, char *arg); +int smtp_lhlo(smtp_t *handle, char *arg); +int smtp_mailfrom(smtp_t *handle, char *arg); +int smtp_rcptto(smtp_t *handle, char *arg); +int smtp_data(smtp_t *handle); +int smtp_datasend(smtp_t *handle, char *data); +int smtp_dataend(smtp_t *handle); +int smtp_rset(smtp_t *handle); +int smtp_quit(smtp_t *handle); +@end verbatim + +Note: @code{host_address} in @code{smtp_init2} is a quad-dotted IP +address, no hostname. + +@node +@subsection @code{safe_write.h} + + @bye