void cleanup_state_free(CLEANUP_STATE *state) { vstring_free(state->attr_buf); vstring_free(state->temp1); vstring_free(state->temp2); if (cleanup_strip_chars) vstring_free(state->stripped_buf); if (state->fullname) myfree(state->fullname); if (state->sender) myfree(state->sender); if (state->recip) myfree(state->recip); if (state->orig_rcpt) myfree(state->orig_rcpt); if (state->return_receipt) myfree(state->return_receipt); if (state->errors_to) myfree(state->errors_to); argv_free(state->auto_hdrs); if (state->hbc_rcpt) argv_free(state->hbc_rcpt); if (state->queue_name) myfree(state->queue_name); if (state->queue_id) myfree(state->queue_id); been_here_free(state->dups); if (state->reason) myfree(state->reason); if (state->smtp_reply) myfree(state->smtp_reply); nvtable_free(state->attr); if (state->mime_state) mime_state_free(state->mime_state); if (state->filter) myfree(state->filter); if (state->redirect) myfree(state->redirect); if (state->dsn_envid) myfree(state->dsn_envid); if (state->dsn_orcpt) myfree(state->dsn_orcpt); if (state->verp_delims) myfree(state->verp_delims); if (state->milters) milter_free(state->milters); if (state->milter_ext_from) vstring_free(state->milter_ext_from); if (state->milter_ext_rcpt) vstring_free(state->milter_ext_rcpt); if (state->milter_err_text) vstring_free(state->milter_err_text); cleanup_region_done(state); myfree((void *) state); }
int main(int argc, char **argv) { MILTERS *milters = 0; char *conn_macros, *helo_macros, *mail_macros, *rcpt_macros; char *data_macros, *eoh_macros, *eod_macros, *unk_macros; VSTRING *inbuf = vstring_alloc(100); char *bufp; char *cmd; int ch; int istty = isatty(vstream_fileno(VSTREAM_IN)); conn_macros = helo_macros = mail_macros = rcpt_macros = data_macros = eoh_macros = eod_macros = unk_macros = ""; msg_vstream_init(argv[0], VSTREAM_ERR); while ((ch = GETOPT(argc, argv, "V:v")) > 0) { switch (ch) { default: msg_fatal("usage: %s [-a action] [-p protocol] [-v]", argv[0]); case 'a': var_milt_def_action = optarg; break; case 'p': var_milt_protocol = optarg; break; case 'v': msg_verbose++; break; } } optind = OPTIND; for (;;) { const char *resp = 0; ARGV *argv; char **args; if (istty) { vstream_printf("- "); vstream_fflush(VSTREAM_OUT); } if (vstring_fgets_nonl(inbuf, VSTREAM_IN) <= 0) break; bufp = vstring_str(inbuf); if (!istty) { vstream_printf("> %s\n", bufp); vstream_fflush(VSTREAM_OUT); } if (*bufp == '#') continue; cmd = mystrtok(&bufp, " "); if (cmd == 0) { usage(); continue; } argv = argv_split(bufp, " "); args = argv->argv; if (strcmp(cmd, "create") == 0 && argv->argc == 1) { if (milters != 0) { msg_warn("deleting existing milters"); milter_free(milters); } milters = milter_create(args[0], var_milt_conn_time, var_milt_cmd_time, var_milt_msg_time, var_milt_protocol, var_milt_def_action, conn_macros, helo_macros, mail_macros, rcpt_macros, data_macros, eoh_macros, eod_macros, unk_macros); } else if (strcmp(cmd, "free") == 0 && argv->argc == 0) { if (milters == 0) { msg_warn("no milters"); continue; } milter_free(milters); milters = 0; } else if (strcmp(cmd, "connect") == 0 && argv->argc == 4) { if (milters == 0) { msg_warn("no milters"); continue; } resp = milter_conn_event(milters, args[0], args[1], args[2], strcmp(args[3], "AF_INET") == 0 ? AF_INET : strcmp(args[3], "AF_INET6") == 0 ? AF_INET6 : strcmp(args[3], "AF_UNIX") == 0 ? AF_UNIX : AF_UNSPEC); } else if (strcmp(cmd, "helo") == 0 && argv->argc == 1) { if (milters == 0) { msg_warn("no milters"); continue; } resp = milter_helo_event(milters, args[0], 0); } else if (strcmp(cmd, "ehlo") == 0 && argv->argc == 1) { if (milters == 0) { msg_warn("no milters"); continue; } resp = milter_helo_event(milters, args[0], 1); } else if (strcmp(cmd, "mail") == 0 && argv->argc > 0) { if (milters == 0) { msg_warn("no milters"); continue; } resp = milter_mail_event(milters, (const char **) args); } else if (strcmp(cmd, "rcpt") == 0 && argv->argc > 0) { if (milters == 0) { msg_warn("no milters"); continue; } resp = milter_rcpt_event(milters, 0, (const char **) args); } else if (strcmp(cmd, "unknown") == 0 && argv->argc > 0) { if (milters == 0) { msg_warn("no milters"); continue; } resp = milter_unknown_event(milters, args[0]); } else if (strcmp(cmd, "data") == 0 && argv->argc == 0) { if (milters == 0) { msg_warn("no milters"); continue; } resp = milter_data_event(milters); } else if (strcmp(cmd, "disconnect") == 0 && argv->argc == 0) { if (milters == 0) { msg_warn("no milters"); continue; } milter_disc_event(milters); } else { usage(); } if (resp != 0) msg_info("%s", resp); argv_free(argv); } if (milters != 0) milter_free(milters); vstring_free(inbuf); return (0); }
MILTERS *milter_receive(VSTREAM *stream, int count) { MILTERS *milters; MILTER *head = 0; MILTER *tail = 0; MILTER *milter = 0; if (msg_verbose) msg_info("receive %d milters", count); /* * XXX We must instantiate a MILTERS structure even when the sender has * no active filters, otherwise the cleanup server would try to use its * own non_smtpd_milters settings. */ #define NO_MILTERS ((char *) 0) #define NO_TIMEOUTS 0, 0, 0 #define NO_PROTOCOL ((char *) 0) #define NO_ACTION ((char *) 0) #define NO_MACROS ((MILTER_MACROS *) 0) milters = milter_new(NO_MILTERS, NO_TIMEOUTS, NO_PROTOCOL, NO_ACTION, NO_MACROS); /* * XXX Optimization: don't send or receive further information when there * aren't any active filters. */ if (count <= 0) return (milters); /* * Receive the global macro name lists. */ milters->macros = milter_macros_alloc(MILTER_MACROS_ALLOC_ZERO); if (attr_scan(stream, ATTR_FLAG_STRICT | ATTR_FLAG_MORE, ATTR_TYPE_FUNC, milter_macros_scan, (void *) milters->macros, ATTR_TYPE_END) != 1) { milter_free(milters); return (0); } /* * Receive the filters. */ for (; count > 0; count--) { if ((milter = milter8_receive(stream, milters)) == 0) { msg_warn("cannot receive milters via service %s socket", VSTREAM_PATH(stream)); milter_free(milters); return (0); } if (head == 0) { /* Coverity: milter_free() depends on milters->milter_list. */ milters->milter_list = head = milter; } else { tail->next = milter; } tail = milter; } /* * Over to you. */ (void) attr_print(stream, ATTR_FLAG_NONE, ATTR_TYPE_INT, MAIL_ATTR_STATUS, 0, ATTR_TYPE_END); return (milters); }