.\" Zmscanner API manual page .\" .\" $Id$ .\" .\" $Log: zmscanner.3,v $ .\" Revision 1.1 2003/12/13 20:47:37 crosser .\" add man page placeholders .\" .\" .\" WHAT IS IT: .\" modularized contentfilter for Zmailer .\" COPYRIGHT: .\" (c) 2003 Eugene G. Crosser .\" LICENSE: .\" The same set as apply to Zmailer code .\" .TH ZMSCANNER 3 "13 Dec 2003" ZMSCANNER ZMSCANNER .SH NAME API functions and macros for Zmscanner plugin modules .SH SYNOPSYS .B #include .PP .B void ZMS_MODULE(char *stage, char *name, int (*init_func)(void **priv), void (*term_func)(void **priv), int (*scan_func)(char *stage, int depth, slab_t data, varpool_t vp, void *priv)); .PP .B ZMS_MODINIT_FUNC { .RS .B ZMS_CLAIM_STAGE(char *stage1, char *name, int (*init_func)(void **priv), void (*term_func)(void **priv), int (*scan_func)(char *stage, int depth, slab_t data, varpool_t vp, void *priv)); .br .B ZMS_CLAIM_STAGE(char *stage2, ...); .RE .B } .PP .B int vp_set(varpool_t vp, char *name, void *object, void (*destructor)(void *)); .br .B int vp_set_int(varpool_t vp, char *name, int value); .br .B int vp_set_str(varpool_t vp, char *name, char *value); .PP .B void * vp_get(varpool_t vp, char *name); .br .B int vp_get_int(varpool_t vp, char *name); .br .B char * vp_get_str(varpool_t vp, char *name); .PP .B int scandata(char *stage, int depth,slab_t data, varpool_t vp); .PP .B vp_set_str(vp, VP_ANSWER_STR, \&"-1 550 5.7.0 Bad content\&"); .PP .B return ZMSCAN_CONTINUE; .br .B return ZMSCAN_STOP; .PP .SH DESCRIPTION .B zmscanner is a framework that allows to use a (runtime configurable) set of functions to analyze various parts of an email message, convert them to other formats and/or break to smaller parts, and make decisions about the message acceptability. In other words, it is a modular email content scanner. .P All processing in .B zmscanner model is done on the objects of the type .BR slab_t ", which is essentially a descriptor of a memory area. Initially, a complete Zmailer queue message is .BR mmap(2) "ed into memory (or read, if the platform does not support .BR mmap(2) "). Processing function may create .B slab_t descriptors for parts of the original area, or for freshly allocated and populated areas, and pass processing of these areas to other modules. Processing functions should return either .BR ZMSCAN_CONTINUE ", or .BR ZMSCAN_STOP ", and the latter denotes that further processing should not take place. .PP In .B zmscanner model, content analyzing functions do not call each other directly. Instead, a module that wants to scan specific parts of messages, \&"\fIclaim\fR\&" a specific \&"\fIstage\fR\&" denoted by a name. On the other hand, when a scanning function wants to pass a part of the message to a function of another module, it should pass it to a \&"\fIstage\fR\&" claimed by that function rather than to the function itself. This is done by calling .B scandata() API function. When calling it, increase .I depth argument by one agains what you've got as parameter, and pass .I vp parameter unchanged. If .B scandata return code is different from .BR ZMSCAN_CONTINUE ", you should immediately free all dynamically acqured resources and return with that return code. .PP More than one module may \&"\fIclaim\fR\&" the same \&"\fIstage\fR\&"; in such case scanning functions of all such modules are called in succession, in arbitrary order, until any one returns other than .B ZMSCAN_CONTINUE return code. .PP Finally, a word about passing state information between modules. There are API functions for maintaing .IR varpool ": pool of pointers to arbitrary data structures associated with symbolic names. Scanning functions that belong to different \&"\fIstages\fR\&" may share the same data structure as long as they all know its name. When a named structure is created with .B vp_set() API function, pointer to a destructor function must be passed. When a a variable is created with the name of already existing variable, the old one is forgotten and the corresponding data structure is destructed by that function. .I Varpool variables should never be destructed by hand. There are \&"simplified\&" API functions, .B vp_set_int() and .B vp_set_str() for integer and string type variables; they use standard builtin destructors, so you need nt take care of destructing them. .PP There is a special string type variable with the name defined by .B VP_ANSWER_STR macro. It is used to pass the scanning result to the SMTP server. It should contain a signed number, whitespace and SMTP answer string containg return code, optionally extended code and comment. Zero number means acceptable message, -1 means reject, and +1 - freeze. Predefined value for this variable is .PP .RS .nf .B \&"0 250 Acceptable\&" .fi .RE .PP All scanning functions must be reentrant. .SH "STANDARD MODULES" .B zmscanner core package comes with a number of general purpose modules statically compiled into it. They are represented in this table: .PP .TS l l l l l l l l l l l l l l l l. PLUGIN CLAIMED CALLED PER STAGE STAGE MSG ------ ------- ------ --- breakzmsg zmsg zhdr multi rfc822 once breakrfc822 rfc822 rfc822hdr multi rfc822hdr_ct multi rfc822 once multibody once body_qp multi body_base64 multi content multi breakbody multibody rfc822 multi decode_qp body_qp content once decode_b64 body_base64 content once dispatch_ct content content_text once content_text_plain once content_text_html once content_text_misc once content_image once content_application once content_misc once check_ct rfc822hdr_ct - - .TE .SH COPYRIGHT 2003-2004, Eugene G. Crosser .br License same as Zmailer (http://www.zmailer.org/) .SH SEE ALSO .BR zmscanner.conf "(5), " zmscanner "(8), " zmsctl "(8)