static void handle_io(int retval, int fd, void* p_private) { long curr_sec; long curr_usec; unsigned int bw_rate; double elapsed; double pause_time; double rate_ratio; struct vsf_session* p_sess = (struct vsf_session*) p_private; if (p_sess->data_fd != fd || vsf_sysutil_retval_is_error(retval) || retval == 0) { return; } /* Note that the session hasn't stalled, i.e. don't time it out */ p_sess->data_progress = 1; /* Apply bandwidth quotas via a little pause, if necessary */ if (p_sess->bw_rate_max == 0) { return; } /* Calculate bandwidth rate */ vsf_sysutil_update_cached_time(); curr_sec = vsf_sysutil_get_cached_time_sec(); curr_usec = vsf_sysutil_get_cached_time_usec(); elapsed = (double) (curr_sec - p_sess->bw_send_start_sec); elapsed += (double) (curr_usec - p_sess->bw_send_start_usec) / (double) 1000000; if (elapsed <= (double) 0) { elapsed = (double) 0.01; } bw_rate = (unsigned int) ((double) retval / elapsed); if (bw_rate <= p_sess->bw_rate_max) { p_sess->bw_send_start_sec = curr_sec; p_sess->bw_send_start_usec = curr_usec; return; } /* Tut! Rate exceeded, calculate a pause to bring things back into line */ rate_ratio = (double) bw_rate / (double) p_sess->bw_rate_max; pause_time = (rate_ratio - (double) 1) * elapsed; vsf_sysutil_sleep(pause_time); vsf_sysutil_update_cached_time(); p_sess->bw_send_start_sec = vsf_sysutil_get_cached_time_sec(); p_sess->bw_send_start_usec = vsf_sysutil_get_cached_time_usec(); }
void vsf_log_start_entry(struct vsf_session* p_sess, enum EVSFLogEntryType what) { if (p_sess->log_type != 0) { bug("non null log_type in vsf_log_start_entry"); } p_sess->log_type = (unsigned long) what; p_sess->log_start_sec = 0; p_sess->log_start_usec = 0; p_sess->transfer_size = 0; str_empty(&p_sess->log_str); if (vsf_log_type_is_transfer(what)) { vsf_sysutil_update_cached_time(); p_sess->log_start_sec = vsf_sysutil_get_cached_time_sec(); p_sess->log_start_usec = vsf_sysutil_get_cached_time_usec(); } }
static void vsf_log_do_log_vsftpd_format(struct vsf_session* p_sess, struct mystr* p_str, int succeeded, enum EVSFLogEntryType what, const struct mystr* p_log_str) { /* Date - vsf_sysutil_get_current_date updates cached time */ str_alloc_text(p_str, vsf_sysutil_get_current_date()); /* Pid */ str_append_text(p_str, " [pid "); str_append_ulong(p_str, vsf_sysutil_getpid()); str_append_text(p_str, "] "); /* User */ if (!str_isempty(&p_sess->user_str)) { str_append_char(p_str, '['); str_append_str(p_str, &p_sess->user_str); str_append_text(p_str, "] "); } /* And the action */ if (what != kVSFLogEntryFTPInput && what != kVSFLogEntryFTPOutput && what != kVSFLogEntryConnection) { if (succeeded) { str_append_text(p_str, "OK "); } else { str_append_text(p_str, "FAIL "); } } switch (what) { case kVSFLogEntryDownload: str_append_text(p_str, "DOWNLOAD"); break; case kVSFLogEntryUpload: str_append_text(p_str, "UPLOAD"); break; case kVSFLogEntryMkdir: str_append_text(p_str, "MKDIR"); break; case kVSFLogEntryLogin: str_append_text(p_str, "LOGIN"); break; case kVSFLogEntryFTPInput: str_append_text(p_str, "FTP command"); break; case kVSFLogEntryFTPOutput: str_append_text(p_str, "FTP response"); break; case kVSFLogEntryConnection: str_append_text(p_str, "CONNECT"); break; case kVSFLogEntryDelete: str_append_text(p_str, "DELETE"); break; case kVSFLogEntryRename: str_append_text(p_str, "RENAME"); break; case kVSFLogEntryRmdir: str_append_text(p_str, "RMDIR"); break; case kVSFLogEntryChmod: str_append_text(p_str, "CHMOD"); break; default: bug("bad entry_type in vsf_log_do_log"); break; } str_append_text(p_str, ": Client \""); str_append_str(p_str, &p_sess->remote_ip_str); str_append_char(p_str, '"'); if (what == kVSFLogEntryLogin && !str_isempty(&p_sess->anon_pass_str)) { str_append_text(p_str, ", anon password \""); str_append_str(p_str, &p_sess->anon_pass_str); str_append_char(p_str, '"'); } if (!str_isempty(p_log_str)) { str_append_text(p_str, ", \""); str_append_str(p_str, p_log_str); str_append_char(p_str, '"'); } if (what != kVSFLogEntryFTPInput && what != kVSFLogEntryFTPOutput) { if (p_sess->transfer_size) { str_append_text(p_str, ", "); str_append_filesize_t(p_str, p_sess->transfer_size); str_append_text(p_str, " bytes"); } if (vsf_log_type_is_transfer(what)) { long delta_sec = vsf_sysutil_get_cached_time_sec() - p_sess->log_start_sec; long delta_usec = vsf_sysutil_get_cached_time_usec() - p_sess->log_start_usec; double time_delta = (double) delta_sec + ((double) delta_usec / (double) 1000000); double kbyte_rate = ((double) p_sess->transfer_size / time_delta) / (double) 1024; str_append_text(p_str, ", "); str_append_double(p_str, kbyte_rate); str_append_text(p_str, "Kbyte/sec"); } } }