Fixes from (or inspired by) OpenBSD:
* Fix yacc parser error recovery so that setjmp(3)/longjmp(3) is unnecessary. * Fix SIGURG handler to set an urgflag that's later tested, rather than abusing setjmp(3)/longjmp(3). * Use "volatile sig_atomic_t" as the type of variables modified by sig handlers. * Use sigaction(3) instead of signal(3) to set the signal handlers. * Only set the main SIGALRM handler once. If we need to change it, cache the old handler and restore appropriately... * Remove a bunch of signal races by improving the signal handlers. * Fix memory leak with 'ESPV ALL'. My stuff: * Clean up the debug message in reply(); use vsnprintf(3) instead of vsyslog(3). * Rework parsing of OOB commands to _not_ use the yacc parser, since the latter isn't reentrant and the hacks to work around that are ugly. We now examine urgflag at appropriate locations and call handleoobcmd() if it's set. Since the only OOB commands we currently implement are ABOR and STAT, this isn't an issue. (I also can't find the reference in RFC2228 where MIC, CONF & ENC are OOB-only commands. Go figure.) I could clean up the is_oob stuff some more, but the remaining stuff in ftpcmd.y is harmless and it's unnecessary churn right this moment.
This commit is contained in:
parent
347097fa08
commit
635a375704
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: cmds.c,v 1.22 2003/08/07 09:46:38 agc Exp $ */
|
||||
/* $NetBSD: cmds.c,v 1.23 2004/08/09 12:56:47 lukem Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999-2001 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1999-2004 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
|
@ -97,7 +97,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: cmds.c,v 1.22 2003/08/07 09:46:38 agc Exp $");
|
||||
__RCSID("$NetBSD: cmds.c,v 1.23 2004/08/09 12:56:47 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -107,7 +107,6 @@ __RCSID("$NetBSD: cmds.c,v 1.22 2003/08/07 09:46:38 agc Exp $");
|
|||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: conf.c,v 1.51 2002/11/29 14:39:59 lukem Exp $ */
|
||||
/* $NetBSD: conf.c,v 1.52 2004/08/09 12:56:47 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997-2001 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1997-2004 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
|
@ -38,7 +38,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: conf.c,v 1.51 2002/11/29 14:39:59 lukem Exp $");
|
||||
__RCSID("$NetBSD: conf.c,v 1.52 2004/08/09 12:56:47 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -51,7 +51,6 @@ __RCSID("$NetBSD: conf.c,v 1.51 2002/11/29 14:39:59 lukem Exp $");
|
|||
#include <fcntl.h>
|
||||
#include <glob.h>
|
||||
#include <netdb.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: extern.h,v 1.49 2003/08/07 09:46:38 agc Exp $ */
|
||||
/* $NetBSD: extern.h,v 1.50 2004/08/09 12:56:47 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997-2001 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1997-2004 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
|
@ -310,7 +310,6 @@ GLOBAL struct sockinet pasv_addr;
|
|||
GLOBAL int connections;
|
||||
GLOBAL struct ftpclass curclass;
|
||||
GLOBAL int debug;
|
||||
GLOBAL jmp_buf errcatch;
|
||||
GLOBAL char *emailaddr;
|
||||
GLOBAL int form;
|
||||
GLOBAL int gidcount; /* number of entries in gidlist[] */
|
||||
|
@ -332,7 +331,6 @@ GLOBAL int quietmessages;
|
|||
GLOBAL char remotehost[MAXHOSTNAMELEN+1];
|
||||
GLOBAL off_t restart_point;
|
||||
GLOBAL char tmpline[FTP_BUFLEN];
|
||||
GLOBAL sig_atomic_t transflag;
|
||||
GLOBAL int type;
|
||||
GLOBAL int usedefault; /* for data transfers */
|
||||
GLOBAL const char *version;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: ftpcmd.y,v 1.79 2004/07/16 08:29:28 lukem Exp $ */
|
||||
/* $NetBSD: ftpcmd.y,v 1.80 2004/08/09 12:56:47 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997-2002 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1997-2004 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
|
@ -79,7 +79,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)ftpcmd.y 8.3 (Berkeley) 4/6/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: ftpcmd.y,v 1.79 2004/07/16 08:29:28 lukem Exp $");
|
||||
__RCSID("$NetBSD: ftpcmd.y,v 1.80 2004/08/09 12:56:47 lukem Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -94,8 +94,6 @@ __RCSID("$NetBSD: ftpcmd.y,v 1.79 2004/07/16 08:29:28 lukem Exp $");
|
|||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -134,7 +132,7 @@ char *fromname;
|
|||
A B C E F I
|
||||
L N P R S T
|
||||
|
||||
SP CRLF COMMA
|
||||
SP CRLF COMMA ALL
|
||||
|
||||
USER PASS ACCT CWD CDUP SMNT
|
||||
QUIT REIN PORT PASV TYPE STRU
|
||||
|
@ -160,7 +158,6 @@ char *fromname;
|
|||
LEXERR
|
||||
|
||||
%token <s> STRING
|
||||
%token <s> ALL
|
||||
%token <u> NUMBER
|
||||
|
||||
%type <u.i> check_login octal_number byte_size
|
||||
|
@ -1299,7 +1296,6 @@ struct tab sitetab[] = {
|
|||
static int check_write(const char *, int);
|
||||
static void help(struct tab *, const char *);
|
||||
static void port_check(const char *, int);
|
||||
static void toolong(int);
|
||||
int yylex(void);
|
||||
|
||||
extern int epsvall;
|
||||
|
@ -1446,19 +1442,6 @@ getline(char *s, int n, FILE *iop)
|
|||
return (s);
|
||||
}
|
||||
|
||||
static void
|
||||
toolong(int signo)
|
||||
{
|
||||
|
||||
reply(421,
|
||||
"Timeout (" LLF " seconds): closing control connection.",
|
||||
(LLT)curclass.timeout);
|
||||
if (logging)
|
||||
syslog(LOG_INFO, "User %s timed out after " LLF " seconds",
|
||||
(pw ? pw->pw_name : "unknown"), (LLT)curclass.timeout);
|
||||
dologout(1);
|
||||
}
|
||||
|
||||
void
|
||||
ftp_handle_line(char *cp)
|
||||
{
|
||||
|
@ -1472,7 +1455,6 @@ ftp_loop(void)
|
|||
{
|
||||
|
||||
while (1) {
|
||||
(void) signal(SIGALRM, toolong);
|
||||
(void) alarm(curclass.timeout);
|
||||
if (getline(cbuf, sizeof(cbuf)-1, stdin) == NULL) {
|
||||
reply(221, "You could at least say goodbye.");
|
||||
|
@ -1628,10 +1610,9 @@ yylex(void)
|
|||
return (NUMBER);
|
||||
}
|
||||
if (strncasecmp(&cmdp[cpos], "ALL", 3) == 0
|
||||
&& !isalnum(cmdp[cpos + 3])) {
|
||||
yylval.s = xstrdup("ALL");
|
||||
&& !isalnum(cmdp[cpos + 3])) {
|
||||
cpos += 3;
|
||||
return ALL;
|
||||
return (ALL);
|
||||
}
|
||||
switch (cmdp[cpos++]) {
|
||||
|
||||
|
@ -1717,9 +1698,7 @@ yylex(void)
|
|||
}
|
||||
yyerror(NULL);
|
||||
state = CMD;
|
||||
is_oob = 0;
|
||||
longjmp(errcatch, 0);
|
||||
/* NOTREACHED */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: ftpd.c,v 1.157 2003/12/10 01:18:56 lukem Exp $ */
|
||||
/* $NetBSD: ftpd.c,v 1.158 2004/08/09 12:56:47 lukem Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997-2003 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1997-2004 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
|
@ -105,7 +105,7 @@ __COPYRIGHT(
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)ftpd.c 8.5 (Berkeley) 4/28/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: ftpd.c,v 1.157 2003/12/10 01:18:56 lukem Exp $");
|
||||
__RCSID("$NetBSD: ftpd.c,v 1.158 2004/08/09 12:56:47 lukem Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -140,7 +140,6 @@ __RCSID("$NetBSD: ftpd.c,v 1.157 2003/12/10 01:18:56 lukem Exp $");
|
|||
#include <limits.h>
|
||||
#include <netdb.h>
|
||||
#include <pwd.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
@ -170,8 +169,10 @@ __RCSID("$NetBSD: ftpd.c,v 1.157 2003/12/10 01:18:56 lukem Exp $");
|
|||
#include "pathnames.h"
|
||||
#include "version.h"
|
||||
|
||||
volatile sig_atomic_t transflag;
|
||||
volatile sig_atomic_t urgflag;
|
||||
|
||||
int data;
|
||||
jmp_buf urgcatch;
|
||||
int sflag;
|
||||
int stru; /* avoid C keyword */
|
||||
int mode;
|
||||
|
@ -222,6 +223,7 @@ int swaitint = SWAITINT;
|
|||
|
||||
enum send_status {
|
||||
SS_SUCCESS,
|
||||
SS_ABORTED, /* transfer aborted */
|
||||
SS_NO_TRANSFER, /* no transfer made yet */
|
||||
SS_FILE_ERROR, /* file read error */
|
||||
SS_DATA_ERROR /* data send error */
|
||||
|
@ -237,7 +239,10 @@ static char *gunique(const char *);
|
|||
static void login_utmp(const char *, const char *, const char *);
|
||||
static void logremotehost(struct sockinet *);
|
||||
static void lostconn(int);
|
||||
static void myoob(int);
|
||||
static void toolong(int);
|
||||
static void sigquit(int);
|
||||
static void sigurg(int);
|
||||
static int handleoobcmd(void);
|
||||
static int receive_data(FILE *, FILE *);
|
||||
static int send_data(FILE *, FILE *, const struct stat *, int);
|
||||
static struct passwd *sgetpwnam(const char *);
|
||||
|
@ -271,6 +276,7 @@ main(int argc, char *argv[])
|
|||
char *p;
|
||||
const char *xferlogname = NULL;
|
||||
long l;
|
||||
struct sigaction sa;
|
||||
|
||||
connections = 1;
|
||||
debug = 0;
|
||||
|
@ -513,10 +519,26 @@ main(int argc, char *argv[])
|
|||
(void)snprintf(ttyline, sizeof(ttyline), "ftp%d", getpid());
|
||||
|
||||
(void) freopen(_PATH_DEVNULL, "w", stderr);
|
||||
(void) signal(SIGPIPE, lostconn);
|
||||
(void) signal(SIGCHLD, SIG_IGN);
|
||||
if (signal(SIGURG, myoob) == SIG_ERR)
|
||||
syslog(LOG_WARNING, "signal: %m");
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_handler = SIG_DFL;
|
||||
sa.sa_flags = SA_RESTART;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
(void) sigaction(SIGCHLD, &sa, NULL);
|
||||
|
||||
sa.sa_handler = sigquit;
|
||||
sa.sa_flags = SA_RESTART;
|
||||
sigfillset(&sa.sa_mask); /* block all sigs in these handlers */
|
||||
(void) sigaction(SIGHUP, &sa, NULL);
|
||||
(void) sigaction(SIGINT, &sa, NULL);
|
||||
(void) sigaction(SIGQUIT, &sa, NULL);
|
||||
(void) sigaction(SIGTERM, &sa, NULL);
|
||||
sa.sa_handler = lostconn;
|
||||
(void) sigaction(SIGPIPE, &sa, NULL);
|
||||
sa.sa_handler = toolong;
|
||||
(void) sigaction(SIGALRM, &sa, NULL);
|
||||
sa.sa_handler = sigurg;
|
||||
(void) sigaction(SIGURG, &sa, NULL);
|
||||
|
||||
/* Try to handle urgent data inline */
|
||||
#ifdef SO_OOBINLINE
|
||||
|
@ -582,7 +604,6 @@ main(int argc, char *argv[])
|
|||
doxferlog |= 2;
|
||||
}
|
||||
|
||||
(void) setjmp(errcatch);
|
||||
ftp_loop();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
@ -596,6 +617,37 @@ lostconn(int signo)
|
|||
dologout(1);
|
||||
}
|
||||
|
||||
static void
|
||||
toolong(int signo)
|
||||
{
|
||||
|
||||
/* XXXSIGRACE */
|
||||
reply(421,
|
||||
"Timeout (" LLF " seconds): closing control connection.",
|
||||
(LLT)curclass.timeout);
|
||||
if (logging)
|
||||
syslog(LOG_INFO, "User %s timed out after " LLF " seconds",
|
||||
(pw ? pw->pw_name : "unknown"), (LLT)curclass.timeout);
|
||||
dologout(1);
|
||||
}
|
||||
|
||||
static void
|
||||
sigquit(int signo)
|
||||
{
|
||||
|
||||
if (debug)
|
||||
syslog(LOG_DEBUG, "got signal %d", signo);
|
||||
dologout(1);
|
||||
}
|
||||
|
||||
static void
|
||||
sigurg(int signo)
|
||||
{
|
||||
|
||||
urgflag = 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Save the result of a getpwnam. Used for USER command, since
|
||||
* the data returned must not be clobbered by any other command
|
||||
|
@ -1793,6 +1845,8 @@ send_data_with_read(int filefd, int netfd, const struct stat *st, int isdata)
|
|||
error = SS_FILE_ERROR;
|
||||
else if (write_data(netfd, buf, c, &bufrem, &then, isdata))
|
||||
error = SS_DATA_ERROR;
|
||||
else if (urgflag && handleoobcmd())
|
||||
error = SS_ABORTED;
|
||||
else
|
||||
continue;
|
||||
|
||||
|
@ -1859,6 +1913,8 @@ send_data_with_mmap(int filefd, int netfd, const struct stat *st, int isdata)
|
|||
isdata);
|
||||
(void) madvise(win, mapsize, MADV_DONTNEED);
|
||||
munmap(win, mapsize);
|
||||
if (urgflag && handleoobcmd())
|
||||
return (SS_ABORTED);
|
||||
if (error)
|
||||
return (SS_DATA_ERROR);
|
||||
off += mapsize;
|
||||
|
@ -1880,10 +1936,9 @@ send_data(FILE *instr, FILE *outstr, const struct stat *st, int isdata)
|
|||
{
|
||||
int c, filefd, netfd, rval;
|
||||
|
||||
urgflag = 0;
|
||||
transflag = 1;
|
||||
rval = -1;
|
||||
if (setjmp(urgcatch))
|
||||
goto cleanup_send_data;
|
||||
|
||||
switch (type) {
|
||||
|
||||
|
@ -1891,6 +1946,8 @@ send_data(FILE *instr, FILE *outstr, const struct stat *st, int isdata)
|
|||
/* XXXLUKEM: rate limit ascii send (get) */
|
||||
(void) alarm(curclass.timeout);
|
||||
while ((c = getc(instr)) != EOF) {
|
||||
if (urgflag && handleoobcmd())
|
||||
goto cleanup_send_data;
|
||||
byte_count++;
|
||||
if (c == '\n') {
|
||||
if (ferror(outstr))
|
||||
|
@ -1931,6 +1988,7 @@ send_data(FILE *instr, FILE *outstr, const struct stat *st, int isdata)
|
|||
case SS_SUCCESS:
|
||||
break;
|
||||
|
||||
case SS_ABORTED:
|
||||
case SS_NO_TRANSFER:
|
||||
goto cleanup_send_data;
|
||||
|
||||
|
@ -1956,11 +2014,12 @@ send_data(FILE *instr, FILE *outstr, const struct stat *st, int isdata)
|
|||
file_err:
|
||||
(void) alarm(0);
|
||||
perror_reply(551, "Error on input file");
|
||||
/* FALLTHROUGH */
|
||||
goto cleanup_send_data;
|
||||
|
||||
cleanup_send_data:
|
||||
(void) alarm(0);
|
||||
transflag = 0;
|
||||
urgflag = 0;
|
||||
if (isdata) {
|
||||
total_files_out++;
|
||||
total_files++;
|
||||
|
@ -1982,16 +2041,22 @@ receive_data(FILE *instr, FILE *outstr)
|
|||
int c, bare_lfs, netfd, filefd, rval;
|
||||
off_t byteswritten;
|
||||
char buf[BUFSIZ];
|
||||
struct sigaction sa, sa_saved;
|
||||
#ifdef __GNUC__
|
||||
(void) &bare_lfs;
|
||||
#endif
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sigfillset(&sa.sa_mask);
|
||||
sa.sa_flags = SA_RESTART;
|
||||
sa.sa_handler = lostconn;
|
||||
(void) sigaction(SIGALRM, &sa, &sa_saved);
|
||||
|
||||
bare_lfs = 0;
|
||||
urgflag = 0;
|
||||
transflag = 1;
|
||||
rval = -1;
|
||||
byteswritten = 0;
|
||||
if (setjmp(urgcatch))
|
||||
goto cleanup_recv_data;
|
||||
|
||||
#define FILESIZECHECK(x) \
|
||||
do { \
|
||||
|
@ -2021,6 +2086,8 @@ receive_data(FILE *instr, FILE *outstr)
|
|||
if ((c = read(netfd, buf,
|
||||
MIN(sizeof(buf), bufrem))) <= 0)
|
||||
goto recvdone;
|
||||
if (urgflag && handleoobcmd())
|
||||
goto cleanup_recv_data;
|
||||
FILESIZECHECK(byte_count + c);
|
||||
if ((d = write(filefd, buf, c)) != c)
|
||||
goto file_err;
|
||||
|
@ -2039,6 +2106,8 @@ receive_data(FILE *instr, FILE *outstr)
|
|||
}
|
||||
} else {
|
||||
while ((c = read(netfd, buf, sizeof(buf))) > 0) {
|
||||
if (urgflag && handleoobcmd())
|
||||
goto cleanup_recv_data;
|
||||
FILESIZECHECK(byte_count + c);
|
||||
if (write(filefd, buf, c) != c)
|
||||
goto file_err;
|
||||
|
@ -2064,6 +2133,8 @@ receive_data(FILE *instr, FILE *outstr)
|
|||
(void) alarm(curclass.timeout);
|
||||
/* XXXLUKEM: rate limit ascii receive (put) */
|
||||
while ((c = getc(instr)) != EOF) {
|
||||
if (urgflag && handleoobcmd())
|
||||
goto cleanup_recv_data;
|
||||
byte_count++;
|
||||
total_data_in++;
|
||||
total_data++;
|
||||
|
@ -2129,7 +2200,9 @@ receive_data(FILE *instr, FILE *outstr)
|
|||
|
||||
cleanup_recv_data:
|
||||
(void) alarm(0);
|
||||
(void) sigaction(SIGALRM, &sa_saved, NULL);
|
||||
transflag = 0;
|
||||
urgflag = 0;
|
||||
total_files_in++;
|
||||
total_files++;
|
||||
total_xfers_in++;
|
||||
|
@ -2419,29 +2492,24 @@ fatal(const char *s)
|
|||
void
|
||||
reply(int n, const char *fmt, ...)
|
||||
{
|
||||
off_t b;
|
||||
va_list ap;
|
||||
char msg[MAXPATHLEN * 2 + 100];
|
||||
size_t b;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
b = 0;
|
||||
if (n == 0)
|
||||
cprintf(stdout, " ");
|
||||
b = snprintf(msg, sizeof(msg), " ");
|
||||
else if (n < 0)
|
||||
cprintf(stdout, "%d-", -n);
|
||||
b = snprintf(msg, sizeof(msg), "%d-", -n);
|
||||
else
|
||||
cprintf(stdout, "%d ", n);
|
||||
b = vprintf(fmt, ap);
|
||||
b = snprintf(msg, sizeof(msg), "%d ", n);
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(msg + b, sizeof(msg) - b, fmt, ap);
|
||||
va_end(ap);
|
||||
total_bytes += b;
|
||||
total_bytes_out += b;
|
||||
cprintf(stdout, "\r\n");
|
||||
cprintf(stdout, "%s\r\n", msg);
|
||||
(void)fflush(stdout);
|
||||
if (debug) {
|
||||
syslog(LOG_DEBUG, "<--- %d%c", abs(n), (n < 0) ? '-' : ' ');
|
||||
va_start(ap, fmt);
|
||||
vsyslog(LOG_DEBUG, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
if (debug)
|
||||
syslog(LOG_DEBUG, "<--- %s", msg);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2463,6 +2531,8 @@ logremotehost(struct sockinet *who)
|
|||
|
||||
/*
|
||||
* Record logout in wtmp file and exit with supplied status.
|
||||
* NOTE: because this is called from signal handlers it cannot
|
||||
* use stdio (or call other functions that use stdio).
|
||||
*/
|
||||
void
|
||||
dologout(int status)
|
||||
|
@ -2489,17 +2559,21 @@ void
|
|||
abor(void)
|
||||
{
|
||||
|
||||
if (!transflag)
|
||||
return;
|
||||
tmpline[0] = '\0';
|
||||
is_oob = 0;
|
||||
reply(426, "Transfer aborted. Data connection closed.");
|
||||
reply(226, "Abort successful");
|
||||
longjmp(urgcatch, 1);
|
||||
transflag = 0; /* flag that the transfer has aborted */
|
||||
}
|
||||
|
||||
void
|
||||
statxfer(void)
|
||||
{
|
||||
|
||||
if (!transflag)
|
||||
return;
|
||||
tmpline[0] = '\0';
|
||||
is_oob = 0;
|
||||
if (file_size != (off_t) -1)
|
||||
|
@ -2512,22 +2586,39 @@ statxfer(void)
|
|||
(LLT)byte_count, PLURAL(byte_count));
|
||||
}
|
||||
|
||||
static void
|
||||
myoob(int signo)
|
||||
/*
|
||||
* Call when urgflag != 0 to handle Out Of Band commands.
|
||||
* Returns non zero if the OOB command aborted the transfer
|
||||
* by setting transflag to 0. (c.f., "ABOR").
|
||||
*/
|
||||
static int
|
||||
handleoobcmd()
|
||||
{
|
||||
char *cp;
|
||||
|
||||
if (!urgflag)
|
||||
return (0);
|
||||
urgflag = 0;
|
||||
/* only process if transfer occurring */
|
||||
if (!transflag)
|
||||
return;
|
||||
return (0);
|
||||
cp = tmpline;
|
||||
if (getline(cp, sizeof(tmpline), stdin) == NULL) {
|
||||
reply(221, "You could at least say goodbye.");
|
||||
dologout(0);
|
||||
}
|
||||
is_oob = 1;
|
||||
ftp_handle_line(cp);
|
||||
is_oob = 0;
|
||||
/*
|
||||
* Manually parse OOB commands, because we can't
|
||||
* recursively call the yacc parser...
|
||||
*/
|
||||
if (strcasecmp(cp, "ABOR\r\n") == 0) {
|
||||
abor();
|
||||
} else if (strcasecmp(cp, "STAT\r\n") == 0) {
|
||||
statxfer();
|
||||
} else {
|
||||
/* XXX: error with "500 unknown command" ? */
|
||||
}
|
||||
return (transflag == 0);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -2955,6 +3046,7 @@ send_file_list(const char *whichf)
|
|||
(void) &simple;
|
||||
(void) &freeglob;
|
||||
#endif
|
||||
urgflag = 0;
|
||||
|
||||
p = NULL;
|
||||
if (strpbrk(whichf, "~{[*?") != NULL) {
|
||||
|
@ -2964,11 +3056,11 @@ send_file_list(const char *whichf)
|
|||
freeglob = 1;
|
||||
if (glob(whichf, flags, 0, &gl)) {
|
||||
reply(550, "not found");
|
||||
goto out;
|
||||
goto cleanup_send_file_list;
|
||||
} else if (gl.gl_pathc == 0) {
|
||||
errno = ENOENT;
|
||||
perror_reply(550, whichf);
|
||||
goto out;
|
||||
goto cleanup_send_file_list;
|
||||
}
|
||||
dirlist = gl.gl_pathv;
|
||||
} else {
|
||||
|
@ -2979,10 +3071,6 @@ send_file_list(const char *whichf)
|
|||
}
|
||||
/* XXX: } for vi sm */
|
||||
|
||||
if (setjmp(urgcatch)) {
|
||||
transflag = 0;
|
||||
goto out;
|
||||
}
|
||||
while ((dirname = *dirlist++) != NULL) {
|
||||
int trailingslash = 0;
|
||||
|
||||
|
@ -2998,7 +3086,7 @@ send_file_list(const char *whichf)
|
|||
|
||||
argv[1] = dirname;
|
||||
retrieve(argv, dirname);
|
||||
goto out;
|
||||
goto cleanup_send_file_list;
|
||||
}
|
||||
perror_reply(550, whichf);
|
||||
goto cleanup_send_file_list;
|
||||
|
@ -3013,8 +3101,8 @@ send_file_list(const char *whichf)
|
|||
if (dout == NULL) {
|
||||
dout = dataconn("file list", (off_t)-1, "w");
|
||||
if (dout == NULL)
|
||||
goto out;
|
||||
transflag++;
|
||||
goto cleanup_send_file_list;
|
||||
transflag = 1;
|
||||
}
|
||||
cprintf(dout, "%s%s\n", dirname,
|
||||
type == TYPE_A ? "\r" : "");
|
||||
|
@ -3031,6 +3119,9 @@ send_file_list(const char *whichf)
|
|||
while ((dir = readdir(dirp)) != NULL) {
|
||||
char nbuf[MAXPATHLEN];
|
||||
|
||||
if (urgflag && handleoobcmd())
|
||||
goto cleanup_send_file_list;
|
||||
|
||||
if (ISDOTDIR(dir->d_name) || ISDOTDOTDIR(dir->d_name))
|
||||
continue;
|
||||
|
||||
|
@ -3053,8 +3144,8 @@ send_file_list(const char *whichf)
|
|||
dout = dataconn("file list", (off_t)-1,
|
||||
"w");
|
||||
if (dout == NULL)
|
||||
goto out;
|
||||
transflag++;
|
||||
goto cleanup_send_file_list;
|
||||
transflag = 1;
|
||||
}
|
||||
p = nbuf;
|
||||
if (nbuf[0] == '.' && nbuf[1] == '/')
|
||||
|
@ -3074,9 +3165,9 @@ send_file_list(const char *whichf)
|
|||
reply(226, "Transfer complete.");
|
||||
|
||||
cleanup_send_file_list:
|
||||
transflag = 0;
|
||||
closedataconn(dout);
|
||||
out:
|
||||
transflag = 0;
|
||||
urgflag = 0;
|
||||
total_xfers++;
|
||||
total_xfers_out++;
|
||||
if (notglob)
|
||||
|
|
|
@ -56,7 +56,6 @@
|
|||
#include <sys/param.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: logwtmp.c,v 1.21 2003/08/07 09:46:40 agc Exp $ */
|
||||
/* $NetBSD: logwtmp.c,v 1.22 2004/08/09 12:56:48 lukem Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1993
|
||||
|
@ -36,7 +36,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)logwtmp.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: logwtmp.c,v 1.21 2003/08/07 09:46:40 agc Exp $");
|
||||
__RCSID("$NetBSD: logwtmp.c,v 1.22 2004/08/09 12:56:48 lukem Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -47,7 +47,6 @@ __RCSID("$NetBSD: logwtmp.c,v 1.21 2003/08/07 09:46:40 agc Exp $");
|
|||
#include <sys/wait.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: popen.c,v 1.29 2003/08/07 09:46:40 agc Exp $ */
|
||||
/* $NetBSD: popen.c,v 1.30 2004/08/09 12:56:48 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999-2001 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1999-2004 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
|
@ -74,7 +74,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)popen.c 8.3 (Berkeley) 4/6/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: popen.c,v 1.29 2003/08/07 09:46:40 agc Exp $");
|
||||
__RCSID("$NetBSD: popen.c,v 1.30 2004/08/09 12:56:48 lukem Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -84,7 +84,6 @@ __RCSID("$NetBSD: popen.c,v 1.29 2003/08/07 09:46:40 agc Exp $");
|
|||
|
||||
#include <errno.h>
|
||||
#include <glob.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* $NetBSD: version.h,v 1.56 2003/12/10 01:18:56 lukem Exp $ */
|
||||
/* $NetBSD: version.h,v 1.57 2004/08/09 12:56:48 lukem Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1999-2003 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1999-2004 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
|
@ -36,5 +36,5 @@
|
|||
*/
|
||||
|
||||
#ifndef FTPD_VERSION
|
||||
#define FTPD_VERSION "NetBSD-ftpd 20031210"
|
||||
#define FTPD_VERSION "NetBSD-ftpd 20040809"
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue