IPA_MOD(3)                                                          IPA_MOD(3)



NAME
       ipa_mod -- IPA modules APIs

SYNOPSIS
       #include <ipa_mod.h>

DESCRIPTION
       This  manual page describes API of all types of IPA modules. Let's call
       any IPA module simply ``a module''. Information given  in  this  manual
       page  is  mainly  for developers, but it can be interesting for anybody
       who wish to understand how IPA utilities work with IPA modules.

       This manual page has descriptions of the following APIs:

       ipa_memfunc API version 1 (IPA_MEMFUNC_API_VERSION);
       ipa_ac_mod API version 1 (IPA_AC_MOD_API_VERSION);
       ipa_db_mod API version 1 (IPA_DB_MOD_API_VERSION);
       ipa_st_mod API version 1 (IPA_ST_MOD_API_VERSION).

       The type u_int used here is actually unsigned int, it is not defined in
       <ipa_mod.h>.

       Module's symbols naming.

       Any  module  is  stored  in  a file with the name like foobar-x.y.z.so.
       After loading a module using the dlopen(3) or similar function, any  of
       IPA  utilities  removes a suffix and a version number from the module's
       file name and  tries  to  find  foobar_ac_mod,  foobar_db_mod  or  foo-
       bar_st_mod  symbol  in  a module if a module is accounting, database or
       statistics module. If a module has a searched symbol, then a module  is
       considered as an IPA module.

       Then  found  (void *)  pointer to a symbol is converted to one of three
       (struct ipa_XX_mod *) pointers. Structures  ipa_XX_mod  determine  APIs
       between IPA utilities and modules.

       Such method of naming symbols in modules allows to have several modules
       of different types in one file. You can create links to a module's file
       with different names to follow above given naming scheme.

       Single-threaded and multi-threaded modules.

       Any module can be single-threaded or multi-threaded. If a module is not
       expected to be blocked in some of its functions, then it can  be  built
       as  single-threaded.  If  a module is expected to be blocked in some of
       its functions or if a module need to continuously monitor  some  event,
       then  it  must  be  built as multi-threaded. Alternatively a module can
       fork(2) another process and use some form of IPC to communicate with it
       from  some  of  its functions, and used IPC functions also must be non-
       blockable.

       If a module is single-threaded, then it can use signals for own purpose
       (for  example  SIGALRM to implement timeout), except signals used by an
       IPA utility, which loaded this module. If a module  is  multi-threaded,
       then it is not allowed to use signals.

       It  is  very important to return from a module's function as quickly as
       possible, since IPA utilities expect, that module's functions will  not
       block.  If  a  module spends too much time in its functions, then time-
       stamps of statistics and reaction on some planned events  will  be  not
       very accurate in IPA utilities.

       Even  if  a module is not designed as multi-threaded, other modules can
       be multi-threaded. All loaded modules must be all  single  threaded  or
       must  be  all  multi-threaded.  So any single-threaded module should be
       able to be built as multi-threaded. A module always should set  correct
       flag in its API structure to say if it is single or multi-threaded.

       IPA utilities are single-threaded by design, but if at least one multi-
       threaded module is used, then they must be built as multi-threaded.  In
       multi-threaded  regime functions from ipa_memfunc, which is exported by
       IPA utilities to modules, become thread-safe.

       Modules are allowed to create threads only after configuration phase.

       Exported memory allocation functions for a module.

       Modules APIs require some type of  organization  of  data  in  modules.
       ipa_memfunc functions are exported to a module and tries to help a mod-
       ule with memory manipulation. A module is free to decide if it will use
       these  functions  or  if  it  will  not.  In some functions modules are
       required to use functions from ipa_memfunc.

       There are four types of functions from ipa_memfunc: initialization  and
       deinitialization  functions, functions for general purpose memory allo-
       cation, functions for working with mzones  and  functions  for  working
       with marrays.

       Functions  mem_* for general purpose memory allocation are wrappers for
       standard library memory  allocation  functions  (malloc(3),  calloc(3),
       realloc(3),  free(3), strdup(3) and for vasprintf(3) function, found on
       some systems). All these functions do  additional  checks.  Any  memory
       allocated  with  some  of mem_* functions should be freed with mem_free
       function. These functions accept extra one  argument,  called  mem_type
       (memory  type),  which  is  used for collecting statistics about memory
       usage. This mem_type should be created by the mem_type_new function.

       Marrays (memory arrays) are used for creating arrays of  items.  Mzones
       (memory  zones)  are used for creating items of the same size. All mar-
       ray_* and mzone_* functions  internally  use  mem_*  memory  allocation
       functions.

       Functions  from  ipa_memfunc  detect wrong pointers and incorrect argu-
       ments in mem_*, marray_* and mzone_* functions.  If some critical error
       is  found in any of these functions, then this function terminates exe-
       cution of a program and a core dump is generated.

       If IPA utilities were built with defined WITH_MEMFUNC_DEBUG macro vari-
       able,  then  allocated  and  freed  memory objects are filled with some
       garbage bytes, so if some part of code uses already freed memory,  then
       it  is likely, that it will get an error. Also mem_realloc in this case
       is equivalent to malloc(3) new area, memcpy(3) old data  to  new  area,
       free(3) old area.

       Any  IPA  utility  during  exit stage and during reconfiguration checks
       size of allocated and not freed memory, if this size is  not  equal  to
       zero,  then a debug message is sent to the log. If some mzone of marray
       was not deinitialized, then its name appears in a debug message.

       The ipa_memfunc has following format:

       typedef struct ipa_mem_type_struct ipa_mem_type;
       typedef struct ipa_marray_struct ipa_marray;
       typedef struct ipa_mzone_struct ipa_mzone;

       typedef struct {
           u_int   api_ver;
           int     (*memfunc_init)(void);
           void    (*memfunc_deinit)(int foreign);
           ipa_mem_type *m_parser;
           ipa_mem_type *(*mem_type_new)(const char *name, const char *desc,
                       u_int flags);
           void    *(*mem_malloc)(size_t size, ipa_mem_type *mem_type);
           void    *(*mem_calloc)(size_t number, size_t size,
                       ipa_mem_type *mem_type);
           void    *(*mem_realloc)(void *ptr, size_t size,
                       ipa_mem_type *mem_type);
           char    *(*mem_strdup)(const char *str, ipa_mem_type *mem_type);
           int     (*mem_vasprintf)(ipa_mem_type *mem_type, char **bufp,
                       const char *format, va_list ap);
           void    (*mem_free)(void *ptr, ipa_mem_type *mem_type);
           ipa_marray *(*marray_init)(const char *name, const char *desc,
                       u_int flags, void **arr, size_t isize, u_int nitems,
                       u_int nalloc);
           void    (*marray_deinit)(ipa_marray *marray);
           int     (*marray_alloc)(ipa_marray *marray, u_int *idxp,
                       int fixed);
           void    (*marray_free)(ipa_marray *marray, u_int idx);
           void    (*marray_minimize)(ipa_marray *marray);
           int     (*marray_check_index)(ipa_marray *marray, u_int idx);
           u_int   (*marray_nused)(ipa_marray *marray);
           ipa_mzone *(*mzone_init)(const char *name, const char *desc,
                       u_int flags, size_t isize, u_int nitems, u_int nalloc);
           void    (*mzone_deinit)(ipa_mzone *mzone);
           void    *(*mzone_alloc)(ipa_mzone *mzone);
           void    (*mzone_free)(ipa_mzone *mzone, void *ptr);
           u_int   (*mzone_nused)(ipa_mzone *mzone);
       } ipa_memfunc;

       api_ver
              Version of the ipa_memfunc API, a module should check values  of
              supported  API versions with IPA_MEMFUNC_API_VERSION during com-
              pilation.

       memfunc_init
              A child of a module can call this  function  to  initialize  all
              other ipa_memfunc functions.

       memfunc_deinit
              A  child  of  a module can call this function to free all memory
              allocated in mzones and  marrays,  and  deinitialize  all  other
              ipa_memfunc own structures. If foreign flag is non-zero then all
              messages about memory leaks will be  suppressed  and  statistics
              about  memory usage will be flushed. Note that this and previous
              functions can be called only in a child of some module.

       m_parser
              This is a pointer to mem_type used by a parser to allocate  mem-
              ory during configuration file parsing.

       mem_type_new
              Create new mem_type, name is a short name for new mem_type, desc
              is its description (usually several words) and  flags  are  ORed
              flags  for  new  mem_type.  Currently  only  one  flag  IPA_MEM-
              FUNC_FLAG_PTHREAD defined, which should be set if memory of this
              mem_type  will  be allocated or freed from several threads asyn-
              chronously. This function returns a pointer to new  mem_type  or
              NULL if an error occurred.

       mem_malloc
              Analogous to malloc(3).

       mem_calloc
              Analogous to calloc(3).

       mem_realloc
              Analogous to realloc(3).

       mem_strdup
              Analogous to strdup(3).

       mem_vasprintf
              Analogous  to  vasprintf(3) found on some systems. This function
              sets *bufp to be a pointer to a  buffer  sufficiently  large  to
              hold  the  formatted string. If sufficient space cannot be allo-
              cated, this function will return -1 and set *bufp to be  a  NULL
              pointer.    format   and  ap  are  the  same  arguments  as  for
              vprintf(3).

       mem_free
              Analogous to free(3).

       marray_init
              Create marray, name is a name of marray, it should  exist  until
              marray  is deinitialized. It is better to give a name for marray
              in a form <module_name>:<marray_name>. desc is  its  description
              (usually  several  words).  flags  determines ORed flags for new
              marray, currently  only  one  flag  IPA_MEMFUNC_FLAG_PTHREAD  is
              defined,  this flag must be set if items from this marray can be
              allocated and freed by several threads asynchronously. arr is  a
              pointer where to store the pointer to the actual array of items.
              isize is a size of one item in marray. nitems  means  number  of
              items  to  allocate  initially.  nalloc means number of items to
              allocate if there is not any unused items in marray. If you  are
              not  sure  about these values, then set them to 1. This function
              returns a pointer to just created marray or  NULL  if  an  error
              occurred.  Note  that the pointer saved in memory pointed by arr
              can be changed by next marray_alloc  and  marray_free  functions
              calls.

       marray_deinit
              Release  memory  used  by marray. If a module does not call this
              function, then an IPA utility will report about leak  of  memory
              and deinitialize module's marray, but this deinitialization does
              not mean that memory leak is avoided,  because  deinitialization
              of  marray  is  not  deep-free for its items. If marray is NULL,
              then this function does nothing.

       marray_alloc
              Allocate a new item in marray. If fixed is non-zero, then  *idxp
              should  be  a desired index number of a new item in marray, else
              this function will allocate an item  with  the  lowest  possible
              unused  index  number  and save this index number in *idxp. This
              function returns 0 if a new item was  allocated  and  -1  if  an
              error  occurred.  Usually a module calls this function with non-
              zero value of the fixed argument.

       marray_free
              Return previously allocated item with index idx to marray.

       marray_minimize
              Try to minimize memory used by marray. Such minimization is pos-
              sible  because  marray_alloc  and  marray_free try to keep extra
              memory for future items allocations.

       marray_check_index
              This function checks if an item with the idx index was allocated
              previously  in  marray  and  if  it was not allocated, then 0 is
              returned, else non-zero value is returned.

       marray_nused
              Return number of allocated items from marray.

       mzone_init
              Create mzone, name is a name of mzone,  it  should  exist  until
              mzone is deinitialized. It is better to give a name for mzone in
              a form <module_name>:<mzone_name>. desc is its description (usu-
              ally  several  words).  flags  means  the same as in marray_init
              function, mzone  also  accepts  IPA_MEMFUNC_FLAG_OPTIMIZE,  this
              flag should be set if it will be many items in a mzone. isize is
              a size of one item in mzone. nitems means  number  of  items  to
              allocate initially.  nalloc means number of items to allocate if
              there is not any unused item in mzone. If you are not sure about
              these  values,  then  set  them  to  1.  This function returns a
              pointer to just created mzone or NULL if an error occurred.

       mzone_deinit
              Release memory used by mzone. If a module  does  not  call  this
              function,  then  an IPA utility will report about leak of memory
              and deinitialize module's mzone, but this deinitialization  does
              not  mean  that memory leak is avoided, because deinitialization
              of mzone is not deep-free for its items. If mzone is NULL,  then
              this function does nothing.

       mzone_alloc
              Allocate  a new item from mzone. This function returns a pointer
              to a new item or NULL if an error occurred.

       mzone_free
              Return previously allocated item pointed by ptr to mzone.

       mzone_nused
              Return number of allocated items from mzone.

       Exported support functions for a module.

       Sometime a module needs to add some macro variable to some  section  of
       the  configuration file, or needs to output own parameters, when an IPA
       utility outputs parsed configuration file, or needs to send a log  mes-
       sage.  Since  a  module  does  not know how to do this, an IPA utility,
       which uses this module, exports ipa_suppfunc functions to a module:

       typedef struct {
           void    (*print_string)(const char *string);
           void    (*print_bytes)(const uint64_t *value);
           void    (*print_time)(const uint64_t *value);
           void    (*print_value)(const uint64_t *value, u_int value_type);
           void    (*print_boolean)(int value);
           void    (*print_space)(void);
           void    (*set_indent)(int indent);
           void    (*print_param_name)(const char *prefix, const char *param);
           void    (*print_param_args)(const char *format, va_list ap);
           void    (*print_param_end)(void);
           void    (*print_sect_name)(const char *prefix, const char *sect);
           void    (*print_sect_args)(const char *format, va_list ap);
           void    (*print_sect_begin)(void);
           void    (*print_sect_end)(void);
           void    (*open_log)(void);
           void    (*close_log)(void);
           void    (*logmsg)(const char *mod_name, int priority, int code,
                       const char *format, va_list ap);
           void    (*logconferr)(const char *mod_name, int code,
                       const char *format, va_list ap);
           int     (*local_sym_add)(char *sym, char *val, int copy_flag);
           int     (*local_sym_del)(cost char *sym);
           int     (*global_sym_add)(char *sym, char *val, int copy_flag);
           int     (*global_sym_del)(cost char *sym);
       } ipa_suppfunc;

       print_string
              This function prints a string with quotes.

       print_bytes
              This function prints bytes value.

       print_time
              This function prints time value.

       print_value
              This function prints bytes, time or 64-bit  unsigned  number  if
              value_type   is   IPA_CONF_TYPE_BYTES,   IPA_CONF_TYPE_TIME   or
              IPA_CONF_TYPE_UINT64 respectively.

       print_boolean
              This function prints boolean value.

       print_space
              This function prints one space character if it was  not  printed
              yet.

       set_indent
              A module should call this function before outputting any parame-
              ter or sections inside own section to set correct indent,  which
              is given as positive indent level.

       print_param_name
              This  function  outputs a parameter's name param with configura-
              tion prefix prefix. If a parameter does not have a configuration
              prefix, then prefix should be NULL.

       print_param_args
              This  vprintf(3)-like function outputs parameter's arguments. It
              can be invoked several times for the same parameter.

       print_param_end
              This function should be called after outputting all  parameter's
              arguments.

       print_sect_name
              This  function  outputs a section's name sect with configuration
              prefix prefix. If a section does not have a  configuration  pre-
              fix, then prefix should be NULL.

       print_sect_args
              This  vprintf(3)-like  function  outputs section's arguments. It
              can be invoked several times for the same section.

       print_sect_begin
              This function should be called after  outputting  all  section's
              arguments.

       print_sect_end
              This function should be called at the end of a module's section.

       open_log

       close_log
              If a module needs to fork another process, then that process can
              use  logmsg function (described below), but if it needs to close
              some descriptors and then use log system again, then  it  should
              call  close_log and then open_log function. Creation of the file
              descriptor for sending log messages is delayed until  the  first
              message is sent.

       logmsg A  module should use this function for sending log messages from
              any part of its code, but not from  configuration  file  parsing
              functions.   mod_name is a module's name. priority is a priority
              of the message: IPA_LOG_INFO,  IPA_LOG_WARNING  or  IPA_LOG_ERR.
              code is the errno(2) value or 0 if there is not any error condi-
              tion. format and ap are vprintf(3)-like arguments.

       logconferr
              A module should use this function  for  sending  messages  about
              errors  during  configuration  file parsing. Arguments means the
              same as for logmsg function.

       local_sym_add
              Create a local macro variable with name sym and  value  val,  if
              copy_flag is non-zero, then memory will be allocated and sym and
              val will be copied to it, else original pointers will  be  used.
              This  function  returns 0 if a macro variable was created and -1
              if something was wrong with memory allocation.

       local_sym_del
              Delete a local macro variable with name  sym.  If  there  is  no
              local  variable with the given name, then -1 is returned, else 0
              is returned. A module has a choice not to call this function for
              each  variable previously created by the local_sym_add function,
              because an IPA utility automatically handles this.

       global_sym_add
              Like local_sym_add, but for global macro variables.

       global_sym_del
              Like local_sym_del, but for global macro variables.

       Configuration section description.

       The ipa_conf_sect structure is defined as:

       typedef struct {
           const char      *sect_name;
           u_int           sect_id;
           int             arg_nargs;
           const char      *arg_pattern;
           regex_t         *arg_regexp;
           u_int           arg_type;
           const u_int     *sect_where;
           int             (*arg_parse)(void *arg);
       } ipa_conf_sect;

       sect_name
              This is a name of the section.

       sect_id
              This is a section ID, which is local for a  module.  This  value
              should be greater than IPA_CONF_SECT_CUSTOM_OFFSET.

       arg_nargs
              This  is  a  number of arguments a section should have. Set this
              field to zero if a section does not expect any arguments.  If  a
              section  can  have  variable  number of arguments, then set this
              field to negative number, which absolute value is equal to mini-
              mal number of arguments a section should have.

       arg_pattern
              A  section's  argument should match given POSIX extended regular
              expression.  If there is not such expression,  then  this  field
              should be set to NULL.

       arg_regexp
              This is a pointer to the variable with regex_t type. If arg_pat-
              tern is not NULL, then this field also should not be NULL. It is
              possible  share  some  regular  expression  between sections and
              parameters and do not waste memory for extra variables. In  this
              case  only  one  section or parameter must have valid pointer in
              arg_pattern,  all  others  sections  and  parameters  must   set
              arg_pattern to NULL.

       arg_type
              This is a type of the argument. There are following types:

              IPA_CONF_TYPE_INT32    - int32_t;
              IPA_CONF_TYPE_UINT32   - uint32_t;
              IPA_CONF_TYPE_INT64    - int64_t;
              IPA_CONF_TYPE_UINT64   - uint64_t;
              IPA_CONF_TYPE_STRING   - a string;
              IPA_CONF_TYPE_BYTES    - bytes;
              IPA_CONF_TYPE_TIME     - time;
              IPA_CONF_TYPE_VALUE    - value;
              IPA_CONF_TYPE_PER_CENT - per cent;
              IPA_CONF_TYPE_BOOLEAN  - boolean;
              IPA_CONF_TYPE_MISC     - without any format.

              Usually  a  module  uses a regular expression (field arg_regexp)
              with IPA_CONF_TYPE_MISC argument type and does not use a regular
              expression  with other argument types. IPA_CONF_TYPE_VALUE means
              time, bytes or uint64_t value. See below details.

       sect_where
              This field determines where this section should be placed, it is
              a  pointer to an array of u_int values, each value is an ID of a
              section, last element in this array should  be  equal  to  zero.
              Predefined sections IDs are follows:

              IPA_CONF_SECT_ROOT   - no section;
              IPA_CONF_SECT_GLOBAL - the global section;
              IPA_CONF_SECT_RULE   - the rule section;
              IPA_CONF_SECT_LIMIT  - the limit section;
              IPA_CONF_SECT_THRESHOLD - the threshold section;
              IPA_CONF_SECT_AUTORULE - the autorule section;
              IPA_CONF_SECT_RULEPAT  - the rulepat section.

       arg_parse
              This  function is called for parsing section arguments. A module
              can set this field to NULL if it has not  any  parsing  function
              for  arguments.  arg is a pointer to some data, which depends on
              arg_type, and arg_parse function should perform following casts:

              IPA_CONF_TYPE_INT32   - *(int32_t *)arg;
              IPA_CONF_TYPE_UINT32  - *(uint32_t *)arg;
              IPA_CONF_TYPE_INT64   - *(int64_t *)arg;
              IPA_CONF_TYPE_UINT64  - *(uint64_t *)arg;
              IPA_CONF_TYPE_STRING  - *(char **)arg;
              IPA_CONF_TYPE_BYTES   - *(uint64_t *)arg;
              IPA_CONF_TYPE_TIME    - *(uint64_t *)arg;
              IPA_CONF_TYPE_VALUE   - *(uint64_t *)arg, *((uint64_t *)arg + 1)
              IPA_CONF_TYPE_BOOLEAN - *(int *)arg;
              IPA_CONF_TYPE_MISC    - *(char **)arg.

              If arg_type is IPA_CONF_TYPE_STRING, then arg is  a  pointer  to
              the  allocated memory with the parsed string (whithout quote) by
              mem_malloc function with m_parser mem_type, and a module  should
              free  this  memory  if it does not need it by mem_free function.
              In other cases arg_parse function should copy  any  needed  data
              and  do  not  use data by pointers, also it is allowed to modify
              data arg points to.  If  arg_type  is  IPA_CONF_TYPE_MISC,  then
              there are not white-space characters at the beginning and at the
              tail of arg, also there is only one ` '  character  between  any
              two  arguments  in arg. If arg_type is IPA_CONF_TYPE_VALUE, then
              arg is a pointer to an array, first item of this array has  type
              of     value    IPA_CONF_TYPE_BYTES,    IPA_CONF_TYPE_TIME    or
              IPA_CONF_TYPE_UINT64, second item has a value itself.

       Configuration parameter description.

       The ipa_conf_param structure is defined as:

       typedef struct {
           const char      *param_name;
           int             arg_nargs;
           const char      *arg_pattern;
           regex_t         *arg_regexp;
           u_int           arg_type;
           const u_int     *param_where;
           int             (*arg_parse)(void *arg);
       } ipa_conf_param;

       param_name
              This is a name of the parameter.

       arg_nargs
              Explained above.

       arg_pattern
              Explained above.

       arg_regexp
              Explained above.

       arg_type
              Explained above.

       param_where
              Explained above for sect_where.

       arg_parse
              Explained above.

       Structure for representing dates.

       The ipa_tm structure is defined as:

       typedef struct tm ipa_tm;

       Only following fields in the ipa_tm structure  can  be  used:  tm_year,
       tm_mon,  tm_mday,  tm_hour, tm_min, tm_sec. These fields determine some
       local date. tm_year is equal to the real value of the year  and  tm_mon
       is equal to the real value of the month.

       Limit's state.

       The state of any limit is kept in the ipa_limit_state structure:

       struct ipa_limit_state {
           uint64_t    lim;
           uint64_t    cnt;
           u_int       event_date_set;
           ipa_tm      event_date[IPA_LIMIT_EVENT_NUM];
       };

       lim    This is a value of the limit parameter.

       cnt    This is a value of the limit's counter.

       event_date_set
              This  is  a  bits  filed,  which  determines  valid  entries  in
              event_date array, each IPA_LIMIT_EVENT_xxx element in event_date
              array   has   corresponding   IPA_LIMIT_EVENT_xxx_SET   bit   in
              event_date_set.

       event_date
              This is an array of limit's events dates.  There  are  following
              entries in this array:

              IPA_LIMIT_EVENT_START - date when the limit started;

              IPA_LIMIT_EVENT_RESTART - date  when  the  limit will restart or
              restarted;

              IPA_LIMIT_EVENT_RESTART_EXEC - date  when   commands   for   the
              restarted limit were run;

              IPA_LIMIT_EVENT_REACH - date when the limit reached;

              IPA_LIMIT_EVENT_REACH_EXEC - date  when commands for the reached
              limit were run;

              IPA_LIMIT_EVENT_EXPIRE - date when the reached limit will expire
              and will restart or expired and restarted;

              IPA_LIMIT_EVENT_EXPIRE_EXEC - date when commands for the expired
              limit were run;

              IPA_LIMIT_EVENT_UPDATED - date when the limit was  updated  last
              time.

       Threshold's state.

       The  state  of  any threshold is kept in the ipa_threshold_state struc-
       ture:

       struct ipa_threshold_state {
           uint64_t    thr;
           uint64_t    cnt;
           ipa_tm      tm_from;
           ipa_tm      tm_updated;
       };

       thr    This is a value of the threshold parameter.

       cnt    This is a value of the threshold's counter.

       tm_from

       tm_updated
              Two timestamps for the threshold.

       Accounting module API.

       Accounting module API is exported by a module to an IPA utility in  the
       ipa_ac_mod structure:

       struct ipa_ac_mod {
           u_int           api_ver;
           u_int           mod_flags;
           const char      *ac_name;
           const ipa_suppfunc *suppfunc;
           const ipa_memfunc *memfunc;
           const char      *conf_prefix;
           ipa_conf_sect   *conf_sect_tbl;
           ipa_conf_param  *conf_param_tbl;
           int             (*conf_init)(void);
           int             (*conf_deinit)(void);
           int             (*conf_event)(u_int event, u_int no,
                               const void *arg);
           int             (*conf_mimic_real)(void);
           int             (*conf_inherit)(u_int rulepatno, u_int ruleno,
                               const char *rule_name);
           void            (*conf_show)(u_int sect_id, u_int no);
           int             (*ac_pre_init)(void)
           int             (*ac_init_autorule)(u_int autoruleno,
                               const char *autorule_name);
           int             (*ac_init_dynrule)(u_int autoruleno, u_int ruleno,
                               const char *rule_name);
           int             (*ac_init_statrule)(u_int ruleno,
                               const char *rule_name);
           int             (*ac_init)(void);
           int             (*ac_deinit_rule)(u_int ruleno);
           int             (*ac_deinit_autorule)(u_int autoruleno);
           int             (*ac_deinit)(void);
           int             (*ac_get_stat)(void);
           int             (*ac_get_rule_stat)(u_int stat_generation,
                               int newstat, u_int ruleno, int *addition,
                               uint64_t *chunk);
           int             (*ac_set_autorule_active)(u_int autoruleno,
                               int active);
           int             (*ac_set_rule_active)(u_int ruleno, int active);
           int             (*ac_set_limit_active)(u_int ruleno, u_int limitno,
                               int active);
           int             (*ac_set_threshold_active)(u_int ruleno,
                               u_int thresholdno, int active);
           int             (*ac_limit_event)(u_int ruleno, u_int limitno,
                               u_int event);
           int             (*ac_threshold_event)(u_int ruleno,
                               u_int thresholdno, u_int event);
           int             (*ac_create_rule)(const char *mod_name,
                               u_int autoruleno, u_int *ruleno,
                               const char *rule_name, const char *rule_info);
           void            (*ac_delete_rule)(const char *mod_name,
                               u_int ruleno);
       };

       api_ver
              This  is  the  version  of  the  accounting module API, a module
              should   check   values   of   supported   API   versions   with
              IPA_AC_MOD_API_VERSION  during compilation. After loading a mod-
              ule, this version number is checked with  version  of  used  API
              version.

       mod_flags
              Flags,  which  describe  module  working  regimes. Only one flag
              IPA_MOD_FLAG_PTHREAD_SAFE is defined, and it must be  set  if  a
              module is thread-safe.

       ac_name
              This is a name of the module's accounting system.

       suppfunc
              This  is  a pointer to ipa_suppfunc structure, which is exported
              to a module.

       memfunc
              This is a pointer to ipa_memfunc structure, which is exported to
              a module.

       conf_prefix
              This is a configuration prefix for module's sections and parame-
              ters.

       conf_sect_tbl
              This is a pointer to the array of the ipa_conf_sect  structures,
              which describe module's sections. Last item in this table should
              have sect_name equal to NULL.

       conf_param_tbl
              This is a pointer to the array of the ipa_param_sect structures,
              which  describe  module's  parameters.  Last  item in this table
              should have param_name equal to NULL.

       conf_init
              After loading a module, this function is called.

       conf_deinit
              After parsing a configuration file, this function is called.

       conf_event
              This function is called each time when some configuration  event
              occurs.  conf_event  describes a configuration event. Configura-
              tion events allows a module to know for which section its param-
              eter  or  section  belongs.  There  are  following configuration
              events:

              IPA_CONF_EVENT_GLOBAL_BEGIN - the begin of the global section;

              IPA_CONF_EVENT_GLOBAL_END - the end of the global section;

              IPA_CONF_EVENT_RULE_BEGIN - the begin of the rule  section,  arg
              points  to a string with the rule's name and should be casted to
              (const char *), no is an ordinal number of this section,  start-
              ing from 0;

              IPA_CONF_EVENT_RULE_END - the end of the rule section;

              IPA_CONF_EVENT_LIMIT_BEGIN - the begin of the limit section, arg
              points to a string with the limit's name and should be casted to
              (const char *),  no  is an ordinal number of this section in the
              current section, starting from 0;

              IPA_CONF_EVENT_LIMIT_END - the end of the limit section;

              IPA_CONF_EVENT_THRESHOLD_BEGIN - the begin of the threshold sec-
              tion,  arg  points  to  a  string  with the threshold's name and
              should be casted to (const char *), no is an ordinal  number  of
              this section in the current section, starting from 0;

              IPA_CONF_EVENT_THRESHOLD_END - the end of the threshold section;

              IPA_CONF_EVENT_AUTORULE_BEGIN - the begin of the  autorule  sec-
              tion, arg points to a string with the autorule's name and should
              be casted to (const char *), no is an  ordinal  number  of  this
              section, starting from 0;

              IPA_CONF_EVENT_AUTORULE_END - the end of the autorule section;

              IPA_CONF_EVENT_RULEPAT_BEGIN - the begin of the rulepat section,
              arg points to a POSIX regular expression and should be casted to
              (const char *),  no is an ordinal number of this section, start-
              ing from 0;

              IPA_CONF_EVENT_RULEPAT_END - the end of the rulepat section;

              IPA_CONF_EVENT_CUSTOM_SECT_BEGIN - the begin  of  some  module's
              section, no is the ID of a module's section;

              IPA_CONF_EVENT_CUSTOM_SECT_END - the  end  of some module's sec-
              tion.

              For each IPA_CONF_EVENT_xxx_END no means the same as for  corre-
              sponding IPA_CONF_EVENT_xxx_BEGIN.

       conf_mimic_real
              If this function is called, then a module should mimic real con-
              figuration.

       conf_inherit
              In this function a module should inherit all settings  from  the
              rulepat section number rulepatno for the rule number ruleno with
              name rule_name. This function is called before ac_pre_init, then
              a  module  should  use  logconferr  function for reporting about
              occurred errors, else logmsg function should be used.

       conf_show
              This function is called when IPA utility outputs the parsed con-
              figuration  file. sect_id is the ID of a section. no is an ordi-
              nal number of a section with the given section ID. If  a  module
              has  some  configuration for this section, then it should output
              this configuration.  A module should  not  directly  output  any
              configuration,  instead  it should use one of the functions from
              the suppfunc structure.

       ac_pre_init
              This function is called after parsing a  configuration  file.  A
              module  should  make general preinitialization of its accounting
              system. This function is always  called  before  other  ac_init*
              functions.

       ac_init_autorule
              This  function is called if some autorule uses a module. autoru-
              leno is a number of the autorule, autorule_name is its name.

       ac_init_dynrule
              This function is called if some  dynamic  rule  uses  a  module.
              autoruleno  is  a number of the autorule from which this dynamic
              rule was generated, ruleno is a  number  of  the  dynamic  rule,
              rule_name  is  its  name.  Data, rule_name points to, will exist
              until ac_deinit_rule is called for this rule. This  function  is
              called when a module calls ac_create_rule from ac_get_stat.

       ac_init_statrule
              The  same  as ac_init_dynrule but for static rules and is called
              after configuration phase.

       ac_init
              This function is  called  after  all  other  ac_init*  functions
              (except ac_init_dynrule, which is called from ac_create_rule).

       ac_deinit_rule
              This  function  is  called  to deinitialize a rule, which uses a
              module.  A module should not expect, that ac_init_*rule for this
              rule  was  called before. This function is called for static and
              dynamic rules.

       ac_deinit_autorule
              This function is called to deinitialize an autorule, which  uses
              a module.  A module should not expect, that ac_init_autorule was
              called for this autorule before.

       ac_deinit
              This function is called  to  deinitialize  a  module.  A  module
              should  not  expect  that ac_*init functions were called before.
              This function is always  called  after  all  others  ac_deinit_*
              functions.

       ac_get_stat
              This  function  is called before calls to ac_get_rule_stat func-
              tion.  There is internal statistics generation number, which  is
              changed  each  time  when  any  module's ac_get_stat function is
              called and its value is always greater than zero.

       ac_get_rule_stat
              This function should  return  statistics  for  the  rule  number
              ruleno.   The  stat_generation  value is the value of statistics
              generation number (see above for description). The newstat  flag
              means,  that a module should consider that this is a first invo-
              cation of this function (for example this flag is non-zero  when
              a  rule  becomes active). chunk points to statistics returned by
              the module and *addition determines what  to  do  with  returned
              statistics,  if  it  is  non-zero,  then  returned statistics is
              added, else it is subtracted. Here statistics  means  statistics
              for period between two invocations of the ac_get_rule_stat func-
              tion. This function is not called if a rule which uses a  module
              is inactive.

       ac_set_autorule_active
              This  function should mark an autorule as active or inactive. If
              flag active is equal to zero, then an autorule should be  marked
              as  inactive  in  a module, else an autorule should be marked as
              active.

       ac_set_rule_active
              The same as above, but for a rule.

       ac_set_limit_active
              The same as above, but for a limit.

       ac_set_threshold_active
              The same as above, but for a threshold.

       ac_limit_event
              This function is called when some event occurred with the limit.
              event can be:

              IPA_LIMIT_EVENT_RESTART - the limit is restarted;
              IPA_LIMIT_EVENT_REACH   - the limit becomes reached;
              IPA_LIMIT_EVENT_EXPIRE  - the reached limit expires;
              IPA_LIMIT_EVENT_STARTUP_IF_REACHED - reached at startup;
              IPA_LIMIT_EVENT_STARTUP_IF_NOT_REACHED - not reached at startup;
              IPA_LIMIT_EVENT_SHUTDOWN_IF_REACHED - reached at shutdown;
              IPA_LIMIT_EVENT_SHUTDOWN_IF_NOT_REACHED - not reached  at  shut-
              down.

       ac_threshold_event
              This  function  is  called  when  some  event  occurred with the
              threshold.  event means that threshold's counter is:

              IPA_THRESHOLD_EVENT_BELOW - below threshold's value;
              IPA_THRESHOLD_EVENT_EQUAL - equal to threshold's value;
              IPA_THRESHOLD_EVENT_ABOVE - above threshold's value.

       ac_create_rule
              This function is exported to a module.

              A module should call this function  only  from  the  ac_get_stat
              function  to  create a dynamic rule. mod_name is a module's name
              (is used only for debugging and only in this function).  autoru-
              leno  is a number of the autorule from which to create a dynamic
              rule.  rule_name is a rule's name and rule_info is its  descrip-
              tion,  these  strings  are  not used by pointers, so if a module
              allocated memory for them, then it should  release  this  memory
              itself.  If  everything  is  correct,  then  ac_init_dynrule  is
              called.

              This function returns 0 if a dynamic rule was created, -2  if  a
              rule  with  the same name already exists and -1 if some critical
              error occurred, in this  case  a  module  must  return  -1  from
              ac_get_stat.

       ac_delete_rule
              This function is exported to a module.

              A  module  should  call  this function only from the ac_get_stat
              function to delete a dynamic rule number ruleno previously  cre-
              ated by the ac_create_rule function. mod_name is a module's name
              (is used only for debugging and only in this function).  At some
              point the ac_deinit_rule is called for the given rule.

              If  everything  is  correct,  then  this functions returns 0. If
              there were problems with the deinitialization, then -1 should be
              returned, in this case a module must return -1 from ac_get_stat.

       If some function, except ac_create_rule, returns integer value, then it
       should  return  the  value -1 if an error occurred, else zero should be
       returned.

       If a module does not support some function for dynamic or static  rule,
       for autorules, for limits or thresholds, then it should set correspond-
       ing field to NULL.

       If some function is exported to a module, then corresponding  field  in
       API structure can be set to any value (usually NULL).

       Database module API.

       Database  module  API  is exported by a module to an IPA utility in the
       ipa_db_mod structure:

       struct ipa_db_mod {
           u_int           api_ver;
           u_int           mod_flags;
           const char      *db_name;
           const ipa_suppfunc *suppfunc;
           const ipa_memfunc *memfunc;
           const char      *conf_prefix;
           ipa_conf_sect   *conf_sect_tbl;
           ipa_conf_param  *conf_param_tbl;
           int             (*conf_init)(void);
           int             (*conf_deinit)(void);
           int             (*conf_event)(u_int event, u_int no,
                               const void *arg);
           int             (*conf_mimic_real)(void);
           int             (*conf_inherit)(u_int rulepatno, u_int ruleno,
                               const char *rule_name);
           void            (*conf_show)(u_int sect_id, u_int no);
           int             (*db_pre_init)(void);
           int             (*db_init_dynrule)(u_int autoruleno, u_int ruleno,
                               const char *rule_name, const char *rule_info);
           int             (*db_init_statrule)(u_int ruleno,
                               const char *rule_name, const char *rule_info);
           int             (*db_init_dynlimit)(u_int autoruleno, u_int ruleno,
                               const char *rule_name, const char *rule_info,
                               u_int limitno, const char *limit_name,
                               const char *limit_info);
           int             (*db_init_statlimit)(u_int ruleno,
                               const char *rule_name, const char *rule_info,
                               u_int limitno, const char *limit_name,
                               const char *limit_info);
           int             (*db_init_dynthreshold)(u_int autoruleno,
                               u_int ruleno, const char *rule_name,
                               const char *rule_info, u_int thresholdno,
                               const char *threshold_name,
                               const char *threshold_info);
           int             (*db_init_statthreshold)(u_int ruleno,
                               const char *rule_name, const char *rule_info,
                               u_int thresholdno, const char *threshold_name,
                               const char *threshold_info);
           int             (*db_init)(void);
           int             (*db_get_limit_state)(u_int ruleno, u_int limitno,
                               struct ipa_limit_state *state);
           int             (*db_set_limit_state)(u_int ruleno, u_int limitno,
                               const struct ipa_limit_state *state,
                               int new_state);
           int             (*db_get_threshold_state)(u_int ruleno,
                               u_int thresholdno,
                               struct ipa_threshold_state *state);
           int             (*db_set_threshold_state)(u_int ruleno,
                               u_int thresholdno,
                               const struct ipa_threshold_state *state);
           int             (*db_deinit_threshold)(u_int ruleno,
                               u_int thresholdno);
           int             (*db_deinit_limit)(u_int ruleno, u_int limitno);
           int             (*db_deinit_rule)(u_int ruleno);
           int             (*db_deinit)(void);
           int             (*db_append_rule)(u_int ruleno,
                               const uint64_t *cnt, const ipa_tm *ctm);
           int             (*db_update_rule)(u_int ruleno,
                               const uint64_t *cnt, const ipa_tm *ctm);
           int             (*db_update_limit)(u_int ruleno, u_int limitno,
                               const uint64_t *value, const ipa_tm *ctm);
           int             (*db_limit_event)(u_int ruleno, u_int limitno,
                               u_int event, const ipa_tm *etm,
                               const ipa_tm *ctm);
           int             (*db_update_threshold)(u_int ruleno,
                               u_int thresholdno, const uint64_t *cnt,
                               const ipa_tm *tm_from,
                               const ipa_tm *tm_updated);
           int             (*db_set_rule_active)(u_int ruleno, int active);
           int             (*db_set_limit_active)(u_int ruleno, u_int limitno,
                               int active);
           int             (*db_set_threshold_active)(u_int ruleno, u_int
                               thresholdno, int active);
       }

       api_ver
              This is the version of the database module API, a module  should
              check  values of supported API versions with IPA_DB_MOD_API_VER-
              SION during compilation. After loading a  module,  this  version
              number is checked with version of used API version.

       mod_flags
              Explained above.

       db_name
              This is a name of the module's database.

       suppfunc
              Explained above.

       memfunc
              Explained above.

       conf_prefix
              Explained above.

       conf_sect_tbl
              Explained above.

       conf_param_tbl
              Explained above.

       conf_init
              Explained above.

       conf_deinit
              Explained above.

       conf_event
              Explained above.

       conf_mimic_real
              Explained above.

       conf_inherit
              Explained above.

       conf_show
              Explained above.

       db_pre_init
              This  function  is  called after parsing a configuration file. A
              module should make general initialization of its database.  This
              function always is called before other db_init* functions.

       db_init_dynrule
              This  function  is  called  if  some dynamic rule uses a module.
              autoruleno is a number of the autorule from which  this  dynamic
              rule  was  generated,  ruleno  is  a number of the dynamic rule,
              rule_name is its name and rule_info is  its  description.   Only
              data,  rule_name  points  to, will exist until db_deinit_rule is
              called for this rule.

       db_init_statrule
              The same as db_init_dynrule but for static rules.

       db_init_dynlimit
              This function is called if some limit from a dynamic rule uses a
              module.   limitno is an ordinal number of the limit in the rule,
              limit_name is its name and limit_info is its  description.  Rest
              of  arguments  means  the same as in db_init_dynrule. Only data,
              rule_name  and   limit_name   point   to,   will   exist   until
              db_deinit_limit  is  called for this limit. Since a rule can use
              another database, than its limits use, then a module should  not
              expect  that  db_init_dynrule  was  called  before for a limit's
              rule. If a limit's rule uses this module too, then  db_init_dyn-
              rule for a rule is called first.

       db_init_statlimit
              The same as db_init_dynlimit but for limits from static rules.

       db_init_dynthreshold
              This  function  is  called if some threshold from a dynamic rule
              uses a module. thresholdno is an ordinal number of the threshold
              in  the  rule,  threshold_name is its name and threshold_info is
              its  description.  Rest  of  arguments  means  the  same  as  in
              db_init_dynrule.   Only data, rule_name and threshold_name point
              to, will exist until  db_deinit_threshold  is  called  for  this
              threshold.  Since  a  rule  can  use  another database, than its
              thresholds  use,  then  a  module   should   not   expect   that
              db_init_dynrule  was  called before for a threshold's rule. If a
              threshold's rule uses this module too, then db_init_dynrule  for
              a rule is called first.

       db_init_statthreshold
              The  same as db_init_dynthreshold but for thresholds from static
              rules.

       db_init
              This function is called after all other db_init_stat* functions.

       db_get_limit_state
              This function should return the current state of the limit. If a
              module does not have current state for the  limit  (for  example
              for the new limit), then the lim field in state should be set to
              zero.

       db_set_limit_state
              This function should set a new state for the limit. If new_state
              is  zero,  then  current limit's state in the database should be
              updated, else a new limit's state should be registered.

       db_get_threshold_state
              This function should return the current state of the  threshold.
              If  a  module does not have current state for the threshold (for
              example for the new threshold), then  the  thr  field  in  state
              should be set to zero.

       db_set_threshold_state
              This function should update the current state for the threshold.

       db_deinit_threshold
              This function is called to deinitialize a threshold, which  uses
              a  module.   A module should not expect, that db_init_*threshold
              was called for this threshold before.

       db_deinit_limit
              This function is called to deinitialize a limit,  which  uses  a
              module.   A  module  should  not expect, that db_init_*limit was
              called for this limit before.

       db_deinit_rule
              This function is called to deinitialize a  rule,  which  uses  a
              module.   If some of rule's limits or thresholds use this module
              too,  then  db_deinit_limit  or  db_deinit_threshold  is  called
              first.   A module should not expect, that db_init_*rule for this
              rule was called before.

       db_deinit
              This function is called  to  deinitialize  a  module.  A  module
              should  not  expect  that db_*init functions were called before.
              This function is always called after all other db_deinit_* func-
              tions.

       db_append_rule
              This function should append a new record for the given rule. cnt
              is a pointer to a new value of the rule's counter.  ctm  is  the
              current local date. This function is called before first call of
              the db_update_rule function.

       db_update_rule
              This function should update a  database  record  for  the  given
              rule. cnt is a pointer to a new value of the rule's counter, ctm
              is the current local date.

       db_update_limit
              This function should update a state of the limit  in  the  data-
              base.   cnt  is  a pointer to a new value of the counter, ctm is
              the current local date. IPA_LIMIT_EVENT_UPDATED date  should  be
              also updated by a module.

       db_limit_event
              This  function  should  register an event event for the limit in
              the database. The given event can take place  right  now  or  in
              future.  etm is the local date of the given event and ctm is the
              current local date. IPA_LIMIT_EVENT_UPDATED date should be  also
              updated  by a module. This function is called only for following
              limit's   events    IPA_LIMIT_EVENT_:    RESTART_EXEC,    REACH,
              REACH_EXEC, EXPIRE and EXPIRE_EXEC.

       db_update_threshold
              This  function  should  update  a  state of the threshold in the
              database.  cnt is a pointer to  a  new  value  of  the  counter,
              tm_from and tm_updated are two timestamps for the threshold.

       db_set_rule_active
              Explained  above in ac_set_rule_active. When a rule is marked as
              active,   then   db_append_rule   will    be    called    before
              db_update_rule.

       db_set_limit_active
              Explained above in ac_set_limit_active.

       db_set_threshold_active
              Explained above in ac_set_threshold_active.

       If some function returns integer value, then it should return the value
       -1 if an error occurred, else zero should be returned.

       If a database module does not support dynamic rules, limits or  thresh-
       olds,  then it should set corresponding db_init_dyn* fields to NULL. If
       a database module does not support static rules, limits or  thresholds,
       then set corresponding db_init_stat* fields to NULL.

       If   a   database   module   does   not   support   db_get_limit_state,
       db_get_threshold_state, db_set_*active function, then set corresponding
       field to NULL.

       If  some  function is exported to a module, then corresponding field in
       API structure can be set to any value (usually NULL).

       Statistics module API.

       Statistics module API is exported by a module to an IPA utility in  the
       ipa_st_mod structure:

       struct ipa_entity_desc {
           char            *name;
           char            *info;
       };

       struct ipa_rule_stat {
           u_int           year;
           unsigned char   mon;
           unsigned char   mday;
           unsigned char   h1, m1, s1;
           unsigned char   h2, m2, s2;
           uint64_t        cnt;
       };

       struct ipa_st_mod {
           u_int           api_ver;
           u_int           mod_flags;
           const char      *st_name;
           const ipa_suppfunc *suppfunc;
           const ipa_memfunc *memfunc;
           const char      *conf_prefix;
           ipa_conf_sect   *conf_sect_tbl;
           ipa_conf_param  *conf_param_tbl;
           int             (*conf_init)(void);
           int             (*conf_deinit)(void);
           int             (*conf_event)(u_int event, u_int no,
                               const void *arg);
           int             (*conf_mimic_real)(void);
           int             (*conf_inherit)(u_int rulepatno, u_int ruleno,
                               const char *rule_name);
           void            (*conf_show)(u_int sect_id, u_int no);
           int             (*st_pre_init)(void);
           int             (*st_init_rule)(u_int ruleno,
                               const char *rule_name);
           int             (*st_init_limit)(u_int ruleno,
                               const char *rule_name, u_int limitno,
                               const char *limit_name);
           int             (*st_init_threshold)(u_int ruleno,
                               const char *rule_name, u_int thresholdno,
                               const char *threshold_name);
           int             (*st_init)(void);
           int             (*st_deinit_threshold)(u_int ruleno,
                               u_int thresholdno);
           int             (*st_deinit_limit)(u_int ruleno, u_int limitno);
           int             (*st_deinit_rule)(u_int ruleno);
           int             (*st_deinit)(void);
           int             (*st_get_rule_info)(u_int ruleno,
                               ipa_mem_type *mem_type, char **infop);
           int             (*st_get_limit_info)(u_int ruleno, u_int limitno,
                               ipa_mem_type *mem_type, char **infop);
           int             (*st_get_threshold_info)(u_int ruleno,
                               u_int thresholdno, ipa_mem_type *mem_type,
                               char **infop);
           int             (*st_get_rules_list)(const char *pat,
                               const regex_t *pat_reg, ipa_mem_type *mem_type,
                               u_int *n, struct ipa_entity_desc **bufp);
           int             (*st_get_limits_list)(u_int ruleno, const char *pat,
                               const regex_t *pat_reg, ipa_mem_type *mem_type,
                               u_int *n, struct ipa_entity_desc **bufp);
           int             (*st_get_thresholds_list)(u_int ruleno,
                               const char *pat, const regex_t *pat_reg,
                               ipa_mem_type *mem_type, u_int *n,
                               struct ipa_entity_desc **bufp);
           int             (*st_get_rule_stat)(u_int ruleno, const ipa_tm *tm1,
                               const ipa_tm *tm2, int exact,
                               ipa_mem_type *mem_type, u_int *n,
                               struct ipa_rule_stat **bufp);
           int             (*st_get_limit_stat)(u_int ruleno, u_int limitno,
                               const ipa_tm *tm1, const ipa_tm *tm2,
                               ipa_mem_type *mem_type, u_int *n,
                               struct ipa_limit_state **bufp);
           int             (*st_get_threshold_stat)(u_int ruleno,
                               u_int thresholdno,
                               struct ipa_threshold_state *buf);
       };

       api_ver
              This  is  the  version  of  the  statistics module API, a module
              should   check   values   of   supported   API   versions   with
              IPA_ST_MOD_API_VERSION  during compilation. After loading a mod-
              ule, this version number is checked with  version  of  used  API
              version.

       mod_flags
              Explained above.

       st_name
              This is a name of the module's statistics system.

       suppfunc
              Explained above.

       memfinc
              Explained above.

       conf_prefix
              Explained above.

       conf_sect_tbl
              Explained above.

       conf_param_tbl
              Explained above.

       conf_init
              Explained above.

       conf_deinit
              Explained above.

       conf_event
              Explained above.

       conf_mimic_real
              Explained above.

       conf_inherit
              Explained above.

       conf_show
              Explained above.

       st_pre_init
              This  function  is  called after parsing a configuration file. A
              module should make general initialization of its statistics sys-
              tem.  This function always is called before other st_init* func-
              tions.

       st_init_rule
              This function is called if a rule uses a  module.  ruleno  is  a
              number  of  the  rule,  rule_name  is  its name. Data, rule_name
              points to, will exist until st_deinit_rule is  called  for  this
              rule.  This  function  can be called for a rule which has corre-
              sponding section in the configuration file, and for a rule which
              was  generated on-the-fly (can be considered as a dynamic rule).

       st_init_limit
              This function is called if some limit from a rule uses a module.
              limitno  is  an  ordinal  number  of  the  limit  in  the  rule,
              limit_name is a its name. Only data,  rule_name  and  limit_name
              point  to,  will  exist until st_deinit_limit is called for this
              limit. Since a rule can use another statistics system, than  its
              limits  use,  then  a module should not expect that st_init_rule
              was called before for a limit's rule. If  a  limit's  rule  uses
              this  module too, then st_init_rule for a limit's rule is called
              first. Like st_init_rule this function can be called for a  rule
              and/or a limit which has corresponding section in the configura-
              tion file, and for a rule and/or limit which was  generated  on-
              the-fly (can be considered as a dynamic rule and/or a limit).

       st_init_threshold
              This  function  is  called  if some threshold from a rule uses a
              module.  thresholdno is an ordinal number of  the  threshold  in
              the rule, threshold_name is a its name. Only data, rule_name and
              threshold_name point to, will exist until st_deinit_threshold is
              called  for this threshold. Since a rule can use another statis-
              tics system, than its thresholds use, then a module  should  not
              expect  that  st_init_rule  was  called before for a threshold's
              rule.  If  a  threshold's  rule  uses  this  module  too,   then
              st_init_rule  for  a  threshold's  rule  is  called  first. Like
              st_init_rule this function can be called for  a  rule  and/or  a
              threshold  which  has corresponding section in the configuration
              file, and for a rule and/or threshold which  was  generated  on-
              the-fly  (can  be  considered as a dynamic rule and/or a thresh-
              old).

       st_init
              This function is called after all other st_init* functions.

       st_deinit_threshold
              This function is called to deinitialize a threshold, which  uses
              a  module.   A  module should not expect, that st_init_threshold
              was called for this threshold before.

       st_deinit_limit
              This function is called to deinitialize a limit,  which  uses  a
              module.   A  module  should  not  expect, that st_init_limit was
              called for this limit before.

       st_deinit_rule
              This function is called to deinitialize a  rule,  which  uses  a
              module.   If some of rule's limits or thresholds use this module
              too, then st_deinit_limit or st_deinit_threshold is  called  for
              such  rule's  limits  or  thresholds before. A module should not
              expect, that st_init_rule for this rule was called before.

       st_deinit
              This function is called  to  deinitialize  a  module.  A  module
              should  not  expect  that st_*init functions were called before.
              This function is always called after all other st_deinit_* func-
              tions.

       st_get_rule_info
              This  function  should  return a description for the rule number
              ruleno, pointer to a rule's description should  be  returned  in
              *infop.  If  a  rule  does  not  have a description, then *infop
              should be set to NULL.

       st_get_limit_info
              The same as st_get_rule_info, but for a limit.

       st_get_threshold_info
              The same as st_get_rule_info, but for a threshold.

       st_get_rules_list
              This function should  return  an  array  with  rules  names  and
              descriptions.   If the POSIX regular expression pat is not NULL,
              then a module should return only rules, with names which matched
              this  regular  expression (pat_reg is a compiled regular expres-
              sion pat). The pointer to the  array  of  struct ipa_entity_desc
              should  be  returned  in  *bufp, number of entries in this array
              should be returned in *n. If number of entries is equal to zero,
              then *bufp must be NULL.

       st_get_limits_list
              The same as st_get_rules_list, buf for limits.

       st_get_thresholds_list
              The same as st_get_rules_list, buf for thresholds.

       st_get_rule_stat
              This  function is used for querying statistics for a rule number
              ruleno for time interval from tm1 till tm2. If  exact  is  zero,
              then  both  of  rule's  records  timestamps should be inside the
              given time interval, else only one of rule's records  timestamps
              should  be  inside  the  given time interval. The pointer to the
              array of struct ipa_rule_stat should be returned in *bufp,  num-
              ber of entries in this array should be returned in *n. If number
              of entries is equal to zero, then *bufp must be NULL.

              Structure  struct ipa_rule_stat  represents  statistics  of  one
              rule's record. In struct ipa_rule_stat fields year, mon and mday
              specify date of both timestamps of a rule's record (a new record
              for  any rule is always appended for a new day, that's why it is
              enough only these three fields for dates  of  both  timestamps).
              t1,  m1 and s1 is time of first timestamp; t2, m2 and s2 is time
              of second timestamp. cnt is statistics for the time interval  in
              one rule's record.

       st_get_limit_stat
              This function is used for querying statistics for a limit number
              limitno in a rule number ruleno, dates when a limit was  started
              should be in time interval from tm1 till tm2. The pointer to the
              array of struct ipa_limit_state should  be  returned  in  *bufp,
              number  of  entries  in  this array should be returned in *n. If
              number of entries is equal to zero, then *bufp must be NULL.  If
              tm1  is  NULL, then current limit state should be returned. If a
              module does not have current state for the limit, then it should
              set the lim field in *bufp entry to zero.

       st_get_threshold_stat
              This function is used for querying current state for a threshold
              number thresholdno in a rule number ruleno. If a module does not
              have current state for the threshold, then it should set the thr
              field in buf to zero.

       If some function returns integer value, then it should return the value
       -1 if an error occurred, else zero should be returned.

       If  a  statistics  module  does not support some functions, which query
       statistics or description, then set corresponding fields to NULL.

       If some function accepts mem_type argument,  then  all  allocated  data
       being  returned by this function should be allocated with the help from
       ipa_memfunc functions with the given mem_type.

       If some function is exported to a module, then corresponding  field  in
       API structure can be set to any value (usually NULL).

SEE ALSO
       ipa(8), ipactl(8), ipastat(8), ipa.conf(5), ipastat.conf(5)

AUTHOR
       Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua>

BUGS
       If you find any, please send email me.



                                April 16, 2005                      IPA_MOD(3)