int main (int argc, char **argv) { struct rspamd_config *cfg; rspamd_main = (struct rspamd_main *)g_malloc (sizeof (struct rspamd_main)); memset (rspamd_main, 0, sizeof (struct rspamd_main)); rspamd_main->server_pool = rspamd_mempool_new (rspamd_mempool_suggest_size (), NULL); cfg = rspamd_config_new (); rspamd_main->cfg = cfg; cfg->cfg_pool = rspamd_mempool_new (rspamd_mempool_suggest_size (), NULL); cfg->log_type = RSPAMD_LOG_CONSOLE; cfg->log_level = G_LOG_LEVEL_INFO; rspamd_set_logger (cfg, g_quark_from_static_string("rspamd-test"), &rspamd_main->logger, rspamd_main->server_pool); (void)rspamd_log_open (rspamd_main->logger); g_test_init (&argc, &argv, NULL); cfg->libs_ctx = rspamd_init_libs (); base = event_init (); rspamd_stat_init (cfg, base); if (g_test_verbose ()) { cfg->log_level = G_LOG_LEVEL_DEBUG; rspamd_set_logger (cfg, g_quark_from_static_string("rspamd-test"), &rspamd_main->logger, rspamd_main->server_pool); (void)rspamd_log_reopen (rspamd_main->logger); } g_log_set_default_handler (rspamd_glib_log_function, rspamd_main->logger); g_test_add_func ("/rspamd/mem_pool", rspamd_mem_pool_test_func); g_test_add_func ("/rspamd/radix", rspamd_radix_test_func); g_test_add_func ("/rspamd/dns", rspamd_dns_test_func); g_test_add_func ("/rspamd/dkim", rspamd_dkim_test_func); g_test_add_func ("/rspamd/rrd", rspamd_rrd_test_func); g_test_add_func ("/rspamd/upstream", rspamd_upstream_test_func); g_test_add_func ("/rspamd/shingles", rspamd_shingles_test_func); g_test_add_func ("/rspamd/http", rspamd_http_test_func); g_test_add_func ("/rspamd/lua", rspamd_lua_test_func); g_test_add_func ("/rspamd/cryptobox", rspamd_cryptobox_test_func); g_test_add_func ("/rspamd/heap", rspamd_heap_test_func); #if 0 g_test_add_func ("/rspamd/url", rspamd_url_test_func); g_test_add_func ("/rspamd/statfile", rspamd_statfile_test_func); g_test_add_func ("/rspamd/aio", rspamd_async_test_func); #endif g_test_run (); g_mime_shutdown (); rspamd_regexp_library_finalize (); return 0; }
int main (int argc, char **argv) { gint i, start = 1, mode = MODE_NORMAL; struct rspamd_config *cfg; rspamd_logger_t *logger = NULL; if (argc > 2 && *argv[1] == '-') { start = 2; if (argv[1][1] == 'g') { mode = MODE_GMIME; } } cfg = rspamd_config_new (); cfg->libs_ctx = rspamd_init_libs (); cfg->log_type = RSPAMD_LOG_CONSOLE; rspamd_set_logger (cfg, g_quark_from_static_string ("mime"), &logger, NULL); (void) rspamd_log_open (logger); g_log_set_default_handler (rspamd_glib_log_function, logger); g_set_printerr_handler (rspamd_glib_printerr_function); rspamd_config_post_load (cfg, RSPAMD_CONFIG_INIT_LIBS|RSPAMD_CONFIG_INIT_URL|RSPAMD_CONFIG_INIT_NO_TLD); for (i = start; i < argc; i ++) { if (argv[i]) { rspamd_process_file (cfg, argv[i], mode); } } rspamd_printf ("Total time parsing: %.4f seconds\n", total_time); rspamd_log_close (logger); REF_RELEASE (cfg); return 0; }
struct rspamd_worker * rspamd_fork_worker (struct rspamd_main *rspamd_main, struct rspamd_worker_conf *cf, guint index, struct event_base *ev_base) { struct rspamd_worker *wrk; gint rc; struct rlimit rlim; /* Starting worker process */ wrk = (struct rspamd_worker *) g_malloc0 (sizeof (struct rspamd_worker)); if (!rspamd_socketpair (wrk->control_pipe)) { msg_err ("socketpair failure: %s", strerror (errno)); exit (-errno); } if (!rspamd_socketpair (wrk->srv_pipe)) { msg_err ("socketpair failure: %s", strerror (errno)); exit (-errno); } wrk->srv = rspamd_main; wrk->type = cf->type; wrk->cf = cf; REF_RETAIN (cf); wrk->index = index; wrk->ctx = cf->ctx; wrk->finish_actions = g_ptr_array_new (); wrk->pid = fork (); switch (wrk->pid) { case 0: /* Update pid for logging */ rspamd_log_update_pid (cf->type, rspamd_main->logger); /* Init PRNG after fork */ rc = ottery_init (rspamd_main->cfg->libs_ctx->ottery_cfg); if (rc != OTTERY_ERR_NONE) { msg_err_main ("cannot initialize PRNG: %d", rc); abort (); } rspamd_random_seed_fast (); #ifdef HAVE_EVUTIL_RNG_INIT evutil_secure_rng_init (); #endif /* Remove the inherited event base */ event_reinit (rspamd_main->ev_base); event_base_free (rspamd_main->ev_base); /* Drop privilleges */ rspamd_worker_drop_priv (rspamd_main); /* Set limits */ rspamd_worker_set_limits (rspamd_main, cf); /* Re-set stack limit */ getrlimit (RLIMIT_STACK, &rlim); rlim.rlim_cur = 100 * 1024 * 1024; rlim.rlim_max = rlim.rlim_cur; setrlimit (RLIMIT_STACK, &rlim); setproctitle ("%s process", cf->worker->name); rspamd_pidfile_close (rspamd_main->pfh); /* Do silent log reopen to avoid collisions */ rspamd_log_close (rspamd_main->logger); rspamd_log_open (rspamd_main->logger); wrk->start_time = rspamd_get_calendar_ticks (); #if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION <= 30)) # if (GLIB_MINOR_VERSION > 20) /* Ugly hack for old glib */ if (!g_thread_get_initialized ()) { g_thread_init (NULL); } # else g_thread_init (NULL); # endif #endif msg_info_main ("starting %s process %P (%d)", cf->worker->name, getpid (), index); /* Close parent part of socketpair */ close (wrk->control_pipe[0]); close (wrk->srv_pipe[0]); rspamd_socket_nonblocking (wrk->control_pipe[1]); rspamd_socket_nonblocking (wrk->srv_pipe[1]); /* Execute worker */ cf->worker->worker_start_func (wrk); exit (EXIT_FAILURE); break; case -1: msg_err_main ("cannot fork main process. %s", strerror (errno)); rspamd_pidfile_remove (rspamd_main->pfh); exit (-errno); break; default: /* Close worker part of socketpair */ close (wrk->control_pipe[1]); close (wrk->srv_pipe[1]); rspamd_socket_nonblocking (wrk->control_pipe[0]); rspamd_socket_nonblocking (wrk->srv_pipe[0]); rspamd_srv_start_watching (wrk, ev_base); /* Insert worker into worker's table, pid is index */ g_hash_table_insert (rspamd_main->workers, GSIZE_TO_POINTER ( wrk->pid), wrk); break; } return wrk; }
gint main (gint argc, gchar **argv, gchar **env) { GError *error = NULL; GOptionContext *context; GOptionGroup *og; struct rspamd_config *cfg; GQuark process_quark; gchar **nargv, **targv; const gchar *cmd_name; const struct rspamadm_command *cmd; gint i, nargc, targc; ucl_vars = g_hash_table_new_full (rspamd_strcase_hash, rspamd_strcase_equal, g_free, g_free); process_quark = g_quark_from_static_string ("rspamadm"); cfg = rspamd_config_new (); cfg->libs_ctx = rspamd_init_libs (); rspamd_main = g_malloc0 (sizeof (*rspamd_main)); rspamd_main->cfg = cfg; rspamd_main->pid = getpid (); rspamd_main->type = process_quark; rspamd_main->server_pool = rspamd_mempool_new (rspamd_mempool_suggest_size (), "rspamadm"); cfg->log_level = G_LOG_LEVEL_WARNING; cfg->log_type = RSPAMD_LOG_CONSOLE; rspamd_set_logger (cfg, process_quark, rspamd_main); (void) rspamd_log_open (rspamd_main->logger); g_log_set_default_handler (rspamd_glib_log_function, rspamd_main->logger); g_set_printerr_handler (rspamd_glib_printerr_function); rspamd_config_post_load (cfg, FALSE); /* Setup logger */ if (verbose) { cfg->log_level = G_LOG_LEVEL_DEBUG; } else { cfg->log_level = G_LOG_LEVEL_INFO; } gperf_profiler_init (cfg, "rspamadm"); setproctitle ("rspamdadm"); /* Now read options and store everything till the first non-dash argument */ nargv = g_malloc0 (sizeof (gchar *) * (argc + 1)); nargv[0] = g_strdup (argv[0]); for (i = 1, nargc = 1; i < argc; i ++) { if (argv[i] && argv[i][0] == '-') { /* Copy to nargv */ nargv[nargc] = g_strdup (argv[i]); nargc ++; } else { break; } } context = g_option_context_new ("command - rspamd administration utility"); og = g_option_group_new ("global", "global options", "global options", NULL, NULL); g_option_context_set_help_enabled (context, FALSE); g_option_group_add_entries (og, entries); g_option_context_set_summary (context, "Summary:\n Rspamd administration utility version " RVERSION "\n Release id: " RID); g_option_context_set_main_group (context, og); targv = nargv; targc = nargc; if (!g_option_context_parse (context, &targc, &targv, &error)) { fprintf (stderr, "option parsing failed: %s\n", error->message); g_error_free (error); exit (1); } g_strfreev (nargv); if (show_version) { rspamadm_version (); exit (EXIT_SUCCESS); } if (show_help) { rspamadm_usage (context); exit (EXIT_SUCCESS); } if (list_commands) { rspamadm_commands (); exit (EXIT_SUCCESS); } cmd_name = argv[nargc]; if (cmd_name == NULL) { cmd_name = "help"; } cmd = rspamadm_search_command (cmd_name); if (cmd == NULL) { fprintf (stderr, "Invalid command name: %s\n", cmd_name); exit (EXIT_FAILURE); } if (nargc < argc) { nargv = g_malloc0 (sizeof (gchar *) * (argc - nargc + 1)); nargv[0] = g_strdup_printf ("%s %s", argv[0], cmd_name); for (i = 1; i < argc - nargc; i ++) { nargv[i] = g_strdup (argv[i + nargc]); } targc = argc - nargc; targv = nargv; cmd->run (targc, targv); g_strfreev (nargv); } else { cmd->run (0, NULL); } rspamd_log_close (rspamd_main->logger); REF_RELEASE (rspamd_main->cfg); g_free (rspamd_main); return 0; }
struct rspamd_worker * rspamd_fork_worker (struct rspamd_main *rspamd_main, struct rspamd_worker_conf *cf, guint index) { struct rspamd_worker *cur; /* Starting worker process */ cur = (struct rspamd_worker *) g_malloc0 (sizeof (struct rspamd_worker)); if (!rspamd_socketpair (cur->control_pipe)) { msg_err ("socketpair failure: %s", strerror (errno)); exit (-errno); } cur->srv = rspamd_main; cur->type = cf->type; cur->cf = g_malloc (sizeof (struct rspamd_worker_conf)); memcpy (cur->cf, cf, sizeof (struct rspamd_worker_conf)); cur->index = index; cur->ctx = cf->ctx; cur->pid = fork (); switch (cur->pid) { case 0: /* Update pid for logging */ rspamd_log_update_pid (cf->type, rspamd_main->logger); /* Lock statfile pool if possible XXX */ /* Init PRNG after fork */ ottery_init (NULL); g_random_set_seed (ottery_rand_uint32 ()); /* Drop privilleges */ rspamd_worker_drop_priv (rspamd_main); /* Set limits */ rspamd_worker_set_limits (rspamd_main, cf); setproctitle ("%s process", cf->worker->name); rspamd_pidfile_close (rspamd_main->pfh); /* Do silent log reopen to avoid collisions */ rspamd_log_close (rspamd_main->logger); rspamd_log_open (rspamd_main->logger); cur->start_time = rspamd_get_calendar_ticks (); #if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION <= 30)) # if (GLIB_MINOR_VERSION > 20) /* Ugly hack for old glib */ if (!g_thread_get_initialized ()) { g_thread_init (NULL); } # else g_thread_init (NULL); # endif #endif msg_info_main ("starting %s process %P", cf->worker->name, getpid ()); /* Close parent part of socketpair */ close (cur->control_pipe[0]); rspamd_socket_nonblocking (cur->control_pipe[1]); /* Execute worker */ cf->worker->worker_start_func (cur); break; case -1: msg_err_main ("cannot fork main process. %s", strerror (errno)); rspamd_pidfile_remove (rspamd_main->pfh); exit (-errno); break; default: /* Close worker part of socketpair */ close (cur->control_pipe[1]); rspamd_socket_nonblocking (cur->control_pipe[0]); /* Insert worker into worker's table, pid is index */ g_hash_table_insert (rspamd_main->workers, GSIZE_TO_POINTER ( cur->pid), cur); break; } return cur; }