X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/1ccd5f670a432f98e94b384dd169a1a760dced9a..7dc8d146a675f52b441310e731314d86c66b2114:/src/src/structs.h diff --git a/src/src/structs.h b/src/src/structs.h index c16899a0c..46abac728 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -2,8 +2,10 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2015 */ +/* Copyright (c) The Exim Maintainers 2020 - 2024 */ +/* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Definitions of various structures. In addition, those that are visible for @@ -25,6 +27,13 @@ struct smtp_outblock; struct transport_info; struct router_info; +/* Growable-string */ +typedef struct gstring { + int size; /* Current capacity of string memory */ + int ptr; /* Offset at which to append further chars */ + uschar * s; /* The string memory */ +} gstring; + /* Structure for remembering macros for the configuration file */ typedef struct macro_item { @@ -58,6 +67,12 @@ typedef enum { CHUNKING_NOT_OFFERED = -1, CHUNKING_ACTIVE, CHUNKING_LAST} chunking_state_t; +typedef enum { TFO_NOT_USED = 0, + TFO_ATTEMPTED_NODATA, + TFO_ATTEMPTED_DATA, + TFO_USED_NODATA, + TFO_USED_DATA } tfo_state_t; + /* Structure for holding information about a host for use mainly by routers, but also used when checking lists of hosts and when transporting. Looking up host addresses is done using this structure. */ @@ -66,14 +81,17 @@ typedef enum {DS_UNK=-1, DS_NO, DS_YES} dnssec_status_t; typedef struct host_item { struct host_item *next; - const uschar *name; /* Host name */ - const uschar *address; /* IP address in text form */ - int port; /* port value in host order (if SRV lookup) */ - int mx; /* MX value if found via MX records */ - int sort_key; /* MX*1000 plus random "fraction" */ - int status; /* Usable, unusable, or unknown */ - int why; /* Why host is unusable */ - int last_try; /* Time of last try if known */ + const uschar *name; /* Host name */ +#ifndef DISABLE_TLS + const uschar *certname; /* Name used for certificate checks */ +#endif + const uschar *address; /* IP address in text form */ + int port; /* port value in host order (if SRV lookup) */ + int mx; /* MX value if found via MX records */ + int sort_key; /* MX*1000 plus random "fraction" */ + int status; /* Usable, unusable, or unknown */ + int why; /* Why host is unusable */ + int last_try; /* Time of last try if known */ dnssec_status_t dnssec; } host_item; @@ -112,23 +130,39 @@ three, the layout of the start of the blocks is kept the same, and represented by the generic structures driver_info and driver_instance. */ typedef struct driver_instance { - struct driver_instance *next; + void *next; uschar *name; /* Instance name */ - struct driver_info *info; /* Points to info for this driver */ + void *info; /* Points to info for this driver */ void *options_block; /* Pointer to private options */ + uschar *driver_name; /* All start with this generic option */ + const uschar *srcfile; /* and config source info for errors */ + int srcline; } driver_instance; typedef struct driver_info { + struct driver_info * next; uschar *driver_name; /* Name of driver */ + optionlist *options; /* Table of private options names */ int *options_count; /* -> Number of entries in table */ void *options_block; /* Points to default private block */ int options_len; /* Length of same in bytes */ void (*init)( /* Initialization entry point */ - struct driver_instance *); + struct driver_instance *); + uint dyn_magic; /* Magic num if dynamic, else zero */ } driver_info; +/* Values for dyn_magic. Encode types and api version. */ +#define ROUTER_MAGIC 0x52544d31 /* RTM1 */ +#define TRANSPORT_MAGIC 0x54504d31 /* TPM1 */ +#define AUTH_MAGIC 0x65554d31 /* AUM1 */ + +typedef struct { + uint magic; + uschar * class; +} driver_magics; + /* Structure for holding information about the configured transports. Some of the generally accessible options are set from the configuration file; others @@ -137,11 +171,8 @@ transports. They need to be generally accessible, however, as they are used by the main transport code. */ typedef struct transport_instance { - struct transport_instance *next; - uschar *name; /* Instance name */ - struct transport_info *info; /* Info for this driver */ - void *options_block; /* Pointer to private options */ - uschar *driver_name; /* Must be first */ + driver_instance drinst; + int (*setup)( /* Setup entry point */ struct transport_instance *, struct address_item *, @@ -158,7 +189,7 @@ typedef struct transport_instance { uschar *expand_multi_domain; /* ) */ BOOL multi_domain; /* ) */ BOOL overrides_hosts; /* ) Used only for remote transports */ - int max_addresses; /* ) */ + uschar *max_addresses; /* ) */ int connection_max_messages;/* ) */ /**************************************/ BOOL deliver_as_creator; /* Used only by pipe at present */ @@ -202,18 +233,12 @@ typedef struct transport_instance { } transport_instance; -/* Structure for holding information about a type of transport. The first six -fields must match driver_info above. */ +/* Structure for holding information about a type of transport. The first +element must be a struct driver_info, to match auths and routers. */ typedef struct transport_info { - uschar *driver_name; /* Driver name */ - optionlist *options; /* Table of private options names */ - int *options_count; /* -> Number of entries in table */ - void *options_block; /* Points to default private block */ - int options_len; /* Length of same in bytes */ - void (*init)( /* Initialization function */ - struct transport_instance *); -/****/ + driver_info drinfo; + BOOL (*code)( /* Main entry point */ transport_instance *, struct address_item *); @@ -238,7 +263,7 @@ typedef int (*tpt_chunk_cmd_cb)(struct transport_context *, unsigned, unsigned); typedef struct transport_context { union { /* discriminated by option topt_output_string */ int fd; /* file descriptor to write message to */ - uschar * msg; /* allocated string with written message */ + gstring * msg; /* allocated string with written message */ } u; transport_instance * tblock; /* transport */ struct address_item * addr; @@ -249,10 +274,6 @@ typedef struct transport_context { /* items below only used with option topt_use_bdat */ tpt_chunk_cmd_cb chunk_cb; /* per-datachunk callback */ void * smtp_context; - - /* items below only used with option topt_output_string */ - int msg_size; - int msg_ptr; } transport_ctx; @@ -265,11 +286,7 @@ typedef struct { /* Structure for holding information about the configured routers. */ typedef struct router_instance { - struct router_instance *next; - uschar *name; - struct router_info *info; - void *options_block; /* Pointer to private options */ - uschar *driver_name; /* Must be first */ + driver_instance drinst; uschar *address_data; /* Arbitrary data */ #ifdef EXPERIMENTAL_BRIGHTMAIL @@ -324,6 +341,7 @@ typedef struct router_instance { BOOL retry_use_local_part; /* Just what it says */ BOOL same_domain_copy_routing; /* TRUE => copy routing for same domain */ BOOL self_rewrite; /* TRUE to rewrite headers if making local */ + uschar *set; /* Variable = value to set; list */ BOOL suffix_optional; /* As it says */ BOOL verify_only; /* Skip this router if not verifying */ BOOL verify_recipient; /* Use this router when verifying a recipient*/ @@ -345,18 +363,12 @@ typedef struct router_instance { } router_instance; -/* Structure for holding information about a type of router. The first six -fields must match driver_info above. */ +/* Structure for holding information about a type of router. The first element +must be a struct driver_info, to match auths and transports. */ typedef struct router_info { - uschar *driver_name; - optionlist *options; /* Table of private options names */ - int *options_count; /* -> Number of entries in table */ - void *options_block; /* Points to default private block */ - int options_len; /* Length of same in bytes */ - void (*init)( /* Initialization function */ - struct router_instance *); -/****/ + driver_info drinfo; + int (*code)( /* Main entry point */ router_instance *, struct address_item *, @@ -381,11 +393,8 @@ typedef struct router_info { mechanisms */ typedef struct auth_instance { - struct auth_instance *next; - uschar *name; /* Exim instance name */ - struct auth_info *info; /* Pointer to driver info block */ - void *options_block; /* Pointer to private options */ - uschar *driver_name; /* Must be first */ + driver_instance drinst; + uschar *advertise_condition; /* Are we going to advertise this?*/ uschar *client_condition; /* Should the client try this? */ uschar *public_name; /* Advertised name */ @@ -401,29 +410,23 @@ typedef struct auth_instance { /* Structure for holding information about an authentication mechanism. The -first six fields must match driver_info above. */ +first element must be a struct driver_info, to match routers and transports. */ typedef struct auth_info { - uschar *driver_name; /* e.g. "condition" */ - optionlist *options; /* Table of private options names */ - int *options_count; /* -> Number of entries in table */ - void *options_block; /* Points to default private block */ - int options_len; /* Length of same in bytes */ - void (*init)( /* initialization function */ - struct auth_instance *); -/****/ + driver_info drinfo; + int (*servercode)( /* server function */ auth_instance *, /* the instance data */ uschar *); /* rest of AUTH command */ int (*clientcode)( /* client function */ struct auth_instance *, - struct smtp_inblock *, /* socket and input buffer */ - struct smtp_outblock *, /* socket and output buffer */ + void *, /* smtp conn, with socket, output and input buffers */ int, /* command timeout */ uschar *, /* buffer for reading response */ int); /* sizeof buffer */ - void (*version_report)( /* diagnostic version reporting */ - FILE *); /* I/O stream to print to */ + gstring * (*version_report)( /* diagnostic version reporting */ + gstring *); /* string to append to */ + void (*macros_create)(void); /* feature-macro creation */ } auth_info; @@ -436,13 +439,14 @@ typedef struct ip_address_item { int port; BOOL v6_include_v4; /* Used in the daemon */ uschar address[46]; + uschar * log; /* portion of "listening on" log line */ } ip_address_item; /* Structure for chaining together arbitrary strings. */ typedef struct string_item { - struct string_item *next; - uschar *text; + struct string_item * next; + uschar * text; } string_item; /* Information about a soft delivery failure, for use when calculating @@ -452,7 +456,7 @@ can be tried. */ typedef struct retry_item { struct retry_item *next; /* for chaining */ - uschar *key; /* string identifying host/address/message */ + const uschar *key; /* string identifying host/address/message */ int basic_errno; /* error code for this destination */ int more_errno; /* additional error information */ uschar *message; /* local error message */ @@ -498,19 +502,17 @@ typedef struct address_item_propagated { uschar *address_data; /* arbitrary data to keep with the address */ uschar *domain_data; /* from "domains" lookup */ uschar *localpart_data; /* from "local_parts" lookup */ - uschar *errors_address; /* where to send errors (NULL => sender) */ + const uschar *errors_address; /* where to send errors (NULL => sender) */ header_line *extra_headers; /* additional headers */ uschar *remove_headers; /* list of those to remove */ + void *variables; /* router-vasriables */ - #ifdef EXPERIMENTAL_SRS - uschar *srs_sender; /* Change return path when delivering */ - #endif BOOL ignore_error:1; /* ignore delivery error */ - #ifdef SUPPORT_I18N +#ifdef SUPPORT_I18N BOOL utf8_msg:1; /* requires SMTPUTF8 processing */ BOOL utf8_downcvt:1; /* mandatory downconvert on delivery */ BOOL utf8_downcvt_maybe:1; /* optional downconvert on delivery */ - #endif +#endif } address_item_propagated; @@ -535,13 +537,15 @@ typedef struct address_item { reply_item *reply; /* data for autoreply */ retry_item *retries; /* chain of retry information */ - uschar *address; /* address being delivered or routed */ + const uschar *address; /* address being delivered or routed */ uschar *unique; /* used for disambiguating */ - uschar *cc_local_part; /* caseful local part */ - uschar *lc_local_part; /* lowercased local part */ - uschar *local_part; /* points to cc or lc version */ - uschar *prefix; /* stripped prefix of local part */ - uschar *suffix; /* stripped suffix of local part */ + const uschar *cc_local_part; /* caseful local part */ + const uschar *lc_local_part; /* lowercased local part */ + const uschar *local_part; /* points to cc or lc version */ + const uschar *prefix; /* stripped prefix of local part */ + const uschar *prefix_v; /* variable part of above */ + const uschar *suffix; /* stripped suffix of local part */ + const uschar *suffix_v; /* variable part of above */ const uschar *domain; /* working domain (lower cased) */ uschar *address_retry_key; /* retry key including full address */ @@ -552,13 +556,17 @@ typedef struct address_item { uschar *message; /* error message */ uschar *user_message; /* error message that can be sent over SMTP or quoted in bounce message */ - uschar *onetime_parent; /* saved original parent for onetime */ + const uschar *onetime_parent; /* saved original parent for onetime */ uschar **pipe_expandn; /* numeric expansions for pipe from filter */ uschar *return_filename; /* name of return file */ uschar *self_hostname; /* after self=pass */ uschar *shadow_message; /* info about shadow transporting */ -#ifdef SUPPORT_TLS + uid_t uid; /* uid for transporting */ + gid_t gid; /* gid for transporting */ + +#ifndef DISABLE_TLS + const uschar *tlsver; /* version used for transport */ uschar *cipher; /* Cipher used for transport */ void *ourcert; /* Certificate offered to peer, binary */ void *peercert; /* Certificate from peer, binary */ @@ -579,9 +587,9 @@ typedef struct address_item { int dsn_flags; /* DSN flags */ int dsn_aware; /* DSN aware flag */ - uid_t uid; /* uid for transporting */ - gid_t gid; /* gid for transporting */ - +#ifndef DISABLE_DKIM + const uschar * dkim_used; /* DKIM info, or NULL */ +#endif /* flags */ struct { BOOL af_allow_file:1; /* allow file in generated address */ @@ -607,32 +615,41 @@ typedef struct address_item { BOOL af_verify_routed:1; /* for cached sender verify: routed OK */ BOOL af_verify_callout:1; /* for cached sender verify: callout was specified */ BOOL af_include_affixes:1; /* delivered with affixes in RCPT */ + BOOL af_new_conn:1; /* delivered on an fresh TCP conn */ + BOOL af_cont_conn:1; /* delivered (with new MAIL cmd) on an existing TCP conn */ BOOL af_cert_verified:1; /* delivered with verified TLS cert */ BOOL af_pass_message:1; /* pass message in bounces */ BOOL af_bad_reply:1; /* filter could not generate autoreply */ BOOL af_tcp_fastopen_conn:1; /* delivery connection used TCP Fast Open */ - BOOL af_tcp_fastopen:1; /* delivery usefuly used TCP Fast Open */ + BOOL af_tcp_fastopen:1; /* delivery usefully used TCP Fast Open */ + BOOL af_tcp_fastopen_data:1; /* delivery sent SMTP commands on TCP Fast Open */ + BOOL af_pipelining:1; /* delivery used (traditional) pipelining */ +#ifndef DISABLE_PIPE_CONNECT + BOOL af_early_pipe:1; /* delivery used connect-time pipelining */ +#endif #ifndef DISABLE_PRDR BOOL af_prdr_used:1; /* delivery used SMTP PRDR */ #endif BOOL af_chunking_used:1; /* delivery used SMTP CHUNKING */ BOOL af_force_command:1; /* force_command in pipe transport */ -#ifdef EXPERIMENTAL_DANE +#ifdef SUPPORT_DANE BOOL af_dane_verified:1; /* TLS cert verify done with DANE */ #endif #ifdef SUPPORT_I18N BOOL af_utf8_downcvt:1; /* downconvert was done for delivery */ +#endif +#ifndef DISABLE_TLS_RESUME + BOOL af_tls_resume:1; /* TLS used a resumed session */ #endif } flags; unsigned int domain_cache[(MAX_NAMED_LIST * 2)/32]; unsigned int localpart_cache[(MAX_NAMED_LIST * 2)/32]; int mode; /* mode for local transporting to a file */ + int basic_errno; /* status after failure */ int more_errno; /* additional error information */ - /* (may need to hold a timestamp) */ - unsigned int delivery_usec; /* subsecond part of delivery time */ + struct timeval delivery_time; /* time taken to do delivery/attempt */ - short int basic_errno; /* status after failure */ unsigned short child_count; /* number of child addresses */ short int return_file; /* fileno of return data file */ short int special_action; /* ( used when when deferred or failed */ @@ -705,11 +722,17 @@ typedef struct tree_node { /* Structure for holding time-limited data such as DNS returns. We use this rather than extending tree_node to avoid wasting space for most tree use (variables...) at the cost of complexity -for the lookups cache */ +for the lookups cache. +We also store any options used for the lookup. */ typedef struct expiring_data { - time_t expiry; /* if nonzero, data invalid after this time */ - void *ptr; /* pointer to data */ + time_t expiry; /* if nonzero, data invalid after this time */ + const uschar * opts; /* options, or NULL */ + union + { + void * ptr; /* pointer to data */ + int val; /* or integer data */ + } data; } expiring_data; /* Structure for holding the handle and the cached last lookup for searches. @@ -719,7 +742,7 @@ to close. */ typedef struct search_cache { void *handle; /* lookup handle, or NULL if closed */ - int search_type; /* search type */ + const lookup_info * li; /* info struct for search type */ tree_node *up; /* LRU up pointer */ tree_node *down; /* LRU down pointer */ tree_node *item_cache; /* tree of cached results */ @@ -736,11 +759,12 @@ typedef struct { const uschar *data; /* pointer to data */ } dns_record; -/* Structure for holding the result of a DNS query. */ +/* Structure for holding the result of a DNS query. A touch over +64k big, so take care to release as soon as possible. */ typedef struct { int answerlen; /* length of the answer */ - uschar answer[MAXPACKET]; /* the answer itself */ + uschar answer[NS_MAXMSG]; /* the answer itself */ } dns_answer; /* Structure for holding the intermediate data while scanning a DNS answer @@ -777,15 +801,40 @@ md5; typedef struct sha1 { unsigned int H[5]; unsigned int length; - } -sha1; +} sha1; + +/* Information for making an smtp connection */ +typedef struct { + transport_instance * tblock; + void * ob; /* smtp_transport_options_block * */ + host_item * host; + int host_af; + uschar * interface; + + int sock; /* used for a bound but not connected socket */ + uschar * sending_ip_address; /* used for TLS resumption */ + const uschar * host_lbserver; /* ditto, for server-behind LB */ + BOOL have_lbserver:1; /* host_lbserver is valid */ + +#ifdef SUPPORT_DANE + BOOL dane:1; /* connection must do dane */ + dns_answer tlsa_dnsa; /* strictly, this should use tainted mem */ +#endif +} smtp_connect_args; + +/* A client-initiated connection. If TLS, the second element is non-NULL */ +typedef struct { + int sock; + void * tls_ctx; +} client_conn_ctx; + /* Structure used to hold incoming packets of SMTP responses for a specific socket. The packets which may contain multiple lines (and in some cases, multiple responses). */ typedef struct smtp_inblock { - int sock; /* the socket */ + client_conn_ctx * cctx; /* the connection */ int buffersize; /* the size of the buffer */ uschar *ptr; /* current position in the buffer */ uschar *ptrend; /* end of data in the buffer */ @@ -797,12 +846,14 @@ specific socket. The packets which may contain multiple lines when pipelining is in use. */ typedef struct smtp_outblock { - int sock; /* the socket */ + client_conn_ctx * cctx; /* the connection */ int cmd_count; /* count of buffered commands */ int buffersize; /* the size of the buffer */ BOOL authenticating; /* TRUE when authenticating */ uschar *ptr; /* current position in the buffer */ uschar *buffer; /* the buffer itself */ + + smtp_connect_args * conn_args; /* to make connection, if not yet made */ } smtp_outblock; /* Structure to hold information about the source of redirection information */ @@ -818,13 +869,23 @@ typedef struct redirect_block { BOOL check_group; /* TRUE, FALSE, or TRUE_UNSET */ } redirect_block; +/* Sieve control data */ + +typedef struct sieve_block { + const uschar * inbox; + const uschar * enotify_mailto_owner; + const uschar * subaddress; + const uschar * useraddress; + const uschar * vacation_dir; +} sieve_block; + /* Structure for passing arguments to check_host() */ typedef struct check_host_block { const uschar *host_name; const uschar *host_address; const uschar *host_ipv4; - BOOL negative; + mcs_flags flags; } check_host_block; /* Structure for remembering lookup data when caching the result of @@ -839,27 +900,30 @@ typedef struct namedlist_cacheblock { /* Structure for holding data for an entry in a named list */ typedef struct namedlist_block { - const uschar *string; /* the list string */ - namedlist_cacheblock *cache_data; /* cached domain_data or localpart_data */ - int number; /* the number of the list for caching */ + const uschar *string; /* the list string */ + namedlist_cacheblock *cache_data; /* cached domain_data or localpart_data */ + short number; /* the number of the list for caching */ + BOOL hide; /* -bP does not display value */ } namedlist_block; /* Structures for Access Control Lists */ typedef struct acl_condition_block { - struct acl_condition_block *next; - uschar *arg; - int type; + struct acl_condition_block * next; + uschar * arg; + int type; union { - BOOL negated; - uschar *varname; + BOOL negated; + uschar * varname; } u; } acl_condition_block; typedef struct acl_block { - struct acl_block *next; - acl_condition_block *condition; - int verb; + struct acl_block * next; + acl_condition_block * condition; + int verb; + int srcline; + const uschar * srcfile; } acl_block; /* smtp transport calc outbound_ip */ @@ -875,7 +939,102 @@ struct ob_dkim { uschar *dkim_sign_headers; uschar *dkim_strict; uschar *dkim_hash; + uschar *dkim_timestamps; BOOL dot_stuffed; + BOOL force_bodyhash; +#ifdef EXPERIMENTAL_ARC + uschar *arc_signspec; +#endif }; + +/* per-queue-runner info */ +typedef struct qrunner { + struct qrunner * next; /* list sorted by next tick */ + + uschar * name; /* NULL for the default queue */ + unsigned interval; /* tick rate, seconds. Zero for a one-time run */ + time_t next_tick; /* next run should, or should have, start(ed) */ + unsigned run_max; /* concurrent queue runner limit */ + unsigned run_count; /* current runners */ + + BOOL queue_run_force :1; + BOOL deliver_force_thaw :1; + BOOL queue_run_first_delivery :1; + BOOL queue_run_local :1; + BOOL queue_2stage :1; +} qrunner; + + +/* Types of variable table entry */ + +enum vtypes { + vtype_int, /* value is address of int */ + vtype_filter_int, /* ditto, but recognized only when filtering */ + vtype_ino, /* value is address of ino_t (not always an int) */ + vtype_uid, /* value is address of uid_t (not always an int) */ + vtype_gid, /* value is address of gid_t (not always an int) */ + vtype_bool, /* value is address of bool */ + vtype_stringptr, /* value is address of pointer to string */ + vtype_msgbody, /* as stringptr, but read when first required */ + vtype_msgbody_end, /* ditto, the end of the message */ + vtype_msgheaders, /* the message's headers, processed */ + vtype_msgheaders_raw, /* the message's headers, unprocessed */ + vtype_localpart, /* extract local part from string */ + vtype_domain, /* extract domain from string */ + vtype_string_func, /* value is string returned by given function */ + vtype_todbsdin, /* value not used; generate BSD inbox tod */ + vtype_tode, /* value not used; generate tod in epoch format */ + vtype_todel, /* value not used; generate tod in epoch/usec format */ + vtype_todf, /* value not used; generate full tod */ + vtype_todl, /* value not used; generate log tod */ + vtype_todlf, /* value not used; generate log file datestamp tod */ + vtype_todzone, /* value not used; generate time zone only */ + vtype_todzulu, /* value not used; generate zulu tod */ + vtype_reply, /* value not used; get reply from headers */ + vtype_pid, /* value not used; result is pid */ + vtype_host_lookup, /* value not used; get host name */ + vtype_load_avg, /* value not used; result is int from os_getloadavg */ + vtype_pspace, /* partition space; value is T/F for spool/log */ + vtype_pinodes, /* partition inodes; value is T/F for spool/log */ + vtype_cert, /* SSL certificate */ +#ifndef DISABLE_DKIM + vtype_dkim, /* Lookup of value in DKIM signature */ +#endif + vtype_module, /* variable lives in a module; value is module name */ +}; + +/* Type for main variable table */ + +typedef struct { + const char *name; + enum vtypes type; + void *value; +} var_entry; + + + +/* dynamic-load module info */ + +typedef struct misc_module_info { + struct misc_module_info * next; + + const uschar * name; + unsigned dyn_magic; + BOOL (*init)(void *); /* arg is the misc_module_info ptr */ + gstring * (*lib_vers_report)(gstring *); /* underlying library */ + int (*conn_init)(const uschar *, const uschar *); + void (*smtp_reset)(void); + int (*msg_init)(void); + + void * options; + unsigned options_count; + void * functions; + unsigned functions_count; + void * variables; + unsigned variables_count; +} misc_module_info; + +#define MISC_MODULE_MAGIC 0x4d4d4d31 /* MMM1 */ + /* End of structs.h */