/* ** Modular Logfile Analyzer ** Copyright 2000 Jan Kneschke ** ** Homepage: http://www.modlogan.org ** This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version, and provided that the above copyright and permission notice is included with all distributed copies of this or derived software. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ** ** $Id: process.c,v 1.12 2004/08/27 20:06:19 ostborn Exp $ */ #include #include #include #include #include #include #include #include #include #include "config.h" #include "mrecord.h" #include "mlocale.h" #include "mconfig.h" #include "mplugins.h" #include "mstate.h" #include "mdatatypes.h" #include "misc.h" #include "plugin_config.h" #include "datatypes/state/datatype.h" #include "datatypes/count/datatype.h" #include "datatypes/visited/datatype.h" #define M_MAIL_IGNORE_SENDER 1 #define M_MAIL_IGNORE_RECEIPIENT 2 #define M_MAIL_IGNORE_DOMAIN 3 #define M_MAIL_GROUP_SENDER 1 #define M_MAIL_GROUP_RECEIPIENT 2 #define M_MAIL_GROUP_DOMAIN 3 #define M_MAIL_HIDE_SENDER 1 #define M_MAIL_HIDE_RECEIPIENT 2 #define M_MAIL_HIDE_DOMAIN 3 int is_matched(mlist *l, const char *url) { int url_len; if (!url || !l) return 0; url_len = strlen(url); for (; l; l = l->next) { mdata *data = l->data; if (data == NULL) { continue; } if (data->type != M_DATA_TYPE_MATCH) { fprintf(stderr, "%s.%d: wrong datatype for a match: %d\n", __FILE__, __LINE__, data->type); continue; } if (strmatch(data->data.match.match, data->data.match.study, url, url_len)) return 1; } return 0; } int hide_field(mconfig *ext_conf, const char *url, int field) { config_processor *conf = ext_conf->plugin_conf; mlist *l = NULL; switch (field) { case M_MAIL_HIDE_SENDER: l = conf->hide_sender; break; case M_MAIL_HIDE_RECEIPIENT: l = conf->hide_receipient; break; case M_MAIL_HIDE_DOMAIN: l = conf->hide_domain; break; default: fprintf(stderr, "%s.%d: Unknown hide field: %d\n", __FILE__, __LINE__, field); break; } if (!url || !l) return 0; return is_matched(l, url); } int ignore_field(mconfig *ext_conf, const char *url, int field) { config_processor *conf = ext_conf->plugin_conf; mlist *l = NULL; int ret; switch (field) { case M_MAIL_IGNORE_SENDER: l = conf->ignore_sender; break; case M_MAIL_IGNORE_RECEIPIENT: l = conf->ignore_receipient; break; case M_MAIL_IGNORE_DOMAIN: l = conf->ignore_domain; break; default: fprintf(stderr, "%s.%d: Unknown ignore field: %d\n", __FILE__, __LINE__, field); break; } if (!url || !l) return 0; ret = is_matched(l, url); return ret; } char * is_grouped (mconfig *ext_conf, mlist *l, const char *str) { int str_len; if (!str || !l) return NULL; str_len = strlen(str); for (; l; l = l->next) { mdata *data = l->data; if (data == NULL) { continue; } if (data->type != M_DATA_TYPE_MATCH) { fprintf(stderr, "%s.%d: wrong datatype for a match: %d\n", __FILE__, __LINE__, data->type); continue; } if (strmatch(data->data.match.match, data->data.match.study, str, str_len)) { char *r = substitute(ext_conf, data->data.match.match, data->data.match.study, data->key, str, str_len); if (r == NULL) fprintf(stderr, "%s.%d: substitute failed: %p - %s - %s\n", __FILE__, __LINE__, data->data.match.match, data->key, str); return r; } } return NULL; } char * group_field (mconfig *ext_conf, const char *str, int field) { config_processor *conf = ext_conf->plugin_conf; mlist *l = NULL; switch (field) { case M_MAIL_GROUP_SENDER: l = conf->group_sender; break; case M_MAIL_GROUP_RECEIPIENT: l = conf->group_receipient; break; case M_MAIL_GROUP_DOMAIN: l = conf->group_domain; break; default: fprintf(stderr, "%s.%d: Unknown group field: %d\n", __FILE__, __LINE__, field); break; } if (!str || !l) return NULL; return is_grouped (ext_conf, l, str); } int mplugins_processor_mail_insert_record(mconfig *ext_conf, mlist *state_list, mlogrec *record) { /* fill the state_list with data */ struct tm *tm; /* record extension */ mlogrec_mail *recmail = NULL; mstate_mail *stamail = NULL; mstate *state = NULL; mdata *data = state_list->data; if (record->ext_type != M_RECORD_TYPE_MAIL) return -1; if (record->ext == NULL) return -1; recmail = record->ext; if (!data) { const char *key = splaytree_insert(ext_conf->strings, ""); data = mdata_State_create(key,NULL,NULL); assert(data); mlist_insert(state_list, data); } state = data->data.state.state; if (state == NULL) return -1; if (state->ext) { switch(state->ext_type) { case M_STATE_TYPE_MAIL: stamail = state->ext; break; default: fprintf(stderr, "%s.%d: unsupport state subtype\n", __FILE__, __LINE__); return -1; } } else { state->ext = mstate_init_mail(); state->ext_type = M_STATE_TYPE_MAIL; stamail = state->ext; } if (recmail->receipient || recmail->sender) { if ( ignore_field(ext_conf, recmail->sender, M_MAIL_IGNORE_SENDER) || ignore_field(ext_conf, recmail->receipient, M_MAIL_IGNORE_RECEIPIENT )) { return 0; } if ((tm = localtime(&(record->timestamp)))) { /* perhaps we have created a new state */ if (!state->timestamp) { state->year = tm->tm_year+1900; state->month = tm->tm_mon+1; } state->timestamp = record->timestamp; /* outgoing */ if (recmail->receipient) { stamail->hours[tm->tm_hour].outgoing_bytes += recmail->bytes_out; stamail->hours[tm->tm_hour].outgoing_mails++; stamail->days[tm->tm_mday-1].outgoing_bytes += recmail->bytes_out; stamail->days[tm->tm_mday-1].outgoing_mails++; if (!hide_field(ext_conf, recmail->receipient, M_MAIL_HIDE_RECEIPIENT)) { char *grouped, *domain; /* set direct email-addr */ if ((grouped = group_field(ext_conf, recmail->receipient, M_MAIL_GROUP_RECEIPIENT))) { const char *key = splaytree_insert(ext_conf->strings, grouped); data = mdata_Visited_create(key, 1, M_DATA_STATE_PLAIN, recmail->bytes_out); free(grouped); } else { const char *key = splaytree_insert(ext_conf->strings, recmail->receipient); data = mdata_Visited_create(key, 1, M_DATA_STATE_PLAIN, recmail->bytes_out); } mhash_insert_sorted(stamail->receipient, data); /* extract the domain part */ if ((domain = strchr(recmail->receipient, '@')) != NULL) { domain++; if ((grouped = group_field(ext_conf, domain, M_MAIL_GROUP_DOMAIN))) { const char *key = splaytree_insert(ext_conf->strings, grouped); data = mdata_Visited_create(key, 1, M_DATA_STATE_PLAIN, recmail->bytes_out); free(grouped); } else { const char *key = splaytree_insert(ext_conf->strings, domain); data = mdata_Visited_create(key, 1, M_DATA_STATE_PLAIN, recmail->bytes_out); } mhash_insert_sorted(stamail->recp_domain, data); } } } else { stamail->hours[tm->tm_hour].incoming_bytes += recmail->bytes_in; stamail->hours[tm->tm_hour].incoming_mails++; stamail->days[tm->tm_mday-1].incoming_bytes += recmail->bytes_in; stamail->days[tm->tm_mday-1].incoming_mails++; if (recmail->sender && !hide_field(ext_conf, recmail->sender, M_MAIL_HIDE_SENDER)) { char *grouped, *domain; if ((grouped = group_field(ext_conf, recmail->sender, M_MAIL_GROUP_SENDER))) { const char *key = splaytree_insert(ext_conf->strings, grouped); data = mdata_Visited_create(key, 1, M_DATA_STATE_PLAIN, recmail->bytes_in); free(grouped); } else { const char *key = splaytree_insert(ext_conf->strings, recmail->sender); data = mdata_Visited_create(key, 1, M_DATA_STATE_PLAIN, recmail->bytes_in); } mhash_insert_sorted(stamail->sender, data); /* extract the domain part */ if ((domain = strchr(recmail->sender, '@')) != NULL) { domain++; if ((grouped = group_field(ext_conf, domain, M_MAIL_GROUP_DOMAIN))) { const char *key = splaytree_insert(ext_conf->strings, grouped); data = mdata_Visited_create(key, 1, M_DATA_STATE_PLAIN, recmail->bytes_in); free(grouped); } else { const char *key = splaytree_insert(ext_conf->strings, domain); data = mdata_Visited_create(key, 1, M_DATA_STATE_PLAIN, recmail->bytes_in); } mhash_insert_sorted(stamail->send_domain, data); } } } } } else if (recmail->ext_type == M_RECORD_TYPE_MAIL_QMAIL_STATUS) { mlogrec_mail_qmail_status *recqm = recmail->ext; if ((tm = localtime(&(record->timestamp)))) { stamail->qstat[tm->tm_mday-1][tm->tm_hour].local_cur += recqm->local_cur; stamail->qstat[tm->tm_mday-1][tm->tm_hour].local_max += recqm->local_max; stamail->qstat[tm->tm_mday-1][tm->tm_hour].remote_cur += recqm->remote_cur; stamail->qstat[tm->tm_mday-1][tm->tm_hour].remote_max += recqm->remote_max; stamail->qstat[tm->tm_mday-1][tm->tm_hour].deliver_cur += recqm->deliver_cur; stamail->qstat[tm->tm_mday-1][tm->tm_hour].queue_cur += recqm->queue_cur; stamail->qstat[tm->tm_mday-1][tm->tm_hour].count++; } } else { } if (recmail->ext_type == M_RECORD_TYPE_MAIL_VIRUS) { mlogrec_mail_virus *recvirus = recmail->ext; if (recvirus->virus) { const char *key = splaytree_insert(ext_conf->strings, recvirus->virus); data = mdata_Count_create(key, 1, M_DATA_STATE_PLAIN); mhash_insert_sorted(stamail->virus, data); } if (recvirus->subject) { const char *key = splaytree_insert(ext_conf->strings, recvirus->subject); data = mdata_Count_create(key, 1, M_DATA_STATE_PLAIN); mhash_insert_sorted(stamail->subject, data); } if (recvirus->scanner) { const char *key = splaytree_insert(ext_conf->strings, recvirus->scanner); data = mdata_Count_create(key, 1, M_DATA_STATE_PLAIN); mhash_insert_sorted(stamail->scanner, data); } } return 0; }