Exemplo n.º 1
0
static void _wi_timer_thread(wi_runtime_instance_t *argument) {
	wi_pool_t			*pool;
	wi_timer_t			*timer, *fire_timer;
	wi_time_interval_t	interval, diff;
	wi_boolean_t		locked;
	
	pool = wi_pool_init(wi_pool_alloc());
	
	while(true) {
		fire_timer	= NULL;
		locked		= true;
		interval	= wi_time_interval();
		timer		= _wi_timer_first_timer();

		if(!timer) {
			locked = wi_condition_lock_lock_when_condition(_wi_timer_lock, 1, 0.0);

			timer = _wi_timer_first_timer();
			interval = wi_time_interval();

			if(timer && timer->fire - interval <= _WI_TIMER_MINIMUM_INTERVAL)
				fire_timer = timer;
		} else {
			diff = timer->fire - interval;

			if(diff <= _WI_TIMER_MINIMUM_INTERVAL) {
				fire_timer = timer;

				locked = false;
			} else {
				locked = wi_condition_lock_lock_when_condition(_wi_timer_lock, 1, diff);
				
				if(!locked)
					fire_timer = _wi_timer_first_timer();
			} 
		}

		if(locked)
			wi_condition_lock_unlock_with_condition(_wi_timer_lock, 0);
		
		if(fire_timer) {
			_wi_timer_invalidate(fire_timer);
				
			wi_timer_fire(fire_timer);

			if(timer->repeats)
				_wi_timer_schedule(fire_timer);
		}
		
		wi_pool_drain(pool);
	}

	wi_release(pool);
}
Exemplo n.º 2
0
static void wd_update_transfers(wi_timer_t *timer) {
	wi_list_node_t		*node, *next_node;
	wd_transfer_t		*transfer;
	wi_time_interval_t	interval;
	wi_boolean_t		update = false;

	if(wi_list_count(wd_transfers) > 0) {
		interval = wi_time_interval();

		wi_list_wrlock(wd_transfers);
		for(node = wi_list_first_node(wd_transfers); node; node = next_node) {
			next_node	= wi_list_node_next_node(node);
			transfer	= wi_list_node_data(node);

			if(transfer->state == WD_TRANSFER_WAITING) {
				if(transfer->queue_time + WD_TRANSFERS_WAITING_INTERVAL < interval) {
					wi_list_remove_node(wd_transfers, node);

					update = true;
				}
			}
		}
		wi_list_unlock(wd_transfers);

		if(update)
			wd_transfers_update_queue();
	}
}
Exemplo n.º 3
0
wi_boolean_t wi_condition_lock_lock_when_condition(wi_condition_lock_t *lock, int condition, wi_time_interval_t time) {
    struct timespec     ts;
    int                 err;
    
    if((err = pthread_mutex_lock(&lock->mutex)) != 0)
        WI_ASSERT(false, "pthread_mutex_lock: %s", strerror(err));
    
    if(lock->condition != condition) {
        if(time > 0.0) {
            ts = wi_dtots(wi_time_interval() + time);
            
            do {
                err = pthread_cond_timedwait(&lock->cond, &lock->mutex, &ts);

                if(err != 0 && err != ETIMEDOUT)
                    WI_ASSERT(false, "pthread_cond_timedwait: %s", strerror(err));
            } while(lock->condition != condition && err != ETIMEDOUT);

            if(err == ETIMEDOUT) {
                if((err = pthread_mutex_unlock(&lock->mutex)) != 0)
                    WI_ASSERT(false, "pthread_mutex_unlock: %s", strerror(err));
                
                return false;
            }
        } else {
            do {
                if((err = pthread_cond_wait(&lock->cond, &lock->mutex)) != 0)
                    WI_ASSERT(false, "pthread_cond_wait: %s", strerror(err));
            } while(lock->condition != condition);
        }
    }
    
    return true;
}
Exemplo n.º 4
0
static void wd_users_update_idle(wi_timer_t *timer) {
	wi_enumerator_t		*enumerator;
	wd_user_t			*user;
	wi_time_interval_t	interval;

	wi_dictionary_rdlock(wd_users);

	if(wi_dictionary_count(wd_users) > 0) {
		interval = wi_time_interval();

		enumerator = wi_dictionary_data_enumerator(wd_users);
		
		while((user = wi_enumerator_next_data(enumerator))) {
			wi_recursive_lock_lock(user->user_lock);
			
			if(user->state == WD_USER_LOGGED_IN && !user->idle &&
			   user->idle_time + wd_settings.idletime < interval) {
				user->idle = true;

				wd_user_broadcast_status(user);
			}

			wi_recursive_lock_unlock(user->user_lock);
		}
	}
		
	wi_dictionary_unlock(wd_users);
}
Exemplo n.º 5
0
void wr_draw_transfers(wi_boolean_t force) {
	static wi_time_interval_t	update;
	wi_enumerator_t				*enumerator;
	wi_mutable_string_t			*string;
    wi_string_t					*status;
	wr_transfer_t				*transfer;
	wi_time_interval_t			interval;
	wi_uinteger_t				i = 0;
	
	interval = wi_time_interval();
	
	if(!force && interval - update < 1.0)
		return;
	
	update = interval;
	
	wi_terminal_set_scroll(wr_terminal, wi_make_range(1 + wi_array_count(wr_transfers),
													  wi_terminal_size(wr_terminal).height - 4));
	
	enumerator = wi_array_data_enumerator(wr_transfers);
	
	while((transfer = wi_enumerator_next_data(enumerator))) {
		wi_terminal_move(wr_terminal, wi_make_point(0, i + 1));
		wi_terminal_clear_line(wr_terminal);
		
		if(transfer->state == WR_TRANSFER_RUNNING && interval - transfer->start_time > 0.0) {
			transfer->speed = ((double) transfer->total_transferred - transfer->total_offset) / (interval - transfer->start_time);
			
			status = wi_string_with_format(WI_STR("%@/%@, %@/s"),
                                           wr_files_string_for_size(transfer->total_transferred),
                                           wr_files_string_for_size(transfer->total_size),
                                           wr_files_string_for_size(transfer->speed));
		}
		else if(transfer->state == WR_TRANSFER_QUEUED) {
			status = wi_string_with_format(WI_STR("queued at %u"),
                                           transfer->queue);
		}
		else {
			status = wi_string_with_cstring("waiting");
		}
		
		string = wi_mutable_string_with_format(WI_STR("%u %3.0f%%  %@"),
                                               transfer->tid,
                                               transfer->total_size > 0
                                               ? 100 * ((double) transfer->total_transferred / (double) transfer->total_size)
                                               : 0,
                                               transfer->name);
		
		wi_terminal_adjust_string_to_fit_width(wr_terminal, string);
		wi_mutable_string_delete_characters_from_index(string, wi_string_length(string) - wi_string_length(status));
		wi_mutable_string_append_string(string, status);
		
		wi_terminal_printf(wr_terminal, WI_STR("%@"), string);
		
		i++;
	}
	
	wr_terminal_reset_location();
}
Exemplo n.º 6
0
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);
    }
}
Exemplo n.º 7
0
static wi_string_t * wd_tempban_description(wi_runtime_instance_t *instance) {
	wd_tempban_t		*tempban = instance;
	
	return wi_string_with_format(WI_STR("<%@ %p>{ip = %@, time_remaining = %.0f}"),
		wi_runtime_class_name(tempban),
		tempban,
		tempban->ip,
		wi_time_interval() - tempban->interval);
}
Exemplo n.º 8
0
static void _wi_timer_schedule(wi_timer_t *timer) {
	timer->fire = wi_time_interval() + timer->interval;
	
	wi_array_wrlock(_wi_timers);
	wi_mutable_array_add_data_sorted(_wi_timers, timer, _wi_timer_compare);
	wi_array_unlock(_wi_timers);
	
	timer->scheduled = true;
}
Exemplo n.º 9
0
static wd_transfer_t * wd_transfer_init(wd_transfer_t *transfer) {
	transfer->queue				= -1;
	transfer->queue_lock		= wi_condition_lock_init_with_condition(wi_condition_lock_alloc(), 0);
	transfer->queue_time		= wi_time_interval();
	transfer->state				= WD_TRANSFER_QUEUED;
	transfer->finished_lock		= wi_condition_lock_init_with_condition(wi_condition_lock_alloc(), 0);
	
	return transfer;
}
Exemplo n.º 10
0
static void wr_msg_202(wi_array_t *arguments) {
	wi_time_interval_t	interval;

	if(wr_ping_time > 0.0) {
		interval = wi_time_interval() - wr_ping_time;
		
		wr_wprintf_prefix(wr_console_window, WI_STR("Ping reply after %.2fms"), interval * 1000.0);
		
		wr_ping_time = 0.0;
	}
}
Exemplo n.º 11
0
void wt_control_thread(wi_runtime_instance_t *argument) {
	wi_pool_t			*pool;
	wt_client_t			*client = argument;
	wi_string_t			*string;
	wi_socket_state_t	state;
	wi_uinteger_t		i = 0;
	
	pool = wi_pool_init(wi_pool_alloc());

	wt_client_set(client);

	while(client->state <= WT_CLIENT_STATE_SAID_HELLO) {
		do {
			state = wi_socket_wait(client->socket, 0.1);
		} while(state == WI_SOCKET_TIMEOUT && client->state <= WT_CLIENT_STATE_SAID_HELLO);

		if(client->state > WT_CLIENT_STATE_SAID_HELLO) {
			/* invalid state */
			break;
		}

		if(state == WI_SOCKET_ERROR) {
			if(wi_error_code() == EINTR) {
				/* got a signal */
				continue;
			} else {
				/* error in TCP communication */
				wi_log_err(WI_STR("Could not read from %@: %m"), client->ip);

				break;
			}
		}

		string = wi_socket_read_to_string(client->socket, 0.0, WI_STR(WT_MESSAGE_SEPARATOR_STR));

		if(!string || wi_string_length(string) == 0) {
			if(!string)
				wi_log_info(WI_STR("Could not read from %@: %m"), client->ip);
			
			break;
		}

		wt_parse_command(string);
		
		if(++i % 10 == 0)
			wi_pool_drain(pool);
	}

	wi_log_info(WI_STR("Disconnect from %@ after %.2fs"),
		client->ip,
		wi_time_interval() - client->connect_time);
	
	wi_release(pool);
}
Exemplo n.º 12
0
static wd_transfer_t * wd_transfer_init_with_user(wd_transfer_t *transfer, wd_user_t *user) {
	transfer->state			= WD_TRANSFER_QUEUED;
	transfer->queue_time	= wi_time_interval();
	transfer->user			= wi_retain(user);
	transfer->hash			= wi_retain(wi_data_sha1(wi_data_with_random_bytes(1024)));
	transfer->socket_lock	= wi_lock_init(wi_lock_alloc());
	transfer->state_lock	= wi_condition_lock_init_with_condition(wi_condition_lock_alloc(), transfer->state);
	transfer->fd			= -1;

	return transfer;
}
Exemplo n.º 13
0
void wr_draw_transfers(wi_boolean_t force) {
	static wi_time_interval_t	update;
	wi_list_node_t				*node;
	wi_string_t					*string, *status;
	wr_transfer_t				*transfer;
	wi_time_interval_t			interval;
	unsigned int				i = 0;
	
	interval = wi_time_interval();
	
	if(!force && interval - update < 1.0)
		return;
	
	update = interval;
	
	wi_terminal_set_scroll(wr_terminal, wi_make_range(1 + wi_list_count(wr_transfers),
													  wi_terminal_size(wr_terminal).height - 3));
	
	WI_LIST_FOREACH(wr_transfers, node, transfer) {
		wi_terminal_move(wr_terminal, wi_make_point(0, i + 1));
		wi_terminal_clear_line(wr_terminal);
		
		if(transfer->state == WR_TRANSFER_RUNNING && interval - transfer->start_time > 0.0) {
			transfer->speed = ((double) transfer->transferred - transfer->offset) / (interval - transfer->start_time);
			
			status = wi_string_with_format(WI_STR("%@/%@, %@/s"),
				wr_files_string_for_size(transfer->transferred),
				wr_files_string_for_size(transfer->size),
				wr_files_string_for_size(transfer->speed));
		}
		else if(transfer->state == WR_TRANSFER_QUEUED) {
			status = wi_string_with_format(WI_STR("queued at %u"),
				transfer->queue);
		}
		else {
			status = wi_string_with_cstring("waiting");
		}
		
		string = wi_string_with_format(WI_STR("%u %3.0f%%  %@"),
			transfer->tid,
			transfer->size > 0
				? 100 * ((double) transfer->transferred / (double) transfer->size)
				: 0,
			transfer->name);
		
		wi_terminal_adjust_string_to_fit_width(wr_terminal, string);
		wi_string_delete_characters_from_index(string, wi_string_length(string) - wi_string_length(status));
		wi_string_append_string(string, status);
		
		wi_terminal_printf(wr_terminal, WI_STR("%@"), string);
		
		i++;
	}
Exemplo n.º 14
0
wi_boolean_t wd_banlist_add_ban(wi_string_t *ip, wi_date_t *expiration_date, wd_user_t *user, wi_p7_message_t *message) {
	wi_dictionary_t		*results;
	wi_string_t			*string;
	
    // check for negative expiration date
	if(expiration_date && wi_date_time_interval(expiration_date) - wi_time_interval() < 1.0) {
		wi_log_error(WI_STR("Could not add ban for \"%@\" expiring at %@: Negative expiration date"),
			ip, wi_date_string_with_format(expiration_date, WI_STR("%Y-%m-%d %H:%M:%S")));
		wd_user_reply_internal_error(user, WI_STR("Ban has negative expiration date"), message);
		
		return false;
	}
	
    // check if an entry already exists for this IP address in the database
	results = wi_sqlite3_execute_statement(wd_database, WI_STR("SELECT ip FROM banlist WHERE ip = ?"),
										   ip,
										   NULL);
    
	// prevents for database statement error
    if(!results) {
		wi_log_error(WI_STR("Could not execute database statement: %m"));
		wd_user_reply_internal_error(user, wi_error_string(), message);
		return false;
	}
	
    // if an entry already exists, replay ban_exists error message and stop
	if(wi_dictionary_count(results) > 0) {
		wd_user_reply_error(user, WI_STR("wired.error.ban_exists"), message);
		
		return false;
	}
	
    // check if the ban is limited in time or not
	string = expiration_date ? wi_date_sqlite3_string(expiration_date) : NULL;
    
    // finally add the new ban entry to the database
	if(!wi_sqlite3_execute_statement(wd_database, WI_STR("INSERT INTO banlist "
														 "(ip, expiration_date) "
														 "VALUES "
														 "(?, ?)"),
									 ip,
									 string,
									 NULL)) {
		wi_log_error(WI_STR("Could not execute database statement: %m"));
		wd_user_reply_internal_error(user, wi_error_string(), message);
		
		return false;
	}
	
	return true;
}
Exemplo n.º 15
0
static void wr_msg_400(wi_array_t *arguments) {
	wi_address_t		*address;
	wr_transfer_t		*transfer;

	transfer = wr_transfers_transfer_with_path(WI_ARRAY(arguments, 0));

	if(!transfer)
		return;
	
	address = wi_copy(wr_address);
	wi_address_set_port(address, wi_address_port(address) + 1);
	
	transfer->state			= WR_TRANSFER_RUNNING;
	transfer->offset		= wi_string_uint64(WI_ARRAY(arguments, 1));
	transfer->transferred	= transfer->offset;
	transfer->key			= wi_retain(WI_ARRAY(arguments, 2));
	transfer->start_time	= wi_time_interval();
	transfer->socket		= wi_socket_init_with_address(wi_socket_alloc(), address, WI_SOCKET_TCP);

	wi_socket_set_interactive(transfer->socket, false);
	
	if(!wi_socket_connect(transfer->socket, wr_socket_context, 15.0)) {
		wr_printf_prefix(WI_STR("Could not connect to %@: %m"), wi_address_string(address));
		
		wr_transfer_stop(transfer);

		goto end;
	}
	
	wi_file_seek(transfer->file, transfer->offset);

	if(transfer->type == WR_TRANSFER_DOWNLOAD) {
		wi_socket_set_direction(transfer->socket, WI_SOCKET_READ);
		wr_runloop_add_socket(transfer->socket, wr_runloop_download_callback);
	} else {
		wi_socket_set_direction(transfer->socket, WI_SOCKET_WRITE);
		wr_runloop_add_socket(transfer->socket, wr_runloop_upload_callback);
	}

	wr_send_command_on_socket(transfer->socket, WI_STR("TRANSFER %#@"), transfer->key);

	wr_printf_prefix(WI_STR("Starting transfer of \"%@\""), transfer->name);
	
	wr_draw_transfers(true);

end:
	wi_release(address);
}
Exemplo n.º 16
0
static wd_user_t * wd_user_init_with_socket(wd_user_t *user, wi_socket_t *socket) {
	wi_address_t	*address;

	user->uid				= wd_user_next_uid();
	user->socket			= wi_retain(socket);
	user->state				= WD_USER_CONNECTED;
	user->login_time		= wi_time_interval();
	user->idle_time			= user->login_time;
	
	address					= wi_socket_address(socket);
	user->ip				= wi_retain(wi_address_string(address));
	user->host				= wi_retain(wi_address_hostname(address));
	
	user->user_lock			= wi_recursive_lock_init(wi_recursive_lock_alloc());
	user->socket_lock		= wi_lock_init(wi_lock_alloc());
	
	user->transfers_queue	= wi_array_init(wi_array_alloc());

	return user;
}
Exemplo n.º 17
0
static void wt_update_servers(wi_timer_t *timer) {
	wi_enumerator_t		*enumerator;
	wt_server_t			*server;
	void				*key;
	wi_time_interval_t	interval, update;
	wi_boolean_t		changed = false;

	wi_dictionary_wrlock(wt_servers);
		
	if(wi_dictionary_count(wt_servers) > 0) {
		interval = wi_time_interval();

		enumerator = wi_array_data_enumerator(wi_dictionary_all_keys(wt_servers));
		
		while((key = wi_enumerator_next_data(enumerator))) {
			server = wi_dictionary_data_for_key(wt_servers, key);
			update = server->update_time > 0.0 ? server->update_time : server->register_time;
			
			if(interval - update > wt_settings.minupdatetime) {
				wi_log_warn(WI_STR("Deleting \"%@\" with URL %@: Last update %.0f seconds ago considered too slow"),
							server->name, server->url, interval - update);

				wt_servers_remove_stats_for_server(server);
				wi_dictionary_remove_data_for_key(wt_servers, key);
				
				changed = true;
			}
		}
	}

	wi_dictionary_unlock(wt_servers);

	if(changed) {
		wi_lock_lock(wt_status_lock);
		wt_write_status(true);
		wi_lock_unlock(wt_status_lock);

		wt_servers_write_file();
	}
}
Exemplo n.º 18
0
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));
}
Exemplo n.º 19
0
static void wt_update_servers(wi_timer_t *timer) {
	wi_list_node_t		*node, *next_node;
	wt_server_t			*server;
	wi_time_interval_t	interval, update;
	unsigned int		count = 0;

	if(wi_list_count(wt_servers) > 0) {
		interval = wi_time_interval();

		wi_list_rdlock(wt_servers);
		for(node = wi_list_first_node(wt_servers); node; node = next_node) {
			next_node	= wi_list_node_next_node(node);
			server		= wi_list_node_data(node);
			update		= server->update_time > 0.0 ? server->update_time : server->register_time;

			if(interval - update > wt_settings.minupdatetime) {
				wi_log_warn(WI_STR("Deleting \"%@\" with URL %@: Last update %.0f seconds ago considered too slow"),
					server->name, server->url, interval - update);

				wt_server_stats_remove(server);
				wi_list_remove_node(wt_servers, node);

				count++;
			}
		}
		wi_list_unlock(wt_servers);

		if(count > 0) {
			wi_lock_lock(wt_status_lock);
			wt_write_status(true);
			wi_lock_unlock(wt_status_lock);

			wt_write_servers();
		}
	}
}
Exemplo n.º 20
0
wi_time_interval_t wi_date_time_interval_since_now(wi_date_t *date) {
	return wi_time_interval() - date->interval;
}
Exemplo n.º 21
0
wi_date_t * wi_date_init(wi_date_t *date) {
	return wi_date_init_with_time_interval(date, wi_time_interval());
}
Exemplo n.º 22
0
void wt_read_servers(void) {
	FILE				*fp;
	wt_server_packed_t	server_packed;
	wt_server_t			*server;
	char				magic[5];
	wi_time_interval_t	interval, update;
	unsigned int		version, count = 0;

	wi_lock_lock(wt_servers_lock);
	fp = fopen(wi_string_cstring(wt_settings.servers), "r");

	if(!fp) {
		if(errno != ENOENT) {
			wi_log_err(WI_STR("Could not open %@: %s"),
				wt_settings.servers, strerror(errno));
		}

		goto end;
	}

	if(fread(&magic, 4, 1, fp) != 1 || strncmp(magic, WT_SERVER_MAGIC, 4) != 0) {
		wi_log_warn(WI_STR("Could not read %@: %s"), wt_settings.servers, "Not a server file");

		goto end;
	}

	if(fread(&version, 4, 1, fp) != 1 || version != WT_SERVER_VERSION) {
		wi_log_warn(WI_STR("Could not read %@: %s"), wt_settings.servers, "Wrong version");

		goto end;
	}

	wi_log_info(WI_STR("Reading %@"), wt_settings.servers);

	interval = wi_time_interval();

	wi_list_wrlock(wt_servers);
	while((fread(&server_packed, sizeof(wt_server_packed_t), 1, fp)) > 0) {
		update = server_packed.update_time > 0 ? server_packed.update_time : server_packed.register_time;

		if(interval - update < wt_settings.minupdatetime) {
			server = wt_server_init_with_packed(wt_server_alloc(), server_packed);

			wi_lock_lock(wt_status_lock);
			wt_current_servers++;
			wt_current_users += server->users;
			wt_current_files += server->files;
			wt_current_size += server->size;
			wi_lock_unlock(wt_status_lock);

			wi_list_append_data(wt_servers, server);
			wi_release(server);

			count++;
		}
	}
	wi_list_unlock(wt_servers);

	if(count > 0) {
		wi_lock_lock(wt_status_lock);
		wt_write_status(true);
		wi_lock_unlock(wt_status_lock);

		wi_log_info(WI_STR("Loaded %u %s from %@"),
			count,
			count == 1
				? "server"
				: "servers",
			wt_settings.servers);
	}

end:
	wi_lock_unlock(wt_servers_lock);
}
Exemplo n.º 23
0
void wd_transfers_update_queue(void) {
	wi_list_node_t      *client_node, *transfer_node;
	wd_transfer_t       *transfer;
	wd_client_t         *client;
	unsigned int        position_downloads, position_uploads;
	unsigned int        client_downloads, client_uploads;
	unsigned int        all_downloads, all_uploads;
	unsigned int        position;

	wi_list_rdlock(wd_clients);
	wi_list_rdlock(wd_transfers);

	/* count total number of active transfers */
	all_downloads = all_uploads = 0;

	WI_LIST_FOREACH(wd_transfers, transfer_node, transfer) {
		if(transfer->state == WD_TRANSFER_WAITING ||
		   transfer->state == WD_TRANSFER_RUNNING) {
			if(transfer->type == WD_TRANSFER_DOWNLOAD)
				all_downloads++;
			else
				all_uploads++;
		}
	}

	WI_LIST_FOREACH(wd_clients, client_node, client) {
		position_downloads = position_uploads = 0;
		client_downloads = client_uploads = 0;

		/* count number of active transfers for this client */
		WI_LIST_FOREACH(wd_transfers, transfer_node, transfer) {
			if(transfer->client == client) {
				if(transfer->state == WD_TRANSFER_WAITING ||
				   transfer->state == WD_TRANSFER_RUNNING) {
					if(transfer->type == WD_TRANSFER_DOWNLOAD)
						client_downloads++;
					else
						client_uploads++;
				}
			}
		}

		/* traverse the transfer queue */
		WI_LIST_FOREACH(wd_transfers, transfer_node, transfer) {
			if(transfer->type == WD_TRANSFER_DOWNLOAD)
				position_downloads++;
			else
				position_uploads++;

			if(transfer->state == WD_TRANSFER_QUEUED && transfer->client == client) {
				/* calculate number in queue */
				if(transfer->type == WD_TRANSFER_DOWNLOAD) {
					if(all_downloads >= wd_settings.totaldownloads)
						position = position_downloads - all_downloads;
					else if(client_downloads >= wd_settings.clientdownloads)
						position = position_downloads - client_downloads;
					else
						position = 0;
				} else {
					if(all_uploads >= wd_settings.totaluploads)
						position = position_uploads - all_uploads;
					else if(client_uploads >= wd_settings.clientuploads)
						position = position_uploads - client_uploads;
					else
						position = 0;
				}

				if(position > 0) {
					if(transfer->queue != position) {
						/* queue position changed */
						transfer->queue = position;

						wd_client_lock_socket(client);
						wd_sreply(client->socket, 401, WI_STR("%#@%c%u"),
								  transfer->path,	WD_FIELD_SEPARATOR,
								  transfer->queue);
						wd_client_unlock_socket(client);
					}
				} else {
					/* queue position reached 0 */
					transfer->queue = 0;
					transfer->state = WD_TRANSFER_WAITING;
					transfer->queue_time = wi_time_interval();

					wd_client_lock_socket(client);
					wd_sreply(client->socket, 400, WI_STR("%#@%c%llu%c%#@"),
							  transfer->path,		WD_FIELD_SEPARATOR,
							  transfer->offset,		WD_FIELD_SEPARATOR,
							  transfer->hash);
					wd_client_unlock_socket(client);

					if(transfer->type == WD_TRANSFER_DOWNLOAD) {
						all_downloads++;
						client_downloads++;
					} else {
						all_uploads++;
						client_uploads++;
					}
				}
			}
		}
	}
Exemplo n.º 24
0
static void wd_transfers_update_queue(void) {
	wi_mutable_set_t		*users;
	wi_mutable_array_t		*sorted_users, *transfers_queue, *failed_transfers;
	wd_transfer_t			*transfer;
	wd_user_t				*user;
	wi_uinteger_t			position;
	wi_uinteger_t			i, count;
	wi_uinteger_t			total_downloads, total_uploads, user_downloads, user_uploads, active_downloads, active_uploads;
	wi_boolean_t			queue;
	
	wi_array_rdlock(wd_transfers);
	
	total_downloads		= wd_settings.totaldownloads;
	user_downloads		= wd_settings.clientdownloads;
	total_uploads		= wd_settings.totaluploads;
	user_uploads		= wd_settings.clientuploads;
	active_downloads	= 0;
	active_uploads		= 0;
	
	failed_transfers	= wi_array_init(wi_mutable_array_alloc());

	users				= wi_set_init(wi_mutable_set_alloc());
	count				= wi_array_count(wd_transfers);
	
	for(i = 0; i < count; i++) {
		transfer = WI_ARRAY(wd_transfers, i);
		
		if(wd_transfer_state(transfer) == WD_TRANSFER_QUEUED) {
			wi_mutable_array_add_data(wd_user_transfers_queue(transfer->user), transfer);
			wi_mutable_set_add_data(users, transfer->user);
		}
		
		wd_user_clear_downloads(transfer->user);
		wd_user_clear_uploads(transfer->user);
	}
	
	for(i = 0; i < count; i++) {
		transfer = WI_ARRAY(wd_transfers, i);
		
		if(wd_transfer_state(transfer) == WD_TRANSFER_RUNNING) {
			if(transfer->type == WD_TRANSFER_DOWNLOAD) {
				active_downloads++;
				wd_user_increase_downloads(transfer->user);
			} else {
				active_uploads++;
				wd_user_increase_uploads(transfer->user);
			}
		}
	}

	count = wi_set_count(users);
	
	if(count > 0) {
		sorted_users = wi_autorelease(wi_mutable_copy(wi_set_all_data(users)));
		
		wi_mutable_array_sort(sorted_users, wd_transfers_compare_user);
		
		position = 1;
		
		while(count > 0) {
			for(i = 0; i < count; i++) {
				user = WI_ARRAY(sorted_users, i);
				transfers_queue = wd_user_transfers_queue(user);
				transfer = WI_ARRAY(transfers_queue, 0);
				
				if(transfer->type == WD_TRANSFER_DOWNLOAD) {
					queue = ((total_downloads > 0 && active_downloads >= total_downloads) ||
							 (user_downloads > 0 && wd_user_downloads(transfer->user) >= user_downloads));
				} else {
					queue = ((total_uploads > 0 && active_uploads >= total_uploads) ||
							 (user_uploads > 0 && wd_user_uploads(transfer->user) >= user_uploads));
				}
				
				if(queue) {
					if(transfer->queue != position) {
						transfer->queue = position;
						
						wd_user_lock_socket(transfer->user);
						wd_sreply(wd_user_socket(transfer->user), 401, WI_STR("%#@%c%u"),
								  transfer->path,	WD_FIELD_SEPARATOR,
								  transfer->queue);
						wd_user_unlock_socket(transfer->user);
					}

					position++;
				} else {
					transfer->queue = 0;
					transfer->waiting_time = wi_time_interval();
					
					wd_transfer_set_state(transfer, WD_TRANSFER_WAITING);
					
					if(wd_transfer_open(transfer)) {
						wd_transfer_create_timer(transfer);
						
						wd_user_lock_socket(transfer->user);
						wd_sreply(wd_user_socket(transfer->user), 400, WI_STR("%#@%c%llu%c%#@"),
								  transfer->path,		WD_FIELD_SEPARATOR,
								  transfer->offset,		WD_FIELD_SEPARATOR,
								  transfer->hash);
						wd_user_unlock_socket(transfer->user);
					} else {
						wd_user_lock_socket(transfer->user);
						wd_sreply(wd_user_socket(transfer->user), 500, WI_STR("Command Failed"));
						wd_user_unlock_socket(transfer->user);
						
						wi_mutable_array_add_data(failed_transfers, transfer);
					}
				}
				
				wi_mutable_array_remove_data_at_index(transfers_queue, 0);
				
				if(wi_array_count(transfers_queue) == 0) {
					wi_mutable_array_remove_data_at_index(sorted_users, i);
					
					i--;
					count--;
				}
			}
		}
	}
	
	wi_mutable_array_remove_data_in_array(wd_transfers, failed_transfers);
	wi_array_unlock(wd_transfers);
	
	wi_release(users);
	wi_release(failed_transfers);
}
Exemplo n.º 25
0
static wi_boolean_t wd_transfer_download(wd_transfer_t *transfer) {
	wi_pool_t				*pool;
	wi_socket_t				*socket;
	wi_p7_socket_t			*p7_socket;
	wd_account_t			*account;
	char					buffer[WD_TRANSFER_BUFFER_SIZE];
	wi_socket_state_t		state;
	wi_time_interval_t		timeout, interval, speedinterval, statusinterval, accountinterval;
	wi_file_offset_t		sendbytes, speedbytes, statsbytes;
	wi_uinteger_t			i, transfers;
	ssize_t					readbytes;
	int						sd;
	wi_boolean_t			data, result;
	wd_user_state_t			user_state;
	
	interval				= wi_time_interval();
	speedinterval			= interval;
	statusinterval			= interval;
	accountinterval			= interval;
	speedbytes				= 0;
	statsbytes				= 0;
	i						= 0;
	socket					= wd_user_socket(transfer->user);
	sd						= wi_socket_descriptor(socket);
	p7_socket				= wd_user_p7_socket(transfer->user);
	account					= wd_user_account(transfer->user);
	data					= true;
	result					= true;
	
	wd_transfers_note_statistics(WD_TRANSFER_DOWNLOAD, WD_TRANSFER_STATISTICS_ADD, 0);
	
	wi_dictionary_rdlock(wd_transfers_user_downloads);
	
	transfers = (wi_integer_t) wi_dictionary_data_for_key(wd_transfers_user_downloads, transfer->key);
	
	wi_dictionary_unlock(wd_transfers_user_downloads);

	pool = wi_pool_init(wi_pool_alloc());
	
	wd_user_lock_socket(transfer->user);
	
	while(wd_user_state(transfer->user) == WD_USER_LOGGED_IN) {
		if(data && transfer->remainingdatasize == 0)
			data = false;
			  
		if(!data && transfer->remainingrsrcsize == 0)
			break;
		
		readbytes = read(data ? transfer->datafd : transfer->rsrcfd, buffer, sizeof(buffer));
		
		if(readbytes <= 0) {
			if(readbytes < 0) {
				wi_log_error(WI_STR("Could not read download from \"%@\": %m"),
					data ? transfer->realdatapath : transfer->realrsrcpath, strerror(errno));
			}
			
			result = false;
			break;
		}

		timeout = wi_time_interval();
		
		do {
			user_state		= wd_user_state(transfer->user);
			state			= wi_socket_wait_descriptor(sd, 0.1, false, true);
			
			if(state == WI_SOCKET_TIMEOUT) {
				if(wi_time_interval() - timeout >= 30.0)
					break;
			}
		} while(state == WI_SOCKET_TIMEOUT && user_state == WD_USER_LOGGED_IN);

		if(state == WI_SOCKET_ERROR || wi_time_interval() - timeout >= 30.0) {
			wi_log_error(WI_STR("Could not wait for download to %@: %@"),
				wd_user_identifier(transfer->user),
				(state == WI_SOCKET_ERROR) ? wi_error_string() : WI_STR("Timed out"));
			
			result = false;
			break;
		}
		
		if(user_state != WD_USER_LOGGED_IN) {
			result = false;
			break;
		}

		if(data) {
			sendbytes = (transfer->remainingdatasize < (wi_file_offset_t) readbytes)
				? transfer->remainingdatasize
				: (wi_file_offset_t) readbytes;
		} else {
			sendbytes = (transfer->remainingrsrcsize < (wi_file_offset_t) readbytes)
				? transfer->remainingrsrcsize
				: (wi_file_offset_t) readbytes;
		}
		
		if(!wi_p7_socket_write_oobdata(p7_socket, 30.0, buffer, sendbytes)) {
			wi_log_error(WI_STR("Could not write download to %@: %m"),
				wd_user_identifier(transfer->user));
			
			result = false;
			break;
		}
		
		if(data)
			transfer->remainingdatasize		-= sendbytes;
		else
			transfer->remainingrsrcsize		-= sendbytes;
		
		interval							= wi_time_interval();
		transfer->transferred				+= sendbytes;
		transfer->actualtransferred			+= sendbytes;
		speedbytes							+= sendbytes;
		statsbytes							+= sendbytes;
		transfer->speed						= speedbytes / (interval - speedinterval);

		wd_transfer_limit_speed(transfer,
								wd_transfers_total_download_speed,
								wd_account_transfer_download_speed_limit(account),
								wd_current_downloads,
								transfers,
								speedbytes,
								interval,
								speedinterval);
		
		if(interval - speedinterval > 30.0) {
			speedbytes = 0;
			speedinterval = interval;
		}

		if(interval - statusinterval > wd_current_downloads) {
			wd_transfers_note_statistics(WD_TRANSFER_DOWNLOAD, WD_TRANSFER_STATISTICS_DATA, statsbytes);

			statsbytes = 0;
			statusinterval = interval;
		}
		
		if(interval - accountinterval > 15.0) {
			account = wd_user_account(transfer->user);
			accountinterval = interval;

			wi_dictionary_rdlock(wd_transfers_user_downloads);
			
			transfers = (wi_integer_t) wi_dictionary_data_for_key(wd_transfers_user_downloads, transfer->key);
			
			wi_dictionary_unlock(wd_transfers_user_downloads);
		}
		
		if(++i % 1000 == 0)
			wi_pool_drain(pool);
	}
	
	wd_user_unlock_socket(transfer->user);
	
	wi_release(pool);

	wd_transfers_note_statistics(WD_TRANSFER_DOWNLOAD, WD_TRANSFER_STATISTICS_REMOVE, statsbytes);
	
	return result;
}
Exemplo n.º 26
0
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);
}
Exemplo n.º 27
0
static void wd_transfer_upload(wd_transfer_t *transfer) {
	wi_pool_t				*pool;
	wi_string_t				*path;
	wd_account_t			*account;
	char					buffer[WD_TRANSFER_BUFFER_SIZE];
	wi_time_interval_t		timeout, interval, speedinterval, statusinterval, accountinterval;
	wi_socket_state_t		state;
	ssize_t					result, speedbytes, statsbytes;
	int						sd, bytes;

	pool = wi_pool_init(wi_pool_alloc());

	/* start upload */
	wi_log_info(WI_STR("Receiving \"%@\" from %@"),
		transfer->path,
		wd_user_identifier(transfer->user));
	
	wi_socket_set_direction(transfer->socket, WI_SOCKET_READ);

//	if(!wi_socket_set_blocking(transfer->socket, false))
//		wi_log_warn(WI_STR("Could not set non-blocking for %@: %m"), wd_user_ip(transfer->user));

	sd = wi_socket_descriptor(transfer->socket);
	speedinterval = statusinterval = accountinterval = wi_time_interval();
	speedbytes = statsbytes = 0;
	account = wd_user_account(transfer->user);

	/* update status */
	wi_lock_lock(wd_status_lock);
	wd_current_uploads++;
	wd_total_uploads++;
	wd_write_status(true);
	wi_lock_unlock(wd_status_lock);

	while(wd_transfer_state(transfer) == WD_TRANSFER_RUNNING && transfer->transferred < transfer->size) {
		/* wait to read */
		timeout = 0.0;
		
		do {
			state = wi_socket_wait_descriptor(sd, 0.1, true, false);
			
			if(state == WI_SOCKET_TIMEOUT) {
				timeout += 0.1;
				
				if(timeout >= 30.0)
					break;
			}
		} while(state == WI_SOCKET_TIMEOUT && wd_transfer_state(transfer) == WD_TRANSFER_RUNNING);
		
		if(state == WI_SOCKET_ERROR) {
			wi_log_err(WI_STR("Could not wait for upload from %@: %m"),
				wd_user_ip(transfer->user));

			break;
		}
		
		if(timeout >= 30.0) {
			wi_log_err(WI_STR("Timed out waiting to read upload from %@"),
				wd_user_ip(transfer->user));
			
			break;
		}

		/* read data */
		bytes = wi_socket_read_buffer(transfer->socket, 30.0, buffer, sizeof(buffer));
		
		if(bytes <= 0) {
			if(bytes < 0) {
				wi_log_err(WI_STR("Could not read upload from %@: %m"),
					wd_user_ip(transfer->user));
			}
			
			break;
		}
		
		if((wi_file_offset_t) bytes > transfer->size - transfer->transferred)
			bytes = transfer->size - transfer->transferred;

		/* write data */
		result = write(transfer->fd, buffer, bytes);
		
		if(result <= 0) {
			if(result < 0) {
				wi_log_err(WI_STR("Could not write upload to %@: %s"),
					transfer->realpath, strerror(errno));
			}
			
			break;
		}

		/* update counters */
		interval = wi_time_interval();
		transfer->transferred += bytes;
		speedbytes += bytes;
		statsbytes += bytes;

		/* update speed */
		transfer->speed = speedbytes / (interval - speedinterval);

		wd_transfer_limit_upload_speed(transfer, account, speedbytes, interval, speedinterval);
		
		if(interval - speedinterval > 30.0) {
			speedbytes = 0;
			speedinterval = interval;
		}

		/* update status */
		if(interval - statusinterval > wd_current_uploads) {
			wi_lock_lock(wd_status_lock);
			wd_uploads_traffic += statsbytes;
			wd_write_status(false);
			wi_lock_unlock(wd_status_lock);

			statsbytes = 0;
			statusinterval = interval;
		}
		
		/* update account */
		if(interval - accountinterval > 15.0) {
			account = wd_user_account(transfer->user);
			accountinterval = interval;
		}
		
		wi_pool_drain(pool);
	}

	wi_log_info(WI_STR("Received %@/%@ (%llu/%llu bytes) of \"%@\" from %@"),
		wd_files_string_for_bytes(transfer->transferred - transfer->offset),
		wd_files_string_for_bytes(transfer->size - transfer->offset),
		transfer->transferred - transfer->offset,
		transfer->size - transfer->offset,
		transfer->path,
		wd_user_identifier(transfer->user));

	/* update status */
	wd_transfer_set_state(transfer, WD_TRANSFER_STOPPED);
	
	wi_lock_lock(wd_status_lock);
	wd_current_uploads--;
	wd_uploads_traffic += statsbytes;
	wd_write_status(true);
	wi_lock_unlock(wd_status_lock);

	if(transfer->transferred == transfer->size) {
		path = wi_string_by_deleting_path_extension(transfer->realpath);

		if(wi_fs_rename_path(transfer->realpath, path)) {
			path = wi_string_by_appending_path_extension(transfer->path, WI_STR(WD_TRANSFERS_PARTIAL_EXTENSION));

			wd_files_move_comment(path, transfer->path);
		} else {
			wi_log_warn(WI_STR("Could not move %@ to %@: %m"),
				transfer->realpath, path);
		}
	}

	wi_release(pool);
}
Exemplo n.º 28
0
static wd_tempban_t * wd_tempban_init_with_ip(wd_tempban_t *tempban, wi_string_t *ip) {
	tempban->ip			= wi_retain(ip);
	tempban->interval	= wi_time_interval();
	
	return tempban;
}