/* $Id: dspam_merge.c,v 1.158 2011/06/28 00:13:48 sbajic Exp $ */ /* DSPAM COPYRIGHT (C) 2002-2012 DSPAM PROJECT This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ #ifdef HAVE_CONFIG_H #include #endif #define DEBUG 1 #include #include #include #include #include #include #include #include #include #include #include #include "config.h" #include "util.h" #include "libdspam.h" #include "language.h" #include "read_config.h" #include "config_api.h" #define TSYNTAX "syntax: dspam_merge [user1] [user2] ... [userN] [-o user]" DSPAM_CTX *open_ctx, *open_mtx; void dieout (int signal); int main (int argc, char **argv) { char destuser[MAX_USERNAME_LENGTH]; struct nt *users = NULL; struct nt_node *node_nt; struct nt_c c_nt; struct _ds_storage_record *token; ds_diction_t merge1 = NULL; ds_diction_t merge2 = NULL; DSPAM_CTX *CTX, *MTX; ds_term_t ds_term; ds_cursor_t ds_c; long i; #ifndef _WIN32 #ifdef TRUSTED_USER_SECURITY struct passwd *p = getpwuid (getuid ()); #endif #endif /* Read dspam.conf */ agent_config = read_config(NULL); if (!agent_config) { LOG(LOG_ERR, ERR_AGENT_READ_CONFIG); fprintf (stderr, ERR_AGENT_READ_CONFIG "\n"); exit(EXIT_FAILURE); } if (!_ds_read_attribute(agent_config, "Home")) { LOG(LOG_ERR, ERR_AGENT_DSPAM_HOME); fprintf (stderr, ERR_AGENT_DSPAM_HOME "\n"); _ds_destroy_config(agent_config); exit(EXIT_FAILURE); } if (libdspam_init(_ds_read_attribute(agent_config, "StorageDriver")) != 0) { LOG(LOG_ERR, ERR_DRV_INIT); fprintf (stderr, ERR_DRV_INIT "\n"); _ds_destroy_config(agent_config); exit(EXIT_FAILURE); } #ifndef _WIN32 #ifdef TRUSTED_USER_SECURITY if (!_ds_match_attribute(agent_config, "Trust", p->pw_name) && p->pw_uid) { fprintf(stderr, ERR_TRUSTED_MODE "\n"); _ds_destroy_config(agent_config); goto bail; } #endif #endif if (argc < 4) { printf ("%s\n", TSYNTAX); _ds_destroy_config(agent_config); goto bail; } open_ctx = open_mtx = NULL; signal (SIGINT, dieout); signal (SIGPIPE, dieout); signal (SIGTERM, dieout); dspam_init_driver (NULL); users = nt_create (NT_CHAR); if (users == NULL) { fprintf (stderr, ERR_MEM_ALLOC); goto bail; } for (i = 1; i < argc; i++) { if (!strncmp (argv[i], "--profile=", 10)) { if (!_ds_match_attribute(agent_config, "Profile", argv[i]+10)) { LOG(LOG_ERR, ERR_AGENT_NO_SUCH_PROFILE, argv[i]+10); fprintf (stderr, ERR_AGENT_NO_SUCH_PROFILE "\n", argv[i]+10); goto bail; } else { _ds_overwrite_attribute(agent_config, "DefaultProfile", argv[i]+10); } continue; } if (!strcmp (argv[i], "-o")) { strlcpy (destuser, argv[i + 1], sizeof (destuser)); i += 1; continue; } nt_add (users, argv[i]); } #ifdef DEBUG fprintf(stderr, "Destination user: %s\n", destuser); #endif CTX = dspam_create (destuser, NULL, _ds_read_attribute(agent_config, "Home"), DSM_PROCESS, 0); open_ctx = CTX; if (CTX == NULL) { fprintf (stderr, "unable to initialize context: %s\n", strerror (errno)); goto bail; } set_libdspam_attributes(CTX); if (dspam_attach(CTX, NULL)) { LOG (LOG_WARNING, "unable to attach dspam context"); fprintf (stderr, "Unable to attach DSPAM context\n"); goto bail; } node_nt = c_nt_first (users, &c_nt); while (node_nt != NULL) { #ifdef DEBUG printf ("Merging user: %s\n", (const char *) node_nt->ptr); #endif merge1 = ds_diction_create(196613); merge2 = ds_diction_create(196613); if (users == NULL || merge1 == NULL || merge2 == NULL) { fprintf (stderr, ERR_MEM_ALLOC); goto bail; } MTX = dspam_create ((const char *) node_nt->ptr, NULL, _ds_read_attribute(agent_config, "Home"), DSM_CLASSIFY, 0); open_mtx = MTX; if (MTX == NULL) { fprintf (stderr, "unable to initialize context: %s\n", strerror (errno)); node_nt = c_nt_next (users, &c_nt); continue; } set_libdspam_attributes(MTX); if (dspam_attach(MTX, NULL)) { LOG (LOG_WARNING, "unable to attach dspam context"); fprintf (stderr, "Unable to attach DSPAM context\n"); goto bail; } CTX->totals.spam_learned += MTX->totals.spam_learned; CTX->totals.innocent_learned += MTX->totals.innocent_learned; token = _ds_get_nexttoken (MTX); while (token != NULL) { char tok[128]; snprintf(tok, 128, "%llu", token->token); ds_diction_touch (merge1, token->token, tok, 0); ds_diction_touch (merge2, token->token, tok, 0); token = _ds_get_nexttoken (MTX); } _ds_getall_spamrecords(CTX, merge1); _ds_getall_spamrecords(MTX, merge2); ds_c = ds_diction_cursor(merge2); ds_term = ds_diction_next(ds_c); i = 0; while(ds_term) { ds_term_t target = ds_diction_find(merge1, ds_term->key); if (target) { target->s.spam_hits += ds_term->s.spam_hits; target->s.innocent_hits += ds_term->s.innocent_hits; target->s.status |= TST_DIRTY; _ds_set_spamrecord(CTX, target->key, &target->s); } ds_term = ds_diction_next(ds_c); i++; } #ifdef DEBUG printf ("processed %ld tokens\n", i); #endif node_nt = c_nt_next (users, &c_nt); ds_diction_destroy(merge1); ds_diction_destroy(merge2); dspam_destroy (MTX); open_mtx = NULL; } #ifdef DEBUG printf ("storing merged tokens...\n"); #endif #ifdef DEBUG printf ("completed.\n"); #endif nt_destroy (users); dspam_destroy (CTX); open_ctx = NULL; dspam_shutdown_driver (NULL); _ds_destroy_config(agent_config); libdspam_shutdown(); exit (EXIT_SUCCESS); bail: if (merge1 != NULL) ds_diction_destroy(merge1); if (merge2 != NULL) ds_diction_destroy(merge2); if (open_ctx != NULL) dspam_destroy (open_ctx); if (open_mtx != NULL) dspam_destroy (open_mtx); dspam_shutdown_driver (NULL); if (users != NULL) nt_destroy(users); _ds_destroy_config(agent_config); libdspam_shutdown(); exit (EXIT_FAILURE); } void dieout (int signal) { signal = signal; /* Keep compile happy */ fprintf (stderr, "terminated.\n"); if (open_ctx != NULL) dspam_destroy (open_ctx); if (open_mtx != NULL) dspam_destroy (open_mtx); _ds_destroy_config(agent_config); exit (EXIT_SUCCESS); }