END_TEST START_TEST (inet_copy_conn_test) { int fd = -1, sockfd = -1, port = INPORT_ANY; conn_t *conn, *conn2; const char *name; conn = pr_inet_copy_conn(NULL, NULL); fail_unless(conn == NULL, "Failed to handle null arguments"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL, strerror(errno), errno); conn = pr_inet_copy_conn(p, NULL); fail_unless(conn == NULL, "Failed to handle null conn argument"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL, strerror(errno), errno); conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE); fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno)); conn2 = pr_inet_copy_conn(p, conn); fail_unless(conn2 != NULL, "Failed to copy conn: %s", strerror(errno)); pr_inet_close(p, conn); pr_inet_close(p, conn2); conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE); fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno)); name = "127.0.0.1"; conn->remote_addr = pr_netaddr_get_addr(p, name, NULL); fail_unless(conn->remote_addr != NULL, "Failed to resolve '%s': %s", name, strerror(errno)); conn->remote_name = pstrdup(p, name); conn->instrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, fd, PR_NETIO_IO_RD); fail_unless(conn->instrm != NULL, "Failed to open ctrl reading stream: %s", strerror(errno)); conn->outstrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, fd, PR_NETIO_IO_WR); fail_unless(conn->instrm != NULL, "Failed to open ctrl writing stream: %s", strerror(errno)); conn2 = pr_inet_copy_conn(p, conn); fail_unless(conn2 != NULL, "Failed to copy conn: %s", strerror(errno)); mark_point(); pr_inet_lingering_close(NULL, NULL, 0L); pr_inet_lingering_close(p, conn, 0L); pr_inet_close(p, conn2); conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE); fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno)); conn->instrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, fd, PR_NETIO_IO_RD); fail_unless(conn->instrm != NULL, "Failed to open ctrl reading stream: %s", strerror(errno)); conn->outstrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, fd, PR_NETIO_IO_WR); fail_unless(conn->instrm != NULL, "Failed to open ctrl writing stream: %s", strerror(errno)); mark_point(); pr_inet_lingering_abort(NULL, NULL, 0L); pr_inet_lingering_abort(p, conn, 0L); }
/* In order to avoid clearing the transfer counters in session.xfer, we don't * clear session.xfer here, it should be handled by the appropriate * LOG_CMD/LOG_CMD_ERR handler calling pr_data_cleanup(). */ void pr_data_abort(int err, int quiet) { int true_abort = XFER_ABORTED; nstrm = NULL; if (session.d) { if (!true_abort) pr_inet_lingering_close(session.pool, session.d, timeout_linger); else pr_inet_lingering_abort(session.pool, session.d, timeout_linger); session.d = NULL; } if (timeout_noxfer) { pr_timer_reset(PR_TIMER_NOXFER, ANY_MODULE); } if (timeout_stalled) { pr_timer_remove(PR_TIMER_STALLED, ANY_MODULE); } session.sf_flags &= (SF_ALL^SF_PASSIVE); session.sf_flags &= (SF_ALL^(SF_XFER|SF_PASSIVE|SF_ASCII_OVERRIDE)); pr_session_set_idle(); /* Aborts no longer necessary */ signal(SIGURG, SIG_IGN); if (timeout_noxfer) pr_timer_reset(PR_TIMER_NOXFER, ANY_MODULE); if (!quiet) { char *respcode = R_426; char *msg = NULL; char msgbuf[64]; switch (err) { case 0: respcode = R_426; msg = _("Data connection closed"); break; #ifdef ENXIO case ENXIO: respcode = R_451; msg = _("Unexpected streams hangup"); break; #endif #ifdef EAGAIN case EAGAIN: /* FALLTHROUGH */ #endif #ifdef ENOMEM case ENOMEM: #endif #if defined(EAGAIN) || defined(ENOMEM) respcode = R_451; msg = _("Insufficient memory or file locked"); break; #endif #ifdef ETXTBSY case ETXTBSY: /* FALLTHROUGH */ #endif #ifdef EBUSY case EBUSY: #endif #if defined(ETXTBSY) || defined(EBUSY) respcode = R_451; break; #endif #ifdef ENOSPC case ENOSPC: respcode = R_452; break; #endif #ifdef EDQUOT case EDQUOT: /* FALLTHROUGH */ #endif #ifdef EFBIG case EFBIG: #endif #if defined(EDQUOT) || defined(EFBIG) respcode = R_552; break; #endif #ifdef ECOMM case ECOMM: /* FALLTHROUGH */ #endif #ifdef EDEADLK case EDEADLK: /* FALLTHROUGH */ #endif #ifdef EDEADLOCK # if !defined(EDEADLK) || (EDEADLOCK != EDEADLK) case EDEADLOCK: /* FALLTHROUGH */ # endif #endif #ifdef EXFULL case EXFULL: /* FALLTHROUGH */ #endif #ifdef ENOSR case ENOSR: /* FALLTHROUGH */ #endif #ifdef EPROTO case EPROTO: /* FALLTHROUGH */ #endif #ifdef ETIME case ETIME: /* FALLTHROUGH */ #endif #ifdef EIO case EIO: /* FALLTHROUGH */ #endif #ifdef EFAULT case EFAULT: /* FALLTHROUGH */ #endif #ifdef ESPIPE case ESPIPE: /* FALLTHROUGH */ #endif #ifdef EPIPE case EPIPE: #endif #if defined(ECOMM) || defined(EDEADLK) || defined(EDEADLOCK) \ || defined(EXFULL) || defined(ENOSR) || defined(EPROTO) \ || defined(ETIME) || defined(EIO) || defined(EFAULT) \ || defined(ESPIPE) || defined(EPIPE) respcode = R_451; break; #endif #ifdef EREMCHG case EREMCHG: /* FALLTHROUGH */ #endif #ifdef ESRMNT case ESRMNT: /* FALLTHROUGH */ #endif #ifdef ESTALE case ESTALE: /* FALLTHROUGH */ #endif #ifdef ENOLINK case ENOLINK: /* FALLTHROUGH */ #endif #ifdef ENOLCK case ENOLCK: /* FALLTHROUGH */ #endif #ifdef ENETRESET case ENETRESET: /* FALLTHROUGH */ #endif #ifdef ECONNABORTED case ECONNABORTED: /* FALLTHROUGH */ #endif #ifdef ECONNRESET case ECONNRESET: /* FALLTHROUGH */ #endif #ifdef ETIMEDOUT case ETIMEDOUT: #endif #if defined(EREMCHG) || defined(ESRMNT) || defined(ESTALE) \ || defined(ENOLINK) || defined(ENOLCK) || defined(ENETRESET) \ || defined(ECONNABORTED) || defined(ECONNRESET) || defined(ETIMEDOUT) respcode = R_450; msg = _("Link to file server lost"); break; #endif } if (msg == NULL && (msg = strerror(err)) == NULL ) { if (snprintf(msgbuf, sizeof(msgbuf), _("Unknown or out of range errno [%d]"), err) > 0) msg = msgbuf; } pr_log_pri(PR_LOG_NOTICE, "notice: user %s: aborting transfer: %s", session.user, msg); /* If we are aborting, then a 426 response has already been sent, * and we don't want to add another to the error queue. */ if (!true_abort) pr_response_add_err(respcode, _("Transfer aborted. %s"), msg ? msg : ""); } if (true_abort) session.sf_flags |= SF_POST_ABORT; }