/* * uhub - A tiny ADC p2p connection hub * Copyright (C) 2007-2014, Jan Vidar Krey * * 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 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "adcclient.h" static struct ADC_user g_usermap[SID_MAX]; static void user_add(const struct ADC_user* user) { printf(" >> JOIN: %s (%s)\n", user->name, user->address); memcpy(&g_usermap[user->sid], user, sizeof(struct ADC_user)); } static struct ADC_user* user_get(sid_t sid) { struct ADC_user* user = &g_usermap[sid]; uhub_assert(user->sid != 0); return user; } static void user_remove(const struct ADC_client_quit_reason* quit) { struct ADC_user* user = user_get(quit->sid); printf(" << QUIT: %s (%s)\n", user->name, quit->message); memset(&g_usermap[quit->sid], 0, sizeof(struct ADC_user)); } static void on_message(struct ADC_chat_message* chat) { struct ADC_user* user; const char* pm = (chat->flags & chat_flags_private) ? "PM" : " "; const char* brack1 = (chat->flags & chat_flags_action) ? "*" : "<"; const char* brack2 = (chat->flags & chat_flags_action) ? "" : ">"; struct linked_list* lines; int ret; char* line; if (!chat->from_sid) { printf("HUB "); } else { user = user_get(chat->from_sid); printf(" %s %s%s%s ", pm, brack1, user->name, brack2); } lines = list_create(); ret = split_string(chat->message, "\n", lines, 1); ret = 0; LIST_FOREACH(char*, line, lines, { if (ret > 0) printf(" "); printf("%s\n", line); ret++; }); list_clear(lines, &hub_free); list_destroy(lines); } static void status(const char* msg) { printf("*** %s\n", msg); } static int handle(struct ADC_client* client, enum ADC_client_callback_type type, struct ADC_client_callback_data* data) { switch (type) { case ADC_CLIENT_NAME_LOOKUP: status("Looking up hostname..."); break; case ADC_CLIENT_CONNECTING: status("Connecting..."); break; case ADC_CLIENT_CONNECTED: status("Connected."); break; case ADC_CLIENT_DISCONNECTED: status("Disconnected."); break; case ADC_CLIENT_SSL_HANDSHAKE: status("SSL handshake."); break; case ADC_CLIENT_SSL_OK: printf("*** SSL connected (%s/%s).\n", data->tls_info->version, data->tls_info->cipher); break; case ADC_CLIENT_LOGGING_IN: status("Logging in..."); break; case ADC_CLIENT_PASSWORD_REQ: status("Requesting password."); break; case ADC_CLIENT_LOGGED_IN: status("Logged in."); break; case ADC_CLIENT_LOGIN_ERROR: status("Login error"); break; case ADC_CLIENT_MESSAGE: on_message(data->chat); break; case ADC_CLIENT_USER_JOIN: user_add(data->user); break; case ADC_CLIENT_USER_QUIT: user_remove(data->quit); break; case ADC_CLIENT_SEARCH_REQ: break; case ADC_CLIENT_HUB_INFO: printf(" Hub: \"%s\" [%s]\n" " \"%s\"\n", data->hubinfo->name, data->hubinfo->version, data->hubinfo->description); break; default: printf("Not handled event=%d\n", (int) type); return 0; break; } return 1; } static int running = 1; #if !defined(WIN32) static struct uhub_notify_handle* notify_handle; void adm_handle_signal(int sig) { switch (sig) { case SIGINT: LOG_INFO("Interrupted. Shutting down..."); running = 0; break; case SIGTERM: LOG_INFO("Terminated. Shutting down..."); running = 0; break; case SIGPIPE: break; case SIGHUP: break; default: LOG_TRACE("hub_handle_signal(): caught unknown signal: %d", signal); running = 0; break; } } static int signals[] = { SIGINT, /* Interrupt the application */ SIGTERM, /* Terminate the application */ SIGPIPE, /* prevent sigpipe from kills the application */ SIGHUP, /* reload configuration */ 0 }; void adm_setup_signal_handlers() { sigset_t sig_set; struct sigaction act; int i; sigemptyset(&sig_set); act.sa_mask = sig_set; act.sa_flags = SA_ONSTACK | SA_RESTART; act.sa_handler = adm_handle_signal; for (i = 0; signals[i]; i++) { if (sigaction(signals[i], &act, 0) != 0) { LOG_ERROR("Error setting signal handler %d", signals[i]); } } } void adm_setup_control_pipe() { notify_handle = net_notify_create(NULL, NULL); } void adm_shutdown_control_pipe() { net_notify_destroy(notify_handle); notify_handle = NULL; } void adm_shutdown_signal_handlers() { } #endif /* !WIN32 */ int main(int argc, char** argv) { if (argc < 2) { printf("Usage: %s adc[s]://host:port\n", argv[0]); return 1; } hub_set_log_verbosity(5); adm_setup_signal_handlers(); struct ADC_client* client; net_initialize(); adm_setup_control_pipe(); memset(g_usermap, 0, sizeof(g_usermap)); client = ADC_client_create("uhub-admin", "stresstester", NULL); ADC_client_set_callback(client, handle); ADC_client_connect(client, argv[1]); while (running && net_backend_process()) { } adm_shutdown_control_pipe(); ADC_client_destroy(client); net_destroy(); adm_shutdown_signal_handlers(); return 0; }