summaryrefslogtreecommitdiffstats
path: root/contrib/lukemftpd
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2003-01-06 00:06:49 +0000
committerobrien <obrien@FreeBSD.org>2003-01-06 00:06:49 +0000
commit084ff294f9fe2a2fa8ba632892e21866f169b69d (patch)
tree6d7ac7b561542bbf70e108cdee9455256f8cb1ba /contrib/lukemftpd
parent9db57e5cdf59da94793312f43398dee6cf9c2e64 (diff)
parentc9e7985f5a090a80dd013a9bd5b8f3fad5c555ea (diff)
downloadFreeBSD-src-084ff294f9fe2a2fa8ba632892e21866f169b69d.zip
FreeBSD-src-084ff294f9fe2a2fa8ba632892e21866f169b69d.tar.gz
This commit was generated by cvs2svn to compensate for changes in r108746,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'contrib/lukemftpd')
-rw-r--r--contrib/lukemftpd/src/Makefile46
-rw-r--r--contrib/lukemftpd/src/cmds.c36
-rw-r--r--contrib/lukemftpd/src/conf.c320
-rw-r--r--contrib/lukemftpd/src/extern.h42
-rw-r--r--contrib/lukemftpd/src/ftpcmd.y213
-rw-r--r--contrib/lukemftpd/src/ftpd.86
-rw-r--r--contrib/lukemftpd/src/ftpd.c567
-rw-r--r--contrib/lukemftpd/src/logutmp.c13
-rw-r--r--contrib/lukemftpd/src/logwtmp.c31
-rw-r--r--contrib/lukemftpd/src/pathnames.h5
-rw-r--r--contrib/lukemftpd/src/popen.c39
-rw-r--r--contrib/lukemftpd/src/version.h6
12 files changed, 841 insertions, 483 deletions
diff --git a/contrib/lukemftpd/src/Makefile b/contrib/lukemftpd/src/Makefile
new file mode 100644
index 0000000..a70e43b
--- /dev/null
+++ b/contrib/lukemftpd/src/Makefile
@@ -0,0 +1,46 @@
+# $NetBSD: Makefile,v 1.49 2002/08/22 00:09:38 christos Exp $
+# @(#)Makefile 8.2 (Berkeley) 4/4/94
+
+.include <bsd.own.mk>
+
+PROG= ftpd
+SRCS= cmds.c conf.c ftpd.c ftpcmd.y logutmp.c logwtmp.c popen.c
+CPPFLAGS+=-I${.CURDIR} -DSUPPORT_UTMP -DSUPPORT_UTMPX
+DPADD+= ${LIBCRYPT} ${LIBUTIL}
+LDADD+= -lcrypt -lutil
+MAN= ftpd.conf.5 ftpusers.5 ftpd.8
+MLINKS= ftpusers.5 ftpchroot.5
+
+# for `internal' ls
+SRCS+= ls.c cmp.c print.c stat_flags.c util.c
+.PATH: ${NETBSDSRCDIR}/bin/ls
+
+CPPFLAGS+=-DINET6
+.include <bsd.own.mk>
+
+WARNS=2
+
+.if (${USE_SKEY} != "no")
+CPPFLAGS+=-DSKEY
+DPADD+= ${LIBSKEY}
+LDADD+= -lskey
+.endif
+
+ftpd.o ftpcmd.o: version.h
+
+# XXX Kerberos support is broken right now.
+#.PATH: ${NETBSDSRCDIR}/usr.bin/login
+
+#.ifdef KERBEROS5
+#SRCS+= k5login.c
+#CPPFLAGS+=-DKERBEROS5
+#DPADD+= ${LIBKRB5} ${LIBK5CRYPTO} ${LIBCOM_ERR}
+#LDADD+= -lkrb5 -lk5crypto -lcom_err
+#.else
+#SRCS+= klogin.c
+#CPPFLAGS+=-DKERBEROS
+#DPADD+= ${LIBKRB} ${LIBDES} ${LIBCOM_ERR}
+#LDADD+= -lkrb -kdes -lcom_err
+#.endif
+
+.include <bsd.prog.mk>
diff --git a/contrib/lukemftpd/src/cmds.c b/contrib/lukemftpd/src/cmds.c
index 5f5db9f..334078f 100644
--- a/contrib/lukemftpd/src/cmds.c
+++ b/contrib/lukemftpd/src/cmds.c
@@ -1,4 +1,4 @@
-/* $NetBSD: cmds.c,v 1.16 2002/02/13 15:15:23 lukem Exp $ */
+/* $NetBSD: cmds.c,v 1.18 2002/10/12 08:35:16 darrenr Exp $ */
/*
* Copyright (c) 1999-2001 The NetBSD Foundation, Inc.
@@ -98,7 +98,30 @@
* SUCH DAMAGE.
*/
-#include "lukemftpd.h"
+
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: cmds.c,v 1.18 2002/10/12 08:35:16 darrenr Exp $");
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <arpa/ftp.h>
+
+#include <dirent.h>
+#include <errno.h>
+#include <setjmp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <tzfile.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#ifdef KERBEROS5
+#include <krb5/krb5.h>
+#endif
#include "extern.h"
@@ -307,11 +330,11 @@ opts(const char *command)
*ep++ = '\0';
c = lookup(cmdtab, command);
if (c == NULL) {
- reply(502, "Unknown command %s.", command);
+ reply(502, "Unknown command '%s'.", command);
return;
}
if (! CMD_IMPLEMENTED(c)) {
- reply(501, "%s command not implemented.", c->name);
+ reply(502, "%s command not implemented.", c->name);
return;
}
if (! CMD_HAS_OPTIONS(c)) {
@@ -484,12 +507,14 @@ statfilecmd(const char *filename)
{
FILE *fin;
int c;
+ int atstart;
char *argv[] = { INTERNAL_LS, "-lgA", "", NULL };
argv[2] = (char *)filename;
fin = ftpd_popen(argv, "r", STDOUT_FILENO);
reply(-211, "status of %s:", filename);
/* XXX: use fgetln() or fparseln() here? */
+ atstart = 1;
while ((c = getc(fin)) != EOF) {
if (c == '\n') {
if (ferror(stdout)){
@@ -505,7 +530,10 @@ statfilecmd(const char *filename)
}
CPUTC('\r', stdout);
}
+ if (atstart && isdigit(c))
+ CPUTC(' ', stdout);
CPUTC(c, stdout);
+ atstart = (c == '\n');
}
(void) ftpd_pclose(fin);
reply(211, "End of Status");
diff --git a/contrib/lukemftpd/src/conf.c b/contrib/lukemftpd/src/conf.c
index 8ec927f..8f05793 100644
--- a/contrib/lukemftpd/src/conf.c
+++ b/contrib/lukemftpd/src/conf.c
@@ -1,4 +1,4 @@
-/* $NetBSD: conf.c,v 1.46 2001/12/04 13:54:12 lukem Exp $ */
+/* $NetBSD: conf.c,v 1.50 2002/11/16 03:10:34 itojun Exp $ */
/*-
* Copyright (c) 1997-2001 The NetBSD Foundation, Inc.
@@ -36,7 +36,35 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include "lukemftpd.h"
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: conf.c,v 1.50 2002/11/16 03:10:34 itojun Exp $");
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <glob.h>
+#include <netdb.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stringlist.h>
+#include <syslog.h>
+#include <time.h>
+#include <unistd.h>
+#include <util.h>
+
+#ifdef KERBEROS5
+#include <krb5/krb5.h>
+#endif
#include "extern.h"
#include "pathnames.h"
@@ -91,6 +119,11 @@ init_curclass(void)
curclass.timeout = DEFAULT_TIMEOUT;
/* curclass.type is set elsewhere */
curclass.umask = DEFAULT_UMASK;
+ curclass.mmapsize = 0;
+ curclass.readsize = 0;
+ curclass.writesize = 0;
+ curclass.sendbufsize = 0;
+ curclass.sendlowat = 0;
CURCLASS_FLAGS_SET(checkportcmd);
CURCLASS_FLAGS_CLR(denyquick);
@@ -113,11 +146,10 @@ parse_conf(const char *findclass)
size_t len;
LLT llval;
int none, match;
- char *endp;
+ char *endp, errbuf[100];
char *class, *word, *arg, *template;
const char *infile;
size_t line;
- unsigned int timeout;
struct ftpconv *conv, *cnext;
init_curclass();
@@ -136,7 +168,7 @@ parse_conf(const char *findclass)
template = NULL;
for (;
(buf = fparseln(f, &len, &line, NULL, FPARSELN_UNESCCOMM |
- FPARSELN_UNESCCONT | FPARSELN_UNESCESC)) != NULL;
+ FPARSELN_UNESCCONT | FPARSELN_UNESCESC)) != NULL;
free(buf)) {
none = match = 0;
p = buf;
@@ -160,24 +192,37 @@ parse_conf(const char *findclass)
strcasecmp(class, "all") == 0) )
continue;
-#define CONF_FLAG(x) \
- do { \
- if (none || \
- (!EMPTYSTR(arg) && strcasecmp(arg, "off") == 0)) \
- CURCLASS_FLAGS_CLR(x); \
- else \
- CURCLASS_FLAGS_SET(x); \
+#define CONF_FLAG(Field) \
+ do { \
+ if (none || \
+ (!EMPTYSTR(arg) && strcasecmp(arg, "off") == 0)) \
+ CURCLASS_FLAGS_CLR(Field); \
+ else \
+ CURCLASS_FLAGS_SET(Field); \
} while (0)
-#define CONF_STRING(x) \
- do { \
- if (none || EMPTYSTR(arg)) \
- arg = NULL; \
- else \
- arg = xstrdup(arg); \
- REASSIGN(curclass.x, arg); \
+#define CONF_STRING(Field) \
+ do { \
+ if (none || EMPTYSTR(arg)) \
+ arg = NULL; \
+ else \
+ arg = xstrdup(arg); \
+ REASSIGN(curclass.Field, arg); \
} while (0)
+#define CONF_LL(Field,Arg,Min,Max) \
+ do { \
+ if (none || EMPTYSTR(Arg)) \
+ goto nextline; \
+ llval = strsuftollx(#Field, Arg, Min, Max, \
+ errbuf, sizeof(errbuf)); \
+ if (errbuf[0]) { \
+ syslog(LOG_WARNING, "%s line %d: %s", \
+ infile, (int)line, errbuf); \
+ goto nextline; \
+ } \
+ curclass.Field = llval; \
+ } while(0)
if (0) {
/* no-op */
@@ -314,61 +359,40 @@ parse_conf(const char *findclass)
CONF_STRING(homedir);
} else if (strcasecmp(word, "limit") == 0) {
- int limit;
-
curclass.limit = DEFAULT_LIMIT;
REASSIGN(curclass.limitfile, NULL);
- if (none || EMPTYSTR(arg))
- continue;
- limit = (int)strtol(arg, &endp, 10);
- if (*endp != 0) {
- syslog(LOG_WARNING,
- "%s line %d: invalid limit %s",
- infile, (int)line, arg);
- continue;
- }
- curclass.limit = limit;
+ CONF_LL(limit, arg, -1, LLTMAX);
REASSIGN(curclass.limitfile,
EMPTYSTR(p) ? NULL : xstrdup(p));
} else if (strcasecmp(word, "maxfilesize") == 0) {
curclass.maxfilesize = DEFAULT_MAXFILESIZE;
- if (none || EMPTYSTR(arg))
- continue;
- llval = strsuftoll(arg);
- if (llval == -1) {
- syslog(LOG_WARNING,
- "%s line %d: invalid maxfilesize %s",
- infile, (int)line, arg);
- continue;
- }
- curclass.maxfilesize = llval;
+ CONF_LL(maxfilesize, arg, -1, LLTMAX);
} else if (strcasecmp(word, "maxtimeout") == 0) {
curclass.maxtimeout = DEFAULT_MAXTIMEOUT;
- if (none || EMPTYSTR(arg))
- continue;
- timeout = (unsigned int)strtoul(arg, &endp, 10);
- if (*endp != 0) {
- syslog(LOG_WARNING,
- "%s line %d: invalid maxtimeout %s",
- infile, (int)line, arg);
- continue;
- }
- if (timeout < 30) {
- syslog(LOG_WARNING,
- "%s line %d: maxtimeout %d < 30 seconds",
- infile, (int)line, timeout);
- continue;
- }
- if (timeout < curclass.timeout) {
- syslog(LOG_WARNING,
- "%s line %d: maxtimeout %d < timeout (%d)",
- infile, (int)line, timeout,
- curclass.timeout);
- continue;
- }
- curclass.maxtimeout = timeout;
+ CONF_LL(maxtimeout, arg,
+ MIN(30, curclass.timeout), LLTMAX);
+
+ } else if (strcasecmp(word, "mmapsize") == 0) {
+ curclass.mmapsize = 0;
+ CONF_LL(mmapsize, arg, 0, LLTMAX);
+
+ } else if (strcasecmp(word, "readsize") == 0) {
+ curclass.readsize = 0;
+ CONF_LL(readsize, arg, 0, LLTMAX);
+
+ } else if (strcasecmp(word, "writesize") == 0) {
+ curclass.writesize = 0;
+ CONF_LL(writesize, arg, 0, LLTMAX);
+
+ } else if (strcasecmp(word, "sendbufsize") == 0) {
+ curclass.sendbufsize = 0;
+ CONF_LL(sendbufsize, arg, 0, LLTMAX);
+
+ } else if (strcasecmp(word, "sendlowat") == 0) {
+ curclass.sendlowat = 0;
+ CONF_LL(sendlowat, arg, 0, LLTMAX);
} else if (strcasecmp(word, "modify") == 0) {
CONF_FLAG(modify);
@@ -383,107 +407,60 @@ parse_conf(const char *findclass)
CONF_FLAG(passive);
} else if (strcasecmp(word, "portrange") == 0) {
- int minport, maxport;
- char *min, *max;
+ long minport, maxport;
curclass.portmin = 0;
curclass.portmax = 0;
if (none || EMPTYSTR(arg))
continue;
- min = arg;
- NEXTWORD(p, max);
- if (EMPTYSTR(max)) {
+ if (EMPTYSTR(p)) {
syslog(LOG_WARNING,
"%s line %d: missing maxport argument",
infile, (int)line);
continue;
}
- minport = (int)strtol(min, &endp, 10);
- if (*endp != 0 || minport < IPPORT_RESERVED ||
- minport > IPPORT_ANONMAX) {
- syslog(LOG_WARNING,
- "%s line %d: invalid minport %s",
- infile, (int)line, min);
+ minport = strsuftollx("minport", arg, IPPORT_RESERVED,
+ IPPORT_ANONMAX, errbuf, sizeof(errbuf));
+ if (errbuf[0]) {
+ syslog(LOG_WARNING, "%s line %d: %s",
+ infile, (int)line, errbuf);
continue;
}
- maxport = (int)strtol(max, &endp, 10);
- if (*endp != 0 || maxport < IPPORT_RESERVED ||
- maxport > IPPORT_ANONMAX) {
- syslog(LOG_WARNING,
- "%s line %d: invalid maxport %s",
- infile, (int)line, max);
+ maxport = strsuftollx("maxport", p, IPPORT_RESERVED,
+ IPPORT_ANONMAX, errbuf, sizeof(errbuf));
+ if (errbuf[0]) {
+ syslog(LOG_WARNING, "%s line %d: %s",
+ infile, (int)line, errbuf);
continue;
}
if (minport >= maxport) {
syslog(LOG_WARNING,
- "%s line %d: minport %d >= maxport %d",
+ "%s line %d: minport %ld >= maxport %ld",
infile, (int)line, minport, maxport);
continue;
}
- curclass.portmin = minport;
- curclass.portmax = maxport;
+ curclass.portmin = (int)minport;
+ curclass.portmax = (int)maxport;
} else if (strcasecmp(word, "private") == 0) {
CONF_FLAG(private);
} else if (strcasecmp(word, "rateget") == 0) {
- curclass.maxrateget = 0;
- curclass.rateget = 0;
- if (none || EMPTYSTR(arg))
- continue;
- llval = strsuftoll(arg);
- if (llval == -1) {
- syslog(LOG_WARNING,
- "%s line %d: invalid rateget %s",
- infile, (int)line, arg);
- continue;
- }
- curclass.maxrateget = llval;
- curclass.rateget = llval;
+ curclass.maxrateget = curclass.rateget = 0;
+ CONF_LL(rateget, arg, 0, LLTMAX);
+ curclass.maxrateget = curclass.rateget;
} else if (strcasecmp(word, "rateput") == 0) {
- curclass.maxrateput = 0;
- curclass.rateput = 0;
- if (none || EMPTYSTR(arg))
- continue;
- llval = strsuftoll(arg);
- if (llval == -1) {
- syslog(LOG_WARNING,
- "%s line %d: invalid rateput %s",
- infile, (int)line, arg);
- continue;
- }
- curclass.maxrateput = llval;
- curclass.rateput = llval;
+ curclass.maxrateput = curclass.rateput = 0;
+ CONF_LL(rateput, arg, 0, LLTMAX);
+ curclass.maxrateput = curclass.rateput;
} else if (strcasecmp(word, "sanenames") == 0) {
CONF_FLAG(sanenames);
} else if (strcasecmp(word, "timeout") == 0) {
curclass.timeout = DEFAULT_TIMEOUT;
- if (none || EMPTYSTR(arg))
- continue;
- timeout = (unsigned int)strtoul(arg, &endp, 10);
- if (*endp != 0) {
- syslog(LOG_WARNING,
- "%s line %d: invalid timeout %s",
- infile, (int)line, arg);
- continue;
- }
- if (timeout < 30) {
- syslog(LOG_WARNING,
- "%s line %d: timeout %d < 30 seconds",
- infile, (int)line, timeout);
- continue;
- }
- if (timeout > curclass.maxtimeout) {
- syslog(LOG_WARNING,
- "%s line %d: timeout %d > maxtimeout (%d)",
- infile, (int)line, timeout,
- curclass.maxtimeout);
- continue;
- }
- curclass.timeout = timeout;
+ CONF_LL(timeout, arg, 30, curclass.maxtimeout);
} else if (strcasecmp(word, "template") == 0) {
if (none)
@@ -491,19 +468,22 @@ parse_conf(const char *findclass)
REASSIGN(template, EMPTYSTR(arg) ? NULL : xstrdup(arg));
} else if (strcasecmp(word, "umask") == 0) {
- mode_t fumask;
+ u_long fumask;
curclass.umask = DEFAULT_UMASK;
if (none || EMPTYSTR(arg))
continue;
- fumask = (mode_t)strtoul(arg, &endp, 8);
- if (*endp != 0 || fumask > 0777) {
+ errno = 0;
+ endp = NULL;
+ fumask = strtoul(arg, &endp, 8);
+ if (errno || *arg == '\0' || *endp != '\0' ||
+ fumask > 0777) {
syslog(LOG_WARNING,
"%s line %d: invalid umask %s",
infile, (int)line, arg);
continue;
}
- curclass.umask = fumask;
+ curclass.umask = (mode_t)fumask;
} else if (strcasecmp(word, "upload") == 0) {
CONF_FLAG(upload);
@@ -516,6 +496,8 @@ parse_conf(const char *findclass)
infile, (int)line, word);
continue;
}
+ nextline:
+ ;
}
REASSIGN(template, NULL);
fclose(f);
@@ -578,7 +560,7 @@ show_chdir_messages(int code)
return;
memset(&gl, 0, sizeof(gl));
- if (glob(curclass.notify, GLOB_LIMIT, NULL, &gl) != 0
+ if (glob(curclass.notify, GLOB_BRACE|GLOB_LIMIT, NULL, &gl) != 0
|| gl.gl_matchc == 0) {
globfree(&gl);
return;
@@ -669,8 +651,8 @@ display_file(const char *file, int code)
cprintf(stdout, "unlimited");
lastnum = 0;
} else {
- cprintf(stdout, "%d",
- curclass.limit);
+ cprintf(stdout, LLF,
+ (LLT)curclass.limit);
lastnum = curclass.limit;
}
break;
@@ -891,51 +873,6 @@ do_conversion(const char *fname)
}
/*
- * Convert the string `arg' to a long long, which may have an optional SI suffix
- * (`b', `k', `m', `g', `t'). Returns the number for success, -1 otherwise.
- */
-LLT
-strsuftoll(const char *arg)
-{
- char *cp;
- LLT val;
-
- if (!isdigit((unsigned char)arg[0]))
- return (-1);
-
- val = STRTOLL(arg, &cp, 10);
- if (cp != NULL) {
- if (cp[0] != '\0' && cp[1] != '\0')
- return (-1);
- switch (tolower((unsigned char)cp[0])) {
- case '\0':
- case 'b':
- break;
- case 'k':
- val <<= 10;
- break;
- case 'm':
- val <<= 20;
- break;
- case 'g':
- val <<= 30;
- break;
-#ifndef NO_LONG_LONG
- case 't':
- val <<= 40;
- break;
-#endif
- default:
- return (-1);
- }
- }
- if (val < 0)
- return (-1);
-
- return (val);
-}
-
-/*
* Count the number of current connections, reading from
* /var/run/ftpd.pids-<class>
* Does a kill -0 on each pid in that file, and only counts
@@ -959,15 +896,8 @@ count_users(void)
if ((fd = open(fn, O_RDWR | O_CREAT, 0600)) == -1)
return;
-#if HAVE_LOCKF
if (lockf(fd, F_TLOCK, 0) == -1)
goto cleanup_count;
-#elif HAVE_FLOCK
- if (flock(fd, LOCK_EX | LOCK_NB) != 0)
- goto cleanup_count;
-#else
- /* XXX: use fcntl ? */
-#endif
if (fstat(fd, &sb) == -1)
goto cleanup_count;
if ((pids = malloc(sb.st_size + sizeof(pid_t))) == NULL)
@@ -1005,14 +935,8 @@ count_users(void)
(void)ftruncate(fd, count);
cleanup_count:
-#if HAVE_LOCKF
if (lseek(fd, 0, SEEK_SET) != -1)
(void)lockf(fd, F_ULOCK, 0);
-#elif HAVE_FLOCK
- (void)flock(fd, LOCK_UN);
-#else
- /* XXX: use fcntl ? */
-#endif
close(fd);
REASSIGN(pids, NULL);
}
diff --git a/contrib/lukemftpd/src/extern.h b/contrib/lukemftpd/src/extern.h
index 3ddb6bf..25cdf11 100644
--- a/contrib/lukemftpd/src/extern.h
+++ b/contrib/lukemftpd/src/extern.h
@@ -1,4 +1,4 @@
-/* $NetBSD: extern.h,v 1.43 2001/12/04 13:54:12 lukem Exp $ */
+/* $NetBSD: extern.h,v 1.44 2002/05/30 00:24:47 enami Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -108,15 +108,8 @@
# define ULLFP(x) "%" x "lu"
# define ULLT unsigned long
# define STRTOLL(x,y,z) strtol(x,y,z)
-#else
-#if HAVE_PRINTF_QD
-# define LLF "%qd"
-# define LLFP(x) "%" x "qd"
-# define LLT long long
-# define ULLF "%qu"
-# define ULLFP(x) "%" x "qu"
-# define ULLT unsigned long long
-# define STRTOLL(x,y,z) strtoll(x,y,z)
+# define LLTMIN LONG_MIN
+# define LLTMAX LONG_MAX
#else
# define LLF "%lld"
# define LLFP(x) "%" x "lld"
@@ -125,7 +118,8 @@
# define ULLFP(x) "%" x "llu"
# define ULLT unsigned long long
# define STRTOLL(x,y,z) strtoll(x,y,z)
-#endif
+# define LLTMIN LLONG_MIN
+# define LLTMAX LLONG_MAX
#endif
#define FTP_BUFLEN 512
@@ -137,7 +131,7 @@ char *conffilename(const char *);
char **copyblk(char **);
void count_users(void);
void cprintf(FILE *, const char *, ...)
- ;
+ __attribute__((__format__(__printf__, 2, 3)));
void cwd(const char *);
FILE *dataconn(const char *, off_t, const char *);
void delete(const char *);
@@ -177,7 +171,7 @@ void removedir(const char *);
void renamecmd(const char *, const char *);
char *renamefrom(const char *);
void reply(int, const char *, ...)
- ;
+ __attribute__((__format__(__printf__, 2, 3)));
void retrieve(char *[], const char *);
void send_file_list(const char *);
void show_chdir_messages(int);
@@ -186,7 +180,6 @@ void statcmd(void);
void statfilecmd(const char *);
void statxfer(void);
void store(const char *, const char *, int);
-LLT strsuftoll(const char *);
void user(const char *);
char *xstrdup(const char *);
void yyerror(char *);
@@ -271,24 +264,29 @@ struct ftpclass {
char *display; /* File to display upon chdir */
char *homedir; /* Directory to chdir(2) to at login */
classflag_t flags; /* Flags; see classflag_t above */
- int limit; /* Max connections (-1 = unlimited) */
+ LLT limit; /* Max connections (-1 = unlimited) */
char *limitfile; /* File to display if limit reached */
LLT maxfilesize; /* Maximum file size of uploads */
LLT maxrateget; /* Maximum get transfer rate throttle */
LLT maxrateput; /* Maximum put transfer rate throttle */
- unsigned int maxtimeout; /* Maximum permitted timeout */
+ LLT maxtimeout; /* Maximum permitted timeout */
char *motd; /* MotD file to display after login */
char *notify; /* Files to notify about upon chdir */
- int portmin; /* Minumum port for passive mode */
- int portmax; /* Maximum port for passive mode */
+ LLT portmin; /* Minumum port for passive mode */
+ LLT portmax; /* Maximum port for passive mode */
LLT rateget; /* Get (RETR) transfer rate throttle */
LLT rateput; /* Put (STOR) transfer rate throttle */
- unsigned int timeout; /* Default timeout */
+ LLT timeout; /* Default timeout */
class_ft type; /* Class type */
mode_t umask; /* Umask to use */
+ LLT mmapsize; /* mmap window size */
+ LLT readsize; /* data read size */
+ LLT writesize; /* data write size */
+ LLT sendbufsize; /* SO_SNDBUF size */
+ LLT sendlowat; /* SO_SNDLOWAT size */
};
-extern void ftp_loop(void);
+extern void ftp_loop(void) __attribute__ ((noreturn));
extern void ftp_handle_line(char *);
#ifndef GLOBAL
@@ -355,8 +353,8 @@ extern struct tab cmdtab[];
} while (0);
#define CURCLASSTYPE curclass.type == CLASS_GUEST ? "GUEST" : \
- curclass.type == CLASS_CHROOT ? "CHROOT" : \
- curclass.type == CLASS_REAL ? "REAL" : \
+ curclass.type == CLASS_CHROOT ? "CHROOT" : \
+ curclass.type == CLASS_REAL ? "REAL" : \
"<unknown>"
#define ISDOTDIR(x) (x[0] == '.' && x[1] == '\0')
diff --git a/contrib/lukemftpd/src/ftpcmd.y b/contrib/lukemftpd/src/ftpcmd.y
index 68a598b..1039d51 100644
--- a/contrib/lukemftpd/src/ftpcmd.y
+++ b/contrib/lukemftpd/src/ftpcmd.y
@@ -1,7 +1,7 @@
-/* $NetBSD: ftpcmd.y,v 1.66 2001/12/01 10:25:30 lukem Exp $ */
+/* $NetBSD: ftpcmd.y,v 1.71 2002/10/12 08:35:17 darrenr Exp $ */
/*-
- * Copyright (c) 1997-2001 The NetBSD Foundation, Inc.
+ * Copyright (c) 1997-2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -77,7 +77,41 @@
*/
%{
-#include "lukemftpd.h"
+#include <sys/cdefs.h>
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)ftpcmd.y 8.3 (Berkeley) 4/6/94";
+#else
+__RCSID("$NetBSD: ftpcmd.y,v 1.71 2002/10/12 08:35:17 darrenr Exp $");
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+
+#include <netinet/in.h>
+#include <arpa/ftp.h>
+#include <arpa/inet.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <pwd.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <time.h>
+#include <tzfile.h>
+#include <unistd.h>
+#include <netdb.h>
+
+#ifdef KERBEROS5
+#include <krb5/krb5.h>
+#endif
#include "extern.h"
#include "version.h"
@@ -93,7 +127,10 @@ char *fromname;
%}
%union {
- int i;
+ struct {
+ off_t o;
+ int i;
+ } u;
char *s;
}
@@ -128,10 +165,10 @@ char *fromname;
%token <s> STRING
%token <s> ALL
-%token <i> NUMBER
+%token <u> NUMBER
-%type <i> check_login octal_number byte_size
-%type <i> struct_code mode_code type_code form_code decimal_integer
+%type <u.i> check_login octal_number byte_size
+%type <u.i> struct_code mode_code type_code form_code decimal_integer
%type <s> pathstring pathname password username
%type <s> mechanism_name base64data prot_code
@@ -259,32 +296,48 @@ cmd
| LPSV check_login CRLF
{
if ($2) {
- if (epsvall)
- reply(501,
- "LPSV disallowed after EPSV ALL");
- else
- long_passive("LPSV", PF_UNSPEC);
+ if (CURCLASS_FLAGS_ISSET(passive)) {
+ if (epsvall)
+ reply(501,
+ "LPSV disallowed after EPSV ALL");
+ else
+ long_passive("LPSV", PF_UNSPEC);
+ } else
+ reply(500, "LPSV mode not available.");
}
}
| EPSV check_login SP NUMBER CRLF
{
- if ($2)
- long_passive("EPSV", epsvproto2af($4));
+ if ($2) {
+ if (CURCLASS_FLAGS_ISSET(passive))
+ long_passive("EPSV",
+ epsvproto2af($4.i));
+ else
+ reply(500, "EPSV mode not available.");
+ }
}
| EPSV check_login SP ALL CRLF
{
if ($2) {
- reply(200, "EPSV ALL command successful.");
- epsvall++;
+ if (CURCLASS_FLAGS_ISSET(passive)) {
+ reply(200,
+ "EPSV ALL command successful.");
+ epsvall++;
+ } else
+ reply(500, "EPSV mode not available.");
}
}
| EPSV check_login CRLF
{
- if ($2)
- long_passive("EPSV", PF_UNSPEC);
+ if ($2) {
+ if (CURCLASS_FLAGS_ISSET(passive))
+ long_passive("EPSV", PF_UNSPEC);
+ else
+ reply(500, "EPSV mode not available.");
+ }
}
| TYPE check_login SP type_code CRLF
@@ -517,24 +570,28 @@ cmd
{
if ($4) {
reply(200,
- "Current IDLE time limit is %d seconds; max %d",
- curclass.timeout, curclass.maxtimeout);
+ "Current IDLE time limit is " LLF
+ " seconds; max " LLF,
+ (LLT)curclass.timeout,
+ (LLT)curclass.maxtimeout);
}
}
| SITE SP IDLE check_login SP NUMBER CRLF
{
if ($4) {
- if ($6 < 30 || $6 > curclass.maxtimeout) {
+ if ($6.i < 30 || $6.i > curclass.maxtimeout) {
reply(501,
- "IDLE time limit must be between 30 and %d seconds",
- curclass.maxtimeout);
+ "IDLE time limit must be between 30 and "
+ LLF " seconds",
+ (LLT)curclass.maxtimeout);
} else {
- curclass.timeout = $6;
+ curclass.timeout = $6.i;
(void) alarm(curclass.timeout);
reply(200,
- "IDLE time limit set to %d seconds",
- curclass.timeout);
+ "IDLE time limit set to "
+ LLF " seconds",
+ (LLT)curclass.timeout);
}
}
}
@@ -550,19 +607,17 @@ cmd
| SITE SP RATEGET check_login SP STRING CRLF
{
+ char errbuf[100];
char *p = $6;
LLT rate;
if ($4) {
- rate = strsuftoll(p);
- if (rate == -1)
- reply(501, "Invalid RATEGET %s", p);
- else if (curclass.maxrateget &&
- rate > curclass.maxrateget)
- reply(501,
- "RATEGET " LLF " is larger than maximum RATEGET " LLF,
- (LLT)rate,
- (LLT)curclass.maxrateget);
+ rate = strsuftollx("RATEGET", p, 0,
+ curclass.maxrateget
+ ? curclass.maxrateget
+ : LLTMAX, errbuf, sizeof(errbuf));
+ if (errbuf[0])
+ reply(501, "%s", errbuf);
else {
curclass.rateget = rate;
reply(200,
@@ -584,19 +639,17 @@ cmd
| SITE SP RATEPUT check_login SP STRING CRLF
{
+ char errbuf[100];
char *p = $6;
LLT rate;
if ($4) {
- rate = strsuftoll(p);
- if (rate == -1)
- reply(501, "Invalid RATEPUT %s", p);
- else if (curclass.maxrateput &&
- rate > curclass.maxrateput)
- reply(501,
- "RATEPUT " LLF " is larger than maximum RATEPUT " LLF,
- (LLT)rate,
- (LLT)curclass.maxrateput);
+ rate = strsuftollx("RATEPUT", p, 0,
+ curclass.maxrateput
+ ? curclass.maxrateput
+ : LLTMAX, errbuf, sizeof(errbuf));
+ if (errbuf[0])
+ reply(501, "%s", errbuf);
else {
curclass.rateput = rate;
reply(200,
@@ -622,7 +675,7 @@ cmd
{
int oldmask;
- if ($4 && CURCLASS_FLAGS_ISSET(modify)) {
+ if ($4 && check_write("", 0)) {
if (($6 == -1) || ($6 > 0777)) {
reply(501, "Bad UMASK value");
} else {
@@ -827,11 +880,11 @@ cmd
;
rcmd
- : REST check_login SP byte_size CRLF
+ : REST check_login SP NUMBER CRLF
{
if ($2) {
fromname = NULL;
- restart_point = $4; /* XXX: $4 is only "int" */
+ restart_point = $4.o;
reply(350,
"Restarting at " LLF ". Send STORE or RETRIEVE to initiate transfer.",
(LLT)restart_point);
@@ -863,6 +916,9 @@ password
byte_size
: NUMBER
+ {
+ $$ = $1.i;
+ }
;
host_port
@@ -875,9 +931,9 @@ host_port
data_dest.su_len = sizeof(struct sockaddr_in);
data_dest.su_family = AF_INET;
p = (char *)&data_dest.su_port;
- p[0] = $9; p[1] = $11;
+ p[0] = $9.i; p[1] = $11.i;
a = (char *)&data_dest.su_addr;
- a[0] = $1; a[1] = $3; a[2] = $5; a[3] = $7;
+ a[0] = $1.i; a[1] = $3.i; a[2] = $5.i; a[3] = $7.i;
}
;
@@ -892,12 +948,12 @@ host_long_port4
data_dest.su_len = sizeof(struct sockaddr_in);
data_dest.su_family = AF_INET;
p = (char *)&data_dest.su_port;
- p[0] = $15; p[1] = $17;
+ p[0] = $15.i; p[1] = $17.i;
a = (char *)&data_dest.su_addr;
- a[0] = $5; a[1] = $7; a[2] = $9; a[3] = $11;
+ a[0] = $5.i; a[1] = $7.i; a[2] = $9.i; a[3] = $11.i;
/* reject invalid LPRT command */
- if ($1 != 4 || $3 != 4 || $13 != 2)
+ if ($1.i != 4 || $3.i != 4 || $13.i != 2)
memset(&data_dest, 0, sizeof(data_dest));
}
;
@@ -917,12 +973,12 @@ host_long_port6
data_dest.su_len = sizeof(struct sockaddr_in6);
data_dest.su_family = AF_INET6;
p = (char *)&data_dest.su_port;
- p[0] = $39; p[1] = $41;
+ p[0] = $39.i; p[1] = $41.i;
a = (char *)&data_dest.si_su.su_sin6.sin6_addr;
- a[0] = $5; a[1] = $7; a[2] = $9; a[3] = $11;
- a[4] = $13; a[5] = $15; a[6] = $17; a[7] = $19;
- a[8] = $21; a[9] = $23; a[10] = $25; a[11] = $27;
- a[12] = $29; a[13] = $31; a[14] = $33; a[15] = $35;
+ a[0] = $5.i; a[1] = $7.i; a[2] = $9.i; a[3] = $11.i;
+ a[4] = $13.i; a[5] = $15.i; a[6] = $17.i; a[7] = $19.i;
+ a[8] = $21.i; a[9] = $23.i; a[10] = $25.i; a[11] = $27.i;
+ a[12] = $29.i; a[13] = $31.i; a[14] = $33.i; a[15] = $35.i;
if (his_addr.su_family == AF_INET6) {
/* XXX: more sanity checks! */
data_dest.su_scope_id = his_addr.su_scope_id;
@@ -931,7 +987,7 @@ host_long_port6
memset(&data_dest, 0, sizeof(data_dest));
#endif /* INET6 */
/* reject invalid LPRT command */
- if ($1 != 6 || $3 != 16 || $37 != 2)
+ if ($1.i != 6.i || $3.i != 16.i || $37.i != 2)
memset(&data_dest, 0, sizeof(data_dest));
}
;
@@ -1093,7 +1149,7 @@ octal_number
* Convert a number that was read as decimal number
* to what it would be if it had been read as octal.
*/
- dec = $1;
+ dec = $1.i;
multby = 1;
ret = 0;
while (dec) {
@@ -1124,6 +1180,9 @@ prot_code
decimal_integer
: NUMBER
+ {
+ $$ = $1.i;
+ }
;
check_login
@@ -1231,13 +1290,13 @@ struct tab cmdtab[] = {
};
struct tab sitetab[] = {
- { "CHMOD", CHMOD, NSTR, 1, "<sp> mode <sp> file-name" },
- { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]" },
- { "IDLE", IDLE, ARGS, 1, "[ <sp> maximum-idle-time ]" },
- { "RATEGET", RATEGET,OSTR, 1, "[ <sp> get-throttle-rate ]" },
- { "RATEPUT", RATEPUT,OSTR, 1, "[ <sp> put-throttle-rate ]" },
- { "UMASK", UMASK, ARGS, 1, "[ <sp> umask ]" },
- { NULL, 0, 0, 0, NULL }
+ { "CHMOD", CHMOD, NSTR, 1, "<sp> mode <sp> file-name" },
+ { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]" },
+ { "IDLE", IDLE, ARGS, 1, "[ <sp> maximum-idle-time ]" },
+ { "RATEGET", RATEGET,OSTR, 1, "[ <sp> get-throttle-rate ]" },
+ { "RATEPUT", RATEPUT,OSTR, 1, "[ <sp> put-throttle-rate ]" },
+ { "UMASK", UMASK, ARGS, 1, "[ <sp> umask ]" },
+ { NULL, 0, 0, 0, NULL }
};
static int check_write(const char *, int);
@@ -1251,6 +1310,8 @@ extern int epsvall;
/*
* Check if a filename is allowed to be modified (isupload == 0) or
* uploaded (isupload == 1), and if necessary, check the filename is `sane'.
+ * If the filename is NULL, fail.
+ * If the filename is "", don't do the sane name check.
*/
static int
check_write(const char *file, int isupload)
@@ -1271,8 +1332,9 @@ check_write(const char *file, int isupload)
reply(502, "No permission to use this command.");
return (0);
}
+
/* checking sanenames */
- if (CURCLASS_FLAGS_ISSET(sanenames)) {
+ if (file[0] != '\0' && CURCLASS_FLAGS_ISSET(sanenames)) {
const char *p;
if (file[0] == '.')
@@ -1392,11 +1454,11 @@ toolong(int signo)
{
reply(421,
- "Timeout (%d seconds): closing control connection.",
- curclass.timeout);
+ "Timeout (" LLF " seconds): closing control connection.",
+ (LLT)curclass.timeout);
if (logging)
- syslog(LOG_INFO, "User %s timed out after %d seconds",
- (pw ? pw->pw_name : "unknown"), curclass.timeout);
+ syslog(LOG_INFO, "User %s timed out after " LLF " seconds",
+ (pw ? pw->pw_name : "unknown"), (LLT)curclass.timeout);
dologout(1);
}
@@ -1548,7 +1610,7 @@ yylex(void)
;
c = cmdp[cpos];
cmdp[cpos] = '\0';
- yylval.i = atoi(cp);
+ yylval.u.i = atoi(cp);
cmdp[cpos] = c;
state = STR1;
return (NUMBER);
@@ -1563,7 +1625,8 @@ yylex(void)
;
c = cmdp[cpos];
cmdp[cpos] = '\0';
- yylval.i = atoi(cp);
+ yylval.u.i = atoi(cp);
+ yylval.u.o = strtoull(cp, (char **)NULL, 10);
cmdp[cpos] = c;
return (NUMBER);
}
@@ -1736,13 +1799,13 @@ help(struct tab *ctab, const char *s)
}
c = lookup(ctab, s);
if (c == (struct tab *)0) {
- reply(502, "Unknown command %s.", s);
+ reply(502, "Unknown command '%s'.", s);
return;
}
if (CMD_IMPLEMENTED(c))
reply(214, "Syntax: %s%s %s", htype, c->name, c->help);
else
- reply(214, "%s%-*s\t%s; not implemented.", htype, width,
+ reply(504, "%s%-*s\t%s; not implemented.", htype, width,
c->name, c->help);
}
diff --git a/contrib/lukemftpd/src/ftpd.8 b/contrib/lukemftpd/src/ftpd.8
index 5aaadf0..d024633 100644
--- a/contrib/lukemftpd/src/ftpd.8
+++ b/contrib/lukemftpd/src/ftpd.8
@@ -1,6 +1,6 @@
.\" $NetBSD: ftpd.8,v 1.69 2002/02/08 01:30:07 ross Exp $
.\"
-.\" Copyright (c) 1997-2001 The NetBSD Foundation, Inc.
+.\" Copyright (c) 1997-2002 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
@@ -67,7 +67,7 @@
.\"
.\" @(#)ftpd.8 8.2 (Berkeley) 4/19/94
.\"
-.Dd October 13, 2001
+.Dd October 25, 2002
.Dt FTPD 8
.Os
.Sh NAME
@@ -734,7 +734,7 @@ and
.Cm draft-ietf-ftpext-mlst-11
support was implemented in
.Nx 1.3
-and later releases by Luke Mewburn \*[Lt]lukem@netbsd.org\*[Gt].
+and later releases by Luke Mewburn.
.Sh BUGS
The server must run as the super-user to create sockets with
privileged port numbers (i.e, those less than
diff --git a/contrib/lukemftpd/src/ftpd.c b/contrib/lukemftpd/src/ftpd.c
index 7170536..de19ccc 100644
--- a/contrib/lukemftpd/src/ftpd.c
+++ b/contrib/lukemftpd/src/ftpd.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ftpd.c,v 1.138 2002/02/11 11:45:07 lukem Exp $ */
+/* $NetBSD: ftpd.c,v 1.147 2002/11/29 14:40:00 lukem Exp $ */
/*
* Copyright (c) 1997-2001 The NetBSD Foundation, Inc.
@@ -98,20 +98,69 @@
* SUCH DAMAGE.
*/
+#include <sys/cdefs.h>
+#ifndef lint
+__COPYRIGHT(
+"@(#) Copyright (c) 1985, 1988, 1990, 1992, 1993, 1994\n\
+ The Regents of the University of California. All rights reserved.\n");
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)ftpd.c 8.5 (Berkeley) 4/28/95";
+#else
+__RCSID("$NetBSD: ftpd.c,v 1.147 2002/11/29 14:40:00 lukem Exp $");
+#endif
+#endif /* not lint */
+
/*
* FTP server.
*/
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <sys/mman.h>
+#include <sys/resource.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
#define FTP_NAMES
-
-#include "lukemftpd.h"
-
-#if HAVE_GETSPNAM
-#include <shadow.h>
-#endif
-
+#include <arpa/ftp.h>
+#include <arpa/inet.h>
#include <arpa/telnet.h>
+#include <ctype.h>
+#include <dirent.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <fnmatch.h>
+#include <glob.h>
+#include <grp.h>
+#include <limits.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <time.h>
+#include <tzfile.h>
+#include <unistd.h>
+#include <util.h>
+#ifdef SUPPORT_UTMP
+#include <utmp.h>
+#endif
+#ifdef SUPPORT_UTMPX
+#include <utmpx.h>
+#endif
#ifdef SKEY
#include <skey.h>
#endif
@@ -140,7 +189,12 @@ int mapped; /* IPv4 connection on AF_INET6 socket */
off_t file_size;
off_t byte_count;
static char ttyline[20];
+#ifdef SUPPORT_UTMP
static struct utmp utmp; /* for utmp */
+#endif
+#ifdef SUPPORT_UTMPX
+static struct utmpx utmpx; /* for utmpx */
+#endif
static const char *anondir = NULL;
static const char *confdir = _DEFAULT_CONFDIR;
@@ -166,6 +220,13 @@ int epsvall = 0;
int swaitmax = SWAITMAX;
int swaitint = SWAITINT;
+enum send_status {
+ SS_SUCCESS,
+ SS_NO_TRANSFER, /* no transfer made yet */
+ SS_FILE_ERROR, /* file read error */
+ SS_DATA_ERROR /* data send error */
+};
+
static int bind_pasv_addr(void);
static int checkuser(const char *, const char *, int, int, char **);
static int checkaccess(const char *);
@@ -173,12 +234,21 @@ static int checkpassword(const struct passwd *, const char *);
static void end_login(void);
static FILE *getdatasock(const char *);
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 int receive_data(FILE *, FILE *);
-static int send_data(FILE *, FILE *, off_t, int);
+static int send_data(FILE *, FILE *, const struct stat *, int);
static struct passwd *sgetpwnam(const char *);
+static int write_data(int, char *, size_t, off_t *, struct timeval *,
+ int);
+static enum send_status
+ send_data_with_read(int, int, const struct stat *, int);
+static enum send_status
+ send_data_with_mmap(int, int, const struct stat *, int);
+static void logrusage(const struct rusage *, const struct rusage *);
+static void logout_utmp(void);
int main(int, char *[]);
@@ -191,8 +261,6 @@ int k5login(struct passwd *, char *, char *, char *);
void k5destroy(void);
#endif
-char * __progname;
-
int
main(int argc, char *argv[])
{
@@ -201,12 +269,7 @@ main(int argc, char *argv[])
krb5_error_code kerror;
#endif
char *p;
-
- __progname = strrchr(argv[0], '/');
- if (__progname == NULL)
- __progname = argv[0];
- else
- __progname++;
+ long l;
connections = 1;
debug = 0;
@@ -232,7 +295,7 @@ main(int argc, char *argv[])
* LOG_NDELAY sets up the logging connection immediately,
* necessary for anonymous ftp's that chroot and can't do it later.
*/
- openlog("ftpd", LOG_PID | LOG_NDELAY, FTPD_LOGTYPE);
+ openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP);
while ((ch = getopt(argc, argv, "a:c:C:de:h:HlP:qQrst:T:uUvV:wWX"))
!= -1) {
@@ -274,13 +337,17 @@ main(int argc, char *argv[])
break;
case 'P':
- dataport = (int)strtol(optarg, &p, 10);
- if (*p != '\0' || dataport < IPPORT_RESERVED ||
- dataport > IPPORT_ANONMAX) {
+ errno = 0;
+ p = NULL;
+ l = strtol(optarg, &p, 10);
+ if (errno || *optarg == '\0' || *p != '\0' ||
+ l < IPPORT_RESERVED ||
+ l > IPPORT_ANONMAX) {
syslog(LOG_WARNING, "Invalid dataport %s",
optarg);
dataport = 0;
}
+ dataport = (int)l;
break;
case 'q':
@@ -529,7 +596,7 @@ sgetpwnam(const char *name)
static int login_attempts; /* number of failed login attempts */
static int askpasswd; /* had USER command, ask for PASSwd */
static int permitted; /* USER permitted */
-static char curname[10]; /* current USER name */
+static char curname[LOGIN_NAME_MAX]; /* current USER name */
/*
* USER command.
@@ -733,7 +800,7 @@ checkuser(const char *fname, const char *name, int def, int nofile,
line = 0;
for (;
(buf = fparseln(fd, &len, &line, NULL, FPARSELN_UNESCCOMM |
- FPARSELN_UNESCCONT | FPARSELN_UNESCESC)) != NULL;
+ FPARSELN_UNESCCONT | FPARSELN_UNESCESC)) != NULL;
free(buf), buf = NULL) {
word = perm = class = NULL;
p = buf;
@@ -850,6 +917,69 @@ checkaccess(const char *name)
return (checkuser(_PATH_FTPUSERS, name, 1, 0, NULL));
}
+static void
+login_utmp(const char *line, const char *name, const char *host)
+{
+#if defined(SUPPORT_UTMPX) || defined(SUPPORT_UTMP)
+ struct timeval tv;
+ (void)gettimeofday(&tv, NULL);
+#endif
+#ifdef SUPPORT_UTMPX
+ if (doutmp) {
+ (void)memset(&utmpx, 0, sizeof(utmpx));
+ utmpx.ut_tv = tv;
+ utmpx.ut_pid = getpid();
+ utmpx.ut_id[0] = 'f';
+ utmpx.ut_id[1] = 't';
+ utmpx.ut_id[2] = 'p';
+ utmpx.ut_id[3] = '*';
+ utmpx.ut_type = USER_PROCESS;
+ (void)strncpy(utmpx.ut_name, name, sizeof(utmpx.ut_name));
+ (void)strncpy(utmpx.ut_line, line, sizeof(utmpx.ut_line));
+ (void)strncpy(utmpx.ut_host, host, sizeof(utmpx.ut_host));
+ loginx(&utmpx);
+ }
+ if (dowtmp)
+ logwtmpx(line, name, host, 0, USER_PROCESS);
+#endif
+#ifdef SUPPORT_UTMP
+ if (doutmp) {
+ (void)memset(&utmp, 0, sizeof(utmp));
+ (void)time(&utmp.ut_time);
+ (void)strncpy(utmp.ut_name, name, sizeof(utmp.ut_name));
+ (void)strncpy(utmp.ut_line, line, sizeof(utmp.ut_line));
+ (void)strncpy(utmp.ut_host, host, sizeof(utmp.ut_host));
+ login(&utmp);
+ }
+ if (dowtmp)
+ logwtmp(line, name, host);
+#endif
+}
+
+static void
+logout_utmp(void)
+{
+ int okwtmp = dowtmp;
+ if (logged_in) {
+ if (doutmp) {
+#ifdef SUPPORT_UTMPX
+ okwtmp = logoutx(ttyline, 0, DEAD_PROCESS) & dowtmp;
+#endif
+#ifdef SUPPORT_UTMP
+ okwtmp = logout(ttyline) & dowtmp;
+#endif
+ }
+ if (okwtmp) {
+#ifdef SUPPORT_UTMPX
+ logwtmpx(ttyline, "", "", 0, DEAD_PROCESS);
+#endif
+#ifdef SUPPORT_UTMP
+ logwtmp(ttyline, "", "");
+#endif
+ }
+ }
+}
+
/*
* Terminate login as previous user (if any), resetting state;
* used when USER command is given or login fails.
@@ -857,16 +987,7 @@ checkaccess(const char *name)
static void
end_login(void)
{
-
- if (logged_in) {
-#ifdef NO_UTMP
- if (dowtmp)
- logwtmp(ttyline, "", "");
- if (doutmp)
- logout(utmp.ut_line);
-#endif /* NO_UTMP */
- }
- /* reset login state */
+ logout_utmp();
show_chdir_messages(-1); /* flush chdir cache */
if (pw != NULL && pw->pw_passwd != NULL)
memset(pw->pw_passwd, 0, strlen(pw->pw_passwd));
@@ -885,8 +1006,6 @@ pass(const char *passwd)
{
int rval;
char root[MAXPATHLEN];
- char *p;
- int len;
if (logged_in || askpasswd == 0) {
reply(503, "Login with USER first.");
@@ -976,21 +1095,8 @@ pass(const char *passwd)
/* cache groups for cmds.c::matchgroup() */
gidcount = getgroups(sizeof(gidlist), gidlist);
- /* open wtmp before chroot */
-#ifdef NO_UTMP
- if (dowtmp)
- logwtmp(ttyline, pw->pw_name, remotehost);
-
- /* open utmp before chroot */
- if (doutmp) {
- memset((void *)&utmp, 0, sizeof(utmp));
- (void)time(&utmp.ut_time);
- (void)strncpy(utmp.ut_name, pw->pw_name, sizeof(utmp.ut_name));
- (void)strncpy(utmp.ut_host, remotehost, sizeof(utmp.ut_host));
- (void)strncpy(utmp.ut_line, ttyline, sizeof(utmp.ut_line));
- login(&utmp);
- }
-#endif /* NO_UTMP */
+ /* open utmp/wtmp before chroot */
+ login_utmp(ttyline, pw->pw_name, remotehost);
logged_in = 1;
@@ -1002,11 +1108,13 @@ pass(const char *passwd)
(void)display_file(conffilename(curclass.limitfile),
530);
reply(530,
- "User %s access denied, connection limit of %d reached.",
- pw->pw_name, curclass.limit);
+ "User %s access denied, connection limit of " LLF
+ " reached.",
+ pw->pw_name, (LLT)curclass.limit);
syslog(LOG_NOTICE,
- "Maximum connection limit of %d for class %s reached, login refused for %s",
- curclass.limit, curclass.classname, pw->pw_name);
+ "Maximum connection limit of " LLF
+ " for class %s reached, login refused for %s",
+ (LLT)curclass.limit, curclass.classname, pw->pw_name);
goto bad;
}
@@ -1099,9 +1207,7 @@ pass(const char *passwd)
}
break;
}
-#if HAVE_SETLOGIN
setlogin(pw->pw_name);
-#endif
if (dropprivs ||
(curclass.type != CLASS_REAL &&
ntohs(ctrl_addr.su_port) > IPPORT_RESERVED + 1)) {
@@ -1120,15 +1226,7 @@ pass(const char *passwd)
goto bad;
}
}
- len = sizeof("HOME=") + strlen(homedir) + 1;;
- p = malloc(len);
- if (p == NULL) {
- reply(550, "Local resource failure: malloc");
- goto bad;
- }
- snprintf(p, len, "HOME=%s", homedir);
- putenv(p);
- free(p);
+ setenv("HOME", homedir, 1);
if (curclass.type == CLASS_GUEST && passwd[0] == '-')
quietmessages = 1;
@@ -1186,19 +1284,20 @@ retrieve(char *argv[], const char *name)
FILE *fin, *dout;
struct stat st;
int (*closefunc)(FILE *) = NULL;
- int log, sendrv, closerv, stderrfd, isconversion, isdata, isls;
+ int dolog, sendrv, closerv, stderrfd, isconversion, isdata, isls;
struct timeval start, finish, td, *tdp;
+ struct rusage rusage_before, rusage_after;
const char *dispname;
char *error;
sendrv = closerv = stderrfd = -1;
- isconversion = isdata = isls = log = 0;
+ isconversion = isdata = isls = dolog = 0;
tdp = NULL;
dispname = name;
fin = dout = NULL;
error = NULL;
if (argv == NULL) { /* if not running a command ... */
- log = 1;
+ dolog = 1;
isdata = 1;
fin = fopen(name, "r");
closefunc = fclose;
@@ -1231,7 +1330,7 @@ retrieve(char *argv[], const char *name)
if (fin == NULL) {
if (errno != 0) {
perror_reply(550, dispname);
- if (log)
+ if (dolog)
logxfer("get", -1, name, NULL, NULL,
strerror(errno));
}
@@ -1268,15 +1367,20 @@ retrieve(char *argv[], const char *name)
if (dout == NULL)
goto done;
+ (void)getrusage(RUSAGE_SELF, &rusage_before);
(void)gettimeofday(&start, NULL);
- sendrv = send_data(fin, dout, st.st_blksize, isdata);
+ sendrv = send_data(fin, dout, &st, isdata);
(void)gettimeofday(&finish, NULL);
+ (void)getrusage(RUSAGE_SELF, &rusage_after);
closedataconn(dout); /* close now to affect timing stats */
timersub(&finish, &start, &td);
tdp = &td;
done:
- if (log)
+ if (dolog) {
logxfer("get", byte_count, name, NULL, tdp, error);
+ if (tdp != NULL)
+ logrusage(&rusage_before, &rusage_after);
+ }
closerv = (*closefunc)(fin);
if (sendrv == 0) {
FILE *errf;
@@ -1567,21 +1671,173 @@ closedataconn(FILE *fd)
pdata = -1;
}
+int
+write_data(int fd, char *buf, size_t size, off_t *bufrem,
+ struct timeval *then, int isdata)
+{
+ struct timeval now, td;
+ ssize_t c;
+
+ while (size > 0) {
+ c = size;
+ if (curclass.writesize) {
+ if (curclass.writesize < c)
+ c = curclass.writesize;
+ }
+ if (curclass.rateget) {
+ if (*bufrem < c)
+ c = *bufrem;
+ }
+ (void) alarm(curclass.timeout);
+ c = write(fd, buf, c);
+ if (c <= 0)
+ return (1);
+ buf += c;
+ size -= c;
+ byte_count += c;
+ if (isdata) {
+ total_data_out += c;
+ total_data += c;
+ }
+ total_bytes_out += c;
+ total_bytes += c;
+ if (curclass.rateget) {
+ *bufrem -= c;
+ if (*bufrem == 0) {
+ (void)gettimeofday(&now, NULL);
+ timersub(&now, then, &td);
+ if (td.tv_sec == 0) {
+ usleep(1000000 - td.tv_usec);
+ (void)gettimeofday(then, NULL);
+ } else
+ *then = now;
+ *bufrem = curclass.rateget;
+ }
+ }
+ }
+ return (0);
+}
+
+static enum send_status
+send_data_with_read(int filefd, int netfd, const struct stat *st, int isdata)
+{
+ struct timeval then;
+ off_t bufrem;
+ size_t readsize;
+ char *buf;
+ int c, error;
+
+ if (curclass.readsize)
+ readsize = curclass.readsize;
+ else
+ readsize = (size_t)st->st_blksize;
+ if ((buf = malloc(readsize)) == NULL) {
+ perror_reply(451, "Local resource failure: malloc");
+ return (SS_NO_TRANSFER);
+ }
+
+ if (curclass.rateget) {
+ bufrem = curclass.rateget;
+ (void)gettimeofday(&then, NULL);
+ }
+ while (1) {
+ (void) alarm(curclass.timeout);
+ c = read(filefd, buf, readsize);
+ if (c == 0)
+ error = SS_SUCCESS;
+ else if (c < 0)
+ error = SS_FILE_ERROR;
+ else if (write_data(netfd, buf, c, &bufrem, &then, isdata))
+ error = SS_DATA_ERROR;
+ else
+ continue;
+
+ free(buf);
+ return (error);
+ }
+}
+
+static enum send_status
+send_data_with_mmap(int filefd, int netfd, const struct stat *st, int isdata)
+{
+ struct timeval then;
+ off_t bufrem, filesize, off, origoff;
+ size_t mapsize, winsize;
+ int error, sendbufsize, sendlowat;
+ void *win;
+
+ if (curclass.sendbufsize) {
+ sendbufsize = curclass.sendbufsize;
+ if (setsockopt(netfd, SOL_SOCKET, SO_SNDBUF,
+ &sendbufsize, sizeof(int)) == -1)
+ syslog(LOG_WARNING, "setsockopt(SO_SNDBUF, %d): %m",
+ sendbufsize);
+ }
+
+ if (curclass.sendlowat) {
+ sendlowat = curclass.sendlowat;
+ if (setsockopt(netfd, SOL_SOCKET, SO_SNDLOWAT,
+ &sendlowat, sizeof(int)) == -1)
+ syslog(LOG_WARNING, "setsockopt(SO_SNDLOWAT, %d): %m",
+ sendlowat);
+ }
+
+ winsize = curclass.mmapsize;
+ filesize = st->st_size;
+ if (debug)
+ syslog(LOG_INFO, "mmapsize = %ld, writesize = %ld",
+ (long)winsize, (long)curclass.writesize);
+ if (winsize == 0)
+ goto try_read;
+
+ off = lseek(filefd, (off_t)0, SEEK_CUR);
+ if (off == -1)
+ goto try_read;
+
+ origoff = off;
+ if (curclass.rateget) {
+ bufrem = curclass.rateget;
+ (void)gettimeofday(&then, NULL);
+ }
+ while (1) {
+ mapsize = MIN(filesize - off, winsize);
+ if (mapsize == 0)
+ break;
+ win = mmap(NULL, mapsize, PROT_READ,
+ MAP_FILE|MAP_SHARED, filefd, off);
+ if (win == MAP_FAILED) {
+ if (off == origoff)
+ goto try_read;
+ return (SS_FILE_ERROR);
+ }
+ (void) madvise(win, mapsize, MADV_SEQUENTIAL);
+ error = write_data(netfd, win, mapsize, &bufrem, &then,
+ isdata);
+ (void) madvise(win, mapsize, MADV_DONTNEED);
+ munmap(win, mapsize);
+ if (error)
+ return (SS_DATA_ERROR);
+ off += mapsize;
+ }
+ return (SS_SUCCESS);
+
+ try_read:
+ return (send_data_with_read(filefd, netfd, st, isdata));
+}
+
/*
* Tranfer the contents of "instr" to "outstr" peer using the appropriate
- * encapsulation of the data subject * to Mode, Structure, and Type.
+ * encapsulation of the data subject to Mode, Structure, and Type.
*
* NB: Form isn't handled.
*/
static int
-send_data(FILE *instr, FILE *outstr, off_t blksize, int isdata)
+send_data(FILE *instr, FILE *outstr, const struct stat *st, int isdata)
{
int c, filefd, netfd, rval;
- char *buf;
transflag = 1;
rval = -1;
- buf = NULL;
if (setjmp(urgcatch))
goto cleanup_send_data;
@@ -1624,66 +1880,22 @@ send_data(FILE *instr, FILE *outstr, off_t blksize, int isdata)
case TYPE_I:
case TYPE_L:
- if ((buf = malloc((size_t)blksize)) == NULL) {
- perror_reply(451, "Local resource failure: malloc");
- goto cleanup_send_data;
- }
filefd = fileno(instr);
netfd = fileno(outstr);
- (void) alarm(curclass.timeout);
- if (curclass.rateget) {
- while (1) {
- int d;
- struct timeval then, now, td;
- off_t bufrem;
- char *bufp;
+ switch (send_data_with_mmap(filefd, netfd, st, isdata)) {
- (void)gettimeofday(&then, NULL);
- errno = c = d = 0;
- bufrem = curclass.rateget;
- while (bufrem > 0) {
- if ((c = read(filefd, buf,
- MIN(blksize, bufrem))) <= 0)
- goto senddone;
- (void) alarm(curclass.timeout);
- bufrem -= c;
- byte_count += c;
- if (isdata) {
- total_data_out += c;
- total_data += c;
- }
- total_bytes_out += c;
- total_bytes += c;
- for (bufp = buf; c > 0;
- c -= d, bufp += d)
- if ((d =
- write(netfd, bufp, c)) <= 0)
- break;
- if (d < 0)
- goto data_err;
- }
- (void)gettimeofday(&now, NULL);
- timersub(&now, &then, &td);
- if (td.tv_sec == 0)
- usleep(1000000 - td.tv_usec);
- }
- } else {
- while ((c = read(filefd, buf, (size_t)blksize)) > 0) {
- if (write(netfd, buf, c) != c)
- goto data_err;
- (void) alarm(curclass.timeout);
- byte_count += c;
- if (isdata) {
- total_data_out += c;
- total_data += c;
- }
- total_bytes_out += c;
- total_bytes += c;
- }
- }
- senddone:
- if (c < 0)
+ case SS_SUCCESS:
+ break;
+
+ case SS_NO_TRANSFER:
+ goto cleanup_send_data;
+
+ case SS_FILE_ERROR:
goto file_err;
+
+ case SS_DATA_ERROR:
+ goto data_err;
+ }
rval = 0;
goto cleanup_send_data;
@@ -1705,8 +1917,6 @@ send_data(FILE *instr, FILE *outstr, off_t blksize, int isdata)
cleanup_send_data:
(void) alarm(0);
transflag = 0;
- if (buf)
- free(buf);
if (isdata) {
total_files_out++;
total_files++;
@@ -1888,7 +2098,7 @@ statcmd(void)
{
struct sockinet *su = NULL;
static char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
- u_char *a, *p;
+ u_char *a, *p;
int ispassive, af;
off_t otbi, otbo, otb;
@@ -1929,7 +2139,7 @@ statcmd(void)
strunames[stru], modenames[mode]);
ispassive = 0;
if (data != -1) {
- reply(0, "Data connection open");
+ reply(0, "Data connection open");
su = NULL;
} else if (pdata != -1) {
reply(0, "in Passive mode");
@@ -2053,13 +2263,14 @@ statcmd(void)
reply(0, "Display file: %s", curclass.display);
if (! EMPTYSTR(curclass.notify))
reply(0, "Notify fileglob: %s", curclass.notify);
- reply(0, "Idle timeout: %d, maximum timeout: %d",
- curclass.timeout, curclass.maxtimeout);
+ reply(0, "Idle timeout: " LLF ", maximum timeout: " LLF,
+ (LLT)curclass.timeout, (LLT)curclass.maxtimeout);
reply(0, "Current connections: %d", connections);
if (curclass.limit == -1)
reply(0, "Maximum connections: unlimited");
else
- reply(0, "Maximum connections: %d", curclass.limit);
+ reply(0, "Maximum connections: " LLF,
+ (LLT)curclass.limit);
if (curclass.limitfile)
reply(0, "Connection limit exceeded message file: %s",
conffilename(curclass.limitfile));
@@ -2096,8 +2307,8 @@ statcmd(void)
reply(0, "PASV advertise address: %s", bp);
}
if (curclass.portmin && curclass.portmax)
- reply(0, "PASV port range: %d - %d",
- curclass.portmin, curclass.portmax);
+ reply(0, "PASV port range: " LLF " - " LLF,
+ (LLT)curclass.portmin, (LLT)curclass.portmax);
if (curclass.rateget)
reply(0, "Rate get limit: " LLF " bytes/sec",
(LLT)curclass.rateget);
@@ -2108,6 +2319,28 @@ statcmd(void)
(LLT)curclass.rateput);
else
reply(0, "Rate put limit: disabled");
+ if (curclass.mmapsize)
+ reply(0, "Mmap size: " LLF, (LLT)curclass.mmapsize);
+ else
+ reply(0, "Mmap size: disabled");
+ if (curclass.readsize)
+ reply(0, "Read size: " LLF, (LLT)curclass.readsize);
+ else
+ reply(0, "Read size: default");
+ if (curclass.writesize)
+ reply(0, "Write size: " LLF, (LLT)curclass.writesize);
+ else
+ reply(0, "Write size: default");
+ if (curclass.sendbufsize)
+ reply(0, "Send buffer size: " LLF,
+ (LLT)curclass.sendbufsize);
+ else
+ reply(0, "Send buffer size: default");
+ if (curclass.sendlowat)
+ reply(0, "Send low water mark: " LLF,
+ (LLT)curclass.sendlowat);
+ else
+ reply(0, "Send low water mark: default");
reply(0, "Umask: %.04o", curclass.umask);
for (cp = curclass.conversions; cp != NULL; cp=cp->next) {
if (cp->suffix == NULL || cp->types == NULL ||
@@ -2195,14 +2428,8 @@ dologout(int status)
* back to the main program loop.
*/
transflag = 0;
-
+ logout_utmp();
if (logged_in) {
-#ifdef NO_UTMP
- if (dowtmp)
- logwtmp(ttyline, "", "");
- if (doutmp)
- logout(utmp.ut_line);
-#endif /* NO_UTMP */
#ifdef KERBEROS
if (!notickets && krbtkfile_env)
unlink(krbtkfile_env);
@@ -2535,13 +2762,15 @@ extended_port(const char *arg)
}
/* some more sanity checks */
+ errno = 0;
p = NULL;
(void)strtoul(result[2], &p, 10);
- if (!*result[2] || *p)
+ if (errno || !*result[2] || *p)
goto parsefail;
+ errno = 0;
p = NULL;
proto = strtoul(result[0], &p, 10);
- if (!*result[0] || *p)
+ if (errno || !*result[0] || *p)
goto protounsupp;
memset(&hints, 0, sizeof(hints));
@@ -2830,12 +3059,12 @@ conffilename(const char *s)
* if elapsed != NULL, append "in xxx.yyy seconds"
* if error != NULL, append ": " + error
*
- * if doxferlog != 0, bytes != -1, and command is "get", "put",
+ * if doxferlog != 0, bytes != -1, and command is "get", "put",
* or "append", syslog a wu-ftpd style xferlog entry
*/
void
logxfer(const char *command, off_t bytes, const char *file1, const char *file2,
- const struct timeval *elapsed, const char *error)
+ const struct timeval *elapsed, const char *error)
{
char buf[MAXPATHLEN * 2 + 100], realfile[MAXPATHLEN];
const char *r1, *r2;
@@ -2922,6 +3151,31 @@ logxfer(const char *command, off_t bytes, const char *file1, const char *file2,
}
/*
+ * Log the resource usage.
+ *
+ * XXX: more resource usage to logging?
+ */
+void
+logrusage(const struct rusage *rusage_before,
+ const struct rusage *rusage_after)
+{
+ struct timeval usrtime, systime;
+
+ if (logging <= 1)
+ return;
+
+ timersub(&rusage_after->ru_utime, &rusage_before->ru_utime, &usrtime);
+ timersub(&rusage_after->ru_stime, &rusage_before->ru_stime, &systime);
+ syslog(LOG_INFO, "%ld.%.03du %ld.%.03ds %ld+%ldio %ldpf+%ldw",
+ usrtime.tv_sec, (int)(usrtime.tv_usec / 1000),
+ systime.tv_sec, (int)(systime.tv_usec / 1000),
+ rusage_after->ru_inblock - rusage_before->ru_inblock,
+ rusage_after->ru_oublock - rusage_before->ru_oublock,
+ rusage_after->ru_majflt - rusage_before->ru_majflt,
+ rusage_after->ru_nswap - rusage_before->ru_nswap);
+}
+
+/*
* Determine if `password' is valid for user given in `pw'.
* Returns 2 if password expired, 1 if otherwise failed, 0 if ok
*/
@@ -2930,24 +3184,13 @@ checkpassword(const struct passwd *pwent, const char *password)
{
char *orig, *new;
time_t expire;
-#if HAVE_GETSPNAM
- struct spwd *spw;
-#endif
expire = 0;
if (pwent == NULL)
return 1;
-#if HAVE_GETSPNAM
- if ((spw = getspnam(pwent->pw_name)) == NULL)
- return 1;
- orig = spw->sp_pwdp;
-#else
orig = pwent->pw_passwd; /* save existing password */
-#if HAVE_PW_EXPIRE
expire = pwent->pw_expire;
-#endif
-#endif /* HAVE_GETSPNAM */
if (orig[0] == '\0') /* don't allow empty passwords */
return 1;
diff --git a/contrib/lukemftpd/src/logutmp.c b/contrib/lukemftpd/src/logutmp.c
index 7ef6437..cdd05bc 100644
--- a/contrib/lukemftpd/src/logutmp.c
+++ b/contrib/lukemftpd/src/logutmp.c
@@ -32,7 +32,16 @@
* SUCH DAMAGE.
*/
-#include "lukemftpd.h"
+#include <sys/types.h>
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ttyent.h>
+#include <unistd.h>
+#include <utmp.h>
+#include <util.h>
typedef struct utmp UTMP;
@@ -60,7 +69,7 @@ login(const UTMP *ut)
}
if ((topslot < 0) || ((fd < 0)
&& (fd = open(_PATH_UTMP, O_RDWR|O_CREAT, 0644)) < 0))
- return;
+ return;
/*
* Now find a slot that's not in use...
diff --git a/contrib/lukemftpd/src/logwtmp.c b/contrib/lukemftpd/src/logwtmp.c
index b7f2925..5da4a1d 100644
--- a/contrib/lukemftpd/src/logwtmp.c
+++ b/contrib/lukemftpd/src/logwtmp.c
@@ -1,4 +1,4 @@
-/* $NetBSD: logwtmp.c,v 1.16 2001/02/04 22:04:12 christos Exp $ */
+/* $NetBSD: logwtmp.c,v 1.17 2002/09/12 08:55:31 itojun Exp $ */
/*
* Copyright (c) 1988, 1993
@@ -34,7 +34,34 @@
*
*/
-#include "lukemftpd.h"
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)logwtmp.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: logwtmp.c,v 1.17 2002/09/12 08:55:31 itojun Exp $");
+#endif
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#include <fcntl.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <utmp.h>
+#include <util.h>
+
+#ifdef KERBEROS5
+#include <krb5/krb5.h>
+#endif
#include "extern.h"
diff --git a/contrib/lukemftpd/src/pathnames.h b/contrib/lukemftpd/src/pathnames.h
index a5766b5..056122e 100644
--- a/contrib/lukemftpd/src/pathnames.h
+++ b/contrib/lukemftpd/src/pathnames.h
@@ -1,4 +1,4 @@
-/* $NetBSD: pathnames.h,v 1.10 2000/03/06 21:42:26 lukem Exp $ */
+/* $NetBSD: pathnames.h,v 1.9 2000/01/08 11:09:56 lukem Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -35,6 +35,8 @@
* @(#)pathnames.h 8.1 (Berkeley) 6/4/93
*/
+#include <paths.h>
+
#ifndef _DEFAULT_CONFDIR
#define _DEFAULT_CONFDIR "/etc"
#endif
@@ -42,7 +44,6 @@
#define _PATH_FTPCHROOT "ftpchroot"
#define _PATH_FTPDCONF "ftpd.conf"
#define _PATH_FTPLOGINMESG "motd"
-#undef _PATH_FTPUSERS
#define _PATH_FTPUSERS "ftpusers"
#define _PATH_FTPWELCOME "ftpwelcome"
diff --git a/contrib/lukemftpd/src/popen.c b/contrib/lukemftpd/src/popen.c
index 95123e7..aaaebca 100644
--- a/contrib/lukemftpd/src/popen.c
+++ b/contrib/lukemftpd/src/popen.c
@@ -1,4 +1,4 @@
-/* $NetBSD: popen.c,v 1.27 2001/12/01 10:25:30 lukem Exp $ */
+/* $NetBSD: popen.c,v 1.26 2001/04/25 01:46:26 lukem Exp $ */
/*-
* Copyright (c) 1999-2001 The NetBSD Foundation, Inc.
@@ -73,7 +73,33 @@
*
*/
-#include "lukemftpd.h"
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)popen.c 8.3 (Berkeley) 4/6/94";
+#else
+__RCSID("$NetBSD: popen.c,v 1.26 2001/04/25 01:46:26 lukem Exp $");
+#endif
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <glob.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stringlist.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#ifdef KERBEROS5
+#include <krb5/krb5.h>
+#endif
#include "extern.h"
@@ -146,11 +172,7 @@ ftpd_popen(char *argv[], const char *ptype, int stderrfd)
isls = (strcmp(sl->sl_str[0], INTERNAL_LS) == 0);
#endif
-#if HAVE_VFORK
pid = isls ? fork() : vfork();
-#else
- pid = fork();
-#endif
switch (pid) {
case -1: /* error */
(void)close(pdes[0]);
@@ -177,10 +199,7 @@ ftpd_popen(char *argv[], const char *ptype, int stderrfd)
}
#ifndef NO_INTERNAL_LS
if (isls) { /* use internal ls */
-#if HAVE_OPTRESET
- optreset = 1;
-#endif
- optind = optopt = 1;
+ optreset = optind = optopt = 1;
closelog();
exit(ls_main(sl->sl_cur - 1, sl->sl_str));
}
diff --git a/contrib/lukemftpd/src/version.h b/contrib/lukemftpd/src/version.h
index e741257..482a47a 100644
--- a/contrib/lukemftpd/src/version.h
+++ b/contrib/lukemftpd/src/version.h
@@ -1,6 +1,6 @@
-/* $NetBSD: version.h,v 1.42 2002/02/13 15:15:23 lukem Exp $ */
+/* $NetBSD: version.h,v 1.48 2002/10/26 04:19:56 lukem Exp $ */
/*-
- * Copyright (c) 1999-2001 The NetBSD Foundation, Inc.
+ * Copyright (c) 1999-2002 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 20020214"
+#define FTPD_VERSION "NetBSD-ftpd 20021130"
#endif
OpenPOWER on IntegriCloud