static wi_p7_message_t * _wi_p7_socket_read_xml_message(wi_p7_socket_t *p7_socket, wi_time_interval_t timeout, wi_string_t *prefix) { wi_string_t *string; wi_p7_message_t *p7_message; p7_message = wi_autorelease(wi_p7_message_init(wi_p7_message_alloc(), p7_socket)); while(true) { string = wi_socket_read_to_string(p7_socket->socket, timeout, WI_STR(">")); if(!string || wi_string_length(string) == 0) return NULL; wi_string_delete_surrounding_whitespace(string); if(!p7_message->xml_string) p7_message->xml_string = wi_copy(string); else wi_string_append_string(p7_message->xml_string, string); if(wi_string_has_suffix(string, WI_STR("</p7:message>")) || (wi_string_has_suffix(string, WI_STR("/>")) && wi_string_has_prefix(string, WI_STR("<p7:message")))) { break; } } wi_retain(p7_message->xml_string); if(prefix) wi_string_insert_string_at_index(p7_message->xml_string, prefix, 0); wi_string_delete_surrounding_whitespace(p7_message->xml_string); return p7_message; }
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); }
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 wi_tests_run_test(const char *name, wi_run_test_func_t *function) { wi_pool_t *pool; wi_assert_handler_func_t *handler; wi_time_interval_t interval; if(_wi_tests_name) { if(wi_string_index_of_string(wi_string_with_utf8_string(name), _wi_tests_name, 0) == WI_NOT_FOUND) return; } if(wi_string_has_suffix(wi_string_with_utf8_string(name), WI_STR("initialize"))) { (*function)(); } else { _wi_tests_current_test = _wi_test_init_with_function(_wi_test_alloc(), wi_string_with_utf8_string(name), function); handler = wi_assert_handler; wi_assert_handler = _wi_tests_assert_handler; interval = wi_time_interval(); pool = wi_pool_init(wi_pool_alloc()); if(setjmp(_wi_tests_jmp_buf) == 0) (*_wi_tests_current_test->function)(); wi_release(pool); _wi_tests_current_test->interval = wi_time_interval() - interval; wi_assert_handler = handler; if(_wi_tests_current_test->passed) { wi_log_info(WI_STR("Test \"%@\" passed (%.3f seconds)"), _wi_tests_current_test->name, _wi_tests_current_test->interval); wi_tests_passed++; } else { wi_log_info(WI_STR("Test \"%@\" failed (%.3f seconds)"), _wi_tests_current_test->name, _wi_tests_current_test->interval); wi_tests_failed++; } wi_release(_wi_tests_current_test); } }
wi_string_t * wi_time_interval_string_with_format(wi_time_interval_t interval, wi_string_t *format) { struct tm tm; char string[1024]; time_t time; time = interval; memset(&tm, 0, sizeof(tm)); if(wi_string_has_suffix(format, WI_STR("Z"))) gmtime_r(&time, &tm); else localtime_r(&time, &tm); (void) strftime(string, sizeof(string), wi_string_utf8_string(format), &tm); return wi_string_with_utf8_string(string); }
wd_transfer_t * wd_transfer_upload_transfer(wi_string_t *path, wi_file_offset_t datasize, wi_file_offset_t rsrcsize, wi_boolean_t executable, wd_user_t *user, wi_p7_message_t *message) { wi_string_t *realdatapath, *realrsrcpath; wd_transfer_t *transfer; wi_file_offset_t dataoffset, rsrcoffset; wi_fs_stat_t sb; int datafd, rsrcfd; realdatapath = wi_string_by_resolving_aliases_in_path(wd_files_real_path(path, user)); if(wi_fs_stat_path(realdatapath, &sb)) { wd_user_reply_error(user, WI_STR("wired.error.file_exists"), message); return NULL; } if(!wi_string_has_suffix(realdatapath, WI_STR(WD_TRANSFERS_PARTIAL_EXTENSION))) realdatapath = wi_string_by_appending_path_extension(realdatapath, WI_STR(WD_TRANSFERS_PARTIAL_EXTENSION)); if(wi_fs_stat_path(realdatapath, &sb)) dataoffset = sb.size; else dataoffset = 0; datafd = open(wi_string_cstring(realdatapath), O_WRONLY | O_APPEND | O_CREAT, 0666); if(datafd < 0) { wi_log_error(WI_STR("Could not open \"%@\" for upload: %s"), realdatapath, strerror(errno)); wd_user_reply_file_errno(user, message); return NULL; } if(lseek(datafd, dataoffset, SEEK_SET) < 0) { wi_log_error(WI_STR("Could not seek to %llu in \"%@\" for upload: %s"), dataoffset, realdatapath, strerror(errno)); wd_user_reply_file_errno(user, message); close(datafd); return NULL; } if(rsrcsize > 0) { realrsrcpath = wi_fs_resource_fork_path_for_path(realdatapath); if(!realrsrcpath) { wd_user_reply_error(user, WI_STR("wired.error.rsrc_not_supported"), message); close(datafd); return NULL; } if(wi_fs_stat_path(realrsrcpath, &sb)) rsrcoffset = sb.size; else rsrcoffset = 0; rsrcfd = open(wi_string_cstring(realrsrcpath), O_WRONLY | O_APPEND | O_CREAT, 0666); if(rsrcfd < 0) { wi_log_error(WI_STR("Could not open \"%@\" for upload: %s"), realrsrcpath, strerror(errno)); wd_user_reply_file_errno(user, message); close(datafd); return NULL; } if(lseek(rsrcfd, rsrcoffset, SEEK_SET) < 0) { wi_log_error(WI_STR("Could not seek to %llu in \"%@\" for upload: %s"), rsrcoffset, realrsrcpath, strerror(errno)); wd_user_reply_file_errno(user, message); close(datafd); close(rsrcfd); return NULL; } } else { realrsrcpath = NULL; rsrcoffset = 0; rsrcfd = -1; } transfer = wd_transfer_init(wd_transfer_alloc()); transfer->type = WD_TRANSFER_UPLOAD; transfer->user = user; transfer->key = wi_retain(wd_transfers_transfer_key_for_user(user)); transfer->path = wi_retain(path); transfer->realdatapath = wi_retain(realdatapath); transfer->realrsrcpath = wi_retain(realrsrcpath); transfer->datafd = datafd; transfer->rsrcfd = rsrcfd; transfer->datasize = datasize; transfer->rsrcsize = rsrcsize; transfer->dataoffset = dataoffset; transfer->rsrcoffset = rsrcoffset; transfer->transferred = dataoffset + rsrcoffset; transfer->executable = executable; transfer->remainingdatasize = datasize - dataoffset; transfer->remainingrsrcsize = rsrcsize - rsrcoffset; return wi_autorelease(transfer); }
void wr_transfer_request(wr_transfer_t *transfer) { wi_string_t *local_path; wi_fs_stat_t sb; if(wi_array_count(transfer->local_paths) == 0) { wr_transfer_start_next_or_stop(transfer); return; } if(transfer->type == WR_TRANSFER_DOWNLOAD) { local_path = wi_array_first_data(transfer->local_paths); if(wi_fs_stat_path(local_path, &sb)) { if(!transfer->recursive) { wr_printf_prefix(WI_STR("get: File already exists at %@"), local_path); } wr_transfer_close(transfer); if(transfer->recursive) { transfer->total_transferred += sb.size; wr_transfer_start_next_or_stop(transfer); } return; } if(!wi_string_has_suffix(local_path, WI_STR(WR_TRANSFERS_SUFFIX))) { local_path = wi_string_by_appending_string(local_path, WI_STR(WR_TRANSFERS_SUFFIX)); wi_mutable_array_replace_data_at_index(transfer->local_paths, local_path, 0); } if(wi_fs_stat_path(local_path, &sb)) { transfer->file_offset = sb.size; if(sb.size >= WR_CHECKSUM_SIZE) transfer->checksum = wi_retain(wi_fs_sha1_for_path(local_path, WR_CHECKSUM_SIZE)); } transfer->file = wi_retain(wi_file_for_updating(local_path)); if(!transfer->file) { wr_printf_prefix(WI_STR("get: Could not open %@: %m"), local_path); wr_transfer_close(transfer); if(transfer->recursive) wr_transfer_start_next_or_stop(transfer); return; } transfer->file_size = wr_file_size(wi_array_first_data(transfer->files)); // wr_send_command(WI_STR("GET %#@%c%llu"), // wi_array_first_data(transfer->remote_paths), WR_FIELD_SEPARATOR, // transfer->file_offset); } else { local_path = wi_array_first_data(transfer->local_paths); transfer->file = wi_retain(wi_file_for_reading(local_path)); if(!transfer->file) { wr_printf_prefix(WI_STR("put: Could not open %@: %m"), local_path); wr_transfer_close(transfer); if(transfer->recursive) wr_transfer_start_next_or_stop(transfer); return; } if(!wi_fs_stat_path(local_path, &sb)) { wr_printf_prefix(WI_STR("put: Could not open %@: %m"), local_path); wr_transfer_close(transfer); if(transfer->recursive) wr_transfer_start_next_or_stop(transfer); return; } transfer->file_size = sb.size; transfer->checksum = wi_retain(wi_fs_sha1_for_path(local_path, WR_CHECKSUM_SIZE)); // wr_send_command(WI_STR("PUT %#@%c%llu%c%#@"), // wi_array_first_data(transfer->remote_paths), WR_FIELD_SEPARATOR, // transfer->file_size, WR_FIELD_SEPARATOR, // transfer->checksum); } }