bin/52072: Wrong behaviour of the ftpd when the OOB data
received
Nick Leuta
skynick at stu.lipetsk.ru
Sun May 11 15:20:16 PDT 2003
The following reply was made to PR bin/52072; it has been noted by GNATS.
From: Nick Leuta <skynick at stu.lipetsk.ru>
To: freebsd-gnats-submit at FreeBSD.org, alexs at 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;
More information about the freebsd-bugs
mailing list