static void handle_sigterm(void* duff) { (void) duff; /* Blow away the connection to make sure no process lingers. */ vsf_sysutil_shutdown_failok(VSFTP_COMMAND_FD); /* Will call the registered exit function to clean up u/wtmp if needed. */ vsf_sysutil_exit(1); }
void vsf_cmdio_write_exit(struct vsf_session* p_sess, int status, const char* p_text) { /* Unblock any readers on the dying control channel. This is needed for SSL * connections, where the SSL control channel slave is in a separate * process. */ vsf_sysutil_shutdown_read_failok(VSFTP_COMMAND_FD); ftp_write_text_common(p_sess, status, p_text, 1, ' '); vsf_sysutil_shutdown_failok(VSFTP_COMMAND_FD); vsf_sysutil_exit(0); }
static void handle_sigalrm(void* p_private) { struct vsf_session* p_sess = (struct vsf_session*) p_private; if (!p_sess->data_progress) { p_sess->data_timeout = 1; vsf_sysutil_shutdown_failok(p_sess->data_fd); vsf_sysutil_shutdown_read_failok(VSFTP_COMMAND_FD); vsf_sysutil_activate_noblock(VSFTP_COMMAND_FD); } else { p_sess->data_progress = 0; start_data_alarm(p_sess); } }
static void handle_sigurg(void* p_private) { struct mystr async_cmd_str = INIT_MYSTR; struct mystr async_arg_str = INIT_MYSTR; struct mystr real_cmd_str = INIT_MYSTR; unsigned int len; struct vsf_session* p_sess = (struct vsf_session*) p_private; /* Did stupid client sent something OOB without a data connection? */ if (p_sess->data_fd == -1) { return; } /* Get the async command - blocks (use data timeout alarm) */ vsf_cmdio_get_cmd_and_arg(p_sess, &async_cmd_str, &async_arg_str, 0); /* Chop off first four characters; they are telnet characters. The client * should have sent the first two normally and the second two as urgent * data. */ len = str_getlen(&async_cmd_str); if (len >= 4) { str_right(&async_cmd_str, &real_cmd_str, len - 4); } if (str_equal_text(&real_cmd_str, "ABOR")) { p_sess->abor_received = 1; vsf_sysutil_shutdown_failok(p_sess->data_fd); } else { /* Sorry! */ vsf_cmdio_write(p_sess, FTP_BADCMD, "Unknown command."); } str_free(&async_cmd_str); str_free(&async_arg_str); str_free(&real_cmd_str); }
void vsf_cmdio_get_cmd_and_arg(struct vsf_session* p_sess, struct mystr* p_cmd_str, struct mystr* p_arg_str, int set_alarm) { int ret; /* Prepare an alarm to timeout the session.. */ if (set_alarm) { vsf_cmdio_set_alarm(p_sess); } /* Blocks */ ret = control_getline(p_cmd_str, p_sess); if (p_sess->idle_timeout) { vsf_cmdio_write_exit(p_sess, FTP_IDLE_TIMEOUT, "Timeout.", 1); } if (ret == 0) { /* Remote end hung up without a polite QUIT. The shutdown is to make * sure buggy clients don't ever see an OOPS message. */ vsf_sysutil_shutdown_failok(VSFTP_COMMAND_FD); vsf_sysutil_exit(1); } /* View a single space as a command of " ", which although a useless command, * permits the caller to distinguish input of "" from " ". */ if (str_getlen(p_cmd_str) == 1 && str_get_char_at(p_cmd_str, 0) == ' ') { str_empty(p_arg_str); } else { str_split_char(p_cmd_str, p_arg_str, ' '); } str_upper(p_cmd_str); if (!str_isempty(p_arg_str)) { char *tmp_str; tmp_str = remote2local(str_getbuf(p_arg_str)); if (tmp_str != NULL) { str_empty(p_arg_str); str_append_text(p_arg_str, tmp_str); vsf_sysutil_free(tmp_str); } } if (tunable_log_ftp_protocol) { static struct mystr s_log_str; if (str_equal_text(p_cmd_str, "PASS")) { str_alloc_text(&s_log_str, "PASS <password>"); } else { str_copy(&s_log_str, p_cmd_str); if (!str_isempty(p_arg_str)) { str_append_char(&s_log_str, ' '); str_append_str(&s_log_str, p_arg_str); } } vsf_log_line(p_sess, kVSFLogEntryFTPInput, &s_log_str); } }