END_TEST START_TEST(test_mgr_clear) { bloom_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); bloom_filtmgr *mgr; res = init_filter_manager(&config, &mgr); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "dub2", NULL); fail_unless(res == 0); res = filtmgr_unmap_filter(mgr, "dub2"); fail_unless(res == 0); // Should be not proxied still res = filtmgr_clear_filter(mgr, "dub2"); fail_unless(res == 0); // Force a vacuum filtmgr_vacuum(mgr); res = filtmgr_create_filter(mgr, "dub2", NULL); fail_unless(res == 0); res = filtmgr_drop_filter(mgr, "dub2"); fail_unless(res == 0); res = destroy_filter_manager(mgr); fail_unless(res == 0); }
END_TEST /* Scale up */ START_TEST(test_mgr_grow) { bloom_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); config.in_memory = 1; config.initial_capacity = 10000; bloom_filtmgr *mgr; res = init_filter_manager(&config, &mgr); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "scale1", NULL); fail_unless(res == 0); // Try to add keys now char *keys[10]; char result[10]; for (int iter=0;iter<10000;iter++) { // Generate the keys for (int i=0;i<10;i++) asprintf(&keys[i], "test_key_%d", i*iter); res = filtmgr_set_keys(mgr, "scale1", (char**)&keys, 10, (char*)&result); fail_unless(res == 0); for (int i=0;i<10;i++) free(keys[i]); } res = filtmgr_drop_filter(mgr, "scale1"); fail_unless(res == 0); res = destroy_filter_manager(mgr); fail_unless(res == 0); }
END_TEST START_TEST(test_config_empty_file) { int fh = open("/tmp/zero_file", O_CREAT|O_RDWR, 0777); fchmod(fh, 777); close(fh); statsite_config config; int res = config_from_filename("/tmp/zero_file", &config); fail_unless(res == 0); // Should get the defaults... fail_unless(config.tcp_port == 8125); fail_unless(config.udp_port == 8125); fail_unless(strcmp(config.log_level, "DEBUG") == 0); fail_unless(config.syslog_log_level == LOG_DEBUG); fail_unless(config.timer_eps == 1e-2); fail_unless(strcmp(config.stream_cmd, "cat") == 0); fail_unless(config.flush_interval == 10); fail_unless(config.daemonize == false); fail_unless(config.binary_stream == false); fail_unless(strcmp(config.pid_file, "/var/run/statsite.pid") == 0); fail_unless(config.input_counter == NULL); unlink("/tmp/zero_file"); }
END_TEST START_TEST(test_mgr_check_no_keys) { bloom_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); bloom_filtmgr *mgr; res = init_filter_manager(&config, &mgr); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "zab2", NULL); fail_unless(res == 0); char *keys[] = {"hey","there","person"}; char result[] = {1, 1, 1}; res = filtmgr_check_keys(mgr, "zab2", (char**)&keys, 3, (char*)&result); fail_unless(res == 0); fail_unless(!result[0]); fail_unless(!result[1]); fail_unless(!result[2]); res = filtmgr_drop_filter(mgr, "zab2"); fail_unless(res == 0); res = destroy_filter_manager(mgr); fail_unless(res == 0); }
END_TEST /* Custom config */ START_TEST(test_mgr_create_custom_config) { bloom_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); bloom_filtmgr *mgr; res = init_filter_manager(&config, &mgr); fail_unless(res == 0); // Custom config bloom_config *custom = malloc(sizeof(bloom_config)); memcpy(custom, &config, sizeof(bloom_config)); custom->in_memory = 1; res = filtmgr_create_filter(mgr, "custom1", custom); fail_unless(res == 0); res = filtmgr_drop_filter(mgr, "custom1"); fail_unless(res == 0); res = destroy_filter_manager(mgr); fail_unless(res == 0); }
END_TEST START_TEST(test_mgr_list_cold) { bloom_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); bloom_filtmgr *mgr; res = init_filter_manager(&config, &mgr); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "zab6", NULL); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "zab7", NULL); fail_unless(res == 0); bloom_filter_list_head *head; res = filtmgr_list_cold_filters(mgr, &head); fail_unless(res == 0); fail_unless(head->size == 0); // Check the keys in one, so that it stays hot char *keys[] = {"hey","there","person"}; char result[] = {0, 0, 0}; res = filtmgr_set_keys(mgr, "zab6", (char**)&keys, 3, (char*)&result); fail_unless(res == 0); fail_unless(result[0]); fail_unless(result[1]); fail_unless(result[2]); // Check cold again res = filtmgr_list_cold_filters(mgr, &head); fail_unless(res == 0); fail_unless(head->size == 1); int has_zab6 = 0; int has_zab7 = 0; bloom_filter_list *node = head->head; while (node) { if (strcmp(node->filter_name, "zab6") == 0) has_zab6 = 1; else if (strcmp(node->filter_name, "zab7") == 0) has_zab7 = 1; node = node->next; } fail_unless(!has_zab6); fail_unless(has_zab7); res = filtmgr_drop_filter(mgr, "zab6"); fail_unless(res == 0); res = filtmgr_drop_filter(mgr, "zab7"); fail_unless(res == 0); filtmgr_cleanup_list(head); res = destroy_filter_manager(mgr); fail_unless(res == 0); }
END_TEST START_TEST(test_mgr_clear_reload) { bloom_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); bloom_filtmgr *mgr; res = init_filter_manager(&config, &mgr); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "zab9", NULL); fail_unless(res == 0); // Try to add keys now char *keys[] = {"hey","there","person"}; char result[] = {0, 0, 0}; res = filtmgr_set_keys(mgr, "zab9", (char**)&keys, 3, (char*)&result); fail_unless(res == 0); fail_unless(result[0]); fail_unless(result[1]); fail_unless(result[2]); res = filtmgr_unmap_filter(mgr, "zab9"); fail_unless(res == 0); // F*****G annoying umask permissions bullshit // Cused by the Check test framework fail_unless(chmod("/tmp/bloomd/bloomd.zab9/config.ini", 0777) == 0); fail_unless(chmod("/tmp/bloomd/bloomd.zab9/data.000.mmap", 0777) == 0); res = filtmgr_clear_filter(mgr, "zab9"); fail_unless(res == 0); // Force a vacuum filtmgr_vacuum(mgr); // This should rediscover res = filtmgr_create_filter(mgr, "zab9", NULL); fail_unless(res == 0); // Try to check keys now res = filtmgr_check_keys(mgr, "zab9", (char**)&keys, 3, (char*)&result); fail_unless(res == 0); fail_unless(result[0]); fail_unless(result[1]); fail_unless(result[2]); res = filtmgr_drop_filter(mgr, "zab9"); fail_unless(res == 0); res = destroy_filter_manager(mgr); fail_unless(res == 0); }
END_TEST START_TEST(test_validate_default_config) { statsite_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); res = validate_config(&config); fail_unless(res == 0); }
END_TEST /* Close & Restore */ START_TEST(test_mgr_restore) { bloom_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); bloom_filtmgr *mgr; res = init_filter_manager(&config, &mgr); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "zab8", NULL); fail_unless(res == 0); char *keys[] = {"hey","there","person"}; char result[] = {0, 0, 0}; res = filtmgr_set_keys(mgr, "zab8", (char**)&keys, 3, (char*)&result); fail_unless(res == 0); fail_unless(result[0]); fail_unless(result[1]); fail_unless(result[2]); // Shutdown res = destroy_filter_manager(mgr); fail_unless(res == 0); // F*****G annoying umask permissions bullshit // Cused by the Check test framework fail_unless(chmod("/tmp/bloomd/bloomd.zab8/config.ini", 0777) == 0); fail_unless(chmod("/tmp/bloomd/bloomd.zab8/data.000.mmap", 0777) == 0); // Restrore res = init_filter_manager(&config, &mgr); fail_unless(res == 0); for (int i=0;i<3;i++) result[i] = 0; res = filtmgr_check_keys(mgr, "zab8", (char**)&keys, 3, (char*)&result); fail_unless(res == 0); fail_unless(result[0]); fail_unless(result[1]); fail_unless(result[2]); res = filtmgr_drop_filter(mgr, "zab8"); fail_unless(res == 0); res = destroy_filter_manager(mgr); fail_unless(res == 0); }
END_TEST START_TEST(test_validate_bad_config) { statsite_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); // Set an absurd eps, should fail config.timer_eps = 1.0; res = validate_config(&config); fail_unless(res == 1); }
END_TEST START_TEST(test_mgr_list_prefix) { bloom_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); bloom_filtmgr *mgr; res = init_filter_manager(&config, 0, &mgr); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "bar1", NULL); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "bar2", NULL); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "zyx", NULL); fail_unless(res == 0); bloom_filter_list_head *head; res = filtmgr_list_filters(mgr, "bar", &head); fail_unless(res == 0); fail_unless(head->size == 2); int has_bar1 = 0; int has_bar2 = 0; bloom_filter_list *node = head->head; while (node) { if (strcmp(node->filter_name, "bar1") == 0) has_bar1 = 1; else if (strcmp(node->filter_name, "bar2") == 0) has_bar2 = 1; node = node->next; } fail_unless(has_bar1); fail_unless(has_bar2); res = filtmgr_drop_filter(mgr, "bar1"); fail_unless(res == 0); res = filtmgr_drop_filter(mgr, "bar2"); fail_unless(res == 0); res = filtmgr_drop_filter(mgr, "zyx"); fail_unless(res == 0); filtmgr_cleanup_list(head); res = destroy_filter_manager(mgr); fail_unless(res == 0); }
END_TEST /* Clear command */ START_TEST(test_mgr_clear_no_filter) { bloom_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); bloom_filtmgr *mgr; res = init_filter_manager(&config, &mgr); fail_unless(res == 0); res = filtmgr_clear_filter(mgr, "noop2"); fail_unless(res == -1); res = destroy_filter_manager(mgr); fail_unless(res == 0); }
END_TEST /* Flush */ START_TEST(test_mgr_flush_no_filter) { bloom_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); bloom_filtmgr *mgr; res = init_filter_manager(&config, 0, &mgr); fail_unless(res == 0); res = filtmgr_flush_filter(mgr, "noop1"); fail_unless(res == -1); res = destroy_filter_manager(mgr); fail_unless(res == 0); }
END_TEST /* Unmap in memory */ START_TEST(test_mgr_unmap_in_mem) { bloom_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); config.in_memory = 1; bloom_filtmgr *mgr; res = init_filter_manager(&config, &mgr); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "mem1", NULL); fail_unless(res == 0); // Try to add keys now char *keys[] = {"hey","there","person"}; char result[] = {0, 0, 0}; res = filtmgr_set_keys(mgr, "mem1", (char**)&keys, 3, (char*)&result); fail_unless(res == 0); fail_unless(result[0]); fail_unless(result[1]); fail_unless(result[2]); res = filtmgr_unmap_filter(mgr, "mem1"); fail_unless(res == 0); // Try to add keys now for (int i=0;i<3;i++) result[i] = 0; res = filtmgr_check_keys(mgr, "mem1", (char**)&keys, 3, (char*)&result); fail_unless(res == 0); fail_unless(result[0]); fail_unless(result[1]); fail_unless(result[2]); res = filtmgr_drop_filter(mgr, "mem1"); fail_unless(res == 0); res = destroy_filter_manager(mgr); fail_unless(res == 0); }
END_TEST START_TEST(test_config_bad_file) { statsite_config config; int res = config_from_filename("/tmp/does_not_exist", &config); fail_unless(res == -ENOENT); // Should get the defaults... fail_unless(config.tcp_port == 8125); fail_unless(config.udp_port == 8125); fail_unless(strcmp(config.log_level, "DEBUG") == 0); fail_unless(config.syslog_log_level == LOG_DEBUG); fail_unless(config.timer_eps == 1e-2); fail_unless(strcmp(config.stream_cmd, "cat") == 0); fail_unless(config.flush_interval == 10); fail_unless(config.daemonize == false); fail_unless(config.binary_stream == false); fail_unless(strcmp(config.pid_file, "/var/run/statsite.pid") == 0); fail_unless(config.input_counter == NULL); }
END_TEST START_TEST(test_build_radix) { statsite_config config; int res = config_from_filename(NULL, &config); histogram_config c1 = {"foo", 100, 200, 10, 0, NULL, 0}; histogram_config c2 = {"bar", 100, 200, 10, 0, NULL, 0}; histogram_config c3 = {"baz", 100, 200, 10, 0, NULL, 0}; config.hist_configs = &c1; c1.next = &c2; c2.next = &c3; fail_unless(build_prefix_tree(&config) == 0); fail_unless(config.histograms != NULL); histogram_config *conf = NULL; fail_unless(radix_search(config.histograms, "baz", (void**)&conf) == 0); fail_unless(conf == &c3); }
END_TEST START_TEST(test_mgr_list_no_filters) { bloom_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); bloom_filtmgr *mgr; res = init_filter_manager(&config, &mgr); fail_unless(res == 0); bloom_filter_list_head *head; res = filtmgr_list_filters(mgr, &head); fail_unless(res == 0); fail_unless(head->size == 0); filtmgr_cleanup_list(head); res = destroy_filter_manager(mgr); fail_unless(res == 0); }
END_TEST START_TEST(test_mgr_create_drop) { bloom_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); bloom_filtmgr *mgr; res = init_filter_manager(&config, &mgr); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "foo1", NULL); fail_unless(res == 0); res = filtmgr_drop_filter(mgr, "foo1"); fail_unless(res == 0); res = destroy_filter_manager(mgr); fail_unless(res == 0); }
END_TEST START_TEST(test_config_basic_config) { int fh = open("/tmp/basic_config", O_CREAT|O_RDWR, 0777); char *buf = "[statsite]\n\ port = 10000\n\ udp_port = 10001\n\ flush_interval = 120\n\ timer_eps = 0.005\n\ set_eps = 0.03\n\ stream_cmd = foo\n\ log_level = INFO\n\ daemonize = true\n\ binary_stream = true\n\ input_counter = foobar\n\ pid_file = /tmp/statsite.pid\n"; write(fh, buf, strlen(buf)); fchmod(fh, 777); close(fh); statsite_config config; int res = config_from_filename("/tmp/basic_config", &config); fail_unless(res == 0); // Should get the config fail_unless(config.tcp_port == 10000); fail_unless(config.udp_port == 10001); fail_unless(strcmp(config.log_level, "INFO") == 0); fail_unless(config.timer_eps == 0.005); fail_unless(config.set_eps == 0.03); fail_unless(strcmp(config.stream_cmd, "foo") == 0); fail_unless(config.flush_interval == 120); fail_unless(config.daemonize == true); fail_unless(config.binary_stream == true); fail_unless(strcmp(config.pid_file, "/tmp/statsite.pid") == 0); fail_unless(strcmp(config.input_counter, "foobar") == 0); unlink("/tmp/basic_config"); }
END_TEST START_TEST(test_mgr_add_check_keys) { bloom_config config; int res = config_from_filename(NULL, &config); fail_unless(res == 0); bloom_filtmgr *mgr; res = init_filter_manager(&config, 0, &mgr); fail_unless(res == 0); res = filtmgr_create_filter(mgr, "zab1", NULL); fail_unless(res == 0); char *keys[] = {"hey","there","person"}; char result[] = {0, 0, 0}; res = filtmgr_set_keys(mgr, "zab1", (char**)&keys, 3, (char*)&result); fail_unless(res == 0); fail_unless(result[0]); fail_unless(result[1]); fail_unless(result[2]); for (int i=0;i<3;i++) result[i] = 0; res = filtmgr_check_keys(mgr, "zab1", (char**)&keys, 3, (char*)&result); fail_unless(res == 0); fail_unless(result[0]); fail_unless(result[1]); fail_unless(result[2]); res = filtmgr_drop_filter(mgr, "zab1"); fail_unless(res == 0); res = destroy_filter_manager(mgr); fail_unless(res == 0); }
int main(int argc, char **argv) { // temporarily set the syslog facilty to main and init it setup_syslog(LOG_USER, 0); // Parse the command line char *config_file = NULL; int parse_res = parse_cmd_line_args(argc, argv, &config_file); if (parse_res) return 1; // Parse the config file statsite_config *config = alloc_config(); int config_res = config_from_filename(config_file, config); if (config_res != 0) { syslog(LOG_ERR, "Failed to read the configuration file!"); return 1; } // Validate the config file if (validate_config(config)) { syslog(LOG_ERR, "Invalid configuration!"); return 1; } // close the initial syslog closelog(); // Initialize syslog with configured facility setup_syslog(config->syslog_log_facility, config->daemonize); // Set prefixes for each message type if (prepare_prefixes(config)) { syslog(LOG_ERR, "Failed to get prefixes!"); return 1; } // Build the prefix tree if (build_prefix_tree(config)) { syslog(LOG_ERR, "Failed to build prefix tree!"); return 1; } // Set the syslog mask setlogmask(config->syslog_log_level); // Initialize libcurl curl_global_init(CURL_GLOBAL_DEFAULT); // Daemonize if (config->daemonize) { pid_t pid, sid; int fd; syslog(LOG_INFO, "Daemonizing."); pid = fork(); // Exit if we failed to fork if (pid < 0) { syslog(LOG_ERR, "Failed to fork() daemon!"); return 1; } // Parent process returns if (pid) return 0; // Create a new session sid = setsid(); if (sid < 0) { syslog(LOG_ERR, "Failed to set daemon SID!"); return 1; } int write_pidfile_res = write_pidfile(config->pid_file, sid); if (write_pidfile_res) { syslog(LOG_ERR, "Failed to write pidfile. Terminating."); return 1; } if ((fd = open("/dev/null", O_RDWR, 0)) != -1) { dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); if (fd > STDERR_FILENO) close(fd); } } // Log that we are starting up syslog(LOG_INFO, "Starting statsite."); // Build the sinks sink* sinks = NULL; init_sinks(&sinks, config); // Initialize the networking statsite_networking *netconf = NULL; int net_res = init_networking(config, &netconf, sinks); if (net_res != 0) { syslog(LOG_ERR, "Failed to initialize networking!"); return 1; } // Setup signal handlers signal(SIGPIPE, SIG_IGN); // Ignore SIG_IGN signal(SIGHUP, SIG_IGN); // Ignore SIG_IGN signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); // Join the networking loop, blocks until exit enter_networking_loop(netconf, &SIGNUM); if (SIGNUM != 0) { syslog(LOG_WARNING, "Received signal [%s]! Exiting...", strsignal(SIGNUM)); } // Begin the shutdown/cleanup shutdown_networking(netconf); // Do the final flush final_flush(sinks); // If daemonized, remove the pid file if (config->daemonize && unlink(config->pid_file)) { syslog(LOG_ERR, "Failed to delete pid file!"); } // Free our memory free_config(config); // Tear down libcurl curl_global_cleanup(); // Done return 0; }
END_TEST START_TEST(test_config_histograms) { int fh = open("/tmp/histogram_basic", O_CREAT|O_RDWR, 0777); char *buf = "[statsite]\n\ port = 10000\n\ udp_port = 10001\n\ flush_interval = 120\n\ timer_eps = 0.005\n\ stream_cmd = foo\n\ log_level = INFO\n\ daemonize = true\n\ binary_stream = true\n\ input_counter = foobar\n\ pid_file = /tmp/statsite.pid\n\ \n\ [histogram_n1]\n\ prefix=api.\n\ min=0\n\ max=100\n\ width=10\n\ \n\ [histogram_n2]\n\ prefix=site.\n\ min=0\n\ max=200\n\ width=10\n\ \n\ [histogram_n3]\n\ prefix=\n\ min=-500\n\ max=500\n\ width=25\n\ \n\ "; write(fh, buf, strlen(buf)); fchmod(fh, 777); close(fh); statsite_config config; int res = config_from_filename("/tmp/histogram_basic", &config); fail_unless(res == 0); // Should get the config fail_unless(config.tcp_port == 10000); fail_unless(config.udp_port == 10001); fail_unless(strcmp(config.log_level, "INFO") == 0); fail_unless(config.timer_eps == 0.005); fail_unless(strcmp(config.stream_cmd, "foo") == 0); fail_unless(config.flush_interval == 120); fail_unless(config.daemonize == true); fail_unless(config.binary_stream == true); fail_unless(strcmp(config.pid_file, "/tmp/statsite.pid") == 0); fail_unless(strcmp(config.input_counter, "foobar") == 0); histogram_config *c = config.hist_configs; fail_unless(c != NULL); fail_unless(strcmp(c->prefix, "") == 0); fail_unless(c->min_val == -500); fail_unless(c->max_val == 500); fail_unless(c->bin_width == 25); c = c->next; fail_unless(strcmp(c->prefix, "site.") == 0); fail_unless(c->min_val == 0); fail_unless(c->max_val == 200); fail_unless(c->bin_width == 10); c = c->next; fail_unless(strcmp(c->prefix, "api.") == 0); fail_unless(c->min_val == 0); fail_unless(c->max_val == 100); fail_unless(c->bin_width == 10); unlink("/tmp/histogram_basic"); }
int main(int argc, char **argv) { // Initialize syslog setup_syslog(); // Parse the command line char *config_file = NULL; int parse_res = parse_cmd_line_args(argc, argv, &config_file); if (parse_res) return 1; // Parse the config file statsite_config *config = calloc(1, sizeof(statsite_config)); int config_res = config_from_filename(config_file, config); if (config_res != 0) { syslog(LOG_ERR, "Failed to read the configuration file!"); return 1; } // Validate the config file if (validate_config(config)) { syslog(LOG_ERR, "Invalid configuration!"); return 1; } // Set prefixes for each message type if (prepare_prefixes(config)) { syslog(LOG_ERR, "Failed to get prefixes!"); return 1; } // Build the prefix tree if (build_prefix_tree(config)) { syslog(LOG_ERR, "Failed to build prefix tree!"); return 1; } // Set the syslog mask setlogmask(config->syslog_log_level); // Daemonize if (config->daemonize) { pid_t pid, sid; int fd; syslog(LOG_INFO, "Daemonizing."); pid = fork(); // Exit if we failed to fork if (pid < 0) { syslog(LOG_ERR, "Failed to fork() daemon!"); return 1; } // Parent process returns if (pid) return 0; // Create a new session sid = setsid(); if (sid < 0) { syslog(LOG_ERR, "Failed to set daemon SID!"); return 1; } int write_pidfile_res = write_pidfile(config->pid_file, sid); if (write_pidfile_res) { syslog(LOG_ERR, "Failed to write pidfile. Terminating."); return 1; } if ((fd = open("/dev/null", O_RDWR, 0)) != -1) { dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); if (fd > STDERR_FILENO) close(fd); } } // Log that we are starting up syslog(LOG_INFO, "Starting statsite."); // Initialize the networking statsite_networking *netconf = NULL; int net_res = init_networking(config, &netconf); if (net_res != 0) { syslog(LOG_ERR, "Failed to initialize networking!"); return 1; } // Setup signal handlers signal(SIGPIPE, SIG_IGN); // Ignore SIG_IGN signal(SIGHUP, SIG_IGN); // Ignore SIG_IGN signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); // Join the networking loop, blocks until exit enter_networking_loop(netconf, &SHOULD_RUN); // Begin the shutdown/cleanup shutdown_networking(netconf); // Do the final flush final_flush(); // If daemonized, remove the pid file if (config->daemonize && unlink(config->pid_file)) { syslog(LOG_ERR, "Failed to delete pid file!"); } // Free our memory free(config); // Done return 0; }
int main(int argc, char *argv[]) { int err; int max_descr; fd_set sock_set; struct timeval select_timeout; int running = 1; irc_connection con; unsigned irc_port; char *irc_server; conf = config_from_filename("ircb.conf"); assert(conf); if (argc == 3) { irc_server = argv[1]; irc_port = atoi(argv[2]); } if (argc == 2) { irc_server = argv[1]; irc_port = 6667; } else if (argc == 1) { config_group *g = config_get_group(conf, "irc"); irc_server = Conf("server", "INVALID"); if (!strcmp(irc_server, "INVALID")) { Printerr("No IRC server address given!\n"); return 1; } char *portstr = Conf("port", "6667"); assert(irc_server && portstr); irc_port = atoi(portstr); } else return 1; err = irc_connect(&con, irc_server, irc_port); if (err) { Printerr("Got no connection to IRC server!\n"); return 1; } module_load_module_dir(&con, conf); config_group *g = config_get_group(conf, "bot"); irc_set_nick(&con, Conf("nickname", "cbot")); irc_set_user(&con, Conf("username", "cbot_user"), Conf("hostname", "cbot_host"), Conf("servername", "cbot_server"), Conf("realname", "The CBot!")); max_descr = MAX(STDIN_FILENO, con.sockfd) + 1; while (running) { FD_ZERO(&sock_set); FD_SET(STDIN_FILENO, &sock_set); FD_SET(con.sockfd, &sock_set); select_timeout.tv_sec = 120; select_timeout.tv_usec = 0; err = select(max_descr, &sock_set, NULL, NULL, &select_timeout); if (!err) { /* Handle timeout */ } if (FD_ISSET(con.sockfd, &sock_set)) /* Incoming data from IRC network */ running = !handle_irc_messages(&con); if (FD_ISSET(STDIN_FILENO, &sock_set)) /* Local user input */ running = handle_keyboard_input(&con) != -2; } module_unload_all(&con); irc_close(&con, "bye."); return 0; }
int main(int argc, char **argv) { // Initialize syslog setup_syslog(); // Parse the command line char *config_file = NULL; int parse_res = parse_cmd_line_args(argc, argv, &config_file); if (parse_res) return 1; // Parse the config file statsite_proxy_config *config = calloc(1, sizeof(statsite_proxy_config)); int config_res = config_from_filename(config_file, config); if (config_res != 0) { syslog(LOG_ERR, "Failed to read the configuration file!"); return 1; } // Validate the config file int validate_res = validate_config(config); if (validate_res != 0) { syslog(LOG_ERR, "Invalid configuration!"); return 1; } // Set the syslog mask setlogmask(config->syslog_log_level); // Daemonize if (config->daemonize) { pid_t pid, sid; syslog(LOG_INFO, "Daemonizing."); pid = fork(); // Exit if we failed to fork if (pid < 0) { syslog(LOG_ERR, "Failed to fork() daemon!"); return 1; } // Parent process returns if (pid) return 0; // Create a new session sid = setsid(); if (sid < 0) { syslog(LOG_ERR, "Failed to set daemon SID!"); return 1; } int write_pidfile_res = write_pidfile(config->pid_file, sid); if (write_pidfile_res) { syslog(LOG_ERR, "Failed to write pidfile. Terminating."); return 1; } close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); } // Log that we are starting up syslog(LOG_INFO, "Starting statsite-proxy."); syslog(LOG_INFO, "Loaded Servers config: %s", config->servers); // Initialize proxy proxy *proxy = NULL; int proxy_res = proxy_init(&proxy, config->servers); if (proxy_res != 0) { syslog(LOG_ERR, "Failed to initialize proxy!"); return 1; } // Initialize the networking statsite_proxy_networking *netconf = NULL; int net_res = init_networking(config, &netconf, proxy); if (net_res != 0) { syslog(LOG_ERR, "Failed to initialize networking!"); return 1; } // Start the network workers pthread_t thread; pthread_create(&thread, NULL, (void*(*)(void*))start_networking_worker, netconf); /** * Loop forever, until we get a signal that * indicates we should shutdown. */ signal(SIGPIPE, SIG_IGN); // Ignore SIG_IGN signal(SIGHUP, SIG_IGN); // Ignore SIG_IGN signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); while (SHOULD_RUN) { sleep(1); } // Begin the shutdown/cleanup shutdown_networking(netconf); // If daemonized, remove the pid file if (config->daemonize && unlink(config->pid_file)) { syslog(LOG_ERR, "Failed to delete pid file!"); } // Free our memory proxy_destroy(proxy); free(config); // Done return 0; }