From owner-freebsd-bugs@FreeBSD.ORG Sun May 11 15:20:15 2003 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D2AF937B428 for ; Sun, 11 May 2003 15:20:15 -0700 (PDT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 6903043F3F for ; Sun, 11 May 2003 15:20:14 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.9/8.12.9) with ESMTP id h4BMKDUp005223 for ; Sun, 11 May 2003 15:20:13 -0700 (PDT) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.9/8.12.9/Submit) id h4BMKDNQ005222; Sun, 11 May 2003 15:20:13 -0700 (PDT) Date: Sun, 11 May 2003 15:20:13 -0700 (PDT) Message-Id: <200305112220.h4BMKDNQ005222@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org From: Nick Leuta Subject: Re: bin/52072: Wrong behaviour of the ftpd when the OOB data received X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: Nick Leuta List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 11 May 2003 22:20:16 -0000 The following reply was made to PR bin/52072; it has been noted by GNATS. From: Nick Leuta To: freebsd-gnats-submit@FreeBSD.org, alexs@ratmir.ru Cc: Subject: Re: bin/52072: Wrong behaviour of the ftpd when the OOB data received Date: Mon, 12 May 2003 02:12:57 +0400 There is another approach to the solution. I don't know what's better... This patch tries to fix a potential incomplite write() call - SIGURG signal may be received at a time of writing a data to a socket. Also I don't know the reasons for "sa.sa_flags = 0;", but it's possible that I simple don't know them... --- ftpd.ori/ftpd.c Tue Feb 11 17:10:48 2003 +++ ftpd/ftpd.c Mon May 12 01:42:35 2003 @@ -239,8 +239,7 @@ static void selecthost(union sockunion *); #endif static void ack(char *); -static void sigurg(int); -static void myoob(void); +static void myoob(int signo); static int checkuser(char *, char *, int, char **); static FILE *dataconn(char *, off_t, char *); static void dolog(struct sockaddr *); @@ -546,8 +545,8 @@ sa.sa_handler = SIG_DFL; (void)sigaction(SIGCHLD, &sa, NULL); - sa.sa_handler = sigurg; - sa.sa_flags = 0; /* don't restart syscalls for SIGURG */ + sa.sa_handler = myoob; + sa.sa_flags = SA_RESTART; (void)sigaction(SIGURG, &sa, NULL); sigfillset(&sa.sa_mask); /* block all signals in handler */ @@ -1991,8 +1990,8 @@ send_data(FILE *instr, FILE *outstr, off_t blksize, off_t filesize, int isreg) { int c, filefd, netfd; - char *buf; - off_t cnt; + char *buf, *bp; + off_t cnt = 0, len; transflag++; switch (type) { @@ -2069,16 +2068,23 @@ return (-1); } - while ((cnt = read(filefd, buf, (u_int)blksize)) > 0 && - write(netfd, buf, cnt) == cnt) - byte_count += cnt; + while ((len = read(filefd, buf, (u_int)blksize)) > 0) { + bp = buf; + do { + cnt = write(netfd, bp, len); + len -= cnt; + bp += cnt; + if (cnt > 0) byte_count += cnt; + if (recvurg) + goto got_oob; + } while (cnt > 0 && len > 0); + } transflag = 0; (void)free(buf); - if (cnt != 0) { - if (cnt < 0) - goto file_err; - goto data_err; - } + if (len < 0) + goto file_err; + if (cnt < 0) + goto data_err; reply(226, "Transfer complete."); return (0); default: @@ -2098,7 +2104,6 @@ return (-1); got_oob: - myoob(); recvurg = 0; transflag = 0; return (-1); @@ -2194,7 +2199,6 @@ return (-1); got_oob: - myoob(); recvurg = 0; transflag = 0; return (-1); @@ -2612,14 +2616,7 @@ } static void -sigurg(int signo) -{ - - recvurg = 1; -} - -static void -myoob(void) +myoob(int signo) { char *cp; @@ -2636,6 +2633,9 @@ tmpline[0] = '\0'; reply(426, "Transfer aborted. Data connection closed."); reply(226, "Abort successful"); + + recvurg = 1; + return; } if (strcmp(cp, "STAT\r\n") == 0) { tmpline[0] = '\0'; @@ -3022,7 +3022,6 @@ char nbuf[MAXPATHLEN]; if (recvurg) { - myoob(); recvurg = 0; transflag = 0; goto out;