1 /* This file is part of Mailfromd. 2 Copyright (C) 2005-2021 Sergey Poznyakoff 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 3, or (at your option) 7 any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 16 17 #include <sys/types.h> 18 #include <regex.h> 19 #include <mailutils/cctype.h> 20 #include <mailutils/mailutils.h> 21 #include <mfapi.h> 22 #include <dns.h> 23 #include <mailutils/alloc.h> 24 #include <sysexits.h> 25 #include "libmf.h" 26 #include "mfdb.h" 27 #include "bitmask.h" 28 #include "filenames.h" 29 30 /* A simplified version of the bitmask above, used for SMTP state mask */ 31 #define STATMASK(n) ((unsigned)1<<(n)) 32 33 #define SP(s) ((s) ? (s) : "(null)") 34 35 #ifndef INADDR_NONE 36 # define INADDR_NONE ((unsigned long) -1) 37 #endif 38 39 /* Exception codes. */ 40 typedef enum mf_exception_code { 41 #include <mflib/status.ex> 42 mf_exception_count 43 } mf_exception; 44 45 /* SMTP states */ 46 enum smtp_state { 47 smtp_state_none, 48 smtp_state_begin, 49 smtp_state_first=smtp_state_begin, 50 smtp_state_connect, 51 smtp_state_helo, 52 smtp_state_envfrom, 53 smtp_state_envrcpt, 54 smtp_state_data, 55 smtp_state_header, 56 smtp_state_eoh, 57 smtp_state_body, 58 smtp_state_eom, 59 60 smtp_state_end, 61 62 smtp_state_count 63 }; 64 65 #define MFAM_STDIO 0 66 #define MFAM_UNIX 1 67 #define MFAM_INET 2 68 #define MFAM_INET6 3 69 70 71 mf_status dns_to_mf_status(dns_status s); 72 73 mf_status resolve_ipstr(const char *ipstr, char **hbuf); 74 mf_status resolve_ipstr_domain(const char *ipstr, const char *domain, 75 char **phbuf); 76 mf_status resolve_hostname(const char *host, char **pipbuf); 77 78 79 /* Debugging macros */ 80 extern mu_debug_handle_t mfd_debug_handle; 81 #include "mfd-dbgmod.h" 82 83 84 /* Syslog flavor */ 85 #ifdef USE_SYSLOG_ASYNC 86 # include <syslog_async.h> 87 #endif 88 89 90 /* FIXME */ 91 void enable_prog_trace(const char *modlist); 92 void disable_prog_trace(const char *modlist); 93 94 95 /* Global variables declarations */ 96 #define MAILFROMD_DAEMON 0 97 #define MAILFROMD_TEST 1 98 #define MAILFROMD_SHOW_DEFAULTS 2 99 #define MAILFROMD_RUN 3 100 101 extern char *script_file; 102 extern char *ext_pp; 103 extern char *ext_pp_options; 104 extern int ext_pp_options_given; 105 extern int location_column_option; 106 extern int mode; 107 extern int mtasim_option; 108 extern unsigned optimization_level; 109 extern enum smtp_state test_state; 110 extern int regex_flags; 111 extern size_t variable_count; 112 extern int script_dump_macros; 113 extern int script_dump_xref; 114 extern int stack_trace_option; 115 extern const char *program_version; 116 extern char *callout_server_url; 117 118 extern size_t stack_size; 119 extern size_t stack_max_size; 120 extern size_t stack_expand_incr; 121 enum stack_expand_policy { 122 stack_expand_twice, 123 stack_expand_add 124 }; 125 extern enum stack_expand_policy stack_expand_policy; 126 127 extern size_t max_match_mx; 128 129 130 /* Filter script parser */ 131 132 typedef enum { 133 dtype_unspecified, 134 dtype_string, 135 dtype_number, 136 dtype_pointer 137 } data_type_t; 138 139 /* Parse tree node */ 140 typedef struct node NODE; 141 142 typedef struct mu_locus_range mf_yyltype_t; 143 144 struct if_node { /* if statement */ 145 NODE *cond; /* Condition */ 146 NODE *if_true; /* True branch */ 147 NODE *if_false; /* False branch */ 148 }; 149 150 struct poll_data { /* Poll test */ 151 NODE *email; 152 NODE *client_addr; 153 NODE *ehlo; 154 NODE *mailfrom; 155 }; 156 157 /* Opcodes for available binary operations */ 158 enum bin_opcode { 159 bin_and, 160 bin_or, 161 bin_eq, 162 bin_ne, 163 bin_lt, 164 bin_le, 165 bin_gt, 166 bin_ge, 167 bin_match, 168 bin_fnmatch, 169 bin_add, 170 bin_sub, 171 bin_mul, 172 bin_div, 173 bin_mod, 174 bin_logand, 175 bin_logor, 176 bin_logxor, 177 bin_shl, 178 bin_shr 179 }; 180 181 #define QUALIFIER_MX 0x1 182 183 struct bin_node { /* A binary operation */ 184 enum bin_opcode opcode; /* Operation code */ 185 int qualifier; /* Used to indicate MX MATCHES/FNMATCHES */ 186 NODE *arg[2]; /* arg[0] - left side argument, 187 arg[1] - right side argument */ 188 }; 189 190 /* Unary operations */ 191 enum un_opcode { 192 unary_not, 193 unary_minus, 194 unary_lognot 195 }; 196 197 struct un_node { /* A unary operation node */ 198 enum un_opcode opcode; /* Operation code */ 199 data_type_t result_type; /* Result type */ 200 NODE *arg; /* Argument */ 201 }; 202 203 /* Return action node: accept/reject/tempfail/continue */ 204 struct return_node { 205 sfsistat stat; /* Return status */ 206 NODE *code; /* Code */ 207 NODE *xcode; /* Extended code */ 208 NODE *message; /* Textual message */ 209 }; 210 211 enum msgmod_opcode { /* Message modification operation */ 212 header_add, /* Add a header */ 213 header_replace, /* Replace a header value */ 214 header_delete, /* Delete a header */ 215 header_insert, /* Insert a header */ 216 rcpt_add, /* Add a recipient */ 217 rcpt_delete, /* Delete a recipient */ 218 quarantine, /* Quarantine a message */ 219 body_repl, /* Replace message body */ 220 body_repl_fd, /* Replace message body from file */ 221 set_from /* Change envelope sender */ 222 }; 223 224 struct msgmod_closure { 225 enum msgmod_opcode opcode; /* Operation code */ 226 char *name; /* Object name */ 227 char *value; /* Object value */ 228 unsigned idx; /* Object index */ 229 }; 230 231 struct header_node { 232 enum msgmod_opcode opcode; /* Operation code */ 233 struct literal *name; /* Header name */ 234 NODE *value; /* Header value */ 235 }; 236 237 struct builtin_node { /* Call to a built-in function */ 238 const struct builtin *builtin; /* Buit-in function */ 239 NODE *args; /* Actual arguments */ 240 }; 241 242 struct concat_node { /* Concatenation of arg[0] and arg[1] */ 243 NODE *arg[2]; 244 }; 245 246 struct asgn_node { /* Assignment */ 247 struct variable *var; /* Variable */ 248 size_t nframes; /* Number of frames to skip */ 249 NODE *node; /* Expression to be evaluated and assigned 250 to it */ 251 }; 252 253 enum lexical_context { 254 context_none, 255 context_handler, 256 context_catch, 257 context_function 258 }; 259 260 struct catch_node { 261 struct exmask *exmask; /* Exception mask */ 262 enum lexical_context context; /* Context in which it occurs */ 263 NODE *node; /* Subtree */ 264 }; 265 266 struct try_node { 267 NODE *node; /* Subtree */ 268 NODE *catch; /* Catch node */ 269 }; 270 271 struct function_call { 272 struct function *func; /* Function description */ 273 NODE *args; /* List of actual arguments */ 274 }; 275 276 struct value { 277 data_type_t type; 278 union { 279 long number; 280 struct literal *literal; 281 } v; 282 }; 283 284 struct valist { 285 struct valist *next; 286 struct value value; 287 }; 288 289 struct case_stmt { 290 struct case_stmt *next; 291 struct mu_locus_range locus; 292 struct valist *valist; 293 NODE *node; 294 }; 295 296 struct switch_stmt { 297 NODE *node; /* Condition */ 298 struct case_stmt *cases; /* Switch branches */ 299 /* Auxiliary data for code generation */ 300 size_t tabsize; /* Size of the XLAT table */ 301 size_t off; /* Offset of the table in DS */ 302 struct switch_stmt *next; /* Link to the next switch statement */ 303 }; 304 305 struct cast_node { 306 data_type_t data_type; 307 NODE *node; 308 }; 309 310 struct positional_arg { 311 data_type_t data_type; 312 int number; 313 }; 314 315 struct progdecl { 316 enum smtp_state tag; 317 size_t auto_count; 318 NODE *tree; 319 }; 320 321 struct funcdecl { 322 struct function *func; 323 size_t auto_count; 324 NODE *tree; 325 }; 326 327 struct throw_node { 328 int code; 329 NODE *expr; 330 }; 331 332 struct var_ref { 333 struct variable *variable; /* Variable being referenced */ 334 size_t nframes; /* Number of frames to skip */ 335 }; 336 337 struct regcomp_data { 338 NODE *expr; 339 int flags; 340 size_t regind; 341 }; 342 343 struct loop_node { 344 struct literal *ident; 345 NODE *stmt; 346 NODE *for_stmt; 347 NODE *beg_while; 348 NODE *end_while; 349 NODE *body; 350 }; 351 352 struct argx_node { 353 int nargs; 354 NODE *node; 355 }; 356 357 struct sedcomp_node { 358 size_t index; 359 NODE *expr; /* Substitution expression */ 360 int flags; 361 }; 362 363 struct sed_node { 364 NODE *comp; 365 NODE *arg; 366 }; 367 368 #include "node-type.h" 369 370 /* Parse tree node */ 371 struct node { 372 NODE *next; /* Link to the next node */ 373 enum node_type type; /* Node type */ 374 struct mu_locus_range locus; /* Corresponding input location */ 375 union { 376 struct literal *literal; 377 long number; 378 struct if_node cond; 379 struct bin_node bin; 380 struct un_node un; 381 struct return_node ret; 382 struct header_node hdr; 383 struct builtin_node builtin; 384 NODE *node; 385 struct concat_node concat; 386 struct var_ref var_ref; 387 struct asgn_node asgn; 388 void *val; 389 struct catch_node catch; 390 struct try_node try; 391 struct throw_node throw; 392 struct function_call call; 393 struct switch_stmt switch_stmt; 394 struct cast_node cast; 395 struct positional_arg arg; 396 struct progdecl progdecl; 397 struct funcdecl funcdecl; 398 struct regcomp_data regcomp_data; 399 struct sym_regex *regex; 400 struct loop_node loop; 401 struct argx_node argx; 402 struct sedcomp_node sedcomp; 403 struct sed_node sed; 404 } v; 405 }; 406 407 struct stmtlist { 408 NODE *head; 409 NODE *tail; 410 }; 411 412 struct exmask { 413 struct exmask *next; 414 struct bitmask bm; 415 int all; /* If 1, set all bits in the exmask */ 416 size_t off; /* Offset of the table in DS */ 417 }; 418 419 420 /* Expressions, built-in functions and variables */ 421 422 typedef struct eval_environ *eval_environ_t; /* Evaluation environment */ 423 typedef unsigned long prog_counter_t; /* Program counter */ 424 425 /* Data types */ 426 427 #define SYMENT_STRUCT(name) \ 428 char *name;\ 429 unsigned refcnt 430 431 #define SYM_VOLATILE 0x01 /* Variable can change outside of the compiled 432 code */ 433 #define SYM_REFERENCED 0x02 /* Variable is referenced */ 434 #define SYM_INITIALIZED 0x04 /* Variable is initialized by set */ 435 #define SYM_PRECIOUS 0x08 /* Variable is precious, i.e. is not affected 436 by rset */ 437 #define SYM_EXTERN 0x10 /* Symbol is external (for future use) */ 438 #define SYM_STATIC 0x20 /* Symbol is static */ 439 #define SYM_PUBLIC 0x40 /* Symbol is public */ 440 441 #define SYM_PASSTOGGLE 0x80 /* Symbol processing pass toggle, used 442 in _ds_variable_count_fun and friends. */ 443 444 struct mf_symbol { 445 SYMENT_STRUCT(name); /* Variable name */ 446 struct mf_symbol *alias; 447 struct module *module; /* Backlink to the module where it is 448 defined */ 449 struct mu_locus_range locus; /* Location of the definition */ 450 unsigned flags; /* SYM_ flags */ 451 }; 452 453 #define MFD_BUILTIN_CAPTURE 0x01 /* Builtin needs message capturing */ 454 #define MFD_BUILTIN_VARIADIC 0x02 /* Builtin is variadic */ 455 #define MFD_BUILTIN_NO_PROMOTE 0x04 /* For variadic functions: 456 do not promote varargs to string */ 457 #define MFD_BUILTIN_REGEX_FLAGS 0x08 /* The built-in takes the value of the 458 regex_flags as the first (implicit) 459 argument. */ 460 461 struct builtin { 462 SYMENT_STRUCT(name); 463 void (*handler) (eval_environ_t); /* C handler */ 464 size_t parmcount; /* Number of parameters */ 465 data_type_t *parmtype; /* Parameter types */ 466 size_t optcount; /* Number of optional parameters 467 (size_t) -1 for varargs */ 468 data_type_t rettype; /* Return type */ 469 unsigned statemask; /* States where the function can 470 be used */ 471 int flags; /* Flags */ 472 }; 473 474 struct function { /* User-defined function */ 475 struct mf_symbol sym; 476 NODE *node; /* Function definition (syntax tree) */ 477 prog_counter_t entry; /* Entry point to the function code */ 478 struct exmask *exmask; /* Exception mask */ 479 unsigned statemask; /* States where the function can 480 be used */ 481 size_t parmcount; /* Number of parameters */ 482 size_t optcount; /* Number of optional parameters */ 483 int varargs; /* 1 if function takes variable number of 484 arguments */ 485 data_type_t *parmtype; /* Parameter types */ 486 data_type_t rettype; /* Return type */ 487 }; 488 489 typedef enum { 490 storage_extern, 491 storage_auto, 492 storage_param 493 } storage_class_t; 494 495 struct variable { 496 struct mf_symbol sym; 497 data_type_t type; /* Variable type */ 498 storage_class_t storage_class; /* Storage class */ 499 size_t off; /* Offset in the data segment */ 500 size_t ord; /* Ordinal number in the parmlist 501 (for parameters only) */ 502 size_t *addrptr; /* Address pointer (for built-in vars) */ 503 struct variable *shadowed; /* Points to the variable shadowed by 504 this one */ 505 int initialized; /* Is the variable initialized (for 506 automatic variables) */ 507 mu_list_t xref; /* List of struct mu_locus_range */ 508 struct variable *next; /* Next variable in this class */ 509 }; 510 511 struct literal { 512 SYMENT_STRUCT(text); 513 unsigned flags; /* SYM_* flags */ 514 size_t off; /* Offset in DS */ 515 struct sym_regex *regex; /* Any correspondig regexes */ 516 }; 517 518 struct constant { 519 struct mf_symbol sym; 520 struct value value; /* Constant value */ 521 }; 522 523 #define REG_EXTENDED_NAME "extended" 524 #define REG_ICASE_NAME "icase" 525 #define REG_NEWLINE_NAME "newline" 526 527 #define REGEX_STRING_BUFSIZE \ 528 (sizeof(REG_EXTENDED_NAME) + \ 529 sizeof(REG_ICASE_NAME) + \ 530 sizeof(REG_NEWLINE_NAME) + 1) 531 532 char *regex_flags_to_string(int flags, char *buf, size_t size); 533 534 int add_legacy_milter_port(const char *str); 535 536 void mflog_setup(void); 537 void mflog_reopen(const char *tag); 538 539 void builtin_setup(void); 540 void pragma_setup(void); 541 542 void print_code(void); 543 void print_xref(void); 544 void print_used_macros(void); 545 546 /* symbols.c */ 547 extern struct symtab *stab_module; 548 extern struct symtab *stab_builtin; 549 extern struct symtab *stab_pragma; 550 extern struct symtab *stab_literal; 551 552 void init_symbols(void); 553 void free_symbols(void); 554 555 struct mf_symbol *symbol_resolve_alias(struct mf_symbol *sp); 556 void va_builtin_install (char *name, void (*handler) (eval_environ_t), 557 data_type_t rettype, size_t argcount, ...); 558 void va_builtin_install_ex (char *name, void (*handler) (eval_environ_t), 559 unsigned statemsk, 560 data_type_t rettype, size_t argcount, 561 size_t optcount, int flags, ...); 562 563 const struct builtin *builtin_lookup(const char *name); 564 struct variable *variable_install(const char *name); 565 struct variable *variable_lookup(const char *name); 566 struct variable *variable_replace(const char *name, struct variable *newvar); 567 void variable_remove(struct variable *var); 568 struct variable *builtin_variable_install(const char *name, 569 data_type_t type, 570 unsigned flags, 571 size_t *addrptr); 572 void defer_initialize_variable(const char *arg, const char *val, 573 struct mu_locus_range const *locus); 574 575 int variable_or_constant_lookup(const char *name, void **dptr); 576 577 struct function *function_install(const char *name, 578 size_t parmcnt, size_t optcnt, int varargs, 579 data_type_t *parmtypes, 580 data_type_t rettype, 581 const struct mu_locus_range *locus); 582 struct function *function_lookup(const char *name); 583 struct literal *literal_lookup(const char *text); 584 struct constant *define_constant(const char *name, struct value *value, 585 unsigned flags, 586 struct mu_locus_range const *loc); 587 const struct constant *constant_lookup(const char *name); 588 const struct value *constant_lookup_value(const char *name); 589 590 struct sym_regex { 591 struct literal *lit; /* Corresponding literal */ 592 int regflags; /* Compilation flags */ 593 unsigned flags; /* VAR_* flags */ 594 size_t index; /* Index in the regtab */ 595 struct sym_regex *next; /* Next sym_regex with the same name, but 596 different regflags */ 597 }; 598 599 struct sym_regex *install_regex(struct literal *lit, unsigned regflags); 600 601 void install_alias(const char *name, struct function *fun, 602 const struct mu_locus_range *locus); 603 604 605 struct rt_regex { 606 int compiled; 607 regex_t re; 608 size_t expr; 609 int regflags; 610 }; 611 612 void register_regex(struct sym_regex *rp); 613 void finalize_regex(void); 614 615 size_t next_transform_index(void); 616 void install_transform(size_t index, transform_t tp); 617 transform_t get_transform(size_t index); 618 619 620 struct pragma { 621 SYMENT_STRUCT(name); 622 int minargs; 623 int maxargs; 624 void (*handler) (int, char **, const char *); 625 }; 626 627 void install_pragma(const char *name, int minargs, int maxargs, 628 void (*handler) (int, char **, const char *)); 629 const struct pragma *lookup_pragma(const char *name); 630 631 632 enum import_type { 633 import_literal, 634 import_regex, 635 import_transform 636 }; 637 638 struct import_rule { 639 struct import_rule *next; /* Next rule */ 640 enum import_type type; /* Type of this rule */ 641 struct literal *literal; /* Literal */ 642 int neg; /* Negate regex */ 643 regex_t re; /* Regular expression */ 644 transform_t xform; /* Transform expression */ 645 }; 646 647 struct import_rule_list { 648 struct import_rule *head, *tail; 649 }; 650 651 struct import_rule *import_rule_create(struct literal *lit); 652 653 654 enum module_namespace { 655 namespace_function, 656 namespace_variable, 657 namespace_constant 658 }; 659 #define MODULE_NAMESPACE_COUNT 3 660 661 struct module { 662 SYMENT_STRUCT(name); 663 const char *file; 664 const char *dclname; 665 unsigned flags; 666 struct symtab *symtab[MODULE_NAMESPACE_COUNT]; 667 struct import_rule *import_rules; 668 struct module_list *submodule_head, *submodule_tail; 669 mu_list_t /* of struct input_file_ident */ incl_sources; 670 }; 671 672 struct module_list { 673 struct module *module; 674 struct module_list *next; 675 }; 676 677 extern struct module *top_module; 678 679 #define MODULE_SYMTAB(m,ns) ((m)->symtab[ns]) 680 #define TOP_MODULE_SYMTAB(ns) MODULE_SYMTAB(top_module,ns) 681 int set_top_module(const char *name, const char *file, 682 struct import_rule *import_rules, 683 struct mu_locus_range const *locus); 684 void pop_top_module(void); 685 void collect_modules(struct module ***pmodv, size_t *pmodc); 686 int module_symtab_enumerate(enum module_namespace ns, symtab_enumerator_t fun, 687 void *data); 688 689 690 /* Preprocessor functions */ 691 struct input_file_ident { 692 ino_t i_node; 693 dev_t device; 694 }; 695 696 void include_path_setup(void); 697 698 FILE *pp_extrn_start(const char *name, pid_t *ppid); 699 void pp_extrn_shutdown(FILE *file, pid_t pid); 700 int preprocess_input(void); 701 702 void require_module(const char *modname, struct import_rule *import_rules); 703 704 int parse_include(const char *text, int once); 705 int parse_require(const char *text, mf_yyltype_t *loc); 706 int parse_line(char *text, struct mu_locus_point *pt); 707 int parse_line_cpp(char *text, struct mu_locus_point *pt); 708 void alloc_ext_pp(void); 709 int source_lookup(struct input_file_ident *idptr); 710 711 #define LEX_NONE 0 712 #define LEX_ONCE 1 713 #define LEX_MODULE 2 714 715 int lex_new_source(const char *name, int once); 716 void lex_bye(void); 717 void lex_drain_input(void); 718 void tie_in_onblock(int enable); 719 720 /* Parser functions */ 721 int yyparse(); 722 int yylex(); 723 int yyerror(char const *s); 724 void free_parser_data(void); 725 void add_include_dir(const char *dir); 726 int parse_program(char *name, int ydebug); 727 void parse_pragma(const char *text); 728 struct mu_locus_range const *get_locus(void); 729 const char *msgmod_opcode_str(enum msgmod_opcode opcode); 730 const char *sfsistat_str(sfsistat s); 731 const char *mf_exception_str(unsigned ex); 732 733 mf_exception mf_status_to_exception(mf_status s); 734 735 const char *storage_class_str(storage_class_t sc); 736 enum smtp_state string_to_state(const char *name); 737 const char *state_to_string(enum smtp_state state); 738 void parse_error(const char *fmt, ...) MU_PRINTFLIKE(1,2); 739 void parse_error_locus(struct mu_locus_range const *loc, const char *fmt, ...) 740 MU_PRINTFLIKE(2,3); 741 void parse_warning(const char *fmt, ...) MU_PRINTFLIKE(1,2); 742 void parse_warning_locus(struct mu_locus_range const *loc, const char *fmt, ...) 743 MU_PRINTFLIKE(2,3); 744 745 void print_syntax_tree(void); 746 void print_macros(void); 747 const char *function_name(void); 748 void lex_setup(void); 749 struct literal *string_alloc(const char *str, size_t len); 750 void string_begin(void); 751 void string_add(const char *str, size_t len); 752 void string_add_char(unsigned char c); 753 struct literal *string_finish(void); 754 void free_string_space(void); 755 void init_string_space(void); 756 data_type_t builtin_const_value(const char *s, size_t len, 757 const char **sval, long *nval); 758 const char *symbit_to_qualifier(unsigned f); 759 void advance_line(void); 760 761 char *mf_strdup(const char *str); 762 763 void regex_push(void); 764 void regex_pop(void); 765 766 void register_macro(enum smtp_state tag, const char *macro); 767 char *get_stage_macro_string(enum gacopyz_stage i); 768 struct exmask *exmask_create(void); 769 770 void variable_check_initialized(struct variable *var, 771 struct mu_locus_range const *loc); 772 773 774 /* Data types and declarations for handling compiled configuration code */ 775 776 /* Entry points for each SMTP state */ 777 extern prog_counter_t entry_point[smtp_state_count]; 778 779 /* Functions for accessing %rcpt_count */ 780 unsigned long get_rcpt_count(eval_environ_t env); 781 void clear_rcpt_count(eval_environ_t env); 782 void incr_rcpt_count(eval_environ_t env); 783 784 void set_last_poll_helo(eval_environ_t env, const char *text); 785 void set_last_poll_greeting(eval_environ_t env, const char *text); 786 void set_last_poll_host(eval_environ_t env, const char *host_addr); 787 void set_last_poll_sent(eval_environ_t env, const char *send); 788 void set_last_poll_recv(eval_environ_t env, const char *recv); 789 790 void set_milter_client_address(eval_environ_t env, milter_sockaddr_t *addr, 791 socklen_t len); 792 void set_milter_server_address(eval_environ_t env, milter_sockaddr_t *addr, 793 socklen_t len); 794 void set_milter_server_id(eval_environ_t env, const char *id); 795 796 void set_cache_used(eval_environ_t env, int value); 797 798 /* Evaluation environment functions */ 799 eval_environ_t 800 create_environment(SMFICTX *ctx, 801 const char *(*getsym)(void *data, const char *str), 802 int (*setreply)(void *data, char *code, char *xcode, 803 char *message), 804 void (*msgmod)(void *data, struct msgmod_closure *op), 805 void *data); 806 void destroy_environment(eval_environ_t env); 807 void env_init(eval_environ_t env); 808 void env_init_dataseg(eval_environ_t env); 809 void env_save_catches(eval_environ_t env); 810 811 # ifndef ATTRIBUTE_NORETURN 812 # define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) 813 # endif 814 815 void env_throw(eval_environ_t env, mf_exception exception, 816 const char *fmt, ...) 817 MU_PRINTFLIKE(3,4) ATTRIBUTE_NORETURN; 818 void env_throw_bi(eval_environ_t env, mf_exception exception, 819 const char *biname, 820 const char *fmt, ...) MU_PRINTFLIKE(4,5) ATTRIBUTE_NORETURN; 821 void env_throw_0(eval_environ_t env, mf_exception exception, 822 size_t text_off) ATTRIBUTE_NORETURN; 823 824 void env_push_string(eval_environ_t env, char *arg); 825 void env_push_number(eval_environ_t env, long arg); 826 void env_push_pointer(eval_environ_t env, void *arg); 827 void env_make_frame(eval_environ_t env); 828 void env_make_frame0(eval_environ_t env); 829 void env_leave_frame(eval_environ_t env, int nargs); 830 int env_set_variable(eval_environ_t env, char *ident, char *value); 831 int eval_environment(eval_environ_t env, prog_counter_t pc); 832 sfsistat environment_get_status(eval_environ_t env); 833 const char *environment_get_null_symbol(eval_environ_t env, 834 struct mu_locus_range *locus); 835 SMFICTX *env_get_context(eval_environ_t env); 836 size_t env_get_line_count(eval_environ_t env); 837 int env_get_stream(eval_environ_t env, mu_stream_t *pstr); 838 int env_get_header(eval_environ_t env, mu_header_t *hdr); 839 void env_reposition(eval_environ_t env); 840 int env_capture_start(eval_environ_t env); 841 int env_capture_write(eval_environ_t env, const char *buf, size_t size); 842 int env_capture_write_args(eval_environ_t env, ...); 843 void env_final_gc(eval_environ_t env); 844 845 void env_msgmod_append(eval_environ_t env, enum msgmod_opcode opcode, 846 const char *name, const char *value, unsigned idx); 847 void env_msgmod_clear(eval_environ_t env); 848 size_t env_msgmod_count(eval_environ_t env); 849 int env_msgmod_apply(eval_environ_t env, mu_list_action_t fun, void *data); 850 851 void capture_on(void); 852 const char *env_get_macro(eval_environ_t env, const char *symbol); 853 854 void mfl_smtp_io_callback(void *data, const char *key, const char *value); 855 856 857 /* Runtime functions */ 858 const char *mailfromd_msgid(SMFICTX *ctx); 859 void log_status(sfsistat status, SMFICTX *ctx); 860 void trace(const char *fmt, ...) MU_PRINTFLIKE(1,2); 861 int convert_rate(const char *arg, double *rate); 862 void priv_setup(void); 863 void mailfromd_daemon(void); 864 void save_cmdline(int argc, char **argv); 865 void pp_define(const char *symbol); 866 void test_message_data_init(eval_environ_t env); 867 868 void mailfromd_test(int argc, char **argv); 869 void mailfromd_run(prog_counter_t entry, int argc, char **argv); 870 871 void milter_enable_state(enum smtp_state state); 872 int milter_session_server(const char *id, 873 int fd, 874 struct sockaddr const *sa, socklen_t len, 875 void *server_data, void *srvman_data); 876 int mfd_callout_session_server(const char *id, int fd, 877 struct sockaddr const *sa, socklen_t len, 878 void *server_data, void *srvman_data); 879 void milter_setlogmask(int mask); 880 void milter_settimeout(time_t t); 881 882 int xeval(eval_environ_t env, enum smtp_state tag); 883 884 int relayed_domain_p(char *name); 885 size_t mem_search(const char *str, int c, size_t size); 886 887 888 889 typedef struct mf_stack *mf_stack_t; 890 mf_stack_t mf_stack_create(size_t elsize, size_t count); 891 void mf_stack_destroy(mf_stack_t *pstk); 892 void mf_stack_push(mf_stack_t stk, void *item); 893 int mf_stack_pop(mf_stack_t stk, void *ptr); 894 int mf_stack_peek(mf_stack_t stk, size_t n, void *ptr); 895 896 size_t mf_stack_count(mf_stack_t stk); 897 898 typedef int (*mf_stack_enumerator) (void *item, void *data); 899 900 int mf_stack_enumerate_desc(mf_stack_t stk, mf_stack_enumerator fun, 901 void *data); 902 int mf_stack_enumerate_asc(mf_stack_t stk, mf_stack_enumerator fun, 903 void *data); 904 905 906 int mf_stream_to_message(mu_stream_t stream, mu_message_t *msg); 907 void mf_add_runtime_params(struct mu_cfg_param *p); 908 909 910 /* deprecation.c */ 911 void deprecation_warning(const char *fmt, ...) MU_PRINTFLIKE(1,2); 912 void deprecation_warning_locus(const struct mu_locus_range *locus, const char *fmt, ...) 913 MU_PRINTFLIKE(2,3); 914 915 void final_deprecation_warning(void); 916 int enable_deprecation_warnings(void); 917 918 919 enum fixup_op 920 { 921 fixup_noop, 922 fixup_delete_line, 923 fixup_insert_line, 924 fixup_append_line, 925 fixup_replace_line, 926 fixup_delete_chars, 927 fixup_insert_chars, 928 fixup_replace_chars, 929 fixup_rename_file, 930 fixup_end 931 }; 932 933 void add_fixup_command(enum fixup_op opcode, mf_yyltype_t *locus, char *arg); 934 void add_fixup_command_fmt(enum fixup_op opcode, mf_yyltype_t *locus, 935 const char *fmt, ...) 936 MU_PRINTFLIKE(3,4); 937 void add_fixup_command_locus(enum fixup_op opcode, const struct mu_locus_range *locus, 938 char *arg); 939 void fixup_create_script(void); 940 941 /* savsrv.c */ 942 int callout_session_server(const char *id, int fd, 943 struct sockaddr const *sa, socklen_t len, 944 void *server_data, void *srvman_data); 945 void trimcrlf(char *buf); 946 947 /* savclt.c */ 948 void schedule_callout(const char *email, const char *ehlo, 949 const char *mailfrom, 950 const char *client_addr); 951 extern struct sockaddr *callout_server_sa; 952 extern socklen_t callout_server_sa_len; 953 954 /* exclist.c */ 955 void define_exception(struct literal *lit, struct mu_locus_range const *locus); 956 void enumerate_exceptions(int (*efn)(const struct constant *cp, 957 const struct literal *lit, 958 void *data), 959 void *data); 960 void fixup_exceptions(void); 961 void free_exceptions(void); 962 963 964