static int check_logged_in(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd) { struct hub_user* lookup1 = uman_get_user_by_nick(hub->users, user->id.nick); struct hub_user* lookup2 = uman_get_user_by_cid(hub->users, user->id.cid); if (lookup1 == user) { return 0; } if (lookup1 || lookup2) { if (lookup1 == lookup2) { LOG_DEBUG("check_logged_in: exact same user is logged in: %s", user->id.nick); hub_disconnect_user(hub, lookup1, quit_ghost_timeout); return 0; } else { if (lookup1) { LOG_DEBUG("check_logged_in: nickname is in use: %s", user->id.nick); return status_msg_inf_error_nick_taken; } else { LOG_DEBUG("check_logged_in: CID is in use: %s", user->id.cid); return status_msg_inf_error_cid_taken; } } } return 0; }
void net_event(struct net_connection* con, int event, void *arg) { struct hub_user* user = (struct hub_user*) arg; int flag_close = 0; #ifdef DEBUG_SENDQ LOG_TRACE("net_event() : fd=%d, ev=%d, arg=%p", con->sd, (int) event, arg); #endif if (event == NET_EVENT_TIMEOUT) { if (user_is_connecting(user)) { hub_disconnect_user(g_hub, user, quit_timeout); } return; } if (event & NET_EVENT_READ) { flag_close = handle_net_read(user); if (flag_close) { hub_disconnect_user(g_hub, user, flag_close); return; } } if (event & NET_EVENT_WRITE) { flag_close = handle_net_write(user); if (flag_close) { hub_disconnect_user(g_hub, user, flag_close); return; } } }
void on_update_failure(struct hub_info* hub, struct hub_user* u, enum status_message msg) { plugin_log_user_update_error(hub, u, hub_get_status_message_log(hub, msg)); hub_send_status(hub, u, msg, status_level_fatal); hub_disconnect_user(hub, u, quit_update_error); }
int hub_handle_support(struct hub_info* hub, struct hub_user* u, struct adc_message* cmd) { int ret = 0; int index = 0; int ok = 1; char* arg = adc_msg_get_argument(cmd, index); if (hub->status == hub_status_disabled && u->state == state_protocol) { on_login_failure(hub, u, status_msg_hub_disabled); hub_free(arg); return -1; } while (arg) { if (strlen(arg) == 6) { fourcc_t fourcc = FOURCC(arg[2], arg[3], arg[4], arg[5]); if (strncmp(arg, ADC_SUP_FLAG_ADD, 2) == 0) { user_support_add(u, fourcc); } else if (strncmp(arg, ADC_SUP_FLAG_REMOVE, 2) == 0) { user_support_remove(u, fourcc); } else { ok = 0; } } else { ok = 0; } index++; hub_free(arg); arg = adc_msg_get_argument(cmd, index); } if (u->state == state_protocol) { if (index == 0) ok = 0; /* Need to support *SOMETHING*, at least BASE */ if (!ok) { /* disconnect user. Do not send crap during initial handshake! */ hub_disconnect_user(hub, u, quit_logon_error); return -1; } if (user_flag_get(u, feature_base)) { /* User supports ADC/1.0 and a hash we know */ if (user_flag_get(u, feature_tiger)) { hub_send_handshake(hub, u); /* TODO: timeouts for mux users */ if (u->connection) net_con_set_timeout(u->connection, TIMEOUT_HANDSHAKE); } else { // no common hash algorithm. hub_send_status(hub, u, status_msg_proto_no_common_hash, status_level_fatal); hub_disconnect_user(hub, u, quit_protocol_error); } } else if (user_flag_get(u, feature_bas0)) { if (hub->config->obsolete_clients) { hub_send_handshake(hub, u); /* TODO: timeouts for mux users */ if (u->connection) net_con_set_timeout(u->connection, TIMEOUT_HANDSHAKE); } else { /* disconnect user for using an obsolete client. */ char* tmp = adc_msg_escape(hub->config->msg_proto_obsolete_adc0); struct adc_message* message = adc_msg_construct(ADC_CMD_IMSG, 6 + strlen(tmp)); adc_msg_add_argument(message, tmp); hub_free(tmp); route_to_user(hub, u, message); adc_msg_free(message); hub_disconnect_user(hub, u, quit_protocol_error); } } else { /* Not speaking a compatible protocol - just disconnect. */ hub_disconnect_user(hub, u, quit_logon_error); } } return ret; }