void on_nick_change(struct hub_info* hub, struct hub_user* u, const char* nick) { if (user_is_logged_in(u)) { plugin_log_user_nick_change(hub, u, nick); } }
void hub_send_support(struct hub_info* hub, struct hub_user* u) { if (user_is_connecting(u) || user_is_logged_in(u)) { route_to_user(hub, u, hub->command_support); } }
void hub_disconnect_user(struct hub_info* hub, struct hub_user* user, int reason) { struct event_data post; int need_notify = 0; /* is user already being disconnected ? */ if (user_is_disconnecting(user)) { return; } /* stop reading from user */ net_shutdown_r(net_con_get_sd(user->connection)); net_con_close(user->connection); user->connection = 0; LOG_TRACE("hub_disconnect_user(), user=%p, reason=%d, state=%d", user, reason, user->state); need_notify = user_is_logged_in(user) && hub->status == hub_status_running; user->quit_reason = reason; user_set_state(user, state_cleanup); if (need_notify) { memset(&post, 0, sizeof(post)); post.id = UHUB_EVENT_USER_QUIT; post.ptr = user; event_queue_post(hub->queue, &post); } else { hub_schedule_destroy_user(hub, user); } }
int uman_send_user_list(struct hub_info* hub, struct hub_user* target) { int ret = 1; struct hub_user* user; user_flag_set(target, flag_user_list); user = (struct hub_user*) list_get_first(hub->users->list); /* iterate users - only on INF or PAS msg */ while (user) { if (user_is_logged_in(user)) { ret = route_to_user(hub, target, user->info); if (!ret) break; } user = (struct hub_user*) list_get_next(hub->users->list); } #if 0 FIXME: FIXME FIXME handle send queue excess if (!target->send_queue_size) { user_flag_unset(target, flag_user_list); } #endif return ret; }
/* Notify plugins, etc */ void on_login_success(struct hub_info* hub, struct hub_user* u) { /* Send user list of all existing users */ if (!uman_send_user_list(hub, hub->users, u)) return; /* Mark as being in the normal state, and add user to the user list */ user_set_state(u, state_normal); uman_add(hub->users, u); /* Announce new user to all connected users */ if (user_is_logged_in(u)) route_info_message(hub, u); plugin_log_user_login_success(hub, u); /* reset timeout */ net_con_clear_timeout(u->connection); }
/* Notify plugins, etc */ void on_login_success(struct hub_info* hub, struct hub_user* u) { /* Send user list of all existing users */ if (!uman_send_user_list(hub, hub->users, u)) return; /* Mark as being in the normal state, and add user to the user list */ user_set_state(u, state_normal); uman_add(hub->users, u); // Make operators receive hub notifications by default. if (user_is_protected(u)) user_flag_set(u, flag_opnotify); /* Announce new user to all connected users */ if (user_is_logged_in(u)) route_info_message(hub, u); plugin_log_user_login_success(hub, u); /* reset timeout */ net_con_clear_timeout(u->connection); }
static int check_limits(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd) { char* arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_SHARED_SIZE); if (arg) { int64_t shared_size = atoll(arg); if (shared_size < 0) shared_size = 0; if (user_is_logged_in(user)) { hub->users->shared_size -= user->limits.shared_size; hub->users->shared_size += shared_size; } user->limits.shared_size = shared_size; hub_free(arg); arg = 0; } arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_SHARED_FILES); if (arg) { int shared_files = atoi(arg); if (shared_files < 0) shared_files = 0; if (user_is_logged_in(user)) { hub->users->shared_files -= user->limits.shared_files; hub->users->shared_files += shared_files; } user->limits.shared_files = shared_files; hub_free(arg); arg = 0; } arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_NORMAL); if (arg) { int num = atoi(arg); if (num < 0) num = 0; user->limits.hub_count_user = num; hub_free(arg); arg = 0; } arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_REGISTER); if (arg) { int num = atoi(arg); if (num < 0) num = 0; user->limits.hub_count_registered = num; hub_free(arg); arg = 0; } arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_OPERATOR); if (arg) { int num = atoi(arg); if (num < 0) num = 0; user->limits.hub_count_operator = num; hub_free(arg); arg = 0; } arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_UPLOAD_SLOTS); if (arg) { int num = atoi(arg); if (num < 0) num = 0; user->limits.upload_slots = num; hub_free(arg); arg = 0; } /* summarize total slots */ user->limits.hub_count_total = user->limits.hub_count_user + user->limits.hub_count_registered + user->limits.hub_count_operator; if (!user_is_protected(user)) { if (user->limits.shared_size < hub_get_min_share(hub) && hub_get_min_share(hub)) { return status_msg_user_share_size_low; } if (user->limits.shared_size > hub_get_max_share(hub) && hub_get_max_share(hub)) { return status_msg_user_share_size_high; } if ((user->limits.hub_count_user > hub_get_max_hubs_user(hub) && hub_get_max_hubs_user(hub)) || (user->limits.hub_count_registered > hub_get_max_hubs_reg(hub) && hub_get_max_hubs_reg(hub)) || (user->limits.hub_count_operator > hub_get_max_hubs_op(hub) && hub_get_max_hubs_op(hub)) || (user->limits.hub_count_total > hub_get_max_hubs_total(hub) && hub_get_max_hubs_total(hub))) { return status_msg_user_hub_limit_high; } if ((user->limits.hub_count_user < hub_get_min_hubs_user(hub) && hub_get_min_hubs_user(hub)) || (user->limits.hub_count_registered < hub_get_min_hubs_reg(hub) && hub_get_min_hubs_reg(hub)) || (user->limits.hub_count_operator < hub_get_min_hubs_op(hub) && hub_get_min_hubs_op(hub))) { return status_msg_user_hub_limit_low; } if (user->limits.upload_slots < hub_get_min_slots(hub) && hub_get_min_slots(hub)) { return status_msg_user_slots_low; } if (user->limits.upload_slots > hub_get_max_slots(hub) && hub_get_max_slots(hub)) { return status_msg_user_slots_high; } } return 0; }
int hub_handle_message(struct hub_info* hub, struct hub_user* u, const char* line, size_t length) { int ret = 0; struct adc_message* cmd = 0; LOG_PROTO("recv %s: %s", sid_to_string(u->id.sid), line); if (user_is_disconnecting(u)) return -1; cmd = adc_msg_parse_verify(u, line, length); if (cmd) { switch (cmd->cmd) { case ADC_CMD_HSUP: CHECK_FLOOD(extras, 0); ret = hub_handle_support(hub, u, cmd); break; case ADC_CMD_HPAS: CHECK_FLOOD(extras, 0); ret = hub_handle_password(hub, u, cmd); break; case ADC_CMD_BINF: CHECK_FLOOD(update, 1); ret = hub_handle_info(hub, u, cmd); break; case ADC_CMD_DINF: case ADC_CMD_EINF: case ADC_CMD_FINF: case ADC_CMD_BQUI: case ADC_CMD_DQUI: case ADC_CMD_EQUI: case ADC_CMD_FQUI: /* these must never be allowed for security reasons, so we ignore them. */ CHECK_FLOOD(extras, 1); break; case ADC_CMD_EMSG: case ADC_CMD_DMSG: case ADC_CMD_BMSG: case ADC_CMD_FMSG: CHECK_FLOOD(chat, 1); ret = hub_handle_chat_message(hub, u, cmd); break; case ADC_CMD_BSCH: case ADC_CMD_DSCH: case ADC_CMD_ESCH: case ADC_CMD_FSCH: cmd->priority = -1; if (plugin_handle_search(hub, u, cmd->cache) == st_deny) break; CHECK_FLOOD(search, 1); ROUTE_MSG; case ADC_CMD_FRES: // spam case ADC_CMD_BRES: // spam case ADC_CMD_ERES: // pointless. CHECK_FLOOD(extras, 1); break; case ADC_CMD_DRES: cmd->priority = -1; if (plugin_handle_search_result(hub, u, uman_get_user_by_sid(hub->users, cmd->target), cmd->cache) == st_deny) break; /* CHECK_FLOOD(search, 0); */ ROUTE_MSG; case ADC_CMD_DRCM: cmd->priority = -1; if (plugin_handle_revconnect(hub, u, uman_get_user_by_sid(hub->users, cmd->target)) == st_deny) break; CHECK_FLOOD(connect, 1); ROUTE_MSG; case ADC_CMD_DCTM: cmd->priority = -1; if (plugin_handle_connect(hub, u, uman_get_user_by_sid(hub->users, cmd->target)) == st_deny) break; CHECK_FLOOD(connect, 1); ROUTE_MSG; case ADC_CMD_BCMD: case ADC_CMD_DCMD: case ADC_CMD_ECMD: case ADC_CMD_FCMD: case ADC_CMD_HCMD: CHECK_FLOOD(extras, 1); break; default: CHECK_FLOOD(extras, 1); ROUTE_MSG; } adc_msg_free(cmd); } else { if (!user_is_logged_in(u)) { ret = -1; } } return ret; }
void hub_send_hubinfo(struct hub_info* hub, struct hub_user* u) { struct adc_message* info = adc_msg_copy(hub->command_info); int value = 0; uint64_t size = 0; if (user_flag_get(u, feature_ping)) { /* FIXME: These are missing: HH - Hub Host address ( DNS or IP ) WS - Hub Website NE - Hub Network OW - Hub Owner name */ adc_msg_add_named_argument(info, "UC", uhub_itoa(hub_get_user_count(hub))); adc_msg_add_named_argument(info, "MC", uhub_itoa(hub_get_max_user_count(hub))); adc_msg_add_named_argument(info, "SS", uhub_ulltoa(hub_get_shared_size(hub))); adc_msg_add_named_argument(info, "SF", uhub_ulltoa(hub_get_shared_files(hub))); /* Maximum/minimum share size */ size = hub_get_max_share(hub); if (size) adc_msg_add_named_argument(info, "XS", uhub_ulltoa(size)); size = hub_get_min_share(hub); if (size) adc_msg_add_named_argument(info, "MS", uhub_ulltoa(size)); /* Maximum/minimum upload slots allowed per user */ value = hub_get_max_slots(hub); if (value) adc_msg_add_named_argument(info, "XL", uhub_itoa(value)); value = hub_get_min_slots(hub); if (value) adc_msg_add_named_argument(info, "ML", uhub_itoa(value)); /* guest users must be on min/max hubs */ value = hub_get_max_hubs_user(hub); if (value) adc_msg_add_named_argument(info, "XU", uhub_itoa(value)); value = hub_get_min_hubs_user(hub); if (value) adc_msg_add_named_argument(info, "MU", uhub_itoa(value)); /* registered users must be on min/max hubs */ value = hub_get_max_hubs_reg(hub); if (value) adc_msg_add_named_argument(info, "XR", uhub_itoa(value)); value = hub_get_min_hubs_reg(hub); if (value) adc_msg_add_named_argument(info, "MR", uhub_itoa(value)); /* operators must be on min/max hubs */ value = hub_get_max_hubs_op(hub); if (value) adc_msg_add_named_argument(info, "XO", uhub_itoa(value)); value = hub_get_min_hubs_op(hub); if (value) adc_msg_add_named_argument(info, "MO", uhub_itoa(value)); /* uptime in seconds */ adc_msg_add_named_argument(info, "UP", uhub_itoa((int) difftime(time(0), hub->tm_started))); } if (user_is_connecting(u) || user_is_logged_in(u)) { route_to_user(hub, u, info); } adc_msg_free(info); /* Only send banner when connecting */ if (hub->config->show_banner && user_is_connecting(u)) { route_to_user(hub, u, hub->command_banner); } }
int hub_handle_chat_message(struct hub_info* hub, struct hub_user* u, struct adc_message* cmd) { char* message = adc_msg_get_argument(cmd, 0); char* message_decoded = NULL; int ret = 0; int relay = 1; int broadcast; int private_msg; int command; int offset; if (!message) return 0; message_decoded = adc_msg_unescape(message); if (!message_decoded) { hub_free(message); return 0; } if (!user_is_logged_in(u)) { hub_free(message); return 0; } broadcast = (cmd->cache[0] == 'B'); private_msg = (cmd->cache[0] == 'D' || cmd->cache[0] == 'E'); command = (message[0] == '!' || message[0] == '+'); if (broadcast && command) { /* * A message such as "++message" is handled as "+message", by removing the first character. * The first character is removed by memmoving the string one byte to the left. */ if (message[1] == message[0]) { relay = 1; offset = adc_msg_get_arg_offset(cmd); memmove(cmd->cache+offset+1, cmd->cache+offset+2, cmd->length - offset); cmd->length--; } else { relay = command_invoke(hub->commands, u, message_decoded); } } /* FIXME: Plugin should do this! */ if (relay && (((hub->config->chat_is_privileged && !user_is_protected(u)) || (user_flag_get(u, flag_muted))) && broadcast)) { relay = 0; } if (relay) { plugin_st status = st_default; if (broadcast) { status = plugin_handle_chat_message(hub, u, message_decoded, 0); } else if (private_msg) { struct hub_user* target = uman_get_user_by_sid(hub->users, cmd->target); if (target) status = plugin_handle_private_message(hub, u, target, message_decoded, 0); else relay = 0; } if (status == st_deny) relay = 0; } if (relay) { /* adc_msg_remove_named_argument(cmd, "PM"); */ if (broadcast) { plugin_log_chat_message(hub, u, message_decoded, 0); } ret = route_message(hub, u, cmd); } hub_free(message); hub_free(message_decoded); return ret; }
int hub_handle_message(struct hub_info* hub, struct hub_user* u, const char* line, size_t length) { int ret = 0; struct adc_message* cmd = 0; LOG_PROTO("recv %s: %s", sid_to_string(u->id.sid), line); if (user_is_disconnecting(u)) return -1; cmd = adc_msg_parse_verify(u, line, length); if (cmd) { switch (cmd->cmd) { case ADC_CMD_HSUP: CHECK_FLOOD(extras, 0); ret = hub_handle_support(hub, u, cmd); break; case ADC_CMD_HPAS: CHECK_FLOOD(extras, 0); ret = hub_handle_password(hub, u, cmd); break; case ADC_CMD_BINF: CHECK_FLOOD(update, 1); ret = hub_handle_info(hub, u, cmd); break; case ADC_CMD_DINF: case ADC_CMD_EINF: case ADC_CMD_FINF: /* these must never be allowed for security reasons, so we ignore them. */ break; case ADC_CMD_EMSG: case ADC_CMD_DMSG: case ADC_CMD_BMSG: case ADC_CMD_FMSG: CHECK_FLOOD(chat, 1); ret = hub_handle_chat_message(hub, u, cmd); break; case ADC_CMD_BSCH: case ADC_CMD_DSCH: case ADC_CMD_ESCH: case ADC_CMD_FSCH: cmd->priority = -1; CHECK_CHAT_ONLY; CHECK_FLOOD(search, 1); ROUTE_MSG; case ADC_CMD_DRES: cmd->priority = -1; CHECK_CHAT_ONLY; /* CHECK_FLOOD(search, 0); */ ROUTE_MSG; case ADC_CMD_DRCM: case ADC_CMD_DCTM: cmd->priority = -1; CHECK_CHAT_ONLY; CHECK_FLOOD(connect, 1); ROUTE_MSG; default: CHECK_FLOOD(extras, 1); ROUTE_MSG; } adc_msg_free(cmd); } else { if (!user_is_logged_in(u)) { ret = -1; } } return ret; }