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_decline(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(wd_chat_contains_client(chat, client)) return; wd_broadcast_lock(); wd_broadcast(chat->cid, 332, WI_STR("%u%c%u"), chat->cid, WD_FIELD_SEPARATOR, client->uid); wd_broadcast_unlock(); }
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); }
wi_boolean_t wi_p7_message_get_uint32_for_name(wi_p7_message_t *p7_message, wi_p7_uint32_t *value, wi_string_t *field_name) { wi_string_t *string; wi_p7_int32_t p7_int32; if(p7_message->serialization == WI_P7_BINARY) { if(!wi_p7_message_get_int32_for_name(p7_message, &p7_int32, field_name)) return false; *value = (wi_p7_uint32_t) p7_int32; } else { string = _wi_p7_message_xml_value_for_name(p7_message, field_name); if(!string) return false; *value = wi_string_uint32(string); } return true; }
static void wr_msg_200(wi_array_t *arguments) { wi_string_t *password; double protocol; protocol = wi_string_double(wr_protocol_version_string); wr_server = wr_server_init(wr_server_alloc()); wr_server->version = wi_retain(WI_ARRAY(arguments, 0)); wr_server->protocol = wi_string_double(WI_ARRAY(arguments, 1)); wr_server->name = wi_retain(WI_ARRAY(arguments, 2)); wr_server->description = wi_retain(WI_ARRAY(arguments, 3)); wr_server->startdate = wi_date_init_with_rfc3339_string(wi_date_alloc(), WI_ARRAY(arguments, 4)); wr_server->files = wi_string_uint32(WI_ARRAY(arguments, 5)); wr_server->size = wi_string_uint64(WI_ARRAY(arguments, 6)); wr_draw_divider(); if(!wr_logged_in) { if(wr_server->protocol > protocol) { wr_wprintf_prefix(wr_console_window, WI_STR("Server protocol version %.1f may not be fully compatible with client protocol version %.1f"), wr_server->protocol, protocol); } wr_send_command(WI_STR("CLIENT %#@"), wr_client_version_string); wr_send_command(WI_STR("NICK %#@"), wr_nick); wr_send_command(WI_STR("STATUS %#@"), wr_status); wr_send_command(WI_STR("ICON %u%c%#@"), 0, WR_FIELD_SEPARATOR, wr_icon); wr_send_command(WI_STR("USER %#@"), wr_login ? wr_login : WI_STR("guest")); if(wr_password && wi_string_length(wr_password) > 0) password = wi_string_sha1(wr_password); else password = NULL; wr_send_command(WI_STR("PASS %#@"), password); wr_send_command(WI_STR("WHO %u"), 1); wr_logged_in = true; } }
static void wd_cmd_leave(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)); if(cid == WD_PUBLIC_CID) return; chat = wd_chat_with_cid(cid); if(!chat) return; wd_chat_remove_client(chat, client); wd_broadcast_lock(); wd_client_broadcast_leave(client, cid); wd_broadcast_unlock(); }
static void wr_msg_305(wi_array_t *arguments) { wr_user_t *user; wr_window_t *window; wr_uid_t uid; uid = wi_string_uint32(WI_ARRAY(arguments, 0)); user = wr_chat_user_with_uid(wr_public_chat, uid); if(user && !wr_is_ignored(wr_user_nick(user))) { window = wr_windows_window_with_user(user); if(!window) { window = wr_window_init_with_user(wr_window_alloc(), user); wr_windows_add_window(window); wi_release(window); } wr_wprint_msg(window, wr_user_nick(user), WI_ARRAY(arguments, 1)); wr_reply_uid = wr_user_id(user); } }
wi_boolean_t _wi_settings_set_user(wi_settings_t *settings, wi_uinteger_t index, wi_string_t *name, wi_string_t *value) { struct passwd *user; uint32_t uid; user = getpwnam(wi_string_cstring(value)); if(!user) { uid = wi_string_uint32(value); if(uid != 0 || wi_is_equal(value, WI_STR("0"))) user = getpwuid(uid); } if(!user) { wi_error_set_libwired_error(WI_ERROR_SETTINGS_NOSUCHUSER); return false; } *(uid_t *) settings->spec[index].setting = user->pw_uid; return true; }
static void wr_msg_304(wi_array_t *arguments) { wi_string_t *nick; wr_user_t *user; wr_uid_t uid; uid = wi_string_uint32(WI_ARRAY(arguments, 0)); user = wr_chat_user_with_uid(wr_public_chat, uid); if(user) { nick = WI_ARRAY(arguments, 4); if(!wi_is_equal(wr_user_nick(user), nick)) { wr_wprintf_prefix(wr_console_window, WI_STR("%@ is now known as %@"), wr_user_nick(user), nick); wr_user_set_nick(user, nick); } wr_user_set_idle(user, wi_string_bool(WI_ARRAY(arguments, 1))); wr_user_set_admin(user, wi_string_bool(WI_ARRAY(arguments, 2))); wr_user_set_status(user, WI_ARRAY(arguments, 5)); } }
static void wr_command_unignore(wi_array_t *arguments) { wi_enumerator_t *enumerator; wi_string_t *string; wr_ignore_t *ignore; wr_iid_t iid; if(wi_array_count(arguments) > 0) { string = WI_ARRAY(arguments, 0); iid = wi_string_uint32(string); if(iid > 0) ignore = wr_ignore_with_iid(iid); else ignore = wr_ignore_with_string(string); if(ignore) { wr_printf_prefix(WI_STR("No longer ignoring \"%@\""), wr_ignore_string(ignore)); wi_mutable_array_remove_data(wr_ignores, ignore); } else { wr_printf_prefix(WI_STR("No ignore matching \"%@\""), string); } } else { wr_printf_prefix(WI_STR("Ignores:")); if(wi_array_count(wr_ignores) == 0) { wr_printf_block(WI_STR("(none)")); } else { enumerator = wi_array_data_enumerator(wr_ignores); while((ignore = wi_enumerator_next_data(enumerator))) wr_printf_block(WI_STR("%u: %@"), wr_ignore_id(ignore), wr_ignore_string(ignore)); } } }
static void wd_cmd_info(wi_array_t *arguments) { wd_client_t *client = wd_client(); wi_list_node_t *node; wi_string_t *info, *login, *idle, *downloads, *uploads; wd_client_t *peer; wd_transfer_t *transfer; wd_uid_t uid; if(!client->account->get_user_info) { 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; } downloads = wi_string(); uploads = wi_string(); wi_list_rdlock(wd_transfers); WI_LIST_FOREACH(wd_transfers, node, transfer) { if(transfer->client == peer && transfer->state == WD_TRANSFER_RUNNING) { if(!client->account->view_dropboxes) { if(wd_files_path_is_dropbox(transfer->path)) continue; } info = wi_string_with_format(WI_STR("%#@%c%llu%c%llu%c%u"), transfer->path, WD_RECORD_SEPARATOR, transfer->transferred, WD_RECORD_SEPARATOR, transfer->size, WD_RECORD_SEPARATOR, transfer->speed); if(transfer->type == WD_TRANSFER_DOWNLOAD) { if(wi_string_length(downloads) > 0) wi_string_append_format(downloads, WI_STR("%c"), WD_GROUP_SEPARATOR); wi_string_append_string(downloads, info); } else { if(wi_string_length(uploads) > 0) wi_string_append_format(uploads, WI_STR("%c"), WD_GROUP_SEPARATOR); wi_string_append_string(uploads, info); } } } wi_list_unlock(wd_transfers); login = wi_date_iso8601_string(wi_date_with_time_interval(peer->login_time)); idle = wi_date_iso8601_string(wi_date_with_time_interval(peer->idle_time)); wd_reply(308, WI_STR("%u%c%u%c%u%c%u%c%#@%c%#@%c%#@%c%#@%c%#@%c%#@%c%u%c%#@%c%#@%c%#@%c%#@%c%#@%c%#@"), peer->uid, WD_FIELD_SEPARATOR, peer->idle, WD_FIELD_SEPARATOR, peer->admin, WD_FIELD_SEPARATOR, peer->icon, WD_FIELD_SEPARATOR, peer->nick, WD_FIELD_SEPARATOR, peer->login, WD_FIELD_SEPARATOR, peer->ip, WD_FIELD_SEPARATOR, peer->host, WD_FIELD_SEPARATOR, peer->version, WD_FIELD_SEPARATOR, wi_socket_cipher_name(peer->socket), WD_FIELD_SEPARATOR, wi_socket_cipher_bits(peer->socket), WD_FIELD_SEPARATOR, login, WD_FIELD_SEPARATOR, idle, WD_FIELD_SEPARATOR, downloads, WD_FIELD_SEPARATOR, uploads, WD_FIELD_SEPARATOR, peer->status, WD_FIELD_SEPARATOR, peer->image); }
wi_boolean_t _wi_settings_set_number(wi_settings_t *settings, uint32_t index, wi_string_t *name, wi_string_t *value) { *(uint32_t *) settings->spec[index].setting = wi_string_uint32(value); return true; }
static void wr_msg_308(wi_array_t *arguments) { wi_enumerator_t *enumerator; wi_date_t *date; wi_array_t *array, *transfers; wi_string_t *string, *interval, *name, *transferred, *size, *speed; wi_uinteger_t n; wi_boolean_t first; wr_printf_prefix(WI_STR("User info:"), WI_ARRAY(arguments, 4)); wr_printf_block(WI_STR("Nick: %@"), WI_ARRAY(arguments, 4)); if(wr_server->protocol >= 1.1) wr_printf_block(WI_STR("Status: %@"), WI_ARRAY(arguments, 15)); wr_printf_block(WI_STR("Login: %@"), WI_ARRAY(arguments, 5)); wr_printf_block(WI_STR("ID: %@"), WI_ARRAY(arguments, 0)); wr_printf_block(WI_STR("Address: %@"), WI_ARRAY(arguments, 6)); wr_printf_block(WI_STR("Host: %@"), WI_ARRAY(arguments, 7)); wr_printf_block(WI_STR("Client: %@"), WI_ARRAY(arguments, 8)); wr_printf_block(WI_STR("Cipher: %@/%@ bits"), WI_ARRAY(arguments, 9), WI_ARRAY(arguments, 10)); date = wi_date_with_rfc3339_string(WI_ARRAY(arguments, 11)); interval = wi_time_interval_string(wi_date_time_interval_since_now(date)); string = wi_date_string_with_format(date, WI_STR("%a %b %e %T %Y")); wr_printf_block(WI_STR("Login Time: %@, since %@"), interval, string); date = wi_date_with_rfc3339_string(WI_ARRAY(arguments, 12)); interval = wi_time_interval_string(wi_date_time_interval_since_now(date)); string = wi_date_string_with_format(date, WI_STR("%a %b %e %T %Y")); wr_printf_block(WI_STR("Idle Time: %@, since %@"), interval, string); for(n = WR_TRANSFER_DOWNLOAD; n <= WR_TRANSFER_UPLOAD; n++) { string = WI_ARRAY(arguments, (n == WR_TRANSFER_DOWNLOAD) ? 13 : 14); transfers = wi_string_components_separated_by_string(string, WI_STR(WR_GROUP_SEPARATOR_STR)); enumerator = wi_array_data_enumerator(transfers); first = true; while((string = wi_enumerator_next_data(enumerator))) { array = wi_string_components_separated_by_string(string, WI_STR(WR_RECORD_SEPARATOR_STR)); if(wi_array_count(array) == 4) { name = wi_string_last_path_component(WI_ARRAY(array, 0)); transferred = wr_files_string_for_size(wi_string_uint64(WI_ARRAY(array, 1))); size = wr_files_string_for_size(wi_string_uint64(WI_ARRAY(array, 2))); speed = wr_files_string_for_size(wi_string_uint32(WI_ARRAY(array, 3))); if(first) { if(n == WR_TRANSFER_DOWNLOAD) { wr_printf_block(WI_STR("Downloads: %@, %@ of %@, %@/s"), name, transferred, size, speed); } else { wr_printf_block(WI_STR("Uploads: %@, %@ of %@, %@/s"), name, transferred, size, speed); } } else { wr_printf_block(WI_STR(" %@, %@ of %@, %@/s"), name, transferred, size, speed); } } first = false; } } }
static void wr_msg_402(wi_array_t *arguments) { wi_date_t *date; wi_string_t *path, *kind, *string; wr_file_t *file; wr_transfer_t *transfer; wi_file_offset_t size; wr_file_type_t type; path = WI_ARRAY(arguments, 0); type = wi_string_uint32(WI_ARRAY(arguments, 1)); size = wi_string_uint64(WI_ARRAY(arguments, 2)); if(wr_stat_state == WR_STAT_FILE) { wr_printf_prefix(WI_STR("File info for %@:"), wi_string_last_path_component(path)); wr_printf_block(WI_STR("Path: %@"), path); switch(type) { case WR_FILE_FILE: kind = WI_STR("File"); break; case WR_FILE_DIRECTORY: kind = WI_STR("Folder"); break; case WR_FILE_UPLOADS: kind = WI_STR("Uploads Folder"); break; case WR_FILE_DROPBOX: kind = WI_STR("Drop Box Folder"); break; default: kind = NULL; break; } wr_printf_block(WI_STR("Kind: %@"), kind); if(type == WR_FILE_FILE) string = wr_files_string_for_size(size); else string = wr_files_string_for_count(size); wr_printf_block(WI_STR("Size: %@"), string); date = wi_date_with_rfc3339_string(WI_ARRAY(arguments, 3)); string = wi_date_string_with_format(date, WI_STR("%a %b %e %T %Y")); wr_printf_block(WI_STR("Created: %@"), string); date = wi_date_with_rfc3339_string(WI_ARRAY(arguments, 4)); string = wi_date_string_with_format(date, WI_STR("%a %b %e %T %Y")); wr_printf_block(WI_STR("Modified: %@"), string); if(type == WR_FILE_FILE) wr_printf_block(WI_STR("Checksum: %@"), WI_ARRAY(arguments, 5)); if(wr_server->protocol >= 1.1) wr_printf_block(WI_STR("Comment: %@"), WI_ARRAY(arguments, 6)); } else if(wr_stat_state == WR_STAT_TRANSFER) { transfer = wr_transfers_transfer_with_remote_path(WI_ARRAY(arguments, 0)); if(transfer) { if(type == WR_FILE_FILE) { if(transfer->checksum && !wi_is_equal(transfer->checksum, WI_ARRAY(arguments, 5))) { wr_printf_prefix(WI_STR("get: Checksum mismatch for \"%@\""), transfer->name); wr_transfer_stop(transfer); return; } if(!transfer->recursive) { file = wr_file_init_with_arguments(wr_file_alloc(), arguments); wr_transfer_download_add_file(transfer, file, false); wi_release(file); } wr_transfer_request(transfer); } else { wr_ls_state = WR_LS_TRANSFER; transfer->recursive = true; wr_files_clear(); wr_send_command(WI_STR("LISTRECURSIVE %#@"), path); } } } }
static void wt_cmd_register(wi_array_t *arguments) { wt_client_t *client = wt_client(); wi_enumerator_t *enumerator; wi_array_t *array; wi_address_t *address, *hostaddress; wi_url_t *url; wi_string_t *hostname; wt_server_t *server; wi_boolean_t failed = false, passed; uint32_t bandwidth; url = wi_autorelease(wi_url_init_with_string(wi_url_alloc(), WI_ARRAY(arguments, 1))); hostname = wi_url_host(url); address = wi_socket_address(client->socket); if(!wi_url_is_valid(url)) { /* invalid URL */ if(wt_settings.strictlookup) { wt_reply(503, WI_STR("Syntax Error")); wi_log_warn(WI_STR("Register from %@ as \"%@\" URL %@ aborted: %s"), client->ip, WI_ARRAY(arguments, 2), WI_ARRAY(arguments, 1), "Invalid URL"); return; } failed = true; goto failed; } if(wi_ip_version(hostname) > 0) { /* hostname is numeric, compare with source address */ if(!wi_is_equal(hostname, client->ip)) { /* IP mismatch */ if(wt_settings.strictlookup) { wt_reply(530, WI_STR("Address Mismatch")); wi_log_warn(WI_STR("Register from %@ as \"%@\" URL %@ denied: %s"), client->ip, WI_ARRAY(arguments, 2), WI_ARRAY(arguments, 1), "IP mismatch"); return; } failed = true; goto failed; } } else { /* hostname is symbolic */ if(wt_settings.lookup) { /* look up and compare with source address */ passed = false; array = wi_host_addresses(wi_host_with_string(hostname)); if(array) { enumerator = wi_array_data_enumerator(array); while((hostaddress = wi_enumerator_next_data(enumerator))) { if(wi_is_equal(hostaddress, address)) { passed = true; break; } } } if(!passed) { /* lookup failed */ if(wt_settings.strictlookup) { wt_reply(531, WI_STR("Address Mismatch")); wi_log_warn(WI_STR("Register from %@ as \"%@\" URL %@ denied: %s"), client->ip, WI_ARRAY(arguments, 2), WI_ARRAY(arguments, 1), "Lookup failed"); return; } failed = true; goto failed; } } if(wt_settings.reverselookup) { /* reverse look up and compare to hostname */ if(!wi_is_equal(wi_address_hostname(address), hostname)) { /* reverse lookup failed */ if(wt_settings.strictlookup) { wt_reply(531, WI_STR("Address Mismatch")); wi_log_warn(WI_STR("Register from %@ as \"%@\" URL % denied: %@"), client->ip, WI_ARRAY(arguments, 2), WI_ARRAY(arguments, 1), "Reverse lookup failed"); return; } failed = true; goto failed; } } } failed: /* get bandwidth */ bandwidth = wi_string_uint32(WI_ARRAY(arguments, 3)); /* bandwidth too low? */ if(wt_settings.minbandwidth > 0 && bandwidth < wt_settings.minbandwidth) { wt_reply(516, WI_STR("Permission Denied")); wi_log_warn(WI_STR("Register from %@ as \"%@\" URL %@ denied: Bandwidth %.0f Kbps considered too low"), client->ip, WI_ARRAY(arguments, 2), WI_ARRAY(arguments, 1), bandwidth / 128.0); return; } /* bandwidth too high? */ if(wt_settings.maxbandwidth > 0 && bandwidth > wt_settings.maxbandwidth) { wt_reply(516, WI_STR("Permission Denied")); wi_log_warn(WI_STR("Register from %@ as \"%@\" URL %@ denied: Bandwidth %.0f Kbps considered too high"), client->ip, WI_ARRAY(arguments, 2), WI_ARRAY(arguments, 1), bandwidth / 128.0); return; } /* is there an existing server from this host? */ server = wt_servers_server_with_ip(client->ip); if(server) { if(server->port == wi_url_port(url)) { /* remove existing server in preparation for re-registration */ wt_servers_remove_stats_for_server(server); wt_servers_remove_server(server); } else { /* multiple servers from the same IP allowed? */ if(!wt_settings.allowmultiple) { wt_reply(530, WI_STR("Address Registered")); wi_log_warn(WI_STR("Register from %@ as \"%@\" URL %@ denied: %s"), client->ip, WI_ARRAY(arguments, 2), WI_ARRAY(arguments, 1), "A server from the same address is already registered"); return; } } } /* rewrite URL if host verification failed */ if(failed) { wi_url_set_scheme(url, WI_STR("wired")); wi_url_set_host(url, client->ip); if(wi_string_length(WI_ARRAY(arguments, 1)) == 0) wi_log_info(WI_STR("Rewriting URL to %@"), wi_url_string(url)); else wi_log_info(WI_STR("Rewriting URL from %@ to %@"), WI_ARRAY(arguments, 1), wi_url_string(url)); } /* create new server */ server = wt_server_init(wt_server_alloc()); server->key = wi_retain(wi_string_sha1(wi_autorelease(wi_string_init_random_string_with_length(wi_string_alloc(), 1024)))); server->port = wi_url_port(url); server->bandwidth = bandwidth; server->register_time = wi_time_interval(); server->update_time = 0.0; server->ip = wi_retain(client->ip); server->category = wt_servers_category_is_valid(WI_ARRAY(arguments, 0)) ? wi_retain(WI_ARRAY(arguments, 0)) : wi_string_init(wi_string_alloc()); server->name = wi_retain(WI_ARRAY(arguments, 2)); server->description = wi_retain(WI_ARRAY(arguments, 4)); server->url = wi_copy(wi_url_string(url)); wt_servers_add_server(server); wt_servers_add_stats_for_server(server); /* reply 700 */ wt_reply(700, WI_STR("%@"), server->key); wi_log_info(WI_STR("Registered \"%@\" with URL %@"), server->name, server->url); wt_servers_write_file(); wi_release(server); }
static void wr_msg_402(wi_array_t *arguments) { wi_date_t *date; wi_string_t *path, *kind, *string; wr_transfer_t *transfer; wi_file_offset_t size; wr_file_type_t type; path = WI_ARRAY(arguments, 0); type = wi_string_uint32(WI_ARRAY(arguments, 1)); size = wi_string_uint64(WI_ARRAY(arguments, 2)); if(wr_stat_state == WR_STAT_FILE) { wr_printf_prefix(WI_STR("File info for %@:"), wi_string_last_path_component(path)); wr_printf_block(WI_STR("Path: %@"), path); switch(type) { case WR_FILE_FILE: kind = WI_STR("File"); break; case WR_FILE_DIRECTORY: kind = WI_STR("Folder"); break; case WR_FILE_UPLOADS: kind = WI_STR("Uploads Folder"); break; case WR_FILE_DROPBOX: kind = WI_STR("Drop Box Folder"); break; default: kind = NULL; break; } wr_printf_block(WI_STR("Kind: %@"), kind); if(type == WR_FILE_FILE) string = wr_files_string_for_size(size); else string = wr_files_string_for_count(size); wr_printf_block(WI_STR("Size: %@"), string); date = wi_date_with_iso8601_string(WI_ARRAY(arguments, 3)); string = wi_date_string_with_format(date, WI_STR("%a %b %e %T %Y")); wr_printf_block(WI_STR("Created: %@"), string); date = wi_date_with_iso8601_string(WI_ARRAY(arguments, 4)); string = wi_date_string_with_format(date, WI_STR("%a %b %e %T %Y")); wr_printf_block(WI_STR("Modified: %@"), string); if(type == WR_FILE_FILE) wr_printf_block(WI_STR("Checksum: %@"), WI_ARRAY(arguments, 5)); if(wr_server->protocol >= 1.1) wr_printf_block(WI_STR("Comment: %@"), WI_ARRAY(arguments, 6)); } else if(wr_stat_state == WR_STAT_TRANSFER) { transfer = wr_transfers_transfer_with_path(WI_ARRAY(arguments, 0)); if(transfer) { if(type != WR_FILE_FILE) { wr_printf_prefix(WI_STR("get: Cannot download directories")); wr_transfer_stop(transfer); return; } if(transfer->checksum && !wi_is_equal(transfer->checksum, WI_ARRAY(arguments, 5))) { wr_printf_prefix(WI_STR("get: Checksum mismatch for \"%@\""), transfer->name); wr_transfer_stop(transfer); return; } transfer->size = size; wr_send_command(WI_STR("GET %#@%c%llu"), transfer->path, WR_FIELD_SEPARATOR, transfer->offset); } } }
static wi_runtime_instance_t * _wi_config_instance_for_setting(wi_config_t *config, wi_string_t *name, wi_string_t *value, wi_config_type_t *type) { struct passwd *user; struct group *group; struct servent *servent; wi_uinteger_t port; uint32_t uid, gid; if(!wi_dictionary_contains_key(config->types, name)) { wi_error_set_libwired_error(WI_ERROR_SETTINGS_UNKNOWNSETTING); return NULL; } *type = wi_number_int32(wi_dictionary_data_for_key(config->types, name)); switch(*type) { case WI_CONFIG_INTEGER: return wi_number_with_integer(wi_string_integer(value)); break; case WI_CONFIG_BOOL: return wi_number_with_bool(wi_string_bool(value)); break; case WI_CONFIG_STRING: case WI_CONFIG_STRINGLIST: case WI_CONFIG_PATH: return value; break; case WI_CONFIG_USER: user = getpwnam(wi_string_cstring(value)); if(!user) { uid = wi_string_uint32(value); if(uid != 0 || wi_is_equal(value, WI_STR("0"))) user = getpwuid(uid); } if(!user) { wi_error_set_libwired_error(WI_ERROR_SETTINGS_NOSUCHUSER); return NULL; } return wi_number_with_int32(user->pw_uid); break; case WI_CONFIG_GROUP: group = getgrnam(wi_string_cstring(value)); if(!group) { gid = wi_string_uint32(value); if(gid != 0 || wi_is_equal(value, WI_STR("0"))) group = getgrgid(gid); } if(!group) { wi_error_set_libwired_error(WI_ERROR_SETTINGS_NOSUCHGROUP); return NULL; } return wi_number_with_int32(group->gr_gid); break; case WI_CONFIG_PORT: port = wi_string_uinteger(value); if(port > 65535) { wi_error_set_libwired_error(WI_ERROR_SETTINGS_INVALIDPORT); return NULL; } if(port == 0) { servent = getservbyname(wi_string_cstring(value), "tcp"); if(!servent) { wi_error_set_libwired_error(WI_ERROR_SETTINGS_NOSUCHSERVICE); return NULL; } port = servent->s_port; } return wi_number_with_int32(port); break; case WI_CONFIG_REGEXP: return wi_autorelease(wi_regexp_init_with_string(wi_regexp_alloc(), value)); break; case WI_CONFIG_TIME_INTERVAL: return wi_number_with_double(wi_string_double(value)); break; } return NULL; }
int main(int argc, const char **argv) { wi_mutable_array_t *arguments; wi_pool_t *pool; wi_string_t *string, *root_path; int ch, facility; wi_boolean_t test_config, daemonize, change_directory, switch_user; /* init libwired */ wi_initialize(); wi_load(argc, argv); pool = wi_pool_init(wi_pool_alloc()); wi_log_syslog = true; wi_log_syslog_facility = LOG_DAEMON; /* init core systems */ wt_version_init(); wt_status_lock = wi_lock_init(wi_lock_alloc()); wt_start_date = wi_date_init(wi_date_alloc()); /* set defaults */ root_path = WI_STR(WT_ROOT); wi_settings_config_path = wi_string_init_with_cstring(wi_string_alloc(), WT_CONFIG_PATH); test_config = false; daemonize = true; change_directory = true; switch_user = true; /* init reexec argument list */ arguments = wi_array_init(wi_mutable_array_alloc()); /* parse command line switches */ while((ch = getopt(argc, (char * const *) argv, "46Dd:f:hi:L:ls:tuVvXx")) != -1) { switch(ch) { case '4': wt_address_family = WI_ADDRESS_IPV4; break; case '6': wt_address_family = WI_ADDRESS_IPV6; break; case 'D': daemonize = false; wi_log_stderr = true; break; case 'd': root_path = wi_string_with_cstring(optarg); break; case 'f': wi_release(wi_settings_config_path); wi_settings_config_path = wi_string_init_with_cstring(wi_string_alloc(), optarg); break; case 'i': wi_log_limit = wi_string_uint32(wi_string_with_cstring(optarg)); break; case 'L': wi_log_syslog = false; wi_log_file = true; wi_release(wi_log_path); wi_log_path = wi_string_init_with_cstring(wi_string_alloc(), optarg); break; case 'l': wi_log_level++; break; case 's': string = wi_string_with_cstring(optarg); facility = wi_log_syslog_facility_with_name(string); if(facility < 0) wi_log_fatal(WI_STR("Could not find syslog facility \"%@\": %m"), string); wi_log_syslog_facility = facility; break; case 't': test_config = true; break; case 'u': break; case 'V': case 'v': wt_version(); break; case 'X': daemonize = false; break; case 'x': daemonize = false; change_directory = false; switch_user = false; break; case '?': case 'h': default: wt_usage(); break; } wi_mutable_array_add_data(arguments, wi_string_with_format(WI_STR("-%c"), ch)); if(optarg) wi_mutable_array_add_data(arguments, wi_string_with_cstring(optarg)); } /* detach */ if(daemonize) { wi_mutable_array_add_data(arguments, WI_STR("-X")); switch(wi_fork()) { case -1: wi_log_fatal(WI_STR("Could not fork: %m")); break; case 0: if(!wi_execv(wi_string_with_cstring(argv[0]), arguments)) wi_log_fatal(WI_STR("Could not execute %s: %m"), argv[0]); break; default: _exit(0); break; } } wi_release(arguments); /* change directory */ if(change_directory) { if(!wi_fs_change_directory(root_path)) wi_log_error(WI_STR("Could not change directory to %@: %m"), root_path); } /* open log */ wi_log_open(); /* init subsystems */ wt_ssl_init(); wt_clients_init(); wt_servers_init(); /* read the config file */ wt_settings_init(); if(!wt_settings_read_config()) exit(1); /* apply settings */ wt_settings_apply_settings(); if(test_config) { printf("Config OK\n"); exit(0); } /* dump command line */ wi_log_info(WI_STR("Started as %@ %@"), wi_process_path(wi_process()), wi_array_components_joined_by_string(wi_process_arguments(wi_process()), WI_STR(" "))); /* init tracker */ wi_log_info(WI_STR("Starting Wired Tracker version %@"), wt_version_string); wt_tracker_init(); /* switch user/group */ if(switch_user) wi_switch_user(wt_settings.user, wt_settings.group); /* create tracker threads after privilege drop */ wt_signals_init(); wt_block_signals(); wt_servers_schedule(); wt_tracker_create_threads(); wt_write_pid(); wt_write_status(true); /* clean up pool after startup */ wi_pool_drain(pool); /* enter the signal handling thread in the main thread */ wt_signal_thread(NULL); /* dropped out */ wt_cleanup(); wi_log_close(); wi_release(pool); return 0; }
void wi_p7_message_deserialize(wi_p7_message_t *p7_message, wi_p7_serialization_t serialization) { xmlDocPtr doc; xmlNodePtr root_node, field_node; wi_string_t *field_name, *field_value; wi_p7_spec_message_t *message; wi_p7_spec_field_t *field; wi_uuid_t *uuid; wi_date_t *date; wi_data_t *data; if(serialization == WI_P7_BINARY) { p7_message->binary_id = wi_read_swap_big_to_host_int32(p7_message->binary_buffer, 0); message = wi_p7_spec_message_with_id(p7_message->spec, p7_message->binary_id); if(message) p7_message->name = wi_retain(wi_p7_spec_message_name(message)); } else { p7_message->binary_capacity = _WI_P7_MESSAGE_BINARY_BUFFER_INITIAL_SIZE; p7_message->binary_buffer = wi_malloc(p7_message->binary_capacity); p7_message->binary_size = WI_P7_MESSAGE_BINARY_HEADER_SIZE; doc = xmlParseDoc((xmlChar *) wi_string_cstring(p7_message->xml_string)); root_node = xmlDocGetRootElement(doc); if(root_node) { wi_p7_message_set_name(p7_message, wi_xml_node_attribute_with_name(root_node, WI_STR("name"))); for(field_node = root_node->children; field_node != NULL; field_node = field_node->next) { if(field_node->type == XML_ELEMENT_NODE) { if(wi_is_equal(wi_xml_node_name(field_node), WI_STR("field"))) { field_name = wi_xml_node_attribute_with_name(field_node, WI_STR("name")); field_value = wi_xml_node_content(field_node); field = wi_p7_spec_field_with_name(p7_message->spec, field_name); if(!field_name || !field_value || !field) continue; switch(wi_p7_spec_type_id(wi_p7_spec_field_type(field))) { case WI_P7_BOOL: wi_p7_message_set_bool_for_name(p7_message, wi_string_bool(field_value), field_name); break; case WI_P7_ENUM: wi_p7_message_set_enum_for_name(p7_message, wi_string_uint32(field_value), field_name); break; case WI_P7_INT32: wi_p7_message_set_int32_for_name(p7_message, wi_string_int32(field_value), field_name); break; case WI_P7_UINT32: wi_p7_message_set_uint32_for_name(p7_message, wi_string_uint32(field_value), field_name); break; case WI_P7_INT64: wi_p7_message_set_int64_for_name(p7_message, wi_string_int64(field_value), field_name); break; case WI_P7_UINT64: wi_p7_message_set_uint64_for_name(p7_message, wi_string_uint64(field_value), field_name); break; case WI_P7_DOUBLE: wi_p7_message_set_double_for_name(p7_message, wi_string_double(field_value), field_name); break; case WI_P7_STRING: wi_p7_message_set_string_for_name(p7_message, field_value, field_name); break; case WI_P7_UUID: uuid = wi_uuid_with_string(field_value); if(uuid) wi_p7_message_set_uuid_for_name(p7_message, uuid, field_name); break; case WI_P7_DATE: date = wi_date_with_rfc3339_string(field_value); if(date) wi_p7_message_set_date_for_name(p7_message, date, field_name); break; case WI_P7_DATA: data = wi_autorelease(wi_data_init_with_base64(wi_data_alloc(), field_value)); if(data) wi_p7_message_set_data_for_name(p7_message, data, field_name); break; case WI_P7_OOBDATA: wi_p7_message_set_oobdata_for_name(p7_message, wi_string_uint64(field_value), field_name); break; case WI_P7_LIST: WI_ASSERT(0, "Can't deserialize XML with lists at the moment"); break; } } } } } xmlFreeDoc(doc); } }
int main(int argc, const char **argv) { wi_pool_t *pool; wi_string_t *string; int ch, facility; wi_boolean_t no_chroot, test_config; /* init libwired */ wi_initialize(); wi_load(argc, argv); pool = wi_pool_init(wi_pool_alloc()); wi_log_startup = true; wi_log_syslog = true; wi_log_syslog_facility = LOG_DAEMON; /* init core systems */ wt_init_version(); wt_status_lock = wi_lock_init(wi_lock_alloc()); wt_start_date = wi_date_init(wi_date_alloc()); /* set defaults */ wi_root_path = wi_string_init_with_cstring(wi_string_alloc(), WT_ROOT); wi_settings_config_path = wi_string_init_with_cstring(wi_string_alloc(), WT_CONFIG_PATH); no_chroot = false; test_config = false; /* parse command line switches */ while((ch = getopt(argc, (char * const *) argv, "46Dd:f:hi:L:ls:tuVv")) != -1) { switch(ch) { case '4': wt_address_family = WI_ADDRESS_IPV4; break; case '6': wt_address_family = WI_ADDRESS_IPV6; break; case 'D': wt_daemonize = false; wi_log_stderr = true; break; case 'd': wi_release(wi_root_path); wi_root_path = wi_string_init_with_cstring(wi_string_alloc(), optarg); break; case 'f': wi_release(wi_settings_config_path); wi_settings_config_path = wi_string_init_with_cstring(wi_string_alloc(), optarg); break; case 'i': wi_log_limit = wi_string_uint32(wi_string_with_cstring(optarg)); break; case 'L': wi_log_syslog = false; wi_log_file = true; wi_release(wi_log_path); wi_log_path = wi_string_init_with_cstring(wi_string_alloc(), optarg); break; case 'l': wi_log_level++; break; case 's': string = wi_string_with_cstring(optarg); facility = wi_log_syslog_facility_with_name(string); if(facility < 0) { wi_log_err(WI_STR("Could not find syslog facility \"%@\": %m"), string); } wi_log_syslog_facility = facility; break; case 't': test_config = true; break; case 'u': no_chroot = true; break; case 'V': case 'v': wt_version(); break; case '?': case 'h': default: wt_usage(); break; } } /* open log */ wi_log_open(); /* init subsystems */ wt_init_ssl(); wt_init_clients(); wt_init_servers(); /* read the config file */ wt_settings_chroot = !no_chroot; wt_init_settings(); if(!wt_read_config()) exit(1); /* change root directory */ if(!no_chroot) { if(!wi_change_root()) wi_log_err(WI_STR("Could not change root to %@: %m"), wi_root_path); } /* apply config */ wt_apply_config(); if(test_config) { printf("Config OK\n"); exit(0); } /* dump command line */ if(wi_log_level >= WI_LOG_DEBUG) { wi_log_debug(WI_STR("Started as %@ %@"), wi_process_path(wi_process()), wi_array_components_joined_by_string(wi_process_arguments(wi_process()), WI_STR(" "))); } /* init tracker */ wi_log_info(WI_STR("Starting Wired Tracker version %@"), wt_version_string); wt_init_tracker(); /* detach (don't chdir, don't close i/o channels) */ if(wt_daemonize) { if(!wi_daemon()) wi_log_err(WI_STR("Could not become a daemon: %m")); } /* switch user/group */ wi_switch_user(wt_settings.user, wt_settings.group); /* create tracker threads after privilege drop */ wt_init_signals(); wt_block_signals(); wt_schedule_servers(); wt_fork_tracker(); wt_write_pid(); wt_write_status(true); wi_log_startup = false; wi_release(pool); pool = wi_pool_init(wi_pool_alloc()); /* enter the signal handling thread in the main thread */ wt_signal_thread(NULL); /* dropped out */ wt_cleanup(); wi_log_close(); wi_release(pool); return 0; }