static void wd_cmd_hello(wi_array_t *arguments) { wd_client_t *client = wd_client(); wi_string_t *string; if(client->state != WD_CLIENT_STATE_CONNECTED) return; if(wd_ip_is_banned(client->ip)) { wd_reply(511, WI_STR("Banned")); wi_log_info(WI_STR("Connection from %@ denied, host is banned"), client->ip); client->state = WD_CLIENT_STATE_DISCONNECTED; return; } string = wi_date_iso8601_string(wd_start_date); wd_reply(200, WI_STR("%#@%c%#@%c%#@%c%#@%c%#@%c%u%c%llu"), wd_server_version_string, WD_FIELD_SEPARATOR, wd_protocol_version_string, WD_FIELD_SEPARATOR, wd_settings.name, WD_FIELD_SEPARATOR, wd_settings.description, WD_FIELD_SEPARATOR, string, WD_FIELD_SEPARATOR, wd_files_count, WD_FIELD_SEPARATOR, wd_files_size); client->state = WD_CLIENT_STATE_SAID_HELLO; }
void wd_chat_reply_user_list(wd_chat_t *chat) { wi_enumerator_t *enumerator; wd_user_t *user; wi_array_rdlock(chat->users); enumerator = wi_array_data_enumerator(chat->users); while((user = wi_enumerator_next_data(enumerator))) { if(wd_user_state(user) == WD_USER_LOGGED_IN) { wd_reply(310, WI_STR("%u%c%u%c%u%c%u%c%u%c%#@%c%#@%c%#@%c%#@%c%#@%c%#@"), chat->cid, WD_FIELD_SEPARATOR, wd_user_uid(user), WD_FIELD_SEPARATOR, wd_user_is_idle(user), WD_FIELD_SEPARATOR, wd_user_is_admin(user), WD_FIELD_SEPARATOR, wd_user_icon(user), WD_FIELD_SEPARATOR, wd_user_nick(user), WD_FIELD_SEPARATOR, wd_user_login(user), WD_FIELD_SEPARATOR, wd_user_ip(user), WD_FIELD_SEPARATOR, wd_user_host(user), WD_FIELD_SEPARATOR, wd_user_status(user), WD_FIELD_SEPARATOR, wd_user_image(user)); } } wi_array_unlock(chat->users); wd_reply(311, WI_STR("%u"), chat->cid); }
static void wd_cmd_createuser(wi_array_t *arguments) { wd_client_t *client = wd_client(); wd_account_t *account; if(!client->account->create_accounts) { wd_reply(516, WI_STR("Permission Denied")); return; } account = wd_accounts_read_user(WI_ARRAY(arguments, 0)); if(account) { wd_reply(514, WI_STR("Account Exists")); return; } account = wi_autorelease(wd_account_init_user_with_array(wd_account_alloc(), arguments)); if(!wd_accounts_check_privileges(account)) { wd_reply(516, WI_STR("Permission Denied")); return; } if(wd_accounts_create_user(account)) { wi_log_ll(WI_STR("%@/%@/%@ created the user \"%@\""), client->nick, client->login, client->ip, account->name); } }
static void wd_cmd_delete(wi_array_t *arguments) { wd_client_t *client = wd_client(); wi_string_t *path, *properpath; if(!client->account->delete_files) { wd_reply(516, WI_STR("Permission Denied")); return; } path = WI_ARRAY(arguments, 0); if(!wd_files_path_is_valid(path)) { wd_reply(520, WI_STR("File or Directory Not Found")); return; } if(!client->account->view_dropboxes) { if(wd_files_path_is_dropbox(path)) { wd_reply(520, WI_STR("File or Directory Not Found")); return; } } properpath = wi_string_by_normalizing_path(path); if(wd_files_delete_path(properpath)) { wi_log_ll(WI_STR("%@/%@/%@ deleted \"%@\""), client->nick, client->login, client->ip, properpath); } }
static void wd_cmd_move(wi_array_t *arguments) { wd_client_t *client = wd_client(); wi_string_t *frompath, *topath; wi_string_t *properfrompath, *propertopath; frompath = WI_ARRAY(arguments, 0); topath = WI_ARRAY(arguments, 1); if(!wd_files_path_is_valid(frompath) || !wd_files_path_is_valid(topath)) { wd_reply(520, WI_STR("File or Directory Not Found")); return; } if(!client->account->view_dropboxes) { if(wd_files_path_is_dropbox(frompath)) { wd_reply(520, WI_STR("File or Directory Not Found")); return; } } properfrompath = wi_string_by_normalizing_path(frompath); propertopath = wi_string_by_normalizing_path(topath); if(wd_files_move_path(properfrompath, propertopath)) { wi_log_ll(WI_STR("%@/%@/%@ moved \"%@\" to \"%@\""), client->nick, client->login, client->ip, properfrompath, propertopath); } }
static void wd_cmd_comment(wi_array_t *arguments) { wd_client_t *client = wd_client(); wi_string_t *path; if(!client->account->alter_files) { wd_reply(516, WI_STR("Permission Denied")); return; } path = WI_ARRAY(arguments, 0); if(!wd_files_path_is_valid(path)) { wd_reply(520, WI_STR("File or Directory Not Found")); return; } if(!client->account->view_dropboxes) { if(wd_files_path_is_dropbox(path)) { wd_reply(520, WI_STR("File or Directory Not Found")); return; } } wd_files_set_comment(wi_string_by_normalizing_path(path), WI_ARRAY(arguments, 1)); }
static void wd_cmd_get(wi_array_t *arguments) { wd_client_t *client = wd_client(); wi_string_t *path, *properpath; wi_file_offset_t offset; uint32_t count; if(!client->account->download) { wd_reply(516, WI_STR("Permission Denied")); return; } path = WI_ARRAY(arguments, 0); if(!wd_files_path_is_valid(path)) { wd_reply(520, WI_STR("File or Directory Not Found")); return; } if(!client->account->view_dropboxes) { if(wd_files_path_is_dropbox(path)) { wd_reply(520, WI_STR("File or Directory Not Found")); return; } } count = wd_transfers_count_of_client(client, WD_TRANSFER_DOWNLOAD); if(count >= wd_settings.clientdownloads) { if(count > wd_settings.clientdownloads) { wd_reply(523, WI_STR("Queue Limit Exceeded")); return; } else { wi_thread_sleep(0.5); if(wd_transfers_count_of_client(client, WD_TRANSFER_DOWNLOAD) >= wd_settings.clientdownloads) { wd_reply(523, WI_STR("Queue Limit Exceeded")); return; } } } properpath = wi_string_by_normalizing_path(path); offset = wi_string_uint64(WI_ARRAY(arguments, 1)); wd_transfers_queue_download(properpath, offset); }
static void wd_cmd_folder(wi_array_t *arguments) { wd_client_t *client = wd_client(); wi_string_t *path, *parentpath, *realpath, *properpath; wd_file_type_t type; path = WI_ARRAY(arguments, 0); if(!wd_files_path_is_valid(path)) { wd_reply(520, WI_STR("File or Directory Not Found")); return; } if(!client->account->view_dropboxes) { if(wd_files_path_is_dropbox(path)) { wd_reply(520, WI_STR("File or Directory Not Found")); return; } } realpath = wd_files_real_path(path); wi_string_resolve_aliases_in_path(realpath); parentpath = wi_string_by_deleting_last_path_component(realpath); type = wd_files_type(parentpath); if(type == WD_FILE_TYPE_UPLOADS || type == WD_FILE_TYPE_DROPBOX) { if(!client->account->upload) { wd_reply(516, WI_STR("Permission Denied")); return; } } else { if(!client->account->upload_anywhere && !client->account->create_folders) { wd_reply(516, WI_STR("Permission Denied")); return; } } properpath = wi_string_by_normalizing_path(path); if(wd_files_create_path(properpath, type)) { wi_log_ll(WI_STR("%@/%@/%@ created \"%@\""), client->nick, client->login, client->ip, properpath); } }
void wd_transfers_queue_upload(wi_string_t *path, wi_file_offset_t size, wi_string_t *checksum) { wd_user_t *user = wd_users_user_for_thread(); wi_string_t *realpath, *filechecksum; wd_transfer_t *transfer; wi_file_offset_t offset; wi_fs_stat_t sb; realpath = wi_string_by_resolving_aliases_in_path(wd_files_real_path(path)); if(wi_fs_stat_path(realpath, &sb)) { wd_reply(521, WI_STR("File or Directory Exists")); return; } if(!wi_string_has_suffix(realpath, WI_STR(WD_TRANSFERS_PARTIAL_EXTENSION))) realpath = wi_string_by_appending_path_extension(realpath, WI_STR(WD_TRANSFERS_PARTIAL_EXTENSION)); if(!wi_fs_stat_path(realpath, &sb)) { offset = 0; } else { offset = sb.size; if(sb.size >= WD_FILES_CHECKSUM_SIZE) { filechecksum = wi_fs_sha1_for_path(realpath, WD_FILES_CHECKSUM_SIZE); if(!wi_is_equal(filechecksum, checksum)) { wd_reply(522, WI_STR("Checksum Mismatch")); return; } } } transfer = wi_autorelease(wd_transfer_init_upload_with_user(wd_transfer_alloc(), user)); transfer->path = wi_retain(path); transfer->realpath = wi_retain(realpath); transfer->size = size; transfer->offset = offset; transfer->transferred = offset; wi_lock_lock(wd_transfers_update_queue_lock); wi_array_wrlock(wd_transfers); wi_mutable_array_add_data(wd_transfers, transfer); wi_array_unlock(wd_transfers); wd_transfers_update_queue(); wi_lock_unlock(wd_transfers_update_queue_lock); }
static void wd_cmd_pass(wi_array_t *arguments) { wd_client_t *client = wd_client(); wi_string_t *password; wd_chat_t *chat; if(client->state != WD_CLIENT_STATE_GAVE_USER) return; client->account = wi_retain(wd_accounts_read_user_and_group(client->login)); if(!client->account) { wd_reply(510, WI_STR("Login Failed")); wi_log_info(WI_STR("Login from %@/%@/%@ failed: %@"), client->nick, client->login, client->ip, WI_STR("No such account")); return; } password = WI_ARRAY(arguments, 0); if(!wi_is_equal(client->account->password, password)) { wd_reply(510, WI_STR("Login Failed")); wi_log_info(WI_STR("Login from %@/%@/%@ failed: %@"), client->nick, client->login, client->ip, WI_STR("Wrong password")); return; } wi_log_info(WI_STR("Login from %@/%@/%@ succeeded"), client->nick, client->login, client->ip); wi_lock_lock(client->flag_lock); client->admin = (client->account->kick_users || client->account->ban_users); client->state = WD_CLIENT_STATE_LOGGED_IN; wi_lock_unlock(client->flag_lock); wi_lock_lock(wd_status_lock); wd_current_users++; wd_total_users++; wd_write_status(true); wi_lock_unlock(wd_status_lock); wd_reply(201, WI_STR("%u"), client->uid); chat = wd_chat_with_cid(WD_PUBLIC_CID); wd_chat_add_client(chat, client); }
void wd_transfers_queue_upload(wi_string_t *path, wi_file_offset_t size, wi_string_t *checksum) { wd_client_t *client = wd_client(); wi_string_t *realpath, *filechecksum; wd_transfer_t *transfer; wi_file_offset_t offset; struct stat sb; realpath = wd_files_real_path(path); wi_string_resolve_aliases_in_path(realpath); if(wi_file_stat(realpath, &sb)) { wd_reply(521, WI_STR("File or Directory Exists")); return; } if(!wi_string_has_suffix(realpath, WI_STR(WD_TRANSFERS_PARTIAL_EXTENSION))) wi_string_append_string(realpath, WI_STR(WD_TRANSFERS_PARTIAL_EXTENSION)); if(!wi_file_stat(realpath, &sb)) { offset = 0; } else { offset = sb.st_size; if(sb.st_size >= WD_FILES_CHECKSUM_SIZE) { filechecksum = wi_file_sha1(realpath, WD_FILES_CHECKSUM_SIZE); if(!wi_is_equal(filechecksum, checksum)) { wd_reply(522, WI_STR("Checksum Mismatch")); return; } } } transfer = wd_transfer_init_upload_with_client(wd_transfer_alloc(), client); transfer->path = wi_retain(path); transfer->realpath = wi_retain(realpath); transfer->size = size; transfer->offset = offset; transfer->transferred = offset; wi_list_wrlock(wd_transfers); wi_list_append_data(wd_transfers, transfer); wi_list_unlock(wd_transfers); wi_release(transfer); wd_transfers_update_queue(); }
void wd_reply_errno(int error) { switch(error) { case ENOENT: wd_reply(520, WI_STR("File or Directory Not Found")); break; case EEXIST: wd_reply(521, WI_STR("File or Directory Exists")); break; default: wd_reply(500, WI_STR("Command Failed")); break; } }
static void wd_cmd_invite(wi_array_t *arguments) { wd_client_t *client = wd_client(); wd_client_t *peer; wd_chat_t *chat; wd_uid_t uid; wd_cid_t cid; uid = wi_string_uint32(WI_ARRAY(arguments, 0)); peer = wd_client_with_uid(uid); if(!peer) { wd_reply(512, WI_STR("Client Not Found")); return; } cid = wi_string_uint32(WI_ARRAY(arguments, 1)); chat = wd_chat_with_cid(cid); if(!chat) return; if(!wd_chat_contains_client(chat, client)) return; if(wd_chat_contains_client(chat, peer)) return; wd_client_lock_socket(peer); wd_sreply(peer->socket, 331, WI_STR("%u%c%u"), cid, WD_FIELD_SEPARATOR, client->uid); wd_client_unlock_socket(peer); }
static void wd_cmd_topic(wi_array_t *arguments) { wd_client_t *client = wd_client(); wd_chat_t *chat; wd_cid_t cid; cid = wi_string_uint32(WI_ARRAY(arguments, 0)); chat = wd_chat_with_cid(cid); if(!chat) return; if(cid == WD_PUBLIC_CID) { if(!client->account->set_topic) { wd_reply(516, WI_STR("Permission Denied")); return; } } else { if(!wd_chat_contains_client(chat, client)) return; } wd_chat_set_topic(chat, WI_ARRAY(arguments, 1)); wd_broadcast_lock(); wd_chat_broadcast_topic(chat); wd_broadcast_unlock(); }
static void wd_cmd_ban(wi_array_t *arguments) { wd_client_t *client = wd_client(); wd_client_t *peer; wd_uid_t uid; if(!client->account->ban_users) { wd_reply(516, WI_STR("Permission Denied")); return; } uid = wi_string_uint32(WI_ARRAY(arguments, 0)); peer = wd_client_with_uid(uid); if(!peer) { wd_reply(512, WI_STR("Client Not Found")); return; } if(peer->account->cannot_be_kicked) { wd_reply(515, WI_STR("Cannot Be Disconnected")); return; } wd_broadcast_lock(); wd_broadcast(WD_PUBLIC_CID, 307, WI_STR("%u%c%u%c%#@"), peer->uid, WD_FIELD_SEPARATOR, client->uid, WD_FIELD_SEPARATOR, WI_ARRAY(arguments, 1)); wd_broadcast_unlock(); wi_log_ll(WI_STR("%@/%@/%@ banned %@/%@/%@"), client->nick, client->login, client->ip, peer->nick, peer->login, peer->ip); wd_tempban(peer->ip); wi_lock_lock(peer->flag_lock); peer->state = WD_CLIENT_STATE_DISCONNECTED; wi_lock_unlock(peer->flag_lock); }
static void wd_cmd_post(wi_array_t *arguments) { wd_client_t *client = wd_client(); if(!client->account->post_news) { wd_reply(516, WI_STR("Permission Denied")); return; } wd_post_news(WI_ARRAY(arguments, 0)); }
static void wd_cmd_clearnews(wi_array_t *arguments) { wd_client_t *client = wd_client(); if(!client->account->clear_news) { wd_reply(516, WI_STR("Permission Denied")); return; } wd_clear_news(); }
static void wd_cmd_groups(wi_array_t *arguments) { wd_client_t *client = wd_client(); if(!client->account->edit_accounts) { wd_reply(516, WI_STR("Permission Denied")); return; } wd_reply_group_list(); }
static void wd_cmd_readuser(wi_array_t *arguments) { wd_client_t *client = wd_client(); if(!client->account->edit_accounts) { wd_reply(516, WI_STR("Permission Denied")); return; } wd_reply_user_account(WI_ARRAY(arguments, 0)); }
static void wd_cmd_listrecursive(wi_array_t *arguments) { wi_string_t *path; path = WI_ARRAY(arguments, 0); if(!wd_files_path_is_valid(path)) { wd_reply(520, WI_STR("File or Directory Not Found")); return; } wd_files_list_path(wi_string_by_normalizing_path(path), true); }
static void wd_cmd_privchat(wi_array_t *arguments) { wd_client_t *client = wd_client(); wd_chat_t *chat; chat = wd_chat_init_private(wd_chat_alloc()); wi_list_wrlock(wd_chats); wi_list_append_data(wd_chats, chat); wi_list_append_data(chat->clients, client); wi_list_unlock(wd_chats); wd_reply(330, WI_STR("%u"), chat->cid); }
static void wd_parse_command(wi_string_t *buffer) { wd_client_t *client = wd_client(); wi_array_t *arguments; wi_string_t *command; unsigned int index; wi_parse_wired_command(buffer, &command, &arguments); index = wd_command_index(command); if(index == WI_NOT_FOUND) { wd_reply(501, WI_STR("Command Not Recognized")); return; } if(client->state < wd_commands[index].state) return; if(wi_array_count(arguments) < wd_commands[index].args) { wd_reply(503, WI_STR("Syntax Error")); return; } if(wd_commands[index].activate) { client->idle_time = wi_time_interval(); if(client->idle) { client->idle = false; wd_broadcast_lock(); wd_client_broadcast_status(client); wd_broadcast_unlock(); } } ((*wd_commands[index].action) (arguments)); }
static void wd_cmd_edituser(wi_array_t *arguments) { wd_client_t *client = wd_client(); wd_account_t *account; if(!client->account->edit_accounts) { wd_reply(516, WI_STR("Permission Denied")); return; } account = wi_autorelease(wd_account_init_user_with_array(wd_account_alloc(), arguments)); if(!wd_accounts_check_privileges(account)) { wd_reply(516, WI_STR("Permission Denied")); return; } if(wd_accounts_edit_user(account)) { wi_log_ll(WI_STR("%@/%@/%@ modified the user \"%@\""), client->nick, client->login, client->ip, account->name); } }
static void wd_cmd_broadcast(wi_array_t *arguments) { wd_client_t *client = wd_client(); if(!client->account->broadcast) { wd_reply(516, WI_STR("Permission Denied")); return; } wd_broadcast_lock(); wd_broadcast(WD_PUBLIC_CID, 309, WI_STR("%u%c%#@"), client->uid, WD_FIELD_SEPARATOR, WI_ARRAY(arguments, 0)); wd_broadcast_unlock(); }
void wd_server_send_server_info(wi_boolean_t broadcast) { wi_string_t *string, *start_date; start_date = wi_date_rfc3339_string(wd_start_date); string = wi_string_with_format(WI_STR("%#@%c%#@%c%#@%c%#@%c%#@%c%u%c%llu"), wd_server_version_string, WD_FIELD_SEPARATOR, wd_protocol_version_string, WD_FIELD_SEPARATOR, wd_settings.name, WD_FIELD_SEPARATOR, wd_settings.description, WD_FIELD_SEPARATOR, start_date, WD_FIELD_SEPARATOR, wd_files_count, WD_FIELD_SEPARATOR, wd_files_size); if(broadcast) wd_broadcast(wd_public_chat, 200, WI_STR("%#@"), string); else wd_reply(200, WI_STR("%#@"), string); }
void wd_chat_reply_topic(wd_chat_t *chat) { wi_string_t *string; wd_topic_t *topic; topic = wd_chat_topic(chat); if(topic) { string = wi_date_rfc3339_string(topic->date); wd_reply(341, WI_STR("%u%c%#@%c%#@%c%#@%c%#@%c%#@"), chat->cid, WD_FIELD_SEPARATOR, topic->nick, WD_FIELD_SEPARATOR, topic->login, WD_FIELD_SEPARATOR, topic->ip, WD_FIELD_SEPARATOR, string, WD_FIELD_SEPARATOR, topic->topic); } }
static void wd_cmd_deleteuser(wi_array_t *arguments) { wd_client_t *client = wd_client(); wi_string_t *user; if(!client->account->delete_accounts) { wd_reply(516, WI_STR("Permission Denied")); return; } user = WI_ARRAY(arguments, 0); if(wd_accounts_delete_user(user)) { wi_log_ll(WI_STR("%@/%@/%@ deleted the user \"%@\""), client->nick, client->login, client->ip, user); } }
static void wd_cmd_msg(wi_array_t *arguments) { wd_client_t *client = wd_client(); wd_client_t *peer; wd_uid_t uid; uid = wi_string_uint32(WI_ARRAY(arguments, 0)); peer = wd_client_with_uid(uid); if(!peer) { wd_reply(512, WI_STR("Client Not Found")); return; } wd_client_lock_socket(peer); wd_sreply(peer->socket, 305, WI_STR("%u%c%#@"), client->uid, WD_FIELD_SEPARATOR, WI_ARRAY(arguments, 1)); wd_client_unlock_socket(peer); }
static void wd_cmd_deletegroup(wi_array_t *arguments) { wd_client_t *client = wd_client(); wi_string_t *group; if(!client->account->delete_accounts) { wd_reply(516, WI_STR("Permission Denied")); return; } group = WI_ARRAY(arguments, 0); if(wd_accounts_delete_group(group)) { wd_accounts_clear_group(group); wi_log_ll(WI_STR("%@/%@/%@ deleted the group \"%@\""), client->nick, client->login, client->ip, group); } }
static void wd_cmd_banner(wi_array_t *arguments) { wd_reply(203, WI_STR("%#@"), wd_banner); }