/* $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);
}