summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlukem <lukem@pkgsrc.org>2007-08-06 04:33:23 +0000
committerlukem <lukem@pkgsrc.org>2007-08-06 04:33:23 +0000
commit860d827917e42a54d7e7d3bddd60ffbb2743fd2a (patch)
tree14e64cdb818e9749874609154e29b37a0132c869
parent2010d3d3ecad660f61ea015ed0f001fc179cd8b5 (diff)
downloadpkgsrc-860d827917e42a54d7e7d3bddd60ffbb2743fd2a.tar.gz
Update to tnftp 20070806.
Notable changes: - Implement '-s srcaddr' to set the local IP address for all connections. - Support '-q quittime' when waiting for server replies. - Use IEC 60027-2 "KiB", "MiB" (etc) instead of "KB", "MB", ... - Portability fixes, including for FreeBSD, Mac OS X, and Solaris.
-rw-r--r--net/tnftp/files/configure.ac372
-rw-r--r--net/tnftp/files/src/cmds.c294
-rw-r--r--net/tnftp/files/src/cmdtab.c19
-rw-r--r--net/tnftp/files/src/complete.c51
-rw-r--r--net/tnftp/files/src/domacro.c23
-rw-r--r--net/tnftp/files/src/fetch.c385
-rw-r--r--net/tnftp/files/src/ftp.1219
-rw-r--r--net/tnftp/files/src/ftp.c614
-rw-r--r--net/tnftp/files/src/ftp.cat1248
-rw-r--r--net/tnftp/files/src/ftp_var.h40
-rw-r--r--net/tnftp/files/src/main.c136
-rw-r--r--net/tnftp/files/src/progressbar.c80
-rw-r--r--net/tnftp/files/src/progressbar.h8
-rw-r--r--net/tnftp/files/src/ruserpass.c94
-rw-r--r--net/tnftp/files/src/util.c277
15 files changed, 1886 insertions, 974 deletions
diff --git a/net/tnftp/files/configure.ac b/net/tnftp/files/configure.ac
new file mode 100644
index 00000000000..f9866530e07
--- /dev/null
+++ b/net/tnftp/files/configure.ac
@@ -0,0 +1,372 @@
+# $NetBSD: configure.ac,v 1.1.1.1 2007/08/06 04:42:53 lukem Exp $
+#
+# Process this file with autoconf to produce a configure script.
+
+AC_INIT([tnftp], [20070806], [lukem@NetBSD.org])
+AC_PREREQ([2.61])
+AC_REVISION([$Revision: 1.1.1.1 $])
+
+AS_SHELL_SANITIZE
+
+AC_CONFIG_SRCDIR([tnftp.h])
+AC_CONFIG_AUX_DIR(build-aux)
+AC_CONFIG_HEADERS([config.h])
+
+#
+# Arguments for which features are included.
+#
+AC_CANONICAL_TARGET
+AC_ARG_PROGRAM
+AC_ARG_ENABLE([editcomplete],
+ [AS_HELP_STRING([--enable-editcomplete],
+ [turn on command line editing and completion.
+ (default: enabled)])],
+ [opt_editcomplete=$enableval],
+ [opt_editcomplete=yes])
+AC_ARG_ENABLE([ipv6],
+ [AS_HELP_STRING([--enable-ipv6],
+ [enable IPv6 support (if your OS supports it).
+ (default: enabled)])],
+ [opt_ipv6=$enableval],
+ [opt_ipv6=yes])
+AC_ARG_WITH([socks],
+ [AS_HELP_STRING([--with-socks],
+ [enable support for (Dante) SOCKS5 proxy])],
+ [],
+ [with_socks=check])
+
+#
+# Autoheader templates symbols.
+#
+AH_TEMPLATE([HAVE_POLL],
+ [Define if we have poll() and it is not emulated.])
+AH_TEMPLATE([HAVE_PRINTF_QD],
+ [Define if *printf() uses %qd to print `long long'
+ (otherwise uses %lld).])
+AH_TEMPLATE([HAVE_PRINTF_LONG_LONG],
+ [Define if `long long' is supported and
+ *printf() supports %lld or %qd to print them.])
+AH_TEMPLATE([USE_SOCKS],
+ [Define if using (Dante) SOCKS5 proxy.])
+
+#
+# Checks for programs.
+#
+AC_PROG_MAKE_SET
+AC_PROG_CC
+AC_PROG_AWK
+AC_PROG_INSTALL
+AC_CHECK_TOOL([AR], [ar], [:])
+AC_CHECK_TOOL([RANLIB], [ranlib], [:])
+
+#
+# Checks for tool features.
+#
+AS_CASE([$target_os],
+ [darwin*],
+ [# Mac OS X linker needs -search_paths_first so our private libraries
+ # are used before system libraries.
+ #
+ old_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+ AC_MSG_CHECKING([if ld accepts -search_paths_first])
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([], [[int i;]])],
+ [AC_MSG_RESULT([yes])],
+ [AC_MSG_RESULT([no])
+ LDFLAGS=$old_LDFLAGS])],
+ )
+
+#
+# Checks for libraries.
+#
+AS_IF([test "$opt_editcomplete" = yes],
+ [AC_SEARCH_LIBS([tgetent],
+ [termcap termlib curses ncurses tinfo],
+ [],
+ [AC_MSG_ERROR(
+ [no relevant library found containing tgetent])])
+ AC_SEARCH_LIBS([el_init],
+ [edit],
+ [have_libedit=yes], [have_libedit=no])])
+
+AC_SEARCH_LIBS([gethostbyname], [nsl])
+AC_SEARCH_LIBS([socket],
+ [socket],
+ [],
+ [AC_CHECK_LIB([socket],
+ [socket],
+ [LIBS="-lsocket -lnsl $LIBS"],
+ [],
+ [-lnsl])])
+
+# Check for (Dante) SOCKS5.
+#
+AS_IF([test "$with_socks" != no],
+ [AC_SEARCH_LIBS([SOCKSinit],
+ [socksd socks],
+ [AC_DEFINE([USE_SOCKS], [1])
+ AS_IF([test "$opt_ipv6" = yes],
+ [AC_MSG_WARN(
+ [IPv6 is incompatible with socks, disabling IPv6 support])
+ opt_ipv6=no])],
+ [AS_IF([test "$with_socks" != check],
+ [AC_MSG_FAILURE(
+ [--with-socks was given, but SOCKSinit() wasn't found])])])])
+
+#
+# Checks for header files.
+#
+accheck_includes='
+#include <stdio.h>
+#if defined(HAVE_SYS_TYPES_H)
+# include <sys/types.h>
+#endif
+#if defined(HAVE_SYS_STAT_H)
+# include <sys/stat.h>
+#endif
+#if defined(STDC_HEADERS)
+# include <stdarg.h>
+# include <stdlib.h>
+# include <string.h>
+#endif
+#if defined(HAVE_LIBGEN_H)
+# include <libgen.h>
+#endif
+#if defined(HAVE_PWD_H)
+# include <pwd.h>
+#endif
+#if defined(HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
+#if defined(HAVE_POLL_H)
+# include <poll.h>
+#elif defined(HAVE_SYS_POLL_H)
+# include <sys/poll.h>
+#endif
+#if defined(HAVE_SYS_SOCKET_H)
+# include <sys/socket.h>
+#endif
+#if defined(HAVE_NETINET_IN_H)
+# include <netinet/in.h>
+#endif
+#if defined(HAVE_NETINET_IN_SYSTM_H)
+# include <netinet/in_systm.h>
+#endif
+#if defined(HAVE_NETDB_H)
+# include <netdb.h>
+#endif
+#if defined(HAVE_ARPA_INET_H)
+# include <arpa/inet.h>
+#endif
+#if defined(HAVE_DIRENT_H)
+# include <dirent.h>
+#else
+# define dirent direct
+# if defined(HAVE_SYS_NDIR_H)
+# include <sys/ndir.h>
+# endif
+# if defined(HAVE_SYS_DIR_H)
+# include <sys/dir.h>
+# endif
+# if defined(HAVE_NDIR_H)
+# include <ndir.h>
+# endif
+#endif
+' # accheck_includes
+
+AC_CHECK_HEADERS([sys/types.h sys/ioctl.h sys/param.h sys/stat.h \
+ sys/socket.h sys/syslimits.h sys/time.h sys/wait.h],
+ [], [], [$accheck_includes])
+AC_HEADER_DIRENT
+AC_HEADER_RESOLV
+AC_HEADER_STAT
+AC_HEADER_STDC
+AC_HEADER_TIME
+AC_HEADER_TIOCGWINSZ
+AC_CHECK_HEADERS([arpa/ftp.h arpa/inet.h arpa/nameser.h err.h \
+ fcntl.h libgen.h limits.h malloc.h \
+ netinet/in.h netinet/in_systm.h netinet/ip.h \
+ paths.h poll.h pwd.h sys/poll.h regex.h \
+ setjmp.h signal.h stddef.h termcap.h termios.h \
+ unistd.h utime.h vis.h],
+ [], [], [$accheck_includes])
+
+#
+# Checks for typedefs, structures, and compiler characteristics.
+#
+AC_CHECK_DECLS([AI_NUMERICHOST, dirname, fclose, getpass, h_errno, pclose,
+ optarg, optind],
+ [], [], [$accheck_includes])
+AC_TYPE_LONG_DOUBLE
+AC_TYPE_LONG_LONG_INT
+AC_TYPE_UINT32_T
+AC_TYPE_OFF_T
+AC_TYPE_PID_T
+AC_TYPE_SIGNAL
+AC_TYPE_SIZE_T
+AC_STRUCT_TM
+AC_CHECK_MEMBERS([struct sockaddr.sa_len, struct sockaddr_in.sin_len,
+ struct dirent.d_namlen],
+ [], [], [$accheck_includes])
+AC_CHECK_TYPES([in_port_t, sa_family_t, socklen_t, struct addrinfo],
+ [], [], [$accheck_includes])
+AC_SYS_LARGEFILE
+
+# If IPv6 is enabled, check for necessary items.
+#
+AS_IF([test "$opt_ipv6" = yes],
+ [AC_CHECK_DECLS([AF_INET6, NS_IN6ADDRSZ], [], [],
+[$accheck_includes
+#if defined(HAVE_ARPA_NAMESER_H)
+#include <arpa/nameser.h>
+#endif
+])
+ AC_CHECK_TYPES([struct sockaddr_in6], [], [], [$accheck_includes])])
+
+#
+# Checks for library functions.
+#
+#XXX remove alloca use
+AC_FUNC_ALLOCA
+AC_FUNC_CLOSEDIR_VOID
+AC_FUNC_FORK
+AC_FUNC_FSEEKO
+AC_FUNC_STRCOLL
+AC_REPLACE_FUNCS([dirname err fgetln getaddrinfo getnameinfo \
+ inet_ntop inet_pton mkstemp setprogname sl_init snprintf \
+ strdup strerror strlcat strlcpy strptime strsep strunvis \
+ strvis timegm usleep utimes])
+AC_CHECK_FUNCS([getcwd gethostbyaddr gethostbyname gethostbyname2 gethostname \
+ getpass getpassphrase getpgrp gettimeofday isascii \
+ memchr memmove memset realpath regcomp \
+ select setlocale socket strcasecmp strchr strcspn strdup \
+ strerror strncasecmp strpbrk strrchr strstr strtol strtoul \
+ utime])
+AS_IF([test "$ac_cv_func_getpgrp" = yes], [AC_FUNC_GETPGRP])
+AS_IF([test "$ac_cv_func_strptime" = yes], [AC_CHECK_DECLS([strptime])])
+
+# Always replace glob(); the vendor's may not be secure.
+#
+AC_LIBOBJ([glob])
+
+# We assume that if sprintf() supports %lld or %qd,
+# then all of *printf() does. If not, disable long long
+# support because we don't know how to display it.
+#
+AS_IF([test "$ac_cv_type_long_long_int" = yes],
+ [AC_MSG_CHECKING([*printf() support for %lld])
+ can_printf_longlong=no
+ AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#include <stdio.h>
+int main() {
+ char buf[100];
+ sprintf(buf, "%lld", 4294967300LL);
+ return (strcmp(buf, "4294967300"));
+}
+]])],
+ [AC_MSG_RESULT([yes])
+ can_printf_longlong=yes],
+ [AC_MSG_RESULT([no])],
+ [AC_MSG_RESULT([unknown - cross-compiling])])
+ AS_IF([test "$can_printf_longlong" != yes],
+ [AC_MSG_CHECKING([*printf() support for %qd])
+ AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#include <stdio.h>
+int main() {
+ char buf[100];
+ sprintf(buf, "%qd", 4294967300LL);
+ return (strcmp(buf, "4294967300"));
+}
+]])],
+ [AC_MSG_RESULT([yes])
+ can_printf_longlong=yes
+ AC_DEFINE([HAVE_PRINTF_QD], [1])],
+ [AC_MSG_RESULT([no])],
+ [AC_MSG_RESULT([unknown - cross-compiling])])])
+ AC_MSG_CHECKING([if *printf() can print long long ints])
+ AS_IF([test "$can_printf_longlong" = yes],
+ [AC_MSG_RESULT([yes])
+ AC_DEFINE([HAVE_PRINTF_LONG_LONG], [1])
+ AC_REPLACE_FUNCS([strtoll])],
+ [AC_MSG_RESULT([no])])])
+
+# Handle Darwin 7 having a poll() compatibility function,
+# and don't use it if it's emulated.
+# Be conservative, if we don't find one of poll.h or sys/poll.h,
+# don't attempt to use poll().
+#
+AC_CHECK_TYPES([struct pollfd], [], [], [$accheck_includes])
+AC_CHECK_FUNC([poll],
+ [AC_CHECK_DECL([_POLL_EMUL_H_],
+ [],
+ [AC_DEFINE([HAVE_POLL], [1])],
+ [$accheck_includes])])
+
+# Assume libedit is not up-to-date and force own version.
+#
+have_libedit=no
+AS_IF([test "$opt_editcomplete" = yes],
+ [AC_MSG_CHECKING([for up-to-date libedit])
+ AS_IF([test "$have_libedit" = no],
+ [AC_MSG_RESULT([no - using my own])
+ INCLUDES="-I\${srcdir}/../libedit $INCLUDES"
+ LDFLAGS="-L../libedit $LDFLAGS"
+ LIBS="-ledit $LIBS"
+ LIBEDIT=libedit.a
+ LIBDEPENDS="$LIBDEPENDS ../libedit/libedit.a"],
+ [AC_MSG_RESULT([yes])])],
+ [CFLAGS="-DNO_EDITCOMPLETE $CFLAGS"])
+
+# Replace sl_init() (et al) if it provides the older API.
+#
+AS_IF([test "$ac_cv_func_sl_init" = yes],
+ [AC_MSG_CHECKING([if sl_add() returns int])
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stringlist.h>]],
+ [[int f = sl_add((StringList *)0,
+ "foo");]])],
+ [AC_MSG_RESULT([yes])],
+ [AC_MSG_RESULT([no - using local version])
+ AC_LIBOBJ([sl_init])],
+ [AC_MSG_RESULT([unknown - cross-compiling])])])
+
+# Replace getaddrinfo() if missing or AI_NUMERICHOST isn't declared.
+#
+AC_MSG_CHECKING([for working getaddrinfo()])
+AS_IF([test "$ac_cv_have_decl_AI_NUMERICHOST" = yes],
+ [AC_MSG_RESULT([yes])],
+ [AS_IF([test "$ac_cv_func_getaddrinfo" = yes],
+ [AC_LIBOBJ([getaddrinfo])
+ AC_MSG_RESULT([no - using local version])],
+ [AC_MSG_RESULT([using local version])])])
+
+# Check for VIS_WHITE in <vis.h>
+#
+AS_IF([test "$ac_cv_header_vis_h" = yes],
+ [AC_CHECK_DECL([VIS_WHITE], [], [], [
+#include <vis.h>
+])])
+
+# Build libnetbsd if necessary.
+#
+AS_IF([test -n "$LIBOBJS"],
+ [INCLUDES="$INCLUDES -I\${srcdir}/../libnetbsd"
+ LDFLAGS="$LDFLAGS -L../libnetbsd"
+ LIBS="$LIBS -lnetbsd"
+ LIBNETBSD=libnetbsd.a
+ LIBDEPENDS="$LIBDEPENDS ../libnetbsd/libnetbsd.a"])
+
+#
+# Create the Makefiles.
+#
+AC_SUBST(INCLUDES)
+AC_SUBST(LIBEDIT)
+AC_SUBST(LIBNETBSD)
+AC_SUBST(LIBDEPENDS)
+
+AC_CONFIG_FILES([Makefile
+ libedit/Makefile
+ libedit/makelist
+ libnetbsd/Makefile
+ src/Makefile])
+
+AC_OUTPUT
diff --git a/net/tnftp/files/src/cmds.c b/net/tnftp/files/src/cmds.c
index d9a99d28149..b5ad5e069f5 100644
--- a/net/tnftp/files/src/cmds.c
+++ b/net/tnftp/files/src/cmds.c
@@ -1,8 +1,8 @@
-/* NetBSD: cmds.c,v 1.9 2005/06/10 04:05:01 lukem Exp */
-/* from NetBSD: cmds.c,v 1.115 2005/06/10 00:18:46 lukem Exp */
+/* $NetBSD: cmds.c,v 1.1.1.5 2007/08/06 04:33:23 lukem Exp $ */
+/* from NetBSD: cmds.c,v 1.123 2007/05/24 05:05:18 lukem Exp */
/*-
- * Copyright (c) 1996-2005 The NetBSD Foundation, Inc.
+ * Copyright (c) 1996-2007 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -99,16 +99,46 @@
* SUCH DAMAGE.
*/
+#include "tnftp.h"
+
+#if 0 /* tnftp */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)cmds.c 8.6 (Berkeley) 10/9/94";
+#else
+__RCSID(" NetBSD: cmds.c,v 1.123 2007/05/24 05:05:18 lukem Exp ");
+#endif
+#endif /* not lint */
+
/*
* FTP User Program -- Command Routines.
*/
-
-#include "tnftp.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <arpa/ftp.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <glob.h>
+#include <limits.h>
+#include <netdb.h>
+#include <paths.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#endif /* tnftp */
#include "ftp_var.h"
#include "version.h"
-struct types {
+static struct types {
char *t_name;
char *t_mode;
int t_type;
@@ -122,30 +152,43 @@ struct types {
{ NULL }
};
-sigjmp_buf jabort;
-const char *mname;
+static sigjmp_buf jabort;
static int confirm(const char *, const char *);
+static void mintr(int);
+static void mabort(const char *);
static const char *doprocess(char *, size_t, const char *, int, int, int);
static const char *domap(char *, size_t, const char *);
static const char *docase(char *, size_t, const char *);
static const char *dotrans(char *, size_t, const char *);
+/*
+ * Confirm if "cmd" is to be performed upon "file".
+ * If "file" is NULL, generate a "Continue with" prompt instead.
+ */
static int
confirm(const char *cmd, const char *file)
{
const char *errormsg;
char line[BUFSIZ];
+ const char *promptleft, *promptright;
if (!interactive || confirmrest)
return (1);
+ if (file == NULL) {
+ promptleft = "Continue with";
+ promptright = cmd;
+ } else {
+ promptleft = cmd;
+ promptright = file;
+ }
while (1) {
- fprintf(ttyout, "%s %s [anpqy?]? ", cmd, file);
+ fprintf(ttyout, "%s %s [anpqy?]? ", promptleft, promptright);
(void)fflush(ttyout);
if (getline(stdin, line, sizeof(line), &errormsg) < 0) {
mflag = 0;
- fprintf(ttyout, "%s; %s aborted\n", errormsg, mname);
+ fprintf(ttyout, "%s; %s aborted\n", errormsg, cmd);
return (0);
}
switch (tolower((unsigned char)*line)) {
@@ -160,7 +203,7 @@ confirm(const char *cmd, const char *file)
break;
case 'q':
mflag = 0;
- fprintf(ttyout, "%s aborted.\n", mname);
+ fprintf(ttyout, "%s aborted.\n", cmd);
/* FALLTHROUGH */
case 'n':
return (0);
@@ -193,7 +236,7 @@ settype(int argc, char *argv[])
if (argc == 0 || argc > 2) {
char *sep;
- fprintf(ttyout, "usage: %s [", argv[0]);
+ UPRINTF("usage: %s [", argv[0]);
sep = " ";
for (p = types; p->t_name; p++) {
fprintf(ttyout, "%s%s", sep, p->t_name);
@@ -241,14 +284,13 @@ changetype(int newtype, int show)
newtype = TYPE_I;
if (newtype == curtype)
return;
- if (debug == 0 && show == 0)
+ if (ftp_debug == 0 && show == 0)
verbose = 0;
for (p = types; p->t_name; p++)
if (newtype == p->t_type)
break;
if (p->t_name == 0) {
- warnx("internal error: unknown type %d.", newtype);
- return;
+ errx(1, "changetype: unknown type %d", newtype);
}
if (newtype == TYPE_L && bytename[0] != '\0')
comret = command("TYPE %s %s", p->t_mode, bytename);
@@ -274,7 +316,7 @@ setbinary(int argc, char *argv[])
{
if (argc == 0) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
+ UPRINTF("usage: %s\n", argv[0]);
code = -1;
return;
}
@@ -291,7 +333,7 @@ setascii(int argc, char *argv[])
{
if (argc == 0) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
+ UPRINTF("usage: %s\n", argv[0]);
code = -1;
return;
}
@@ -308,7 +350,7 @@ settenex(int argc, char *argv[])
{
if (argc == 0) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
+ UPRINTF("usage: %s\n", argv[0]);
code = -1;
return;
}
@@ -325,7 +367,7 @@ setftmode(int argc, char *argv[])
{
if (argc != 2) {
- fprintf(ttyout, "usage: %s mode-name\n", argv[0]);
+ UPRINTF("usage: %s mode-name\n", argv[0]);
code = -1;
return;
}
@@ -342,7 +384,7 @@ setform(int argc, char *argv[])
{
if (argc != 2) {
- fprintf(ttyout, "usage: %s format\n", argv[0]);
+ UPRINTF("usage: %s format\n", argv[0]);
code = -1;
return;
}
@@ -359,7 +401,7 @@ setstruct(int argc, char *argv[])
{
if (argc != 2) {
- fprintf(ttyout, "usage: %s struct-mode\n", argv[0]);
+ UPRINTF("usage: %s struct-mode\n", argv[0]);
code = -1;
return;
}
@@ -388,8 +430,7 @@ put(int argc, char *argv[])
goto usage;
if ((argc < 3 && !another(&argc, &argv, "remote-file")) || argc > 3) {
usage:
- fprintf(ttyout, "usage: %s local-file [remote-file]\n",
- argv[0]);
+ UPRINTF("usage: %s local-file [remote-file]\n", argv[0]);
code = -1;
return;
}
@@ -433,15 +474,14 @@ mput(int argc, char *argv[])
const char *tp;
if (argc == 0 || (argc == 1 && !another(&argc, &argv, "local-files"))) {
- fprintf(ttyout, "usage: %s local-files\n", argv[0]);
+ UPRINTF("usage: %s local-files\n", argv[0]);
code = -1;
return;
}
- mname = argv[0];
mflag = 1;
oldintr = xsignal(SIGINT, mintr);
if (sigsetjmp(jabort, 1))
- mabort();
+ mabort(argv[0]);
if (proxy) {
char *cp;
@@ -459,7 +499,7 @@ mput(int argc, char *argv[])
if (!mflag && fromatty) {
ointer = interactive;
interactive = 1;
- if (confirm("Continue with", "mput")) {
+ if (confirm(argv[0], NULL)) {
mflag++;
}
interactive = ointer;
@@ -483,7 +523,7 @@ mput(int argc, char *argv[])
if (!mflag && fromatty) {
ointer = interactive;
interactive = 1;
- if (confirm("Continue with", "mput")) {
+ if (confirm(argv[0], NULL)) {
mflag++;
}
interactive = ointer;
@@ -495,7 +535,7 @@ mput(int argc, char *argv[])
memset(&gl, 0, sizeof(gl));
flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_TILDE;
if (glob(argv[i], flags, NULL, &gl) || gl.gl_pathc == 0) {
- warnx("%s: not found", argv[i]);
+ warnx("Glob pattern `%s' not found", argv[i]);
globfree(&gl);
continue;
}
@@ -511,7 +551,7 @@ mput(int argc, char *argv[])
if (!mflag && fromatty) {
ointer = interactive;
interactive = 1;
- if (confirm("Continue with", "mput")) {
+ if (confirm(argv[0], NULL)) {
mflag++;
}
interactive = ointer;
@@ -562,8 +602,7 @@ getit(int argc, char *argv[], int restartit, const char *mode)
goto usage;
if ((argc < 3 && !another(&argc, &argv, "local-file")) || argc > 3) {
usage:
- fprintf(ttyout, "usage: %s remote-file [local-file]\n",
- argv[0]);
+ UPRINTF("usage: %s remote-file [local-file]\n", argv[0]);
code = -1;
return (0);
}
@@ -586,7 +625,7 @@ getit(int argc, char *argv[], int restartit, const char *mode)
ret = stat(locfile, &stbuf);
if (restartit == 1) {
if (ret < 0) {
- warn("local: %s", locfile);
+ warn("Can't stat `%s'", locfile);
goto freegetit;
}
restart_point = stbuf.st_size;
@@ -614,7 +653,7 @@ getit(int argc, char *argv[], int restartit, const char *mode)
}
/* ARGSUSED */
-void
+static void
mintr(int signo)
{
@@ -624,8 +663,8 @@ mintr(int signo)
siglongjmp(jabort, 1);
}
-void
-mabort(void)
+static void
+mabort(const char *cmd)
{
int ointer, oconf;
@@ -634,7 +673,7 @@ mabort(void)
oconf = confirmrest;
interactive = 1;
confirmrest = 0;
- if (confirm("Continue with", mname)) {
+ if (confirm(cmd, NULL)) {
interactive = ointer;
confirmrest = oconf;
return;
@@ -659,11 +698,10 @@ mget(int argc, char *argv[])
if (argc == 0 ||
(argc == 1 && !another(&argc, &argv, "remote-files"))) {
- fprintf(ttyout, "usage: %s remote-files\n", argv[0]);
+ UPRINTF("usage: %s remote-files\n", argv[0]);
code = -1;
return;
}
- mname = argv[0];
mflag = 1;
restart_point = 0;
restartit = 0;
@@ -677,7 +715,7 @@ mget(int argc, char *argv[])
}
oldintr = xsignal(SIGINT, mintr);
if (sigsetjmp(jabort, 1))
- mabort();
+ mabort(argv[0]);
while ((cp = remglob(argv, proxy, NULL)) != NULL) {
char buf[MAXPATHLEN];
if (*cp == '\0' || !connected) {
@@ -700,7 +738,7 @@ mget(int argc, char *argv[])
if (stat(tp, &stbuf) == 0)
restart_point = stbuf.st_size;
else
- warn("stat %s", tp);
+ warn("Can't stat `%s'", tp);
}
recvrequest("RETR", tp, cp, restart_point ? "r+" : "w",
tp != cp || !interactive, 1);
@@ -708,7 +746,7 @@ mget(int argc, char *argv[])
if (!mflag && fromatty) {
ointer = interactive;
interactive = 1;
- if (confirm("Continue with", "mget"))
+ if (confirm(argv[0], NULL))
mflag++;
interactive = ointer;
}
@@ -723,18 +761,19 @@ mget(int argc, char *argv[])
void
fget(int argc, char *argv[])
{
- char *buf, *mode;
+ char *mode;
FILE *fp;
+ char buf[MAXPATHLEN];
if (argc != 2) {
- fprintf(ttyout, "usage: %s localfile\n", argv[0]);
+ UPRINTF("usage: %s localfile\n", argv[0]);
code = -1;
return;
}
fp = fopen(argv[1], "r");
if (fp == NULL) {
- fprintf(ttyout, "Cannot open source file %s\n", argv[1]);
+ fprintf(ttyout, "Can't open source file %s\n", argv[1]);
code = -1;
return;
}
@@ -742,9 +781,7 @@ fget(int argc, char *argv[])
argv[0] = "get";
mode = restart_point ? "r+" : "w";
- for (;
- (buf = fparseln(fp, NULL, NULL, "\0\0\0", 0)) != NULL;
- free(buf)) {
+ while (getline(fp, buf, sizeof(buf), NULL) >= 0) {
if (buf[0] == '\0')
continue;
argv[1] = buf;
@@ -769,7 +806,7 @@ status(int argc, char *argv[])
{
if (argc == 0) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
+ UPRINTF("usage: %s\n", argv[0]);
code = -1;
return;
}
@@ -863,7 +900,7 @@ togglevar(int argc, char *argv[], int *var, const char *mesg)
} else if (argc == 2 && strcasecmp(argv[1], "off") == 0) {
*var = 0;
} else {
- fprintf(ttyout, "usage: %s [ on | off ]\n", argv[0]);
+ UPRINTF("usage: %s [ on | off ]\n", argv[0]);
return (-1);
}
if (mesg)
@@ -892,7 +929,7 @@ setedit(int argc, char *argv[])
#ifdef NO_EDITCOMPLETE
if (argc == 0) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
+ UPRINTF("usage: %s\n", argv[0]);
code = -1;
return;
}
@@ -926,7 +963,7 @@ sethash(int argc, char *argv[])
if (argc == 1)
hash = !hash;
else if (argc != 2) {
- fprintf(ttyout, "usage: %s [ on | off | bytecount ]\n",
+ UPRINTF("usage: %s [ on | off | bytecount ]\n",
argv[0]);
code = -1;
return;
@@ -1012,7 +1049,7 @@ setgate(int argc, char *argv[])
static char gsbuf[MAXHOSTNAMELEN];
if (argc == 0 || argc > 3) {
- fprintf(ttyout,
+ UPRINTF(
"usage: %s [ on | off | gateserver [port] ]\n", argv[0]);
code = -1;
return;
@@ -1025,7 +1062,7 @@ setgate(int argc, char *argv[])
gatemode = 0;
else {
if (argc == 3)
- gateport = xstrdup(argv[2]);
+ gateport = ftp_strdup(argv[2]);
(void)strlcpy(gsbuf, argv[1], sizeof(gsbuf));
gateserver = gsbuf;
gatemode = 1;
@@ -1073,15 +1110,14 @@ void
setdebug(int argc, char *argv[])
{
if (argc == 0 || argc > 2) {
- fprintf(ttyout, "usage: %s [ on | off | debuglevel ]\n",
- argv[0]);
+ UPRINTF("usage: %s [ on | off | debuglevel ]\n", argv[0]);
code = -1;
return;
} else if (argc == 2) {
if (strcasecmp(argv[1], "on") == 0)
- debug = 1;
+ ftp_debug = 1;
else if (strcasecmp(argv[1], "off") == 0)
- debug = 0;
+ ftp_debug = 0;
else {
int val;
@@ -1092,16 +1128,16 @@ setdebug(int argc, char *argv[])
code = -1;
return;
}
- debug = val;
+ ftp_debug = val;
}
} else
- debug = !debug;
- if (debug)
+ ftp_debug = !ftp_debug;
+ if (ftp_debug)
options |= SO_DEBUG;
else
options &= ~SO_DEBUG;
- fprintf(ttyout, "Debugging %s (debug=%d).\n", onoff(debug), debug);
- code = debug > 0;
+ fprintf(ttyout, "Debugging %s (ftp_debug=%d).\n", onoff(ftp_debug), ftp_debug);
+ code = ftp_debug > 0;
}
/*
@@ -1114,7 +1150,7 @@ cd(int argc, char *argv[])
if (argc == 0 || argc > 2 ||
(argc == 1 && !another(&argc, &argv, "remote-directory"))) {
- fprintf(ttyout, "usage: %s remote-directory\n", argv[0]);
+ UPRINTF("usage: %s remote-directory\n", argv[0]);
code = -1;
return;
}
@@ -1145,13 +1181,13 @@ lcd(int argc, char *argv[])
argv[1] = localhome;
}
if (argc != 2) {
- fprintf(ttyout, "usage: %s [local-directory]\n", argv[0]);
+ UPRINTF("usage: %s [local-directory]\n", argv[0]);
return;
}
if ((locdir = globulize(argv[1])) == NULL)
return;
if (chdir(locdir) == -1)
- warn("lcd %s", locdir);
+ warn("Can't chdir `%s'", locdir);
else {
updatelocalcwd();
if (localcwd[0]) {
@@ -1173,7 +1209,7 @@ delete(int argc, char *argv[])
if (argc == 0 || argc > 2 ||
(argc == 1 && !another(&argc, &argv, "remote-file"))) {
- fprintf(ttyout, "usage: %s remote-file\n", argv[0]);
+ UPRINTF("usage: %s remote-file\n", argv[0]);
code = -1;
return;
}
@@ -1193,15 +1229,14 @@ mdelete(int argc, char *argv[])
if (argc == 0 ||
(argc == 1 && !another(&argc, &argv, "remote-files"))) {
- fprintf(ttyout, "usage: %s [remote-files]\n", argv[0]);
+ UPRINTF("usage: %s [remote-files]\n", argv[0]);
code = -1;
return;
}
- mname = argv[0];
mflag = 1;
oldintr = xsignal(SIGINT, mintr);
if (sigsetjmp(jabort, 1))
- mabort();
+ mabort(argv[0]);
while ((cp = remglob(argv, 0, NULL)) != NULL) {
if (*cp == '\0') {
mflag = 0;
@@ -1213,7 +1248,7 @@ mdelete(int argc, char *argv[])
if (!mflag && fromatty) {
ointer = interactive;
interactive = 1;
- if (confirm("Continue with", "mdelete")) {
+ if (confirm(argv[0], NULL)) {
mflag++;
}
interactive = ointer;
@@ -1235,7 +1270,7 @@ renamefile(int argc, char *argv[])
goto usage;
if ((argc < 3 && !another(&argc, &argv, "to-name")) || argc > 3) {
usage:
- fprintf(ttyout, "usage: %s from-name to-name\n", argv[0]);
+ UPRINTF("usage: %s from-name to-name\n", argv[0]);
code = -1;
return;
}
@@ -1296,11 +1331,9 @@ ls(int argc, char *argv[])
if (argc > 3 || ((pagecmd | mlsdcmd) && argc > 2)) {
usage:
if (pagecmd || mlsdcmd)
- fprintf(ttyout,
- "usage: %s [remote-path]\n", argv[0]);
+ UPRINTF("usage: %s [remote-path]\n", argv[0]);
else
- fprintf(ttyout,
- "usage: %s [remote-path [local-file]]\n",
+ UPRINTF("usage: %s [remote-path [local-file]]\n",
argv[0]);
code = -1;
goto freels;
@@ -1314,12 +1347,11 @@ ls(int argc, char *argv[])
if (EMPTYSTRING(p))
p = DEFAULTPAGER;
len = strlen(p) + 2;
- locfile = xmalloc(len);
+ locfile = ftp_malloc(len);
locfile[0] = '|';
(void)strlcpy(locfile + 1, p, len - 1);
freelocfile = 1;
} else if ((strcmp(locfile, "-") != 0) && *locfile != '|') {
- mname = argv[0];
if ((locfile = globulize(locfile)) == NULL ||
!confirm("output to local-file:", locfile)) {
code = -1;
@@ -1350,13 +1382,12 @@ mls(int argc, char *argv[])
goto usage;
if (argc < 3 && !another(&argc, &argv, "local-file")) {
usage:
- fprintf(ttyout, "usage: %s remote-files local-file\n", argv[0]);
+ UPRINTF("usage: %s remote-files local-file\n", argv[0]);
code = -1;
return;
}
odest = dest = argv[argc - 1];
argv[argc - 1] = NULL;
- mname = argv[0];
if (strcmp(dest, "-") && *dest != '|')
if (((dest = globulize(dest)) == NULL) ||
!confirm("output to local-file:", dest)) {
@@ -1367,7 +1398,7 @@ mls(int argc, char *argv[])
mflag = 1;
oldintr = xsignal(SIGINT, mintr);
if (sigsetjmp(jabort, 1))
- mabort();
+ mabort(argv[0]);
for (i = 1; mflag && i < argc-1 && connected; i++) {
mode = (i == 1) ? "w" : "a";
recvrequest(dolist ? "LIST" : "NLST", dest, argv[i], mode,
@@ -1375,7 +1406,7 @@ mls(int argc, char *argv[])
if (!mflag && fromatty) {
ointer = interactive;
interactive = 1;
- if (confirm("Continue with", argv[0])) {
+ if (confirm(argv[0], NULL)) {
mflag++;
}
interactive = ointer;
@@ -1400,7 +1431,7 @@ shell(int argc, char *argv[])
int wait_status;
if (argc == 0) {
- fprintf(ttyout, "usage: %s [command [args]]\n", argv[0]);
+ UPRINTF("usage: %s [command [args]]\n", argv[0]);
code = -1;
return;
}
@@ -1418,7 +1449,7 @@ shell(int argc, char *argv[])
else
namep++;
(void)strlcpy(shellnam, namep, sizeof(shellnam));
- if (debug) {
+ if (ftp_debug) {
fputs(shell, ttyout);
putc('\n', ttyout);
}
@@ -1428,7 +1459,7 @@ shell(int argc, char *argv[])
else {
execl(shell, shellnam, (char *)0);
}
- warn("%s", shell);
+ warn("Can't execute `%s'", shell);
code = -1;
exit(1);
}
@@ -1437,7 +1468,7 @@ shell(int argc, char *argv[])
;
(void)xsignal(SIGINT, oldintr);
if (pid == -1) {
- warn("Try again later");
+ warn("Can't fork a subshell; try again later");
code = -1;
} else
code = 0;
@@ -1450,6 +1481,7 @@ void
user(int argc, char *argv[])
{
char *password;
+ char emptypass[] = "";
int n, aflag = 0;
if (argc == 0)
@@ -1458,7 +1490,7 @@ user(int argc, char *argv[])
(void)another(&argc, &argv, "username");
if (argc < 2 || argc > 4) {
usage:
- fprintf(ttyout, "usage: %s username [password [account]]\n",
+ UPRINTF("usage: %s username [password [account]]\n",
argv[0]);
code = -1;
return;
@@ -1467,6 +1499,8 @@ user(int argc, char *argv[])
if (n == CONTINUE) {
if (argc < 3) {
password = getpass("Password: ");
+ if (password == NULL)
+ password = emptypass;
} else {
password = argv[2];
}
@@ -1477,6 +1511,8 @@ user(int argc, char *argv[])
aflag++;
if (argc < 4) {
password = getpass("Account: ");
+ if (password == NULL)
+ password = emptypass;
} else {
password = argv[3];
}
@@ -1506,7 +1542,7 @@ pwd(int argc, char *argv[])
code = -1;
if (argc != 1) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
+ UPRINTF("usage: %s\n", argv[0]);
return;
}
if (! remotecwd[0])
@@ -1528,7 +1564,7 @@ lpwd(int argc, char *argv[])
code = -1;
if (argc != 1) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
+ UPRINTF("usage: %s\n", argv[0]);
return;
}
if (! localcwd[0])
@@ -1551,7 +1587,7 @@ makedir(int argc, char *argv[])
if (argc == 0 || argc > 2 ||
(argc == 1 && !another(&argc, &argv, "directory-name"))) {
- fprintf(ttyout, "usage: %s directory-name\n", argv[0]);
+ UPRINTF("usage: %s directory-name\n", argv[0]);
code = -1;
return;
}
@@ -1576,7 +1612,7 @@ removedir(int argc, char *argv[])
if (argc == 0 || argc > 2 ||
(argc == 1 && !another(&argc, &argv, "directory-name"))) {
- fprintf(ttyout, "usage: %s directory-name\n", argv[0]);
+ UPRINTF("usage: %s directory-name\n", argv[0]);
code = -1;
return;
}
@@ -1600,7 +1636,7 @@ quote(int argc, char *argv[])
if (argc == 0 ||
(argc == 1 && !another(&argc, &argv, "command line to send"))) {
- fprintf(ttyout, "usage: %s line-to-send\n", argv[0]);
+ UPRINTF("usage: %s line-to-send\n", argv[0]);
code = -1;
return;
}
@@ -1618,7 +1654,7 @@ site(int argc, char *argv[])
if (argc == 0 ||
(argc == 1 && !another(&argc, &argv, "arguments to SITE command"))){
- fprintf(ttyout, "usage: %s line-to-send\n", argv[0]);
+ UPRINTF("usage: %s line-to-send\n", argv[0]);
code = -1;
return;
}
@@ -1656,7 +1692,7 @@ do_chmod(int argc, char *argv[])
goto usage;
if ((argc < 3 && !another(&argc, &argv, "remote-file")) || argc > 3) {
usage:
- fprintf(ttyout, "usage: %s mode remote-file\n", argv[0]);
+ UPRINTF("usage: %s mode remote-file\n", argv[0]);
code = -1;
return;
}
@@ -1675,7 +1711,7 @@ do_umask(int argc, char *argv[])
int oldverbose = verbose;
if (argc == 0) {
- fprintf(ttyout, "usage: %s [umask]\n", argv[0]);
+ UPRINTF("usage: %s [umask]\n", argv[0]);
code = -1;
return;
}
@@ -1690,7 +1726,7 @@ idlecmd(int argc, char *argv[])
int oldverbose = verbose;
if (argc < 1 || argc > 2) {
- fprintf(ttyout, "usage: %s [seconds]\n", argv[0]);
+ UPRINTF("usage: %s [seconds]\n", argv[0]);
code = -1;
return;
}
@@ -1708,7 +1744,7 @@ rmthelp(int argc, char *argv[])
int oldverbose = verbose;
if (argc == 0) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
+ UPRINTF("usage: %s\n", argv[0]);
code = -1;
return;
}
@@ -1728,7 +1764,7 @@ quit(int argc, char *argv[])
/* this may be called with argc == 0, argv == NULL */
if (argc == 0 && argv != NULL) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
+ UPRINTF("usage: %s\n", argv[0]);
code = -1;
return;
}
@@ -1750,7 +1786,7 @@ disconnect(int argc, char *argv[])
/* this may be called with argc == 0, argv == NULL */
if (argc == 0 && argv != NULL) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
+ UPRINTF("usage: %s\n", argv[0]);
code = -1;
return;
}
@@ -1764,17 +1800,22 @@ void
account(int argc, char *argv[])
{
char *ap;
+ char emptypass[] = "";
if (argc == 0 || argc > 2) {
- fprintf(ttyout, "usage: %s [password]\n", argv[0]);
+ UPRINTF("usage: %s [password]\n", argv[0]);
code = -1;
return;
}
else if (argc == 2)
ap = argv[1];
- else
+ else {
ap = getpass("Account:");
+ if (ap == NULL)
+ ap = emptypass;
+ }
(void)command("ACCT %s", ap);
+ memset(ap, 0, strlen(ap));
}
sigjmp_buf abortprox;
@@ -1806,7 +1847,7 @@ doproxy(int argc, char *argv[])
sigfunc oldintr;
if (argc == 0 || (argc == 1 && !another(&argc, &argv, "command"))) {
- fprintf(ttyout, "usage: %s command\n", argv[0]);
+ UPRINTF("usage: %s command\n", argv[0]);
code = -1;
return;
}
@@ -1898,7 +1939,7 @@ setntrans(int argc, char *argv[])
{
if (argc == 0 || argc > 3) {
- fprintf(ttyout, "usage: %s [inchars [outchars]]\n", argv[0]);
+ UPRINTF("usage: %s [inchars [outchars]]\n", argv[0]);
code = -1;
return;
}
@@ -1962,7 +2003,7 @@ setnmap(int argc, char *argv[])
}
if (argc == 0 ||
(argc < 3 && !another(&argc, &argv, "mapout")) || argc > 3) {
- fprintf(ttyout, "usage: %s [mapin mapout]\n", argv[0]);
+ UPRINTF("usage: %s [mapin mapout]\n", argv[0]);
code = -1;
return;
}
@@ -2162,7 +2203,7 @@ setpassive(int argc, char *argv[])
activefallback = passivemode;
} else if (argc != 2) {
passiveusage:
- fprintf(ttyout, "usage: %s [ on | off | auto ]\n", argv[0]);
+ UPRINTF("usage: %s [ on | off | auto ]\n", argv[0]);
code = -1;
return;
} else if (strcasecmp(argv[1], "on") == 0) {
@@ -2213,11 +2254,11 @@ parserate(int argc, char *argv[], int cmdlineopt)
if (argc > 4 || (argc < (cmdlineopt ? 3 : 2))) {
usage:
if (cmdlineopt)
- fprintf(ttyout,
+ UPRINTF(
"usage: %s (all|get|put),maximum-bytes[,increment-bytes]]\n",
argv[0]);
else
- fprintf(ttyout,
+ UPRINTF(
"usage: %s (all|get|put) [maximum-bytes [increment-bytes]]\n",
argv[0]);
return -1;
@@ -2289,7 +2330,7 @@ cdup(int argc, char *argv[])
int r;
if (argc == 0) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
+ UPRINTF("usage: %s\n", argv[0]);
code = -1;
return;
}
@@ -2314,7 +2355,7 @@ restart(int argc, char *argv[])
{
if (argc == 0 || argc > 2) {
- fprintf(ttyout, "usage: %s [restart-point]\n", argv[0]);
+ UPRINTF("usage: %s [restart-point]\n", argv[0]);
code = -1;
return;
}
@@ -2351,7 +2392,7 @@ syst(int argc, char *argv[])
int oldverbose = verbose;
if (argc == 0) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
+ UPRINTF("usage: %s\n", argv[0]);
code = -1;
return;
}
@@ -2376,7 +2417,7 @@ macdef(int argc, char *argv[])
}
if ((argc < 2 && !another(&argc, &argv, "macro name")) || argc > 2) {
usage:
- fprintf(ttyout, "usage: %s macro_name\n", argv[0]);
+ UPRINTF("usage: %s macro_name\n", argv[0]);
code = -1;
return;
}
@@ -2434,7 +2475,7 @@ sizecmd(int argc, char *argv[])
if (argc == 0 || argc > 2 ||
(argc == 1 && !another(&argc, &argv, "remote-file"))) {
- fprintf(ttyout, "usage: %s remote-file\n", argv[0]);
+ UPRINTF("usage: %s remote-file\n", argv[0]);
code = -1;
return;
}
@@ -2455,13 +2496,14 @@ modtime(int argc, char *argv[])
if (argc == 0 || argc > 2 ||
(argc == 1 && !another(&argc, &argv, "remote-file"))) {
- fprintf(ttyout, "usage: %s remote-file\n", argv[0]);
+ UPRINTF("usage: %s remote-file\n", argv[0]);
code = -1;
return;
}
mtime = remotemodtime(argv[1], 1);
if (mtime != -1)
- fprintf(ttyout, "%s\t%s", argv[1], asctime(localtime(&mtime)));
+ fprintf(ttyout, "%s\t%s", argv[1],
+ rfc2822time(localtime(&mtime)));
code = (mtime > 0);
}
@@ -2473,7 +2515,7 @@ rmtstatus(int argc, char *argv[])
{
if (argc == 0) {
- fprintf(ttyout, "usage: %s [remote-file]\n", argv[0]);
+ UPRINTF("usage: %s [remote-file]\n", argv[0]);
code = -1;
return;
}
@@ -2504,7 +2546,7 @@ lpage(int argc, char *argv[])
if (argc == 0 || argc > 2 ||
(argc == 1 && !another(&argc, &argv, "local-file"))) {
- fprintf(ttyout, "usage: %s local-file\n", argv[0]);
+ UPRINTF("usage: %s local-file\n", argv[0]);
code = -1;
return;
}
@@ -2516,7 +2558,7 @@ lpage(int argc, char *argv[])
if (EMPTYSTRING(p))
p = DEFAULTPAGER;
len = strlen(p) + strlen(locfile) + 2;
- pager = xmalloc(len);
+ pager = ftp_malloc(len);
(void)strlcpy(pager, p, len);
(void)strlcat(pager, " ", len);
(void)strlcat(pager, locfile, len);
@@ -2538,7 +2580,7 @@ page(int argc, char *argv[])
if (argc == 0 || argc > 2 ||
(argc == 1 && !another(&argc, &argv, "remote-file"))) {
- fprintf(ttyout, "usage: %s remote-file\n", argv[0]);
+ UPRINTF("usage: %s remote-file\n", argv[0]);
code = -1;
return;
}
@@ -2546,7 +2588,7 @@ page(int argc, char *argv[])
if (EMPTYSTRING(p))
p = DEFAULTPAGER;
len = strlen(p) + 2;
- pager = xmalloc(len);
+ pager = ftp_malloc(len);
pager[0] = '|';
(void)strlcpy(pager + 1, p, len - 1);
@@ -2571,7 +2613,7 @@ setxferbuf(int argc, char *argv[])
if (argc != 2) {
usage:
- fprintf(ttyout, "usage: %s size\n", argv[0]);
+ UPRINTF("usage: %s size\n", argv[0]);
code = -1;
return;
}
@@ -2611,7 +2653,7 @@ setoption(int argc, char *argv[])
code = -1;
if (argc == 0 || (argc != 1 && argc != 3)) {
- fprintf(ttyout, "usage: %s [option value]\n", argv[0]);
+ UPRINTF("usage: %s [option value]\n", argv[0]);
return;
}
@@ -2628,7 +2670,7 @@ setoption(int argc, char *argv[])
return;
}
FREEPTR(o->value);
- o->value = xstrdup(argv[2]);
+ o->value = ftp_strdup(argv[2]);
if (verbose)
fprintf(ttyout, "Setting `%s' to `%s'.\n",
o->name, o->value);
@@ -2646,7 +2688,7 @@ unsetoption(int argc, char *argv[])
code = -1;
if (argc == 0 || argc != 2) {
- fprintf(ttyout, "usage: %s option\n", argv[0]);
+ UPRINTF("usage: %s option\n", argv[0]);
return;
}
@@ -2669,7 +2711,7 @@ feat(int argc, char *argv[])
int oldverbose = verbose;
if (argc == 0) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
+ UPRINTF("usage: %s\n", argv[0]);
code = -1;
return;
}
@@ -2689,7 +2731,7 @@ mlst(int argc, char *argv[])
int oldverbose = verbose;
if (argc < 1 || argc > 2) {
- fprintf(ttyout, "usage: %s [remote-path]\n", argv[0]);
+ UPRINTF("usage: %s [remote-path]\n", argv[0]);
code = -1;
return;
}
@@ -2709,7 +2751,7 @@ opts(int argc, char *argv[])
int oldverbose = verbose;
if (argc < 2 || argc > 3) {
- fprintf(ttyout, "usage: %s command [options]\n", argv[0]);
+ UPRINTF("usage: %s command [options]\n", argv[0]);
code = -1;
return;
}
diff --git a/net/tnftp/files/src/cmdtab.c b/net/tnftp/files/src/cmdtab.c
index e065f5cb2b4..756088f9962 100644
--- a/net/tnftp/files/src/cmdtab.c
+++ b/net/tnftp/files/src/cmdtab.c
@@ -1,5 +1,5 @@
-/* NetBSD: cmdtab.c,v 1.7 2005/06/10 04:05:01 lukem Exp */
-/* from NetBSD: cmdtab.c,v 1.45 2005/06/09 16:38:29 lukem Exp */
+/* $NetBSD: cmdtab.c,v 1.1.1.5 2007/08/06 04:33:23 lukem Exp $ */
+/* from NetBSD: cmdtab.c,v 1.47 2007/04/11 04:40:19 lukem Exp */
/*-
* Copyright (c) 1996-2005 The NetBSD Foundation, Inc.
@@ -68,6 +68,21 @@
#include "tnftp.h"
+#if 0 /* tnftp */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)cmdtab.c 8.4 (Berkeley) 10/9/94";
+#else
+__RCSID(" NetBSD: cmdtab.c,v 1.47 2007/04/11 04:40:19 lukem Exp ");
+#endif
+#endif /* not lint */
+
+#include <stdio.h>
+
+#endif /* tnftp */
+
#include "ftp_var.h"
/*
diff --git a/net/tnftp/files/src/complete.c b/net/tnftp/files/src/complete.c
index 5dd7ed19b8d..ee0ecef6769 100644
--- a/net/tnftp/files/src/complete.c
+++ b/net/tnftp/files/src/complete.c
@@ -1,5 +1,5 @@
-/* NetBSD: complete.c,v 1.6 2005/06/10 04:05:01 lukem Exp */
-/* from NetBSD: complete.c,v 1.40 2005/06/09 16:38:29 lukem Exp */
+/* $NetBSD: complete.c,v 1.1.1.4 2007/08/06 04:33:23 lukem Exp $ */
+/* from NetBSD: complete.c,v 1.42 2007/04/17 05:52:03 lukem Exp */
/*-
* Copyright (c) 1997-2000,2005 The NetBSD Foundation, Inc.
@@ -37,11 +37,29 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include "tnftp.h"
+
+#if 0 /* tnftp */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID(" NetBSD: complete.c,v 1.42 2007/04/17 05:52:03 lukem Exp ");
+#endif /* not lint */
+
/*
* FTP user program - command and file completion routines
*/
-#include "tnftp.h"
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#endif /* tnftp */
#include "ftp_var.h"
@@ -132,14 +150,14 @@ complete_command(char *word, int list)
size_t wordlen;
unsigned char rv;
- words = xsl_init();
+ words = ftp_sl_init();
wordlen = strlen(word);
for (c = cmdtab; c->c_name != NULL; c++) {
if (wordlen > strlen(c->c_name))
continue;
if (strncmp(word, c->c_name, wordlen) == 0)
- xsl_add(words, c->c_name);
+ ftp_sl_add(words, c->c_name);
}
rv = complete_ambiguous(word, list, words);
@@ -189,7 +207,7 @@ complete_local(char *word, int list)
if ((dd = opendir(dir)) == NULL)
return (CC_ERROR);
- words = xsl_init();
+ words = ftp_sl_init();
len = strlen(file);
for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) {
@@ -206,8 +224,8 @@ complete_local(char *word, int list)
if (strncmp(file, dp->d_name, len) == 0) {
char *tcp;
- tcp = xstrdup(dp->d_name);
- xsl_add(words, tcp);
+ tcp = ftp_strdup(dp->d_name);
+ ftp_sl_add(words, tcp);
}
}
closedir(dd);
@@ -244,14 +262,14 @@ complete_option(char *word, int list)
size_t wordlen;
unsigned char rv;
- words = xsl_init();
+ words = ftp_sl_init();
wordlen = strlen(word);
for (o = optiontab; o->name != NULL; o++) {
if (wordlen > strlen(o->name))
continue;
if (strncmp(word, o->name, wordlen) == 0)
- xsl_add(words, o->name);
+ ftp_sl_add(words, o->name);
}
rv = complete_ambiguous(word, list, words);
@@ -297,7 +315,7 @@ complete_remote(char *word, int list)
if (dirlist != NULL)
sl_free(dirlist, 1);
- dirlist = xsl_init();
+ dirlist = ftp_sl_init();
mflag = 1;
emesg = NULL;
@@ -315,8 +333,8 @@ complete_remote(char *word, int list)
tcp++;
else
tcp = cp;
- tcp = xstrdup(tcp);
- xsl_add(dirlist, tcp);
+ tcp = ftp_strdup(tcp);
+ ftp_sl_add(dirlist, tcp);
}
if (emesg != NULL) {
fprintf(ttyout, "\n%s\n", emesg);
@@ -326,13 +344,13 @@ complete_remote(char *word, int list)
dirchange = 0;
}
- words = xsl_init();
+ words = ftp_sl_init();
for (i = 0; i < dirlist->sl_cur; i++) {
cp = dirlist->sl_str[i];
if (strlen(file) > strlen(cp))
continue;
if (strncmp(file, cp, strlen(file)) == 0)
- xsl_add(words, cp);
+ ftp_sl_add(words, cp);
}
rv = complete_ambiguous(file, list, words);
sl_free(words, 0);
@@ -415,7 +433,8 @@ complete(EditLine *el, int ch)
}
return (complete_remote(word, dolist));
default:
- errx(1, "unknown complete type `%c'", cmpltype);
+ errx(1, "complete: unknown complete type `%c'",
+ cmpltype);
return (CC_ERROR);
}
/* NOTREACHED */
diff --git a/net/tnftp/files/src/domacro.c b/net/tnftp/files/src/domacro.c
index 001df2e2a91..916abf33108 100644
--- a/net/tnftp/files/src/domacro.c
+++ b/net/tnftp/files/src/domacro.c
@@ -1,5 +1,5 @@
-/* NetBSD: domacro.c,v 1.5 2005/06/09 16:47:50 lukem Exp */
-/* from NetBSD: domacro.c,v 1.20 2003/08/07 11:13:53 agc Exp */
+/* $NetBSD: domacro.c,v 1.1.1.5 2007/08/06 04:33:23 lukem Exp $ */
+/* from NetBSD: domacro.c,v 1.21 2005/06/29 02:31:19 christos Exp */
/*
* Copyright (c) 1985, 1993, 1994
@@ -32,6 +32,23 @@
#include "tnftp.h"
+#if 0 /* tnftp */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)domacro.c 8.3 (Berkeley) 4/2/94";
+#else
+__RCSID(" NetBSD: domacro.c,v 1.21 2005/06/29 02:31:19 christos Exp ");
+#endif
+#endif /* not lint */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+#endif /* tnftp */
+
#include "ftp_var.h"
void
@@ -43,7 +60,7 @@ domacro(int argc, char *argv[])
if ((argc == 0 && argv != NULL) ||
(argc < 2 && !another(&argc, &argv, "macro name"))) {
- fprintf(ttyout, "usage: %s macro_name [args]\n", argv[0]);
+ UPRINTF("usage: %s macro_name [args]\n", argv[0]);
code = -1;
return;
}
diff --git a/net/tnftp/files/src/fetch.c b/net/tnftp/files/src/fetch.c
index 2a8f1fdff3e..13b5a10b820 100644
--- a/net/tnftp/files/src/fetch.c
+++ b/net/tnftp/files/src/fetch.c
@@ -1,8 +1,8 @@
-/* NetBSD: fetch.c,v 1.11 2005/06/10 04:05:01 lukem Exp */
-/* from NetBSD: fetch.c,v 1.162 2005/06/10 00:18:46 lukem Exp */
+/* $NetBSD: fetch.c,v 1.1.1.5 2007/08/06 04:33:23 lukem Exp $ */
+/* from NetBSD: fetch.c,v 1.180 2007/06/05 00:31:20 lukem Exp */
/*-
- * Copyright (c) 1997-2005 The NetBSD Foundation, Inc.
+ * Copyright (c) 1997-2007 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -40,11 +40,42 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include "tnftp.h"
+
+#if 0 /* tnftp */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID(" NetBSD: fetch.c,v 1.180 2007/06/05 00:31:20 lukem Exp ");
+#endif /* not lint */
+
/*
* FTP User Program -- Command line file retrieval
*/
-#include "tnftp.h"
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+
+#include <netinet/in.h>
+
+#include <arpa/ftp.h>
+#include <arpa/inet.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+
+#endif /* tnftp */
#include "ftp_var.h"
#include "version.h"
@@ -88,7 +119,7 @@ static int redirect_loop;
* Determine if token is the next word in buf (case insensitive).
* If so, advance buf past the token and any trailing LWS, and
* return a pointer to the token (in buf). Otherwise, return NULL.
- * token may be preceeded by LWS.
+ * token may be preceded by LWS.
* token must be followed by LWS or NUL. (I.e, don't partial match).
*/
static const char *
@@ -134,11 +165,10 @@ auth_url(const char *challenge, char **response, const char *guser,
cp = challenge;
scheme = "Basic"; /* only support Basic authentication */
- if (debug)
- fprintf(ttyout, "auth_url: challenge `%s'\n", challenge);
+ DPRINTF("auth_url: challenge `%s'\n", challenge);
if (! match_token(&cp, scheme)) {
- warnx("Unsupported authentication challenge - `%s'",
+ warnx("Unsupported authentication challenge `%s'",
challenge);
goto cleanup_auth_url;
}
@@ -147,7 +177,7 @@ auth_url(const char *challenge, char **response, const char *guser,
if (STRNEQUAL(cp, REALM))
cp += sizeof(REALM) - 1;
else {
- warnx("Unsupported authentication challenge - `%s'",
+ warnx("Unsupported authentication challenge `%s'",
challenge);
goto cleanup_auth_url;
}
@@ -155,10 +185,10 @@ auth_url(const char *challenge, char **response, const char *guser,
if ((ep = strchr(cp, '\"')) != NULL) {
size_t len = ep - cp;
- realm = (char *)xmalloc(len + 1);
+ realm = (char *)ftp_malloc(len + 1);
(void)strlcpy(realm, cp, len + 1);
} else {
- warnx("Unsupported authentication challenge - `%s'",
+ warnx("Unsupported authentication challenge `%s'",
challenge);
goto cleanup_auth_url;
}
@@ -173,15 +203,19 @@ auth_url(const char *challenge, char **response, const char *guser,
warnx("%s; can't authenticate", errormsg);
goto cleanup_auth_url;
}
- user[strlen(user) - 1] = '\0';
}
if (gpass != NULL)
pass = (char *)gpass;
- else
+ else {
pass = getpass("Password: ");
+ if (pass == NULL) {
+ warnx("Can't read password");
+ goto cleanup_auth_url;
+ }
+ }
clen = strlen(user) + strlen(pass) + 2; /* user + ":" + pass + "\0" */
- clear = (char *)xmalloc(clen);
+ clear = (char *)ftp_malloc(clen);
(void)strlcpy(clear, user, clen);
(void)strlcat(clear, ":", clen);
(void)strlcat(clear, pass, clen);
@@ -190,7 +224,7 @@ auth_url(const char *challenge, char **response, const char *guser,
/* scheme + " " + enc + "\0" */
rlen = strlen(scheme) + 1 + (clen + 2) * 4 / 3 + 1;
- *response = (char *)xmalloc(rlen);
+ *response = (char *)ftp_malloc(rlen);
(void)strlcpy(*response, scheme, rlen);
len = strlcat(*response, " ", rlen);
/* use `clen - 1' to not encode the trailing NUL */
@@ -259,7 +293,7 @@ url_decode(char *url)
/*
- * Parse URL of form:
+ * Parse URL of form (per RFC3986):
* <type>://[<user>[:<password>]@]<host>[:<port>][/<path>]
* Returns -1 if a parse error occurred, otherwise 0.
* It's the caller's responsibility to url_decode() the returned
@@ -269,12 +303,9 @@ url_decode(char *url)
* malloc(3)ed strings of the relevant section, and port to
* the number given, or ftpport if ftp://, or httpport if http://.
*
- * If <host> is surrounded by `[' and ']', it's parsed as an
- * IPv6 address (as per RFC 2732).
- *
- * XXX: this is not totally RFC 1738 compliant; <path> will have the
+ * XXX: this is not totally RFC3986 compliant; <path> will have the
* leading `/' unless it's an ftp:// URL, as this makes things easier
- * for file:// and http:// URLs. ftp:// URLs have the `/' between the
+ * for file:// and http:// URLs. ftp:// URLs have the `/' between the
* host and the URL-path removed, but any additional leading slashes
* in the URL-path are retained (because they imply that we should
* later do "CWD" with a null argument).
@@ -282,11 +313,14 @@ url_decode(char *url)
* Examples:
* input URL output path
* --------- -----------
- * "ftp://host" NULL
- * "http://host/" NULL
+ * "http://host" "/"
+ * "http://host/" "/"
+ * "http://host/path" "/path"
* "file://host/dir/file" "dir/file"
+ * "ftp://host" ""
* "ftp://host/" ""
- * "ftp://host//" NULL
+ * "ftp://host//" "/"
+ * "ftp://host/dir/file" "dir/file"
* "ftp://host//dir/file" "/dir/file"
*/
static int
@@ -341,14 +375,14 @@ parse_url(const char *url, const char *desc, url_t *type,
/* find [user[:pass]@]host[:port] */
ep = strchr(url, '/');
if (ep == NULL)
- thost = xstrdup(url);
+ thost = ftp_strdup(url);
else {
len = ep - url;
- thost = (char *)xmalloc(len + 1);
+ thost = (char *)ftp_malloc(len + 1);
(void)strlcpy(thost, url, len + 1);
if (*type == FTP_URL_T) /* skip first / for ftp URLs */
ep++;
- *path = xstrdup(ep);
+ *path = ftp_strdup(ep);
}
cp = strchr(thost, '@'); /* look for user[:pass]@ in URLs */
@@ -357,11 +391,11 @@ parse_url(const char *url, const char *desc, url_t *type,
anonftp = 0; /* disable anonftp */
*user = thost;
*cp = '\0';
- thost = xstrdup(cp + 1);
+ thost = ftp_strdup(cp + 1);
cp = strchr(*user, ':');
if (cp != NULL) {
*cp = '\0';
- *pass = xstrdup(cp + 1);
+ *pass = ftp_strdup(cp + 1);
}
url_decode(*user);
if (*pass)
@@ -371,7 +405,7 @@ parse_url(const char *url, const char *desc, url_t *type,
#ifdef INET6
/*
* Check if thost is an encoded IPv6 address, as per
- * RFC 2732:
+ * RFC3986:
* `[' ipv6-address ']'
*/
if (*thost == '[') {
@@ -397,8 +431,8 @@ parse_url(const char *url, const char *desc, url_t *type,
cp = NULL;
} else
#endif /* INET6 */
- if ((cp = strchr(thost, ':')) != NULL)
- *cp++ = '\0';
+ if ((cp = strchr(thost, ':')) != NULL)
+ *cp++ = '\0';
*host = thost;
/* look for [:port] */
@@ -416,17 +450,19 @@ parse_url(const char *url, const char *desc, url_t *type,
}
if (tport != NULL)
- *port = xstrdup(tport);
- if (*path == NULL)
- *path = xstrdup("/");
-
- if (debug)
- fprintf(ttyout,
- "parse_url: user `%s' pass `%s' host %s port %s(%d) "
- "path `%s'\n",
- *user ? *user : "<null>", *pass ? *pass : "<null>",
- *host ? *host : "<null>", *port ? *port : "<null>",
- *portnum ? *portnum : -1, *path ? *path : "<null>");
+ *port = ftp_strdup(tport);
+ if (*path == NULL) {
+ const char *emptypath = "/";
+ if (*type == FTP_URL_T) /* skip first / for ftp URLs */
+ emptypath++;
+ *path = ftp_strdup(emptypath);
+ }
+
+ DPRINTF("parse_url: user `%s' pass `%s' host %s port %s(%d) "
+ "path `%s'\n",
+ *user ? *user : "<null>", *pass ? *pass : "<null>",
+ *host ? *host : "<null>", *port ? *port : "<null>",
+ *portnum ? *portnum : -1, *path ? *path : "<null>");
return (0);
}
@@ -447,21 +483,32 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
struct addrinfo hints, *res, *res0 = NULL;
int error;
char hbuf[NI_MAXHOST];
- volatile sigfunc oldintr, oldintp;
- volatile int s;
+ sigfunc volatile oldintr;
+ sigfunc volatile oldintp;
+ int volatile s;
struct stat sb;
- int ischunked, isproxy, rval, hcode;
+ int volatile ischunked;
+ int volatile isproxy;
+ int volatile rval;
+ int volatile hcode;
size_t len;
static size_t bufsize;
static char *xferbuf;
const char *cp, *token;
- char *ep, *buf, *savefile;
- char *auth, *location, *message;
- char *user, *pass, *host, *port, *path, *decodedpath;
+ char *ep;
+ char buf[FTPBUFLEN];
+ const char *errormsg;
+ char *volatile savefile;
+ char *volatile auth;
+ char *volatile location;
+ char *volatile message;
+ char *user, *pass, *host, *port, *path;
+ char *volatile decodedpath;
char *puser, *ppass, *useragent;
off_t hashbytes, rangestart, rangeend, entitylen;
- int (*closefunc)(FILE *);
- FILE *fin, *fout;
+ int (*volatile closefunc)(FILE *);
+ FILE *volatile fin;
+ FILE *volatile fout;
time_t mtime;
url_t urltype;
in_port_t portnum;
@@ -470,28 +517,12 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
closefunc = NULL;
fin = fout = NULL;
s = -1;
- buf = savefile = NULL;
+ savefile = NULL;
auth = location = message = NULL;
ischunked = isproxy = hcode = 0;
rval = 1;
user = pass = host = path = decodedpath = puser = ppass = NULL;
-#ifdef __GNUC__ /* shut up gcc warnings */
- (void)&closefunc;
- (void)&fin;
- (void)&fout;
- (void)&buf;
- (void)&savefile;
- (void)&rval;
- (void)&isproxy;
- (void)&hcode;
- (void)&ischunked;
- (void)&message;
- (void)&location;
- (void)&auth;
- (void)&decodedpath;
-#endif
-
if (parse_url(url, "URL", &urltype, &user, &pass, &host, &port,
&portnum, &path) == -1)
goto cleanup_fetch_url;
@@ -513,29 +544,28 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
}
}
- decodedpath = xstrdup(path);
+ decodedpath = ftp_strdup(path);
url_decode(decodedpath);
if (outfile)
- savefile = xstrdup(outfile);
+ savefile = ftp_strdup(outfile);
else {
cp = strrchr(decodedpath, '/'); /* find savefile */
if (cp != NULL)
- savefile = xstrdup(cp + 1);
+ savefile = ftp_strdup(cp + 1);
else
- savefile = xstrdup(decodedpath);
+ savefile = ftp_strdup(decodedpath);
}
if (EMPTYSTRING(savefile)) {
if (urltype == FTP_URL_T) {
rval = fetch_ftp(url);
goto cleanup_fetch_url;
}
- warnx("no file after directory (you must specify an "
+ warnx("No file after directory (you must specify an "
"output file) `%s'", url);
goto cleanup_fetch_url;
} else {
- if (debug)
- fprintf(ttyout, "savefile `%s'\n", savefile);
+ DPRINTF("savefile `%s'\n", savefile);
}
restart_point = 0;
@@ -551,7 +581,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
direction = "copied";
fin = fopen(decodedpath, "r");
if (fin == NULL) {
- warn("Cannot open file `%s'", decodedpath);
+ warn("Can't open `%s'", decodedpath);
goto cleanup_fetch_url;
}
if (fstat(fileno(fin), &sb) == 0) {
@@ -560,7 +590,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
}
if (restart_point) {
if (lseek(fileno(fin), restart_point, SEEK_SET) < 0) {
- warn("Can't lseek to restart `%s'",
+ warn("Can't seek to restart `%s'",
decodedpath);
goto cleanup_fetch_url;
}
@@ -593,13 +623,13 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
/* check URL against list of no_proxied sites */
no_proxy = getoptionvalue("no_proxy");
if (! EMPTYSTRING(no_proxy)) {
- char *np, *np_copy;
+ char *np, *np_copy, *np_iter;
long np_port;
size_t hlen, plen;
- np_copy = xstrdup(no_proxy);
+ np_iter = np_copy = ftp_strdup(no_proxy);
hlen = strlen(host);
- while ((cp = strsep(&np_copy, " ,")) != NULL) {
+ while ((cp = strsep(&np_iter, " ,")) != NULL) {
if (*cp == '\0')
continue;
if ((np = strrchr(cp, ':')) != NULL) {
@@ -628,6 +658,11 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
}
if (isproxy) {
+ if (restart_point) {
+ warnx("Can't restart via proxy URL `%s'",
+ proxyenv);
+ goto cleanup_fetch_url;
+ }
if (parse_url(proxyenv, "proxy URL", &purltype,
&puser, &ppass, &phost, &pport, &portnum,
&ppath) == -1)
@@ -661,7 +696,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
FREEPTR(port);
port = pport;
FREEPTR(path);
- path = xstrdup(url);
+ path = ftp_strdup(url);
FREEPTR(ppath);
}
} /* ! EMPTYSTRING(proxyenv) */
@@ -673,7 +708,9 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
hints.ai_protocol = 0;
error = getaddrinfo(host, NULL, &hints, &res0);
if (error) {
- warnx("%s: %s", host, gai_strerror(error));
+ warnx("Can't lookup `%s': %s", host,
+ (error == EAI_SYSTEM) ? strerror(errno)
+ : gai_strerror(error));
goto cleanup_fetch_url;
}
if (res0->ai_canonname)
@@ -681,13 +718,10 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
s = -1;
for (res = res0; res; res = res->ai_next) {
- /*
- * see comment in hookup()
- */
ai_unmapped(res);
if (getnameinfo(res->ai_addr, res->ai_addrlen,
hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
- strlcpy(hbuf, "invalid", sizeof(hbuf));
+ strlcpy(hbuf, "?", sizeof(hbuf));
if (verbose && res0->ai_next) {
fprintf(ttyout, "Trying %s...\n", hbuf);
@@ -698,12 +732,13 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
s = socket(res->ai_family, SOCK_STREAM,
res->ai_protocol);
if (s < 0) {
- warn("Can't create socket");
+ warn(
+ "Can't create socket for connection to `%s'",
+ hbuf);
continue;
}
- if (xconnect(s, res->ai_addr, res->ai_addrlen) < 0) {
- warn("Connect to address `%s'", hbuf);
+ if (ftp_connect(s, res->ai_addr, res->ai_addrlen) < 0) {
close(s);
s = -1;
continue;
@@ -714,7 +749,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
}
if (s < 0) {
- warn("Can't connect to %s", host);
+ warnx("Can't connect to `%s'", host);
goto cleanup_fetch_url;
}
@@ -745,7 +780,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
* strip off IPv6 scope identifier, since it is
* local to the node
*/
- h = xstrdup(host);
+ h = ftp_strdup(host);
if (isipv6addr(h) &&
(p = strchr(h, '%')) != NULL) {
*p = '\0';
@@ -804,14 +839,16 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
}
/* Read the response */
- if ((buf = fparseln(fin, &len, NULL, "\0\0\0", 0)) == NULL) {
- warn("Receiving HTTP reply");
+ len = getline(fin, buf, sizeof(buf), &errormsg);
+ if (len < 0) {
+ if (*errormsg == '\n')
+ errormsg++;
+ warnx("Receiving HTTP reply: %s", errormsg);
goto cleanup_fetch_url;
}
while (len > 0 && (ISLWS(buf[len-1])))
buf[--len] = '\0';
- if (debug)
- fprintf(ttyout, "received `%s'\n", buf);
+ DPRINTF("received `%s'\n", buf);
/* Determine HTTP response code */
cp = strchr(buf, ' ');
@@ -822,22 +859,22 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
hcode = strtol(cp, &ep, 10);
if (*ep != '\0' && !isspace((unsigned char)*ep))
goto improper;
- message = xstrdup(cp);
+ message = ftp_strdup(cp);
/* Read the rest of the header. */
while (1) {
- FREEPTR(buf);
- if ((buf = fparseln(fin, &len, NULL, "\0\0\0", 0))
- == NULL) {
- warn("Receiving HTTP reply");
+ len = getline(fin, buf, sizeof(buf), &errormsg);
+ if (len < 0) {
+ if (*errormsg == '\n')
+ errormsg++;
+ warnx("Receiving HTTP reply: %s", errormsg);
goto cleanup_fetch_url;
}
while (len > 0 && (ISLWS(buf[len-1])))
buf[--len] = '\0';
if (len == 0)
break;
- if (debug)
- fprintf(ttyout, "received `%s'\n", buf);
+ DPRINTF("received `%s'\n", buf);
/*
* Look for some headers
@@ -849,10 +886,8 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
filesize = STRTOLL(cp, &ep, 10);
if (filesize < 0 || *ep != '\0')
goto improper;
- if (debug)
- fprintf(ttyout,
- "parsed len as: " LLF "\n",
- (LLT)filesize);
+ DPRINTF("parsed len as: " LLF "\n",
+ (LLT)filesize);
} else if (match_token(&cp, "Content-Range:")) {
if (! match_token(&cp, "bytes"))
@@ -884,7 +919,8 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
if (*cp != '\0')
goto improper;
- if (debug) {
+#ifndef NO_DEBUG
+ if (ftp_debug) {
fprintf(ttyout, "parsed range as: ");
if (rangestart == -1)
fprintf(ttyout, "*");
@@ -894,6 +930,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
(LLT)rangeend);
fprintf(ttyout, "/" LLF "\n", (LLT)entitylen);
}
+#endif
if (! restart_point) {
warnx(
"Received unexpected Content-Range header");
@@ -904,11 +941,12 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
struct tm parsed;
char *t;
- /* RFC 1123 */
+ memset(&parsed, 0, sizeof(parsed));
+ /* RFC1123 */
if ((t = strptime(cp,
"%a, %d %b %Y %H:%M:%S GMT",
&parsed))
- /* RFC 850 */
+ /* RFC0850 */
|| (t = strptime(cp,
"%a, %d-%b-%y %H:%M:%S GMT",
&parsed))
@@ -919,55 +957,49 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
parsed.tm_isdst = -1;
if (*t == '\0')
mtime = timegm(&parsed);
- if (debug && mtime != -1) {
+#ifndef NO_DEBUG
+ if (ftp_debug && mtime != -1) {
fprintf(ttyout,
"parsed date as: %s",
- ctime(&mtime));
+ rfc2822time(localtime(&mtime)));
}
+#endif
}
} else if (match_token(&cp, "Location:")) {
- location = xstrdup(cp);
- if (debug)
- fprintf(ttyout,
- "parsed location as `%s'\n", cp);
+ location = ftp_strdup(cp);
+ DPRINTF("parsed location as `%s'\n", cp);
} else if (match_token(&cp, "Transfer-Encoding:")) {
if (match_token(&cp, "binary")) {
warnx(
- "Bogus transfer encoding - `binary' (fetching anyway)");
+ "Bogus transfer encoding `binary' (fetching anyway)");
continue;
}
if (! (token = match_token(&cp, "chunked"))) {
warnx(
- "Unsupported transfer encoding - `%s'",
+ "Unsupported transfer encoding `%s'",
token);
goto cleanup_fetch_url;
}
ischunked++;
- if (debug)
- fprintf(ttyout,
- "using chunked encoding\n");
+ DPRINTF("using chunked encoding\n");
} else if (match_token(&cp, "Proxy-Authenticate:")
|| match_token(&cp, "WWW-Authenticate:")) {
if (! (token = match_token(&cp, "Basic"))) {
- if (debug)
- fprintf(ttyout,
+ DPRINTF(
"skipping unknown auth scheme `%s'\n",
token);
continue;
}
FREEPTR(auth);
- auth = xstrdup(token);
- if (debug)
- fprintf(ttyout,
- "parsed auth as `%s'\n", cp);
+ auth = ftp_strdup(token);
+ DPRINTF("parsed auth as `%s'\n", cp);
}
}
/* finished parsing header */
- FREEPTR(buf);
switch (hcode) {
case 200:
@@ -983,6 +1015,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
case 302:
case 303:
case 305:
+ case 307:
if (EMPTYSTRING(location)) {
warnx(
"No redirection Location provided by server");
@@ -1054,7 +1087,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
#endif
default:
if (message)
- warnx("Error retrieving file - `%s'", message);
+ warnx("Error retrieving file `%s'", message);
else
warnx("Unknown error retrieving file");
goto cleanup_fetch_url;
@@ -1068,7 +1101,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
oldintp = xsignal(SIGPIPE, SIG_IGN);
fout = popen(savefile + 1, "w");
if (fout == NULL) {
- warn("Can't run `%s'", savefile + 1);
+ warn("Can't execute `%s'", savefile + 1);
goto cleanup_fetch_url;
}
closefunc = pclose;
@@ -1110,7 +1143,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
if (xferbuf)
(void)free(xferbuf);
bufsize = rcvbuf_size;
- xferbuf = xmalloc(bufsize);
+ xferbuf = ftp_malloc(bufsize);
}
bytes = 0;
@@ -1142,9 +1175,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
warnx("Unexpected data following chunksize");
goto cleanup_fetch_url;
}
- if (debug)
- fprintf(ttyout, "got chunksize of " LLF "\n",
- (LLT)chunksize);
+ DPRINTF("got chunksize of " LLF "\n", (LLT)chunksize);
if (chunksize == 0)
break;
}
@@ -1229,7 +1260,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
if (utimes(savefile, tval) == -1) {
fprintf(ttyout,
"Can't change modification time to %s",
- asctime(localtime(&mtime)));
+ rfc2822time(localtime(&mtime)));
}
}
if (bytes > 0)
@@ -1268,7 +1299,6 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
if (ppass != NULL)
memset(ppass, 0, strlen(ppass));
FREEPTR(ppass);
- FREEPTR(buf);
FREEPTR(auth);
FREEPTR(location);
FREEPTR(message);
@@ -1344,18 +1374,18 @@ fetch_ftp(const char *url)
}
} else { /* classic style `[user@]host:[file]' */
urltype = CLASSIC_URL_T;
- host = xstrdup(url);
+ host = ftp_strdup(url);
cp = strchr(host, '@');
if (cp != NULL) {
*cp = '\0';
user = host;
anonftp = 0; /* disable anonftp */
- host = xstrdup(cp + 1);
+ host = ftp_strdup(cp + 1);
}
cp = strchr(host, ':');
if (cp != NULL) {
*cp = '\0';
- path = xstrdup(cp + 1);
+ path = ftp_strdup(cp + 1);
}
}
if (EMPTYSTRING(host))
@@ -1403,14 +1433,12 @@ fetch_ftp(const char *url)
url_decode(file);
/* but still don't url_decode(dir) */
}
- if (debug)
- fprintf(ttyout,
- "fetch_ftp: user `%s' pass `%s' host %s port %s "
- "path `%s' dir `%s' file `%s'\n",
- user ? user : "<null>", pass ? pass : "<null>",
- host ? host : "<null>", port ? port : "<null>",
- path ? path : "<null>",
- dir ? dir : "<null>", file ? file : "<null>");
+ DPRINTF("fetch_ftp: user `%s' pass `%s' host %s port %s "
+ "path `%s' dir `%s' file `%s'\n",
+ user ? user : "<null>", pass ? pass : "<null>",
+ host ? host : "<null>", port ? port : "<null>",
+ path ? path : "<null>",
+ dir ? dir : "<null>", file ? file : "<null>");
dirhasglob = filehasglob = 0;
if (doglob && urltype == CLASSIC_URL_T) {
@@ -1472,12 +1500,12 @@ fetch_ftp(const char *url)
* directories in one step.
*
* If we are dealing with an `ftp://host/path' URL
- * (urltype is FTP_URL_T), then RFC 1738 says we need to
+ * (urltype is FTP_URL_T), then RFC3986 says we need to
* send a separate CWD command for each unescaped "/"
* in the path, and we have to interpret %hex escaping
* *after* we find the slashes. It's possible to get
* empty components here, (from multiple adjacent
- * slashes in the path) and RFC 1738 says that we should
+ * slashes in the path) and RFC3986 says that we should
* still do `CWD ' (with a null argument) in such cases.
*
* Many ftp servers don't support `CWD ', so if there's an
@@ -1535,10 +1563,9 @@ fetch_ftp(const char *url)
url_decode(dir);
} else
nextpart = NULL;
- if (debug)
- fprintf(ttyout, "dir `%s', nextpart `%s'\n",
- dir ? dir : "<null>",
- nextpart ? nextpart : "<null>");
+ DPRINTF("dir `%s', nextpart `%s'\n",
+ dir ? dir : "<null>",
+ nextpart ? nextpart : "<null>");
if (urltype == FTP_URL_T || *dir != '\0') {
xargv[0] = "cd";
xargv[1] = dir;
@@ -1550,8 +1577,8 @@ fetch_ftp(const char *url)
fprintf(stderr,
"\n"
"ftp: The `CWD ' command (without a directory), which is required by\n"
-" RFC 1738 to support the empty directory in the URL pathname (`//'),\n"
-" conflicts with the server's conformance to RFC 959.\n"
+" RFC3986 to support the empty directory in the URL pathname (`//'),\n"
+" conflicts with the server's conformance to RFC0959.\n"
" Try the same URL without the `//' in the URL pathname.\n"
"\n");
goto cleanup_fetch_ftp;
@@ -1610,6 +1637,7 @@ fetch_ftp(const char *url)
rval = 0;
cleanup_fetch_ftp:
+ FREEPTR(port);
FREEPTR(host);
FREEPTR(path);
FREEPTR(user);
@@ -1742,11 +1770,19 @@ auto_fetch(int argc, char *argv[])
}
+/*
+ * Upload multiple files from the command line.
+ *
+ * If an error occurs the return value will be the offset+1 in
+ * argv[] of the file that caused a problem (i.e, argv[x]
+ * returns x+1)
+ * Otherwise, 0 is returned if all files uploaded successfully.
+ */
int
auto_put(int argc, char **argv, const char *uploadserver)
{
char *uargv[4], *path, *pathsep;
- int uargc, rval;
+ int uargc, rval, argpos;
size_t len;
uargc = 0;
@@ -1756,10 +1792,9 @@ auto_put(int argc, char **argv, const char *uploadserver)
pathsep = NULL;
rval = 1;
- if (debug)
- fprintf(ttyout, "auto_put: target `%s'\n", uploadserver);
+ DPRINTF("auto_put: target `%s'\n", uploadserver);
- path = xstrdup(uploadserver);
+ path = ftp_strdup(uploadserver);
len = strlen(path);
if (path[len - 1] != '/' && path[len - 1] != ':') {
/*
@@ -1768,7 +1803,7 @@ auto_put(int argc, char **argv, const char *uploadserver)
if (argc > 1) { /* more than one file to upload */
len = strlen(uploadserver) + 2; /* path + "/" + "\0" */
free(path);
- path = (char *)xmalloc(len);
+ path = (char *)ftp_malloc(len);
(void)strlcpy(path, uploadserver, len);
(void)strlcat(path, "/", len);
} else { /* single file to upload */
@@ -1781,38 +1816,44 @@ auto_put(int argc, char **argv, const char *uploadserver)
goto cleanup_auto_put;
}
pathsep++;
- uargv[2] = xstrdup(pathsep);
+ uargv[2] = ftp_strdup(pathsep);
pathsep[0] = '/';
} else
- uargv[2] = xstrdup(pathsep + 1);
+ uargv[2] = ftp_strdup(pathsep + 1);
pathsep[1] = '\0';
uargc++;
}
}
- if (debug)
- fprintf(ttyout, "auto_put: URL `%s' argv[2] `%s'\n",
- path, uargv[2] ? uargv[2] : "<null>");
+ DPRINTF("auto_put: URL `%s' argv[2] `%s'\n",
+ path, uargv[2] ? uargv[2] : "<null>");
/* connect and cwd */
rval = auto_fetch(1, &path);
- free(path);
if(rval >= 0)
goto cleanup_auto_put;
+ rval = 0;
+
+ /* target filename provided; upload 1 file */
/* XXX : is this the best way? */
if (uargc == 3) {
uargv[1] = argv[0];
put(uargc, uargv);
- goto cleanup_auto_put;
- }
-
- for(; argv[0] != NULL; argv++) {
- uargv[1] = argv[0];
- mput(uargc, uargv);
+ if ((code / 100) != COMPLETE)
+ rval = 1;
+ } else { /* otherwise a target dir: upload all files to it */
+ for(argpos = 0; argv[argpos] != NULL; argpos++) {
+ uargv[1] = argv[argpos];
+ mput(uargc, uargv);
+ if ((code / 100) != COMPLETE) {
+ rval = argpos + 1;
+ break;
+ }
+ }
}
- rval = 0;
cleanup_auto_put:
+ free(path);
FREEPTR(uargv[2]);
return (rval);
}
diff --git a/net/tnftp/files/src/ftp.1 b/net/tnftp/files/src/ftp.1
index eda2f1d7015..5737a3defec 100644
--- a/net/tnftp/files/src/ftp.1
+++ b/net/tnftp/files/src/ftp.1
@@ -1,7 +1,7 @@
-.\" NetBSD: ftp.1,v 1.7 2005/05/11 02:41:28 lukem Exp
-.\" from NetBSD: ftp.1,v 1.109 2005/02/20 20:54:01 wiz Exp
+.\" $NetBSD: ftp.1,v 1.1.1.4 2007/08/06 04:33:23 lukem Exp $
+.\" from NetBSD: ftp.1,v 1.119 2007/07/18 06:40:01 lukem Exp
.\"
-.\" Copyright (c) 1996-2004 The NetBSD Foundation, Inc.
+.\" Copyright (c) 1996-2007 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
@@ -65,7 +65,7 @@
.\"
.\" @(#)ftp.1 8.3 (Berkeley) 10/9/94
.\"
-.Dd January 15, 2005
+.Dd July 18, 2007
.Dt FTP 1
.Os
.Sh NAME
@@ -87,6 +87,7 @@ Internet file transfer program
.Bk -words
.Op Fl q Ar quittime
.Ek
+.Op Fl s Ar srcaddr
.Bk -words
.Op Fl r Ar retry
.Ek
@@ -180,7 +181,7 @@ below for more information.
.Pp
Options may be specified at the command line, or to the
command interpreter.
-.Bl -tag -width "port "
+.Bl -tag -width Fl
.It Fl 4
Forces
.Nm
@@ -273,16 +274,20 @@ if the server does not support passive connections.
.It Fl P Ar port
Sets the port number to
.Ar port .
-.It Fl r Ar wait
-Retry the connection attempt if it failed, pausing for
-.Ar wait
-seconds.
.It Fl q Ar quittime
Quit if the connection has stalled for
.Ar quittime
seconds.
+.It Fl r Ar wait
+Retry the connection attempt if it failed, pausing for
+.Ar wait
+seconds.
.It Fl R
Restart all non-proxied auto-fetches.
+.It Fl s Ar srcaddr
+Uses
+.Ar srcaddr
+as the local IP address for all connections.
.It Fl t
Enables packet tracing.
.It Xo
@@ -352,8 +357,8 @@ is awaiting commands from the user the prompt
is provided to the user.
The following commands are recognized
by
-.Nm ftp :
-.Bl -tag -width Fl
+.Nm ftp :
+.Bl -tag -width Ic
.It Ic \&! Op Ar command Op Ar args
Invoke an interactive shell on the local machine.
If there are arguments, the first is taken to be a command to execute
@@ -456,10 +461,10 @@ when an ascii type transfer is made, these linefeeds may be
distinguished from a record delimiter only when
.Ic \&cr
is off.
-.It Ic debug Op Ar debug-value
+.It Ic ftp_debug Op Ar ftp_debug-value
Toggle debugging mode.
If an optional
-.Ar debug-value
+.Ar ftp_debug-value
is specified it is used to set the debugging level.
When debugging is on,
.Nm
@@ -614,8 +619,9 @@ transferring a
.Xr tar 1
archive of the subtree (in binary mode).
.It Ic hash Op Ar size
-Toggle hash-sign (``#'') printing for each data block
-transferred.
+Toggle hash-sign
+.Pq Sq #
+printing for each data block transferred.
The size of a data block defaults to 1024 bytes.
This can be changed by specifying
.Ar size
@@ -664,24 +670,49 @@ A synonym for
Define a macro.
Subsequent lines are stored as the macro
.Ar macro-name ;
-a null line (consecutive newline characters
-in a file or
-carriage returns from the terminal) terminates macro input mode.
+a null line (consecutive newline characters in a file or carriage
+returns from the terminal) terminates macro input mode.
There is a limit of 16 macros and 4096 total characters in all
defined macros.
-Macros remain defined until a
+Macro names can be a maximum of 8 characters.
+Macros are only applicable to the current session they are
+defined within (or if defined outside a session, to the session
+invoked with the next
+.Ic open
+command), and remain defined until a
.Ic close
command is executed.
-The macro processor interprets `$' and `\e' as special characters.
-A `$' followed by a number (or numbers) is replaced by the
+To invoke a macro, use the
+.Ic $
+command (see above).
+.Pp
+The macro processor interprets
+.Sq $
+and
+.Sq \e
+as special characters.
+A
+.Sq $
+followed by a number (or numbers) is replaced by the
corresponding argument on the macro invocation command line.
-A `$' followed by an `i' signals that macro processor that the
-executing macro is to be looped.
-On the first pass `$i' is
-replaced by the first argument on the macro invocation command line,
-on the second pass it is replaced by the second argument, and so on.
-A `\e' followed by any character is replaced by that character.
-Use the `\e' to prevent special treatment of the `$'.
+A
+.Sq $
+followed by an
+.Sq i
+signals the macro processor that the executing macro is to be
+looped.
+On the first pass
+.Dq $i
+is replaced by the first argument on the macro invocation command
+line, on the second pass it is replaced by the second argument,
+and so on.
+A
+.Sq \e
+followed by any character is replaced by that character.
+Use the
+.Sq \e
+to prevent special treatment of the
+.Sq $ .
.It Ic mdelete Op Ar remote-files
Delete the
.Ar remote-files
@@ -757,7 +788,9 @@ The default (and only supported)
mode is
.Dq stream .
.It Ic modtime Ar remote-file
-Show the last modification time of the file on the remote machine.
+Show the last modification time of the file on the remote machine, in
+.Li RFC2822
+format.
.It Ic more Ar file
A synonym for
.Ic page .
@@ -824,9 +857,18 @@ and
.Ic case
settings).
Variable templating is accomplished by including the
-sequences `$1', `$2', ..., `$9' in
+sequences
+.Dq $1 ,
+.Dq $2 ,
+\&...
+.Dq $9
+in
.Ar inpattern .
-Use `\\' to prevent this special treatment of the `$' character.
+Use
+.Sq \e
+to prevent this special treatment of the
+.Sq $
+character.
All other characters are treated literally, and are used to determine the
.Ic nmap
.Op Ar inpattern
@@ -838,13 +880,19 @@ $1.$2 and the remote file name "mydata.data", $1 would have the value
The
.Ar outpattern
determines the resulting mapped filename.
-The sequences `$1', `$2', ...., `$9' are replaced by any value resulting
-from the
+The sequences
+.Dq $1 ,
+.Dq $2 ,
+\&...
+.Dq $9
+are replaced by any value resulting from the
.Ar inpattern
template.
-The sequence `$0' is replace by the original filename.
+The sequence
+.Dq $0
+is replaced by the original filename.
Additionally, the sequence
-.Ql Op Ar seq1 , Ar seq2
+.Dq Op Ar seq1 , Ar seq2
is replaced by
.Op Ar seq1
if
@@ -863,9 +911,18 @@ the output filename "myfile.data" for input filenames "myfile.data" and
"myfile.myfile" for the input filename ".myfile".
Spaces may be included in
.Ar outpattern ,
-as in the example: `nmap $1 sed "s/ *$//" \*[Gt] $1' .
-Use the `\e' character to prevent special treatment
-of the `$','[',']', and `,' characters.
+as in the example:
+.Dl nmap $1 sed "s/ *$//" \*[Gt] $1
+Use the
+.Sq \e
+character to prevent special treatment
+of the
+.Sq $ ,
+.Sq \&[ ,
+.Sq \&] ,
+and
+.Sq \&,
+characters.
.It Ic ntrans Op Ar inchars Op Ar outchars
Set or unset the filename character translation mechanism.
If no arguments are specified, the filename character
@@ -953,7 +1010,7 @@ traffic.
servers are required to support the
.Dv PASV
command by
-.Li RFC 1123 ,
+.Li RFC1123 ,
some do not.)
.It Ic pdir Op Ar remote-path
Perform
@@ -1440,7 +1497,9 @@ A synonym for
.El
.Pp
Command arguments which have embedded spaces may be quoted with
-quote `"' marks.
+quote
+.Sq \&"
+marks.
.Pp
Commands which toggle settings can take an explicit
.Ic on
@@ -1566,7 +1625,7 @@ ascii or binary (respectively).
The default transfer type is binary.
.Pp
In order to be compliant with
-.Li RFC 1738 ,
+.Li RFC3986 ,
.Nm
interprets the
.Ar path
@@ -1619,7 +1678,7 @@ Any
.Sq Li \&% Ns Ar XX
codes
(per
-.Li RFC 1738 )
+.Li RFC3986 )
within the path components are decoded, with
.Ar XX
representing a character code in hexadecimal.
@@ -1744,6 +1803,26 @@ is in the URL, use them for the first attempt to authenticate.
A local URL, copied from
.Pa / Ns Ar path
on the local host.
+.\" about:
+.It Xo
+.Sm off
+.Li about:
+.Ar topic
+.Sm on
+.Xc
+Display information regarding
+.Ar topic ;
+no file is retrieved for this auto-fetched element.
+Supported values include:
+.Bl -tag -width "about:version"
+.It Li about:ftp
+Information about
+.Nm ftp .
+.It Li about:version
+The version of
+.Nm ftp .
+Useful to provide when reporting problems.
+.El
.El
.Pp
Unless noted otherwise above, and
@@ -1869,11 +1948,12 @@ A particularly
useful example of this mechanism is:
.Dq Li dir \&"\&" \&|more .
.It
-Failing the above checks, if ``globbing'' is enabled,
-local file names are expanded
-according to the rules used in the
+Failing the above checks, if
+.Dq globbing
+is enabled, local file names are expanded according to the rules
+used in the
.Xr csh 1 ;
-c.f. the
+see the
.Ic glob
command.
If the
@@ -2039,6 +2119,20 @@ next
.Pa .netrc
line and continue until a blank line (consecutive new-line
characters) is encountered.
+Like the other tokens in the
+.Pa .netrc
+file, a
+.Ic macdef
+is applicable only to the
+.Ic machine
+definition preceding it.
+A
+.Ic macdef
+entry cannot be utilized by multiple
+.Ic machine
+definitions; rather, it must be defined following each
+.Ic machine
+it is intended to be used with.
If a macro named
.Ic init
is defined, it is automatically executed as the last step in the
@@ -2249,7 +2343,7 @@ URL characters are required in the username or password
or
.Sq / ) ,
encode them with
-.Li RFC 1738
+.Li RFC3986
.Sq Li \&% Ns Ar XX
encoding.
.Pp
@@ -2292,16 +2386,27 @@ for an example of how to make this automatic.
.Xr ftpd 8
.Sh STANDARDS
.Nm
-attempts to be compliant with
-.Li RFC 959 ,
-.Li RFC 1123 ,
-.Li RFC 1738 ,
-.Li RFC 2068 ,
-.Li RFC 2389 ,
-.Li RFC 2428 ,
-.Li RFC 2732 ,
-and
-.Cm draft-ietf-ftpext-mlst-11 .
+attempts to be compliant with:
+.Bl -tag -offset indent -width 8n
+.It Li RFC0959
+.Em File Transfer Protocol
+.It Li RFC1123
+.Em Requirements for Internet Hosts - Application and Support
+.It Li RFC1635
+.Em How to Use Anonymous FTP
+.It Li RFC2389
+.Em Feature negotiation mechanism for the File Transfer Protocol
+.It Li RFC2428
+.Em FTP Extensions for IPv6 and NATs
+.It Li RFC2616
+.Em Hypertext Transfer Protocol -- HTTP/1.1
+.It Li RFC2822
+.Em Internet Message Format
+.It Li RFC3659
+.Em Extensions to FTP
+.It Li RFC3986
+.Em Uniform Resource Identifier (URI)
+.El
.Sh HISTORY
The
.Nm
diff --git a/net/tnftp/files/src/ftp.c b/net/tnftp/files/src/ftp.c
index 770685370a7..a94006b9ba1 100644
--- a/net/tnftp/files/src/ftp.c
+++ b/net/tnftp/files/src/ftp.c
@@ -1,8 +1,8 @@
-/* NetBSD: ftp.c,v 1.11 2005/06/10 04:05:01 lukem Exp */
-/* from NetBSD: ftp.c,v 1.134 2005/06/10 00:18:46 lukem Exp */
+/* $NetBSD: ftp.c,v 1.1.1.6 2007/08/06 04:33:23 lukem Exp $ */
+/* from NetBSD: ftp.c,v 1.152 2007/07/22 05:02:50 lukem Exp */
/*-
- * Copyright (c) 1996-2005 The NetBSD Foundation, Inc.
+ * Copyright (c) 1996-2007 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -96,9 +96,45 @@
*/
#include "tnftp.h"
+#include <arpa/telnet.h>
+
+#if 0 /* tnftp */
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)ftp.c 8.6 (Berkeley) 10/27/94";
+#else
+__RCSID(" NetBSD: ftp.c,v 1.152 2007/07/22 05:02:50 lukem Exp ");
+#endif
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <arpa/inet.h>
+#include <arpa/ftp.h>
#include <arpa/telnet.h>
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+#endif /* tnftp */
+
#include "ftp_var.h"
volatile sig_atomic_t abrtflag;
@@ -118,12 +154,12 @@ struct sockinet {
struct sockaddr_in6 su_sin6;
#endif
} si_su;
-#if !HAVE_SOCKADDR_SA_LEN
+#if !defined(HAVE_STRUCT_SOCKADDR_SA_LEN)
int si_len;
#endif
};
-#if !HAVE_SOCKADDR_SA_LEN
+#if !defined(HAVE_STRUCT_SOCKADDR_SA_LEN)
# define su_len si_len
#else
# define su_len si_su.su_sin.sin_len
@@ -140,7 +176,6 @@ hookup(char *host, char *port)
struct addrinfo hints, *res, *res0;
char hbuf[MAXHOSTNAMELEN];
static char hostnamebuf[MAXHOSTNAMELEN];
- char *cause = "unknown";
socklen_t len;
int on = 1;
@@ -154,7 +189,9 @@ hookup(char *host, char *port)
hints.ai_protocol = 0;
error = getaddrinfo(host, NULL, &hints, &res0);
if (error) {
- warnx("%s: %s", host, gai_strerror(error));
+ warnx("Can't lookup `%s': %s", host,
+ (error == EAI_SYSTEM) ? strerror(errno)
+ : gai_strerror(error));
code = -1;
return (0);
}
@@ -167,49 +204,22 @@ hookup(char *host, char *port)
hostname = hostnamebuf;
for (res = res0; res; res = res->ai_next) {
- /*
- * make sure that ai_addr is NOT an IPv4 mapped address.
- * IPv4 mapped address complicates too many things in FTP
- * protocol handling, as FTP protocol is defined differently
- * between IPv4 and IPv6.
- *
- * This may not be the best way to handle this situation,
- * since the semantics of IPv4 mapped address is defined in
- * the kernel. There are configurations where we should use
- * IPv4 mapped address as native IPv6 address, not as
- * "an IPv6 address that embeds IPv4 address" (namely, SIIT).
- *
- * More complete solution would be to have an additional
- * getsockopt to grab "real" peername/sockname. "real"
- * peername/sockname will be AF_INET if IPv4 mapped address
- * is used to embed IPv4 address, and will be AF_INET6 if
- * we use it as native. What a mess!
- */
ai_unmapped(res);
+ if (getnameinfo(res->ai_addr, res->ai_addrlen,
+ hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST))
+ strlcpy(hbuf, "?", sizeof(hbuf));
if (verbose && res0->ai_next) {
/* if we have multiple possibilities */
- if (getnameinfo(res->ai_addr, res->ai_addrlen,
- hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST))
- strlcpy(hbuf, "?", sizeof(hbuf));
fprintf(ttyout, "Trying %s...\n", hbuf);
}
((struct sockaddr_in *)res->ai_addr)->sin_port = htons(portnum);
s = socket(res->ai_family, SOCK_STREAM, res->ai_protocol);
if (s < 0) {
- cause = "socket";
+ warn("Can't create socket for connection to `%s'",
+ hbuf);
continue;
}
- error = xconnect(s, res->ai_addr, res->ai_addrlen);
- if (error) {
- /* this "if" clause is to prevent print warning twice */
- if (res->ai_next) {
- if (getnameinfo(res->ai_addr, res->ai_addrlen,
- hbuf, sizeof(hbuf), NULL, 0,
- NI_NUMERICHOST))
- strlcpy(hbuf, "?", sizeof(hbuf));
- warn("connect to address %s", hbuf);
- }
- cause = "connect";
+ if (ftp_connect(s, res->ai_addr, res->ai_addrlen) < 0) {
close(s);
s = -1;
continue;
@@ -219,7 +229,7 @@ hookup(char *host, char *port)
break;
}
if (s < 0) {
- warn("%s", cause);
+ warnx("Can't connect to `%s'", host);
code = -1;
freeaddrinfo(res0);
return 0;
@@ -231,7 +241,7 @@ hookup(char *host, char *port)
len = hisctladdr.su_len;
if (getsockname(s, (struct sockaddr *)&myctladdr.si_su, &len) == -1) {
- warn("getsockname");
+ warn("Can't determine my address of connection to `%s'", host);
code = -1;
goto bad;
}
@@ -242,8 +252,7 @@ hookup(char *host, char *port)
int tos = IPTOS_LOWDELAY;
if (setsockopt(s, IPPROTO_IP, IP_TOS,
(void *)&tos, sizeof(tos)) == -1) {
- if (debug)
- warn("setsockopt %s (ignored)",
+ DWARN("setsockopt %s (ignored)",
"IPTOS_LOWDELAY");
}
}
@@ -251,7 +260,7 @@ hookup(char *host, char *port)
cin = fdopen(s, "r");
cout = fdopen(s, "w");
if (cin == NULL || cout == NULL) {
- warnx("fdopen failed.");
+ warnx("Can't fdopen socket");
if (cin)
(void)fclose(cin);
if (cout)
@@ -272,8 +281,7 @@ hookup(char *host, char *port)
if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE,
(void *)&on, sizeof(on)) == -1) {
- if (debug)
- warn("setsockopt %s (ignored)", "SO_OOBINLINE");
+ DWARN("setsockopt %s (ignored)", "SO_OOBINLINE");
}
return (hostname);
@@ -319,7 +327,8 @@ command(const char *fmt, ...)
int r;
sigfunc oldsigint;
- if (debug) {
+#ifndef NO_DEBUG
+ if (ftp_debug) {
fputs("---> ", ttyout);
va_start(ap, fmt);
if (strncmp("PASS ", fmt, 5) == 0)
@@ -331,8 +340,9 @@ command(const char *fmt, ...)
va_end(ap);
putc('\n', ttyout);
}
+#endif
if (cout == NULL) {
- warnx("No control connection for command.");
+ warnx("No control connection for command");
code = -1;
return (0);
}
@@ -354,6 +364,12 @@ command(const char *fmt, ...)
return (r);
}
+static const char *m421[] = {
+ "remote server timed out. Connection closed",
+ "user interrupt. Connection closed",
+ "remote server has closed connection",
+};
+
int
getreply(int expecteof)
{
@@ -374,7 +390,8 @@ getreply(int expecteof)
for (line = 0 ;; line++) {
dig = n = code = 0;
cp = current_line;
- while (alarmtimer(60),((c = getc(cin)) != '\n')) {
+ while (alarmtimer(quit_time ? quit_time : 60),
+ ((c = getc(cin)) != '\n')) {
if (c == IAC) { /* handle telnet commands */
switch (c = getc(cin)) {
case WILL:
@@ -413,18 +430,15 @@ getreply(int expecteof)
cpend = 0;
lostpeer(0);
if (verbose) {
+ size_t midx;
if (reply_timeoutflag)
- fputs(
- "421 Service not available, remote server timed out. Connection closed\n",
- ttyout);
+ midx = 0;
else if (reply_abrtflag)
- fputs(
- "421 Service not available, user interrupt. Connection closed.\n",
- ttyout);
+ midx = 1;
else
- fputs(
- "421 Service not available, remote server has closed connection.\n",
- ttyout);
+ midx = 2;
+ (void)fprintf(ttyout,
+ "421 Service not available, %s.\n", m421[midx]);
(void)fflush(ttyout);
}
code = 421;
@@ -473,7 +487,7 @@ getreply(int expecteof)
if (verbose > 0 || ((verbose > -1 && n == '5') &&
(n < '5' || !retry_connect))) {
(void)putc(c, ttyout);
- (void)fflush (ttyout);
+ (void)fflush(ttyout);
}
if (cp[-1] == '\r')
cp[-1] = '\0';
@@ -521,7 +535,7 @@ empty(FILE *cin, FILE *din, int sec)
pfd[nfd++].events = POLLIN;
}
- if ((nr = xpoll(pfd, nfd, sec * 1000)) <= 0)
+ if ((nr = ftp_poll(pfd, nfd, sec * 1000)) <= 0)
return nr;
nr = 0;
@@ -553,8 +567,7 @@ abortxfer(int notused)
strlcpy(msgbuf, "\nsend", sizeof(msgbuf));
break;
default:
- errx(1, "abortxfer called with unknown direction `%s'",
- direction);
+ errx(1, "abortxfer: unknown direction `%s'", direction);
}
len = strlcat(msgbuf, " aborted. Waiting for remote to finish abort.\n",
sizeof(msgbuf));
@@ -562,30 +575,108 @@ abortxfer(int notused)
siglongjmp(xferabort, 1);
}
+/*
+ * Read data from infd & write to outfd, using buf/bufsize as the temporary
+ * buffer, dealing with short writes.
+ * If rate_limit != 0, rate-limit the transfer.
+ * If hash_interval != 0, fputc('c', ttyout) every hash_interval bytes.
+ * Updates global variables: bytes.
+ * Returns 0 if ok, 1 if there was a read error, 2 if there was a write error.
+ * In the case of error, errno contains the appropriate error code.
+ */
+static int
+copy_bytes(int infd, int outfd, char *buf, size_t bufsize,
+ int rate_limit, int hash_interval)
+{
+ volatile off_t hashc;
+ ssize_t inc, outc;
+ char *bufp;
+ struct timeval tvthen, tvnow, tvdiff;
+ off_t bufrem, bufchunk;
+ int serr;
+
+ hashc = hash_interval;
+ if (rate_limit)
+ bufchunk = rate_limit;
+ else
+ bufchunk = bufsize;
+
+ while (1) {
+ if (rate_limit) {
+ (void)gettimeofday(&tvthen, NULL);
+ }
+ errno = 0;
+ inc = outc = 0;
+ /* copy bufchunk at a time */
+ bufrem = bufchunk;
+ while (bufrem > 0) {
+ inc = read(infd, buf, MIN(bufsize, bufrem));
+ if (inc <= 0)
+ goto copy_done;
+ bytes += inc;
+ bufrem -= inc;
+ bufp = buf;
+ while (inc > 0) {
+ outc = write(outfd, bufp, inc);
+ if (outc < 0)
+ goto copy_done;
+ inc -= outc;
+ bufp += outc;
+ }
+ if (hash_interval) {
+ while (bytes >= hashc) {
+ (void)putc('#', ttyout);
+ hashc += hash_interval;
+ }
+ (void)fflush(ttyout);
+ }
+ }
+ if (rate_limit) { /* rate limited; wait if necessary */
+ while (1) {
+ (void)gettimeofday(&tvnow, NULL);
+ timersub(&tvnow, &tvthen, &tvdiff);
+ if (tvdiff.tv_sec > 0)
+ break;
+ usleep(1000000 - tvdiff.tv_usec);
+ }
+ }
+ }
+
+ copy_done:
+ serr = errno;
+ if (hash_interval && bytes > 0) {
+ if (bytes < hash_interval)
+ (void)putc('#', ttyout);
+ (void)putc('\n', ttyout);
+ (void)fflush(ttyout);
+ }
+ errno = serr;
+ if (inc == -1)
+ return 1;
+ if (outc == -1)
+ return 2;
+
+ return 0;
+}
+
void
sendrequest(const char *cmd, const char *local, const char *remote,
int printnames)
{
struct stat st;
- int c, d;
- FILE *fin, *dout;
- int (*closefunc)(FILE *);
- sigfunc oldintr, oldintp;
- volatile off_t hashbytes;
- char *lmode, *bufp;
+ int c;
+ FILE *volatile fin;
+ FILE *volatile dout;
+ int (*volatile closefunc)(FILE *);
+ sigfunc volatile oldintr;
+ sigfunc volatile oldintp;
+ off_t volatile hashbytes;
+ int hash_interval;
+ char *volatile lmode;
static size_t bufsize;
static char *buf;
int oprogress;
-#ifdef __GNUC__ /* to shut up gcc warnings */
- (void)&fin;
- (void)&dout;
- (void)&closefunc;
- (void)&oldintr;
- (void)&oldintp;
- (void)&lmode;
-#endif
-
hashbytes = mark;
direction = "sent";
dout = NULL;
@@ -593,7 +684,7 @@ sendrequest(const char *cmd, const char *local, const char *remote,
filesize = -1;
oprogress = progress;
if (verbose && printnames) {
- if (local && *local != '-')
+ if (*local != '-')
fprintf(ttyout, "local: %s ", local);
if (remote)
fprintf(ttyout, "remote: %s\n", remote);
@@ -623,7 +714,7 @@ sendrequest(const char *cmd, const char *local, const char *remote,
oldintp = xsignal(SIGPIPE, SIG_IGN);
fin = popen(local + 1, "r");
if (fin == NULL) {
- warn("%s", local + 1);
+ warn("Can't execute `%s'", local + 1);
code = -1;
goto cleanupsend;
}
@@ -632,7 +723,7 @@ sendrequest(const char *cmd, const char *local, const char *remote,
} else {
fin = fopen(local, "r");
if (fin == NULL) {
- warn("local: %s", local);
+ warn("Can't open `%s'", local);
code = -1;
goto cleanupsend;
}
@@ -666,7 +757,7 @@ sendrequest(const char *cmd, const char *local, const char *remote,
break;
}
if (rc < 0) {
- warn("local: %s", local);
+ warn("Can't seek to restart `%s'", local);
goto cleanupsend;
}
if (command("REST " LLF, (LLT)restart_point) != CONTINUE)
@@ -689,86 +780,24 @@ sendrequest(const char *cmd, const char *local, const char *remote,
if (buf)
(void)free(buf);
bufsize = sndbuf_size;
- buf = xmalloc(bufsize);
+ buf = ftp_malloc(bufsize);
}
progressmeter(-1);
oldintp = xsignal(SIGPIPE, SIG_IGN);
+ hash_interval = (hash && (!progress || filesize < 0)) ? mark : 0;
switch (curtype) {
case TYPE_I:
case TYPE_L:
- if (rate_put) { /* rate limited */
- while (1) {
- struct timeval then, now, td;
- off_t bufrem;
-
- (void)gettimeofday(&then, NULL);
- errno = c = d = 0;
- bufrem = rate_put;
- while (bufrem > 0) {
- if ((c = read(fileno(fin), buf,
- MIN(bufsize, bufrem))) <= 0)
- goto senddone;
- bytes += c;
- bufrem -= c;
- for (bufp = buf; c > 0;
- c -= d, bufp += d)
- if ((d = write(fileno(dout),
- bufp, c)) <= 0)
- break;
- if (d < 0)
- goto senddone;
- if (hash &&
- (!progress || filesize < 0) ) {
- while (bytes >= hashbytes) {
- (void)putc('#', ttyout);
- hashbytes += mark;
- }
- (void)fflush(ttyout);
- }
- }
- while (1) {
- (void)gettimeofday(&now, NULL);
- timersub(&now, &then, &td);
- if (td.tv_sec > 0)
- break;
- usleep(1000000 - td.tv_usec);
- }
- }
- } else { /* simpler/faster; no rate limit */
- while (1) {
- errno = c = d = 0;
- if ((c = read(fileno(fin), buf, bufsize)) <= 0)
- goto senddone;
- bytes += c;
- for (bufp = buf; c > 0; c -= d, bufp += d)
- if ((d = write(fileno(dout), bufp, c))
- <= 0)
- break;
- if (d < 0)
- goto senddone;
- if (hash && (!progress || filesize < 0) ) {
- while (bytes >= hashbytes) {
- (void)putc('#', ttyout);
- hashbytes += mark;
- }
- (void)fflush(ttyout);
- }
- }
- }
- senddone:
- if (hash && (!progress || filesize < 0) && bytes > 0) {
- if (bytes < mark)
- (void)putc('#', ttyout);
- (void)putc('\n', ttyout);
- }
- if (c < 0)
- warn("local: %s", local);
- if (d < 0) {
+ c = copy_bytes(fileno(fin), fileno(dout), buf, bufsize,
+ rate_put, hash_interval);
+ if (c == 1) {
+ warn("Reading `%s'", local);
+ } else if (c == 2) {
if (errno != EPIPE)
- warn("netout");
+ warn("Writing to network");
bytes = -1;
}
break;
@@ -776,8 +805,7 @@ sendrequest(const char *cmd, const char *local, const char *remote,
case TYPE_A:
while ((c = getc(fin)) != EOF) {
if (c == '\n') {
- while (hash && (!progress || filesize < 0) &&
- (bytes >= hashbytes)) {
+ while (hash_interval && bytes >= hashbytes) {
(void)putc('#', ttyout);
(void)fflush(ttyout);
hashbytes += mark;
@@ -789,23 +817,23 @@ sendrequest(const char *cmd, const char *local, const char *remote,
}
(void)putc(c, dout);
bytes++;
-#if 0 /* this violates RFC */
+#if 0 /* this violates RFC0959 */
if (c == '\r') {
(void)putc('\0', dout);
bytes++;
}
#endif
}
- if (hash && (!progress || filesize < 0)) {
+ if (hash_interval) {
if (bytes < hashbytes)
(void)putc('#', ttyout);
(void)putc('\n', ttyout);
}
if (ferror(fin))
- warn("local: %s", local);
+ warn("Reading `%s'", local);
if (ferror(dout)) {
if (errno != EPIPE)
- warn("netout");
+ warn("Writing to network");
bytes = -1;
}
break;
@@ -862,32 +890,28 @@ sendrequest(const char *cmd, const char *local, const char *remote,
}
void
-recvrequest(const char *cmd, const char *local, const char *remote,
+recvrequest(const char *cmd, const char *volatile local, const char *remote,
const char *lmode, int printnames, int ignorespecial)
{
- FILE *fout, *din;
- int (*closefunc)(FILE *);
- sigfunc oldintr, oldintp;
+ FILE *volatile fout;
+ FILE *volatile din;
+ int (*volatile closefunc)(FILE *);
+ sigfunc volatile oldintr;
+ sigfunc volatile oldintp;
int c, d;
- volatile int is_retr, tcrflag, bare_lfs;
+ int volatile is_retr;
+ int volatile tcrflag;
+ int volatile bare_lfs;
static size_t bufsize;
static char *buf;
- volatile off_t hashbytes;
+ off_t volatile hashbytes;
+ int hash_interval;
struct stat st;
time_t mtime;
struct timeval tval[2];
int oprogress;
int opreserve;
-#ifdef __GNUC__ /* to shut up gcc warnings */
- (void)&local;
- (void)&fout;
- (void)&din;
- (void)&closefunc;
- (void)&oldintr;
- (void)&oldintp;
-#endif
-
fout = NULL;
din = NULL;
hashbytes = mark;
@@ -899,7 +923,7 @@ recvrequest(const char *cmd, const char *local, const char *remote,
opreserve = preserve;
is_retr = (strcmp(cmd, "RETR") == 0);
if (is_retr && verbose && printnames) {
- if (local && (ignorespecial || *local != '-'))
+ if (ignorespecial || *local != '-')
fprintf(ttyout, "local: %s ", local);
if (remote)
fprintf(ttyout, "remote: %s\n", remote);
@@ -925,7 +949,7 @@ recvrequest(const char *cmd, const char *local, const char *remote,
char *dir = strrchr(local, '/');
if (errno != ENOENT && errno != EACCES) {
- warn("local: %s", local);
+ warn("Can't access `%s'", local);
code = -1;
goto cleanuprecv;
}
@@ -936,13 +960,13 @@ recvrequest(const char *cmd, const char *local, const char *remote,
if (dir != NULL)
*dir = '/';
if (d < 0) {
- warn("local: %s", local);
+ warn("Can't access `%s'", local);
code = -1;
goto cleanuprecv;
}
if (!runique && errno == EACCES &&
chmod(local, (S_IRUSR|S_IWUSR)) < 0) {
- warn("local: %s", local);
+ warn("Can't chmod `%s'", local);
code = -1;
goto cleanuprecv;
}
@@ -994,7 +1018,7 @@ recvrequest(const char *cmd, const char *local, const char *remote,
oldintp = xsignal(SIGPIPE, SIG_IGN);
fout = popen(local + 1, "w");
if (fout == NULL) {
- warn("%s", local+1);
+ warn("Can't execute `%s'", local+1);
goto abort;
}
progress = 0;
@@ -1003,7 +1027,7 @@ recvrequest(const char *cmd, const char *local, const char *remote,
} else {
fout = fopen(local, lmode);
if (fout == NULL) {
- warn("local: %s", local);
+ warn("Can't open `%s'", local);
goto abort;
}
closefunc = fclose;
@@ -1017,10 +1041,11 @@ recvrequest(const char *cmd, const char *local, const char *remote,
if (buf)
(void)free(buf);
bufsize = rcvbuf_size;
- buf = xmalloc(bufsize);
+ buf = ftp_malloc(bufsize);
}
progressmeter(-1);
+ hash_interval = (hash && (!progress || filesize < 0)) ? mark : 0;
switch (curtype) {
@@ -1028,76 +1053,17 @@ recvrequest(const char *cmd, const char *local, const char *remote,
case TYPE_L:
if (is_retr && restart_point &&
lseek(fileno(fout), restart_point, SEEK_SET) < 0) {
- warn("local: %s", local);
+ warn("Can't seek to restart `%s'", local);
goto cleanuprecv;
}
- if (rate_get) { /* rate limiting */
- while (1) {
- struct timeval then, now, td;
- off_t bufrem;
-
- (void)gettimeofday(&then, NULL);
- errno = c = d = 0;
- for (bufrem = rate_get; bufrem > 0; ) {
- if ((c = read(fileno(din), buf,
- MIN(bufsize, bufrem))) <= 0)
- goto recvdone;
- bytes += c;
- bufrem -=c;
- if ((d = write(fileno(fout), buf, c))
- != c)
- goto recvdone;
- if (hash &&
- (!progress || filesize < 0)) {
- while (bytes >= hashbytes) {
- (void)putc('#', ttyout);
- hashbytes += mark;
- }
- (void)fflush(ttyout);
- }
- }
- /* sleep until time is up */
- while (1) {
- (void)gettimeofday(&now, NULL);
- timersub(&now, &then, &td);
- if (td.tv_sec > 0)
- break;
- usleep(1000000 - td.tv_usec);
- }
- }
- } else { /* faster code (no limiting) */
- while (1) {
- errno = c = d = 0;
- if ((c = read(fileno(din), buf, bufsize)) <= 0)
- goto recvdone;
- bytes += c;
- if ((d = write(fileno(fout), buf, c)) != c)
- goto recvdone;
- if (hash && (!progress || filesize < 0)) {
- while (bytes >= hashbytes) {
- (void)putc('#', ttyout);
- hashbytes += mark;
- }
- (void)fflush(ttyout);
- }
- }
- }
- recvdone:
- if (hash && (!progress || filesize < 0) && bytes > 0) {
- if (bytes < mark)
- (void)putc('#', ttyout);
- (void)putc('\n', ttyout);
- }
- if (c < 0) {
+ c = copy_bytes(fileno(din), fileno(fout), buf, bufsize,
+ rate_get, hash_interval);
+ if (c == 1) {
if (errno != EPIPE)
- warn("netin");
+ warn("Reading from network");
bytes = -1;
- }
- if (d < c) {
- if (d < 0)
- warn("local: %s", local);
- else
- warnx("%s: short write", local);
+ } else if (c == 2) {
+ warn("Writing `%s'", local);
}
break;
@@ -1116,7 +1082,7 @@ recvrequest(const char *cmd, const char *local, const char *remote,
}
if (fseeko(fout, (off_t)0, SEEK_CUR) < 0) {
done:
- warn("local: %s", local);
+ warn("Can't seek to restart `%s'", local);
goto cleanuprecv;
}
}
@@ -1124,8 +1090,7 @@ recvrequest(const char *cmd, const char *local, const char *remote,
if (c == '\n')
bare_lfs++;
while (c == '\r') {
- while (hash && (!progress || filesize < 0) &&
- (bytes >= hashbytes)) {
+ while (hash_interval && bytes >= hashbytes) {
(void)putc('#', ttyout);
(void)fflush(ttyout);
hashbytes += mark;
@@ -1148,18 +1113,18 @@ recvrequest(const char *cmd, const char *local, const char *remote,
contin2: ;
}
break2:
- if (hash && (!progress || filesize < 0)) {
+ if (hash_interval) {
if (bytes < hashbytes)
(void)putc('#', ttyout);
(void)putc('\n', ttyout);
}
if (ferror(din)) {
if (errno != EPIPE)
- warn("netin");
+ warn("Reading from network");
bytes = -1;
}
if (ferror(fout))
- warn("local: %s", local);
+ warn("Writing `%s'", local);
break;
}
@@ -1189,7 +1154,8 @@ recvrequest(const char *cmd, const char *local, const char *remote,
if (utimes(local, tval) == -1) {
fprintf(ttyout,
"Can't change modification time on %s to %s",
- local, asctime(localtime(&mtime)));
+ local,
+ rfc2822time(localtime(&mtime)));
}
}
}
@@ -1198,7 +1164,7 @@ recvrequest(const char *cmd, const char *local, const char *remote,
abort:
/*
- * abort using RFC 959 recommended IP,SYNC sequence
+ * abort using RFC0959 recommended IP,SYNC sequence
*/
if (! sigsetjmp(xferabort, 1)) {
/* this is the first call */
@@ -1246,34 +1212,44 @@ initconn(void)
unsigned int af, hal, pal;
socklen_t len;
char *pasvcmd = NULL;
+ int overbose;
#ifdef INET6
- if (myctladdr.su_family == AF_INET6 && debug &&
+#ifndef NO_DEBUG
+ if (myctladdr.su_family == AF_INET6 && ftp_debug &&
(IN6_IS_ADDR_LINKLOCAL(&myctladdr.si_su.su_sin6.sin6_addr) ||
IN6_IS_ADDR_SITELOCAL(&myctladdr.si_su.su_sin6.sin6_addr))) {
- warnx("use of scoped address can be troublesome");
+ warnx("Use of scoped addresses can be troublesome");
}
#endif
+#endif
+
reinit:
if (passivemode) {
data_addr = myctladdr;
data = socket(data_addr.su_family, SOCK_STREAM, 0);
if (data < 0) {
- warn("socket");
+ warn("Can't create socket for data connection");
return (1);
}
if ((options & SO_DEBUG) &&
setsockopt(data, SOL_SOCKET, SO_DEBUG,
(void *)&on, sizeof(on)) == -1) {
- if (debug)
- warn("setsockopt %s (ignored)", "SO_DEBUG");
+ DWARN("setsockopt %s (ignored)", "SO_DEBUG");
}
result = COMPLETE + 1;
switch (data_addr.su_family) {
case AF_INET:
if (epsv4 && !epsv4bad) {
pasvcmd = "EPSV";
+ overbose = verbose;
+ if (ftp_debug == 0)
+ verbose = -1;
result = command("EPSV");
+ verbose = overbose;
+ if (verbose > 0 &&
+ (result == COMPLETE || !connected))
+ fprintf(ttyout, "%s\n", reply_string);
if (!connected)
return (1);
/*
@@ -1288,10 +1264,8 @@ initconn(void)
}
if (result != COMPLETE) {
epsv4bad = 1;
- if (debug)
- fputs(
- "disabling epsv4 for this connection\n",
- ttyout);
+ DPRINTF("disabling epsv4 for this "
+ "connection\n");
}
}
if (result != COMPLETE) {
@@ -1304,7 +1278,14 @@ initconn(void)
#ifdef INET6
case AF_INET6:
pasvcmd = "EPSV";
+ overbose = verbose;
+ if (ftp_debug == 0)
+ verbose = -1;
result = command("EPSV");
+ verbose = overbose;
+ if (verbose > 0 &&
+ (result == COMPLETE || !connected))
+ fprintf(ttyout, "%s\n", reply_string);
if (!connected)
return (1);
/* this code is to be friendly with broken BSDI ftpd */
@@ -1484,8 +1465,8 @@ initconn(void)
} else
goto bad;
- while (xconnect(data, (struct sockaddr *)&data_addr.si_su,
- data_addr.su_len) < 0) {
+ if (ftp_connect(data, (struct sockaddr *)&data_addr.si_su,
+ data_addr.su_len) < 0) {
if (activefallback) {
(void)close(data);
data = -1;
@@ -1495,7 +1476,6 @@ initconn(void)
#endif
goto reinit;
}
- warn("connect for data channel");
goto bad;
}
#ifdef IPTOS_THROUGHPUT
@@ -1503,9 +1483,8 @@ initconn(void)
on = IPTOS_THROUGHPUT;
if (setsockopt(data, IPPROTO_IP, IP_TOS,
(void *)&on, sizeof(on)) == -1) {
- if (debug)
- warn("setsockopt %s (ignored)",
- "IPTOS_THROUGHPUT");
+ DWARN("setsockopt %s (ignored)",
+ "IPTOS_THROUGHPUT");
}
}
#endif
@@ -1520,7 +1499,7 @@ initconn(void)
(void)close(data);
data = socket(data_addr.su_family, SOCK_STREAM, 0);
if (data < 0) {
- warn("socket");
+ warn("Can't create socket for data connection");
if (tmpno)
sendport = 1;
return (1);
@@ -1528,29 +1507,28 @@ initconn(void)
if (!sendport)
if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR,
(void *)&on, sizeof(on)) == -1) {
- warn("setsockopt %s", "SO_REUSEADDR");
+ warn("Can't set SO_REUSEADDR on data connection");
goto bad;
}
if (bind(data, (struct sockaddr *)&data_addr.si_su,
data_addr.su_len) < 0) {
- warn("bind");
+ warn("Can't bind for data connection");
goto bad;
}
if ((options & SO_DEBUG) &&
setsockopt(data, SOL_SOCKET, SO_DEBUG,
(void *)&on, sizeof(on)) == -1) {
- if (debug)
- warn("setsockopt %s (ignored)", "SO_DEBUG");
+ DWARN("setsockopt %s (ignored)", "SO_DEBUG");
}
len = sizeof(data_addr.si_su);
memset((char *)&data_addr, 0, sizeof (data_addr));
if (getsockname(data, (struct sockaddr *)&data_addr.si_su, &len) == -1) {
- warn("getsockname");
+ warn("Can't determine my address of data connection");
goto bad;
}
data_addr.su_len = len;
- if (xlisten(data, 1) < 0)
- warn("listen");
+ if (ftp_listen(data, 1) < 0)
+ warn("Can't listen to data connection");
if (sendport) {
char hname[NI_MAXHOST], sname[NI_MAXSERV];
@@ -1578,16 +1556,21 @@ initconn(void)
sizeof(sname), NI_NUMERICHOST | NI_NUMERICSERV)) {
result = ERROR;
} else {
+ overbose = verbose;
+ if (ftp_debug == 0)
+ verbose = -1;
result = command("EPRT |%d|%s|%s|", af, hname,
sname);
+ verbose = overbose;
+ if (verbose > 0 &&
+ (result == COMPLETE || !connected))
+ fprintf(ttyout, "%s\n", reply_string);
if (!connected)
return (1);
if (result != COMPLETE) {
epsv4bad = 1;
- if (debug)
- fputs(
- "disabling epsv4 for this connection\n",
- ttyout);
+ DPRINTF("disabling epsv4 for this "
+ "connection\n");
}
}
break;
@@ -1641,9 +1624,7 @@ initconn(void)
on = IPTOS_THROUGHPUT;
if (setsockopt(data, IPPROTO_IP, IP_TOS,
(void *)&on, sizeof(on)) == -1)
- if (debug)
- warn("setsockopt %s (ignored)",
- "IPTOS_THROUGHPUT");
+ DWARN("setsockopt %s (ignored)", "IPTOS_THROUGHPUT");
}
#endif
return (0);
@@ -1688,14 +1669,14 @@ dataconn(const char *lmode)
timeout = td.tv_sec * 1000 + td.tv_usec/1000;
if (timeout < 0)
timeout = 0;
- rv = xpoll(pfd, 1, timeout);
+ rv = ftp_poll(pfd, 1, timeout);
} while (rv == -1 && errno == EINTR); /* loop until poll ! EINTR */
if (rv == -1) {
- warn("poll waiting before accept");
+ warn("Can't poll waiting before accept");
goto dataconn_failed;
}
if (rv == 0) {
- warn("poll timeout waiting before accept");
+ warnx("Poll timeout waiting before accept");
goto dataconn_failed;
}
@@ -1705,7 +1686,7 @@ dataconn(const char *lmode)
s = accept(data, (struct sockaddr *) &from.si_su, &fromlen);
} while (s == -1 && errno == EINTR); /* loop until accept ! EINTR */
if (s == -1) {
- warn("accept");
+ warn("Can't accept data connection");
goto dataconn_failed;
}
@@ -1719,9 +1700,7 @@ dataconn(const char *lmode)
int tos = IPTOS_THROUGHPUT;
if (setsockopt(s, IPPROTO_IP, IP_TOS,
(void *)&tos, sizeof(tos)) == -1) {
- if (debug)
- warn("setsockopt %s (ignored)",
- "IPTOS_THROUGHPUT");
+ DWARN("setsockopt %s (ignored)", "IPTOS_THROUGHPUT");
}
}
#endif
@@ -1848,15 +1827,10 @@ abortpt(int notused)
void
proxtrans(const char *cmd, const char *local, const char *remote)
{
- sigfunc oldintr;
+ sigfunc volatile oldintr;
int prox_type, nfnd;
- volatile int secndflag;
- char *cmd2;
-
-#ifdef __GNUC__ /* to shut up gcc warnings */
- (void)&oldintr;
- (void)&cmd2;
-#endif
+ int volatile secndflag;
+ char *volatile cmd2;
oldintr = NULL;
secndflag = 0;
@@ -1960,7 +1934,7 @@ proxtrans(const char *cmd, const char *local, const char *remote)
if (cpend) {
if ((nfnd = empty(cin, NULL, 10)) <= 0) {
if (nfnd < 0)
- warn("abort");
+ warn("Error aborting proxy command");
if (ptabflg)
code = -1;
lostpeer(0);
@@ -1982,13 +1956,13 @@ reset(int argc, char *argv[])
int nfnd = 1;
if (argc == 0 && argv != NULL) {
- fprintf(ttyout, "usage: %s\n", argv[0]);
+ UPRINTF("usage: %s\n", argv[0]);
code = -1;
return;
}
while (nfnd > 0) {
if ((nfnd = empty(cin, NULL, 0)) < 0) {
- warn("reset");
+ warn("Error resetting connection");
code = -1;
lostpeer(0);
} else if (nfnd)
@@ -2010,7 +1984,7 @@ gunique(const char *local)
if (cp)
*cp = '/';
if (d < 0) {
- warn("local: %s", local);
+ warn("Can't access `%s'", local);
return (NULL);
}
len = strlcpy(new, local, sizeof(new));
@@ -2070,7 +2044,7 @@ abort_remote(FILE *din)
int nfnd;
if (cout == NULL) {
- warnx("Lost control connection for abort.");
+ warnx("Lost control connection for abort");
if (ptabflg)
code = -1;
lostpeer(0);
@@ -2084,12 +2058,12 @@ abort_remote(FILE *din)
buf[1] = IP;
buf[2] = IAC;
if (send(fileno(cout), buf, 3, MSG_OOB) != 3)
- warn("abort");
+ warn("Can't send abort message");
fprintf(cout, "%cABOR\r\n", DM);
(void)fflush(cout);
if ((nfnd = empty(cin, din, 10)) <= 0) {
if (nfnd < 0)
- warn("abort");
+ warn("Can't send abort message");
if (ptabflg)
code = -1;
lostpeer(0);
@@ -2105,6 +2079,24 @@ abort_remote(FILE *din)
(void)getreply(0);
}
+/*
+ * Ensure that ai->ai_addr is NOT an IPv4 mapped address.
+ * IPv4 mapped address complicates too many things in FTP
+ * protocol handling, as FTP protocol is defined differently
+ * between IPv4 and IPv6.
+ *
+ * This may not be the best way to handle this situation,
+ * since the semantics of IPv4 mapped address is defined in
+ * the kernel. There are configurations where we should use
+ * IPv4 mapped address as native IPv6 address, not as
+ * "an IPv6 address that embeds IPv4 address" (namely, SIIT).
+ *
+ * More complete solution would be to have an additional
+ * getsockopt to grab "real" peername/sockname. "real"
+ * peername/sockname will be AF_INET if IPv4 mapped address
+ * is used to embed IPv4 address, and will be AF_INET6 if
+ * we use it as native. What a mess!
+ */
void
ai_unmapped(struct addrinfo *ai)
{
@@ -2130,10 +2122,18 @@ ai_unmapped(struct addrinfo *ai)
sin.sin_port = sin6->sin6_port;
ai->ai_family = AF_INET;
-#if HAVE_SOCKADDR_SA_LEN
+#if defined(HAVE_STRUCT_SOCKADDR_SA_LEN)
sin.sin_len = len;
#endif
memcpy(ai->ai_addr, &sin, len);
ai->ai_addrlen = len;
#endif
}
+
+#ifdef NO_USAGE
+void
+xusage(void)
+{
+ fputs("Usage error\n", ttyout);
+}
+#endif
diff --git a/net/tnftp/files/src/ftp.cat1 b/net/tnftp/files/src/ftp.cat1
index ae1d6fb32df..4ce9af518a0 100644
--- a/net/tnftp/files/src/ftp.cat1
+++ b/net/tnftp/files/src/ftp.cat1
@@ -5,7 +5,7 @@ NNAAMMEE
SSYYNNOOPPSSIISS
ffttpp [--4466AAaaddeeffggiinnppRRttvvVV] [--NN _n_e_t_r_c] [--oo _o_u_t_p_u_t] [--PP _p_o_r_t] [--qq _q_u_i_t_t_i_m_e]
- [--rr _r_e_t_r_y] [--TT _d_i_r,_m_a_x[,_i_n_c]] [[_u_s_e_r@]_h_o_s_t [_p_o_r_t]]
+ [--ss _s_r_c_a_d_d_r] [--rr _r_e_t_r_y] [--TT _d_i_r,_m_a_x[,_i_n_c]] [[_u_s_e_r@]_h_o_s_t [_p_o_r_t]]
[[_u_s_e_r@]_h_o_s_t:[_p_a_t_h][/]] [file:///_p_a_t_h]
[ftp://[_u_s_e_r[:_p_a_s_s_w_o_r_d]@]_h_o_s_t[:_p_o_r_t]/_p_a_t_h[/][;type=_X]]
[http://[_u_s_e_r[:_p_a_s_s_w_o_r_d]@]_h_o_s_t[:_p_o_r_t]/_p_a_t_h] [_._._.]
@@ -23,88 +23,92 @@ DDEESSCCRRIIPPTTIIOONN
Options may be specified at the command line, or to the command inter-
preter.
- --44 Forces ffttpp to only use IPv4 addresses.
+ --44 Forces ffttpp to only use IPv4 addresses.
- --66 Forces ffttpp to only use IPv6 addresses.
+ --66 Forces ffttpp to only use IPv6 addresses.
- --AA Force active mode ftp. By default, ffttpp will try to use passive
- mode ftp and fall back to active mode if passive is not sup-
- ported by the server. This option causes ffttpp to always use an
- active connection. It is only useful for connecting to very old
- servers that do not implement passive mode properly.
+ --AA Force active mode ftp. By default, ffttpp will try to use pas-
+ sive mode ftp and fall back to active mode if passive is not
+ supported by the server. This option causes ffttpp to always
+ use an active connection. It is only useful for connecting
+ to very old servers that do not implement passive mode prop-
+ erly.
- --aa Causes ffttpp to bypass normal login procedure, and use an anony-
- mous login instead.
+ --aa Causes ffttpp to bypass normal login procedure, and use an
+ anonymous login instead.
- --dd Enables debugging.
+ --dd Enables debugging.
- --ee Disables command line editing. This is useful for Emacs ange-
- ftp mode.
+ --ee Disables command line editing. This is useful for Emacs
+ ange-ftp mode.
- --ff Forces a cache reload for transfers that go through the FTP or
- HTTP proxies.
+ --ff Forces a cache reload for transfers that go through the FTP
+ or HTTP proxies.
- --gg Disables file name globbing.
+ --gg Disables file name globbing.
- --ii Turns off interactive prompting during multiple file transfers.
+ --ii Turns off interactive prompting during multiple file trans-
+ fers.
- --nn Restrains ffttpp from attempting ``auto-login'' upon initial con-
- nection for non auto-fetch transfers. If auto-login is enabled,
- ffttpp will check the _._n_e_t_r_c (see below) file in the user's home
- directory for an entry describing an account on the remote
- machine. If no entry exists, ffttpp will prompt for the remote
- machine login name (default is the user identity on the local
- machine), and, if necessary, prompt for a password and an
- account with which to login. To override the auto-login for
- auto-fetch transfers, specify the username (and optionally,
- password) as appropriate.
+ --nn Restrains ffttpp from attempting ``auto-login'' upon initial
+ connection for non auto-fetch transfers. If auto-login is
+ enabled, ffttpp will check the _._n_e_t_r_c (see below) file in the
+ user's home directory for an entry describing an account on
+ the remote machine. If no entry exists, ffttpp will prompt for
+ the remote machine login name (default is the user identity
+ on the local machine), and, if necessary, prompt for a pass-
+ word and an account with which to login. To override the
+ auto-login for auto-fetch transfers, specify the username
+ (and optionally, password) as appropriate.
- --NN _n_e_t_r_c
- Use _n_e_t_r_c instead of _~_/_._n_e_t_r_c. Refer to _T_H_E _._n_e_t_r_c _F_I_L_E for
- more information.
+ --NN _n_e_t_r_c Use _n_e_t_r_c instead of _~_/_._n_e_t_r_c. Refer to _T_H_E _._n_e_t_r_c _F_I_L_E for
+ more information.
- --oo _o_u_t_p_u_t
- When auto-fetching files, save the contents in _o_u_t_p_u_t. _o_u_t_p_u_t
- is parsed according to the _F_I_L_E _N_A_M_I_N_G _C_O_N_V_E_N_T_I_O_N_S below. If
- _o_u_t_p_u_t is not `-' or doesn't start with `|', then only the first
- file specified will be retrieved into _o_u_t_p_u_t; all other files
- will be retrieved into the basename of their remote name.
+ --oo _o_u_t_p_u_t When auto-fetching files, save the contents in _o_u_t_p_u_t.
+ _o_u_t_p_u_t is parsed according to the _F_I_L_E _N_A_M_I_N_G _C_O_N_V_E_N_T_I_O_N_S
+ below. If _o_u_t_p_u_t is not `-' or doesn't start with `|', then
+ only the first file specified will be retrieved into _o_u_t_p_u_t;
+ all other files will be retrieved into the basename of their
+ remote name.
- --pp Enable passive mode operation for use behind connection filter-
- ing firewalls. This option has been deprecated as ffttpp now tries
- to use passive mode by default, falling back to active mode if
- the server does not support passive connections.
+ --pp Enable passive mode operation for use behind connection fil-
+ tering firewalls. This option has been deprecated as ffttpp now
+ tries to use passive mode by default, falling back to active
+ mode if the server does not support passive connections.
- --PP _p_o_r_t Sets the port number to _p_o_r_t.
-
- --rr _w_a_i_t Retry the connection attempt if it failed, pausing for _w_a_i_t sec-
- onds.
+ --PP _p_o_r_t Sets the port number to _p_o_r_t.
--qq _q_u_i_t_t_i_m_e
- Quit if the connection has stalled for _q_u_i_t_t_i_m_e seconds.
+ Quit if the connection has stalled for _q_u_i_t_t_i_m_e seconds.
+
+ --rr _w_a_i_t Retry the connection attempt if it failed, pausing for _w_a_i_t
+ seconds.
- --RR Restart all non-proxied auto-fetches.
+ --RR Restart all non-proxied auto-fetches.
- --tt Enables packet tracing.
+ --ss _s_r_c_a_d_d_r Uses _s_r_c_a_d_d_r as the local IP address for all connections.
+
+ --tt Enables packet tracing.
--TT _d_i_r_e_c_t_i_o_n,_m_a_x_i_m_u_m[,_i_n_c_r_e_m_e_n_t]
- Set the maximum transfer rate for _d_i_r_e_c_t_i_o_n to _m_a_x_i_m_u_m
- bytes/second, and if specified, the increment to _i_n_c_r_e_m_e_n_t
- bytes/second. Refer to rraattee for more information.
+ Set the maximum transfer rate for _d_i_r_e_c_t_i_o_n to _m_a_x_i_m_u_m
+ bytes/second, and if specified, the increment to _i_n_c_r_e_m_e_n_t
+ bytes/second. Refer to rraattee for more information.
--uu _U_R_L _f_i_l_e [...]
- Upload files on the command line to _U_R_L where _U_R_L is one of the
- ftp URL types as supported by auto-fetch (with an optional tar-
- get filename for single file uploads), and _f_i_l_e is one or more
- local files to be uploaded.
+ Upload files on the command line to _U_R_L where _U_R_L is one of
+ the ftp URL types as supported by auto-fetch (with an
+ optional target filename for single file uploads), and _f_i_l_e
+ is one or more local files to be uploaded.
- --vv Enable vveerrbboossee and pprrooggrreessss. This is the default if output is
- to a terminal (and in the case of pprrooggrreessss, ffttpp is the fore-
- ground process). Forces ffttpp to show all responses from the
- remote server, as well as report on data transfer statistics.
+ --vv Enable vveerrbboossee and pprrooggrreessss. This is the default if output
+ is to a terminal (and in the case of pprrooggrreessss, ffttpp is the
+ foreground process). Forces ffttpp to show all responses from
+ the remote server, as well as report on data transfer statis-
+ tics.
- --VV Disable vveerrbboossee and pprrooggrreessss, overriding the default of enabled
- when output is to a terminal.
+ --VV Disable vveerrbboossee and pprrooggrreessss, overriding the default of
+ enabled when output is to a terminal.
The client host with which ffttpp is to communicate may be specified on the
command line. If this is done, ffttpp will immediately attempt to establish
@@ -177,11 +181,11 @@ DDEESSCCRRIIPPTTIIOONN
may be distinguished from a record delimiter only when ccrr is
off.
- ddeebbuugg [_d_e_b_u_g_-_v_a_l_u_e]
- Toggle debugging mode. If an optional _d_e_b_u_g_-_v_a_l_u_e is speci-
- fied it is used to set the debugging level. When debugging
- is on, ffttpp prints each command sent to the remote machine,
- preceded by the string `-->'
+ ffttpp__ddeebbuugg [_f_t_p___d_e_b_u_g_-_v_a_l_u_e]
+ Toggle debugging mode. If an optional _f_t_p___d_e_b_u_g_-_v_a_l_u_e is
+ specified it is used to set the debugging level. When debug-
+ ging is on, ffttpp prints each command sent to the remote
+ machine, preceded by the string `-->'
ddeelleettee _r_e_m_o_t_e_-_f_i_l_e
Delete the file _r_e_m_o_t_e_-_f_i_l_e on the remote machine.
@@ -260,7 +264,7 @@ DDEESSCCRRIIPPTTIIOONN
tree (in binary mode).
hhaasshh [_s_i_z_e]
- Toggle hash-sign (``#'') printing for each data block trans-
+ Toggle hash-sign (`#') printing for each data block trans-
ferred. The size of a data block defaults to 1024 bytes.
This can be changed by specifying _s_i_z_e in bytes. Enabling
hhaasshh disables pprrooggrreessss.
@@ -297,18 +301,23 @@ DDEESSCCRRIIPPTTIIOONN
_m_a_c_r_o_-_n_a_m_e; a null line (consecutive newline characters in a
file or carriage returns from the terminal) terminates macro
input mode. There is a limit of 16 macros and 4096 total
- characters in all defined macros. Macros remain defined
- until a cclloossee command is executed. The macro processor
- interprets `$' and `\' as special characters. A `$' followed
- by a number (or numbers) is replaced by the corresponding
- argument on the macro invocation command line. A `$' fol-
- lowed by an `i' signals that macro processor that the execut-
- ing macro is to be looped. On the first pass `$i' is
- replaced by the first argument on the macro invocation com-
- mand line, on the second pass it is replaced by the second
- argument, and so on. A `\' followed by any character is
- replaced by that character. Use the `\' to prevent special
- treatment of the `$'.
+ characters in all defined macros. Macro names can be a maxi-
+ mum of 8 characters. Macros are only applicable to the cur-
+ rent session they are defined within (or if defined outside a
+ session, to the session invoked with the next ooppeenn command),
+ and remain defined until a cclloossee command is executed. To
+ invoke a macro, use the $$ command (see above).
+
+ The macro processor interprets `$' and `\' as special charac-
+ ters. A `$' followed by a number (or numbers) is replaced by
+ the corresponding argument on the macro invocation command
+ line. A `$' followed by an `i' signals the macro processor
+ that the executing macro is to be looped. On the first pass
+ ``$i'' is replaced by the first argument on the macro invoca-
+ tion command line, on the second pass it is replaced by the
+ second argument, and so on. A `\' followed by any character
+ is replaced by that character. Use the `\' to prevent spe-
+ cial treatment of the `$'.
mmddeelleettee [_r_e_m_o_t_e_-_f_i_l_e_s]
Delete the _r_e_m_o_t_e_-_f_i_l_e_s on the remote machine.
@@ -356,7 +365,7 @@ DDEESSCCRRIIPPTTIIOONN
mmooddttiimmee _r_e_m_o_t_e_-_f_i_l_e
Show the last modification time of the file on the remote
- machine.
+ machine, in RFC2822 format.
mmoorree _f_i_l_e A synonym for ppaaggee.
@@ -396,19 +405,19 @@ DDEESSCCRRIIPPTTIIOONN
[_I_n_p_a_t_t_e_r_n] is a template for incoming filenames (which may
have already been processed according to the nnttrraannss and ccaassee
settings). Variable templating is accomplished by including
- the sequences `$1', `$2', ..., `$9' in _i_n_p_a_t_t_e_r_n. Use `\' to
- prevent this special treatment of the `$' character. All
- other characters are treated literally, and are used to
+ the sequences ``$1'', ``$2'', ... ``$9'' in _i_n_p_a_t_t_e_r_n. Use
+ `\' to prevent this special treatment of the `$' character.
+ All other characters are treated literally, and are used to
determine the nnmmaapp [_i_n_p_a_t_t_e_r_n] variable values. For example,
given _i_n_p_a_t_t_e_r_n $1.$2 and the remote file name "mydata.data",
$1 would have the value "mydata", and $2 would have the value
"data". The _o_u_t_p_a_t_t_e_r_n determines the resulting mapped file-
- name. The sequences `$1', `$2', ...., `$9' are replaced by
- any value resulting from the _i_n_p_a_t_t_e_r_n template. The
- sequence `$0' is replace by the original filename. Addition-
- ally, the sequence `[_s_e_q_1, _s_e_q_2]' is replaced by [_s_e_q_1] if
- _s_e_q_1 is not a null string; otherwise it is replaced by _s_e_q_2.
- For example, the command
+ name. The sequences ``$1'', ``$2'', ... ``$9'' are replaced
+ by any value resulting from the _i_n_p_a_t_t_e_r_n template. The
+ sequence ``$0'' is replaced by the original filename. Addi-
+ tionally, the sequence ``[_s_e_q_1, _s_e_q_2]'' is replaced by [_s_e_q_1]
+ if _s_e_q_1 is not a null string; otherwise it is replaced by
+ _s_e_q_2. For example, the command
nmap $1.$2.$3 [$1,$2].[$2,file]
@@ -416,9 +425,10 @@ DDEESSCCRRIIPPTTIIOONN
names "myfile.data" and "myfile.data.old", "myfile.file" for
the input filename "myfile", and "myfile.myfile" for the
input filename ".myfile". Spaces may be included in
- _o_u_t_p_a_t_t_e_r_n, as in the example: `nmap $1 sed "s/ *$//" > $1'
- . Use the `\' character to prevent special treatment of the
- `$','[',']', and `,' characters.
+ _o_u_t_p_a_t_t_e_r_n, as in the example:
+ nmap $1 sed s/ *$// > $1
+ Use the `\' character to prevent special treatment of the
+ `$', `[', `]', and `,' characters.
nnttrraannss [_i_n_c_h_a_r_s [_o_u_t_c_h_a_r_s]]
Set or unset the filename character translation mechanism.
@@ -459,7 +469,7 @@ DDEESSCCRRIIPPTTIIOONN
who connects back to it. Passive mode is useful when using
ffttpp through a gateway router or host that controls the direc-
tionality of traffic. (Note that though FTP servers are
- required to support the PASV command by RFC 1123, some do
+ required to support the PASV command by RFC1123, some do
not.)
ppddiirr [_r_e_m_o_t_e_-_p_a_t_h]
@@ -770,8 +780,8 @@ AAUUTTOO--FFEETTCCHHIINNGG FFIILLEESS
fer type will take place as ascii or binary (respectively). The
default transfer type is binary.
- In order to be compliant with RFC 1738, ffttpp interprets the _p_a_t_h
- part of an ``ftp://'' auto-fetch URL as follows:
+ In order to be compliant with RFC3986, ffttpp interprets the _p_a_t_h part
+ of an ``ftp://'' auto-fetch URL as follows:
++oo The `/' immediately after the _h_o_s_t[:_p_o_r_t] is interpreted as a
separator before the _p_a_t_h, and not as part of the _p_a_t_h itself.
@@ -786,7 +796,7 @@ AAUUTTOO--FFEETTCCHHIINNGG FFIILLEESS
the equivalent of a ccdd command without a directory name. This
is unlikely to be useful.
- ++oo Any `%_X_X' codes (per RFC 1738) within the path components are
+ ++oo Any `%_X_X' codes (per RFC3986) within the path components are
decoded, with _X_X representing a character code in hexadecimal.
This decoding takes place after the _p_a_t_h has been split into
components, but before each component is used in the equivalent
@@ -839,6 +849,15 @@ AAUUTTOO--FFEETTCCHHIINNGG FFIILLEESS
file:///_p_a_t_h
A local URL, copied from _/_p_a_t_h on the local host.
+ about:_t_o_p_i_c
+ Display information regarding _t_o_p_i_c; no file is retrieved for this
+ auto-fetched element. Supported values include:
+
+ about:ftp Information about ffttpp.
+
+ about:version The version of ffttpp. Useful to provide when report-
+ ing problems.
+
Unless noted otherwise above, and --oo _o_u_t_p_u_t is not given, the file is
stored in the current directory as the basename(1) of _p_a_t_h. Note that if
a HTTP redirect is received, the fetch is retried using the new target
@@ -898,7 +917,7 @@ FFIILLEE NNAAMMIINNGG CCOONNVVEENNTTIIOONNSS
example of this mechanism is: ``dir "" |more''.
3. Failing the above checks, if ``globbing'' is enabled, local file
- names are expanded according to the rules used in the csh(1); c.f.
+ names are expanded according to the rules used in the csh(1); see
the gglloobb command. If the ffttpp command expects a single local file
(e.g. ppuutt), only the first filename generated by the "globbing"
operation is used.
@@ -973,8 +992,13 @@ TTHHEE ..nneettrrcc FFIILLEE
mand functions. A macro is defined with the specified name;
its contents begin with the next _._n_e_t_r_c line and continue until
a blank line (consecutive new-line characters) is encountered.
- If a macro named iinniitt is defined, it is automatically executed
- as the last step in the auto-login process. For example,
+ Like the other tokens in the _._n_e_t_r_c file, a mmaaccddeeff is applica-
+ ble only to the mmaacchhiinnee definition preceding it. A mmaaccddeeff
+ entry cannot be utilized by multiple mmaacchhiinnee definitions;
+ rather, it must be defined following each mmaacchhiinnee it is
+ intended to be used with. If a macro named iinniitt is defined, it
+ is automatically executed as the last step in the auto-login
+ process. For example,
default
macdef init
@@ -1074,8 +1098,8 @@ EENNVVIIRROONNMMEENNTT
used in the first attempt to authenticate to the proxy.
If ``unsafe'' URL characters are required in the username
- or password (for example `@' or `/'), encode them with RFC
- 1738 `%_X_X' encoding.
+ or password (for example `@' or `/'), encode them with
+ RFC3986 `%_X_X' encoding.
Note that the use of a username and password in ftp_proxy
and http_proxy may be incompatible with other programs
@@ -1104,8 +1128,26 @@ SSEEEE AALLSSOO
getservbyname(3), editrc(5), services(5), ftpd(8)
SSTTAANNDDAARRDDSS
- ffttpp attempts to be compliant with RFC 959, RFC 1123, RFC 1738, RFC 2068,
- RFC 2389, RFC 2428, RFC 2732, and ddrraafftt--iieettff--ffttppeexxtt--mmllsstt--1111.
+ ffttpp attempts to be compliant with:
+
+ RFC0959 _F_i_l_e _T_r_a_n_s_f_e_r _P_r_o_t_o_c_o_l
+
+ RFC1123 _R_e_q_u_i_r_e_m_e_n_t_s _f_o_r _I_n_t_e_r_n_e_t _H_o_s_t_s _- _A_p_p_l_i_c_a_t_i_o_n _a_n_d _S_u_p_p_o_r_t
+
+ RFC1635 _H_o_w _t_o _U_s_e _A_n_o_n_y_m_o_u_s _F_T_P
+
+ RFC2389 _F_e_a_t_u_r_e _n_e_g_o_t_i_a_t_i_o_n _m_e_c_h_a_n_i_s_m _f_o_r _t_h_e _F_i_l_e _T_r_a_n_s_f_e_r
+ _P_r_o_t_o_c_o_l
+
+ RFC2428 _F_T_P _E_x_t_e_n_s_i_o_n_s _f_o_r _I_P_v_6 _a_n_d _N_A_T_s
+
+ RFC2616 _H_y_p_e_r_t_e_x_t _T_r_a_n_s_f_e_r _P_r_o_t_o_c_o_l _-_- _H_T_T_P_/_1_._1
+
+ RFC2822 _I_n_t_e_r_n_e_t _M_e_s_s_a_g_e _F_o_r_m_a_t
+
+ RFC3659 _E_x_t_e_n_s_i_o_n_s _t_o _F_T_P
+
+ RFC3986 _U_n_i_f_o_r_m _R_e_s_o_u_r_c_e _I_d_e_n_t_i_f_i_e_r _(_U_R_I_)
HHIISSTTOORRYY
The ffttpp command appeared in 4.2BSD.
@@ -1138,4 +1180,4 @@ BBUUGGSS
uses a SIIT translator for IPv6-to-IPv4 translation, ffttpp is unable to
support your configuration.
-NetBSD 3.0_BETA January 15, 2005 NetBSD 3.0_BETA
+NetBSD 3.1.1 July 18, 2007 NetBSD 3.1.1
diff --git a/net/tnftp/files/src/ftp_var.h b/net/tnftp/files/src/ftp_var.h
index 3fd33788013..78bc26159ca 100644
--- a/net/tnftp/files/src/ftp_var.h
+++ b/net/tnftp/files/src/ftp_var.h
@@ -1,8 +1,8 @@
-/* NetBSD: ftp_var.h,v 1.5 2005/05/11 02:41:28 lukem Exp */
-/* from NetBSD: ftp_var.h,v 1.71 2005/04/11 01:49:31 lukem Exp */
+/* $NetBSD: ftp_var.h,v 1.1.1.4 2007/08/06 04:33:23 lukem Exp $ */
+/* from NetBSD: ftp_var.h,v 1.75 2007/07/22 05:02:50 lukem Exp */
/*-
- * Copyright (c) 1996-2005 The NetBSD Foundation, Inc.
+ * Copyright (c) 1996-2007 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -108,6 +108,20 @@
#define NO_PROGRESS
#endif
+#if 0 /* tnftp */
+
+#include <sys/param.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <poll.h>
+
+#include <setjmp.h>
+#include <stringlist.h>
+
+#endif /* tnftp */
+
#ifndef NO_EDITCOMPLETE
#include <histedit.h>
#endif /* !NO_EDITCOMPLETE */
@@ -201,7 +215,7 @@ GLOBAL int sendport; /* use PORT/LPRT cmd for each data connection */
GLOBAL int connected; /* 1 = connected to server, -1 = logged in */
GLOBAL int interactive; /* interactively prompt on m* cmds */
GLOBAL int confirmrest; /* confirm rest of current m* cmd */
-GLOBAL int debug; /* debugging level */
+GLOBAL int ftp_debug; /* debugging level */
GLOBAL int bell; /* ring bell on cmd completion */
GLOBAL int doglob; /* glob local file names */
GLOBAL int autologin; /* establish user account on connection */
@@ -270,6 +284,7 @@ GLOBAL sa_family_t family; /* address family to use for connections */
GLOBAL char *ftpport; /* port number to use for FTP connections */
GLOBAL char *httpport; /* port number to use for HTTP connections */
GLOBAL char *gateport; /* port number to use for gateftp connections */
+GLOBAL struct addrinfo *bindai; /* local address to bind as */
GLOBAL char *outfile; /* filename to output URLs to */
GLOBAL int restartautofetch; /* restart auto-fetch */
@@ -318,7 +333,7 @@ extern struct option optiontab[];
#define FREEPTR(x) if ((x) != NULL) { free(x); (x) = NULL; }
#ifdef BSD4_4
-# define HAVE_SOCKADDR_SA_LEN 1
+# define HAVE_STRUCT_SOCKADDR_SA_LEN 1
#endif
#ifdef NO_LONG_LONG
@@ -326,3 +341,18 @@ extern struct option optiontab[];
#else
# define STRTOLL(x,y,z) strtoll(x,y,z)
#endif
+
+#ifdef NO_DEBUG
+#define DPRINTF(...)
+#define DWARN(...)
+#else
+#define DPRINTF(...) if (ftp_debug) (void)fprintf(ttyout, __VA_ARGS__)
+#define DWARN(...) if (ftp_debug) warn(__VA_ARGS__)
+#endif
+
+#ifdef NO_USAGE
+void xusage(void);
+#define UPRINTF(...) xusage()
+#else
+#define UPRINTF(...) (void)fprintf(ttyout, __VA_ARGS__)
+#endif
diff --git a/net/tnftp/files/src/main.c b/net/tnftp/files/src/main.c
index 67462769552..704cc8ed9d3 100644
--- a/net/tnftp/files/src/main.c
+++ b/net/tnftp/files/src/main.c
@@ -1,5 +1,5 @@
-/* NetBSD: main.c,v 1.11 2005/06/10 04:05:01 lukem Exp */
-/* from NetBSD: main.c,v 1.97 2005/06/10 00:18:46 lukem Exp */
+/* $NetBSD: main.c,v 1.1.1.6 2007/08/06 04:33:23 lukem Exp $ */
+/* from NetBSD: main.c,v 1.105 2007/05/22 05:16:48 lukem Exp */
/*-
* Copyright (c) 1996-2005 The NetBSD Foundation, Inc.
@@ -95,11 +95,44 @@
* SUCH DAMAGE.
*/
+#include "tnftp.h"
+
+#if 0 /* tnftp */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__COPYRIGHT("@(#) Copyright (c) 1985, 1989, 1993, 1994\n\
+ The Regents of the University of California. All rights reserved.\n");
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 10/9/94";
+#else
+__RCSID(" NetBSD: main.c,v 1.105 2007/05/22 05:16:48 lukem Exp ");
+#endif
+#endif /* not lint */
+
/*
* FTP User Program -- Command Interface.
*/
-
-#include "tnftp.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <err.h>
+#include <errno.h>
+#include <netdb.h>
+#include <paths.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <locale.h>
+
+#endif /* tnftp */
#define GLOBAL /* force GLOBAL decls in ftp_var.h to be declared */
#include "ftp_var.h"
@@ -113,18 +146,19 @@ static void setupoption(char *, char *, char *);
int main(int, char *[]);
int
-main(int argc, char *argv[])
+main(int volatile argc, char **volatile argv)
{
int ch, rval;
struct passwd *pw;
- char *cp, *ep, *anonuser, *anonpass, *upload_path;
+ char *cp, *ep, *anonuser, *anonpass, *upload_path, *src_addr;
int dumbterm, s, isupload;
size_t len;
socklen_t slen;
-#if 0 /* XXX */
+ tzset();
+#if 0 /* tnftp */ /* XXX */
setlocale(LC_ALL, "");
-#endif
+#endif /* tnftp */
setprogname(argv[0]);
sigint_raised = 0;
@@ -166,6 +200,7 @@ main(int argc, char *argv[])
epsv4 = 0;
#endif
epsv4bad = 0;
+ src_addr = NULL;
upload_path = NULL;
isupload = 0;
reply_callback = NULL;
@@ -184,15 +219,15 @@ main(int argc, char *argv[])
*/
s = socket(AF_INET, SOCK_STREAM, 0);
if (s == -1)
- err(1, "can't create socket");
+ err(1, "Can't create socket to determine default socket sizes");
slen = sizeof(rcvbuf_size);
if (getsockopt(s, SOL_SOCKET, SO_RCVBUF,
(void *)&rcvbuf_size, &slen) == -1)
- err(1, "unable to get default rcvbuf size");
+ err(1, "Unable to get default rcvbuf size");
slen = sizeof(sndbuf_size);
if (getsockopt(s, SOL_SOCKET, SO_SNDBUF,
(void *)&sndbuf_size, &slen) == -1)
- err(1, "unable to get default sndbuf size");
+ err(1, "Unable to get default sndbuf size");
(void)close(s);
/* sanity check returned buffer sizes */
if (rcvbuf_size <= 0)
@@ -205,7 +240,7 @@ main(int argc, char *argv[])
if (rcvbuf_size > 8 * 1024 * 1024)
rcvbuf_size = 8 * 1024 * 1024;
- marg_sl = xsl_init();
+ marg_sl = ftp_sl_init();
if ((tmpdir = getenv("TMPDIR")) == NULL)
tmpdir = _PATH_TMP;
@@ -223,7 +258,7 @@ main(int argc, char *argv[])
passivemode = 1;
activefallback = 1;
} else
- warnx("unknown $FTPMODE '%s'; using defaults", cp);
+ warnx("Unknown $FTPMODE `%s'; using defaults", cp);
}
if (strcmp(getprogname(), "pftp") == 0) {
@@ -264,7 +299,7 @@ main(int argc, char *argv[])
}
}
- while ((ch = getopt(argc, argv, "46AadefginN:o:pP:q:r:RtT:u:vV")) != -1) {
+ while ((ch = getopt(argc, argv, "46AadefginN:o:pP:q:r:Rs:tT:u:vV")) != -1) {
switch (ch) {
case '4':
family = AF_INET;
@@ -289,7 +324,7 @@ main(int argc, char *argv[])
case 'd':
options |= SO_DEBUG;
- debug++;
+ ftp_debug++;
break;
case 'e':
@@ -339,19 +374,23 @@ main(int argc, char *argv[])
case 'q':
quit_time = strtol(optarg, &ep, 10);
if (quit_time < 1 || *ep != '\0')
- errx(1, "bad quit value: %s", optarg);
+ errx(1, "Bad quit value: %s", optarg);
break;
case 'r':
retry_connect = strtol(optarg, &ep, 10);
if (retry_connect < 1 || *ep != '\0')
- errx(1, "bad retry value: %s", optarg);
+ errx(1, "Bad retry value: %s", optarg);
break;
case 'R':
restartautofetch = 1;
break;
+ case 's':
+ src_addr = optarg;
+ break;
+
case 't':
trace = 1;
break;
@@ -364,11 +403,12 @@ main(int argc, char *argv[])
/* look for `dir,max[,incr]' */
targc = 0;
targv[targc++] = "-T";
- oac = xstrdup(optarg);
+ oac = ftp_strdup(optarg);
while ((cp = strsep(&oac, ",")) != NULL) {
if (*cp == '\0') {
- warnx("bad throttle value: %s", optarg);
+ warnx("Bad throttle value `%s'",
+ optarg);
usage();
/* NOTREACHED */
}
@@ -386,7 +426,7 @@ main(int argc, char *argv[])
{
isupload = 1;
interactive = 0;
- upload_path = xstrdup(optarg);
+ upload_path = ftp_strdup(optarg);
break;
}
@@ -413,6 +453,22 @@ main(int argc, char *argv[])
crflag = 1; /* strip c.r. on ascii gets */
sendport = -1; /* not using ports */
+ if (src_addr != NULL) {
+ struct addrinfo hints;
+ int error;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = family;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_PASSIVE;
+ error = getaddrinfo(src_addr, NULL, &hints, &bindai);
+ if (error) {
+ errx(1, "Can't lookup `%s': %s", src_addr,
+ (error == EAI_SYSTEM) ? strerror(errno)
+ : gai_strerror(error));
+ }
+ }
+
/*
* Cache the user name and home directory.
*/
@@ -421,7 +477,7 @@ main(int argc, char *argv[])
anonuser = "anonymous";
cp = getenv("HOME");
if (! EMPTYSTRING(cp))
- localhome = xstrdup(cp);
+ localhome = ftp_strdup(cp);
pw = NULL;
cp = getlogin();
if (cp != NULL)
@@ -430,8 +486,8 @@ main(int argc, char *argv[])
pw = getpwuid(getuid());
if (pw != NULL) {
if (localhome == NULL && !EMPTYSTRING(pw->pw_dir))
- localhome = xstrdup(pw->pw_dir);
- localname = xstrdup(pw->pw_name);
+ localhome = ftp_strdup(pw->pw_dir);
+ localname = ftp_strdup(pw->pw_name);
anonuser = localname;
}
if (netrc[0] == '\0' && localhome != NULL) {
@@ -443,7 +499,7 @@ main(int argc, char *argv[])
}
}
if (localhome == NULL)
- localhome = xstrdup("/");
+ localhome = ftp_strdup("/");
/*
* Every anonymous FTP server I've encountered will accept the
@@ -453,7 +509,7 @@ main(int argc, char *argv[])
* - thorpej@NetBSD.org
*/
len = strlen(anonuser) + 2;
- anonpass = xmalloc(len);
+ anonpass = ftp_malloc(len);
(void)strlcpy(anonpass, anonuser, len);
(void)strlcat(anonpass, "@", len);
@@ -480,11 +536,6 @@ main(int argc, char *argv[])
(void)xsignal(SIGUSR2, crankrate);
(void)xsignal(SIGWINCH, setttywidth);
-#ifdef __GNUC__ /* to shut up gcc warnings */
- (void)&argc;
- (void)&argv;
-#endif
-
if (argc > 0) {
if (isupload) {
rval = auto_put(argc, argv, upload_path);
@@ -572,7 +623,7 @@ prompt(void)
o = getoption("prompt");
if (o == NULL)
- errx(1, "no such option `prompt'");
+ errx(1, "prompt: no such option `prompt'");
prompt = &(o->value);
}
formatbuf(buf, sizeof(buf), *prompt ? *prompt : DEFAULTPROMPT);
@@ -593,7 +644,7 @@ rprompt(void)
o = getoption("rprompt");
if (o == NULL)
- errx(1, "no such option `rprompt'");
+ errx(1, "rprompt: no such option `rprompt'");
rprompt = &(o->value);
}
formatbuf(buf, sizeof(buf), *rprompt ? *rprompt : DEFAULTRPROMPT);
@@ -608,7 +659,9 @@ cmdscanner(void)
{
struct cmd *c;
char *p;
+#ifndef NO_EDITCOMPLETE
int ch;
+#endif
size_t num;
for (;;) {
@@ -620,8 +673,8 @@ cmdscanner(void)
p = rprompt();
if (*p)
fprintf(ttyout, "%s ", p);
- (void)fflush(ttyout);
}
+ (void)fflush(ttyout);
num = getline(stdin, line, sizeof(line), NULL);
switch (num) {
case -1: /* EOF */
@@ -754,7 +807,7 @@ makeargv(void)
marg_sl->sl_cur = 0; /* reset to start of marg_sl */
for (margc = 0; ; margc++) {
argp = slurpstring();
- xsl_add(marg_sl, argp);
+ ftp_sl_add(marg_sl, argp);
if (argp == NULL)
break;
}
@@ -928,19 +981,19 @@ help(int argc, char *argv[])
cmd = argv[0];
isusage = (strcmp(cmd, "usage") == 0);
if (argc == 0 || (isusage && argc == 1)) {
- fprintf(ttyout, "usage: %s [command [...]]\n", cmd);
+ UPRINTF("usage: %s [command [...]]\n", cmd);
return;
}
if (argc == 1) {
StringList *buf;
- buf = xsl_init();
+ buf = ftp_sl_init();
fprintf(ttyout,
"%sommands may be abbreviated. Commands are:\n\n",
proxy ? "Proxy c" : "C");
for (c = cmdtab; (p = c->c_name) != NULL; c++)
if (!proxy || c->c_proxy)
- xsl_add(buf, p);
+ ftp_sl_add(buf, p);
list_vertical(buf);
sl_free(buf, 0);
return;
@@ -991,11 +1044,11 @@ getoptionvalue(const char *name)
struct option *c;
if (name == NULL)
- errx(1, "getoptionvalue() invoked with NULL name");
+ errx(1, "getoptionvalue: invoked with NULL name");
c = getoption(name);
if (c != NULL)
return (c->value);
- errx(1, "getoptionvalue() invoked with unknown option `%s'", name);
+ errx(1, "getoptionvalue: invoked with unknown option `%s'", name);
/* NOTREACHED */
}
@@ -1021,8 +1074,9 @@ usage(void)
(void)fprintf(stderr,
"usage: %s [-46AadefginpRtvV] [-N netrc] [-o outfile] [-P port] [-q quittime]\n"
-" [-r retry] [-T dir,max[,inc][[user@]host [port]]] [host:path[/]]\n"
-" [file:///file] [ftp://[user[:pass]@]host[:port]/path[/]]\n"
+" [-r retry] [-s srcaddr] [-T dir,max[,inc]]\n"
+" [[user@]host [port]] [host:path[/]] [file:///file]\n"
+" [ftp://[user[:pass]@]host[:port]/path[/]]\n"
" [http://[user[:pass]@]host[:port]/path] [...]\n"
" %s -u URL file [...]\n", progname, progname);
exit(1);
diff --git a/net/tnftp/files/src/progressbar.c b/net/tnftp/files/src/progressbar.c
index f9b1216ce8f..317262b98fd 100644
--- a/net/tnftp/files/src/progressbar.c
+++ b/net/tnftp/files/src/progressbar.c
@@ -1,8 +1,8 @@
-/* NetBSD: progressbar.c,v 1.9 2005/06/10 04:05:01 lukem Exp */
-/* from NetBSD: progressbar.c,v 1.10 2005/06/09 16:38:29 lukem Exp */
+/* $NetBSD: progressbar.c,v 1.1.1.5 2007/08/06 04:33:24 lukem Exp $ */
+/* from NetBSD: progressbar.c,v 1.17 2007/05/05 18:09:24 martin Exp */
/*-
- * Copyright (c) 1997-2005 The NetBSD Foundation, Inc.
+ * Copyright (c) 1997-2007 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -37,11 +37,32 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include "tnftp.h"
+
+#if 0 /* tnftp */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID(" NetBSD: progressbar.c,v 1.17 2007/05/05 18:09:24 martin Exp ");
+#endif /* not lint */
+
/*
* FTP User Program -- Misc support routines
*/
+#include <sys/types.h>
+#include <sys/param.h>
-#include "tnftp.h"
+#include <err.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <tzfile.h>
+#include <unistd.h>
+
+#endif /* tnftp */
#include "progressbar.h"
@@ -81,10 +102,23 @@ updateprogressmeter(int dummy)
}
/*
- * List of order of magnitude prefixes.
- * The last is `P', as 2^64 = 16384 Petabytes
+ * List of order of magnitude suffixes, per IEC 60027-2.
*/
-static const char prefixes[] = " KMGTP";
+static const char * const suffixes[] = {
+ "", /* 2^0 (byte) */
+ "KiB", /* 2^10 Kibibyte */
+ "MiB", /* 2^20 Mebibyte */
+ "GiB", /* 2^30 Gibibyte */
+ "TiB", /* 2^40 Tebibyte */
+ "PiB", /* 2^50 Pebibyte */
+ "EiB", /* 2^60 Exbibyte */
+#if 0
+ /* The following are not necessary for signed 64-bit off_t */
+ "ZiB", /* 2^70 Zebibyte */
+ "YiB", /* 2^80 Yobibyte */
+#endif
+};
+#define NSUFFIXES (sizeof(suffixes) / sizeof(suffixes[0]))
/*
* Display a transfer progress bar if progress is non-zero.
@@ -111,8 +145,7 @@ progressmeter(int flag)
struct timeval td;
off_t abbrevsize, bytespersec;
double elapsed;
- int ratio, i, remaining;
- size_t barlength;
+ int ratio, i, remaining, barlength;
/*
* Work variables for progress bar.
@@ -126,7 +159,7 @@ progressmeter(int flag)
size_t len;
char buf[256]; /* workspace for progress bar */
#ifndef NO_PROGRESS
-#define BAROVERHEAD 43 /* non `*' portion of progress bar */
+#define BAROVERHEAD 45 /* non `*' portion of progress bar */
/*
* stars should contain at least
* sizeof(buf) - BAROVERHEAD entries
@@ -206,7 +239,7 @@ progressmeter(int flag)
*/
barlength = MIN(sizeof(buf) - 1, ttywidth) - BAROVERHEAD;
if (prefix)
- barlength -= strlen(prefix);
+ barlength -= (int)strlen(prefix);
if (barlength > 0) {
i = barlength * ratio / 100;
len += snprintf(buf + len, BUFLEFT,
@@ -215,12 +248,13 @@ progressmeter(int flag)
}
abbrevsize = cursize;
- for (i = 0; abbrevsize >= 100000 && i < sizeof(prefixes); i++)
+ for (i = 0; abbrevsize >= 100000 && i < NSUFFIXES; i++)
abbrevsize >>= 10;
- len += snprintf(buf + len, BUFLEFT, " " LLFP("5") " %c%c ",
+ if (i == NSUFFIXES)
+ i--;
+ len += snprintf(buf + len, BUFLEFT, " " LLFP("5") " %-3s ",
(LLT)abbrevsize,
- prefixes[i],
- i == 0 ? ' ' : 'B');
+ suffixes[i]);
timersub(&now, &start, &td);
elapsed = td.tv_sec + (td.tv_usec / 1000000.0);
@@ -231,13 +265,13 @@ progressmeter(int flag)
if (elapsed > 0.0)
bytespersec /= elapsed;
}
- for (i = 1; bytespersec >= 1024000 && i < sizeof(prefixes); i++)
+ for (i = 1; bytespersec >= 1024000 && i < NSUFFIXES; i++)
bytespersec >>= 10;
len += snprintf(buf + len, BUFLEFT,
- " " LLFP("3") ".%02d %cB/s ",
+ " " LLFP("3") ".%02d %.2sB/s ",
(LLT)(bytespersec / 1024),
(int)((bytespersec % 1024) * 100 / 1024),
- prefixes[i]);
+ suffixes[i]);
if (filesize > 0) {
if (bytes <= 0 || elapsed <= 0.0 || cursize > filesize) {
@@ -323,12 +357,14 @@ ptransfer(int siginfo)
len += snprintf(buf + len, BUFLEFT,
"%02d:%02d ", remaining / 60, remaining % 60);
- for (i = 1; bytespersec >= 1024000 && i < sizeof(prefixes); i++)
+ for (i = 1; bytespersec >= 1024000 && i < NSUFFIXES; i++)
bytespersec >>= 10;
- len += snprintf(buf + len, BUFLEFT, "(" LLF ".%02d %cB/s)",
+ if (i == NSUFFIXES)
+ i--;
+ len += snprintf(buf + len, BUFLEFT, "(" LLF ".%02d %.2sB/s)",
(LLT)(bytespersec / 1024),
(int)((bytespersec % 1024) * 100 / 1024),
- prefixes[i]);
+ suffixes[i]);
if (siginfo && bytes > 0 && elapsed > 0.0 && filesize >= 0
&& bytes + restart_point <= filesize) {
@@ -457,7 +493,7 @@ xsignal(int sig, sigfunc func)
* This is unpleasant, but I don't know what would be better.
* Right now, this "can't happen"
*/
- errx(1, "xsignal_restart called with signal %d", sig);
+ errx(1, "xsignal_restart: called with signal %d", sig);
}
return(xsignal_restart(sig, func, restartable));
diff --git a/net/tnftp/files/src/progressbar.h b/net/tnftp/files/src/progressbar.h
index a3f80d179e9..d9bf1813be5 100644
--- a/net/tnftp/files/src/progressbar.h
+++ b/net/tnftp/files/src/progressbar.h
@@ -1,4 +1,4 @@
-/* NetBSD: progressbar.h,v 1.5 2005/05/11 02:41:28 lukem Exp */
+/* $NetBSD: progressbar.h,v 1.1.1.4 2007/08/06 04:33:24 lukem Exp $ */
/* from NetBSD: progressbar.h,v 1.5 2005/02/10 16:00:38 jmc Exp */
/*-
@@ -91,19 +91,19 @@ void ptransfer(int);
# define ULLFP(x) "%" x "lu"
# define ULLT unsigned long
#else
-#if HAVE_PRINTF_QD
+#if defined(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
-#else
+#else /* !defined(HAVE_PRINTF_QD) */
# define LLF "%lld"
# define LLFP(x) "%" x "lld"
# define LLT long long
# define ULLF "%llu"
# define ULLFP(x) "%" x "llu"
# define ULLT unsigned long long
-#endif
+#endif /* !defined(HAVE_PRINTF_QD) */
#endif
diff --git a/net/tnftp/files/src/ruserpass.c b/net/tnftp/files/src/ruserpass.c
index 491eb9565f9..24db485e816 100644
--- a/net/tnftp/files/src/ruserpass.c
+++ b/net/tnftp/files/src/ruserpass.c
@@ -1,5 +1,5 @@
-/* NetBSD: ruserpass.c,v 1.6 2005/06/10 04:05:01 lukem Exp */
-/* from NetBSD: ruserpass.c,v 1.30 2005/06/10 00:18:47 lukem Exp */
+/* $NetBSD: ruserpass.c,v 1.1.1.5 2007/08/06 04:33:24 lukem Exp $ */
+/* from NetBSD: ruserpass.c,v 1.33 2007/04/17 05:52:04 lukem Exp */
/*
* Copyright (c) 1985, 1993, 1994
@@ -32,6 +32,31 @@
#include "tnftp.h"
+#if 0 /* tnftp */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)ruserpass.c 8.4 (Berkeley) 4/27/95";
+#else
+__RCSID(" NetBSD: ruserpass.c,v 1.33 2007/04/17 05:52:04 lukem Exp ");
+#endif
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#endif /* tnftp */
+
#include "ftp_var.h"
static int token(void);
@@ -75,7 +100,7 @@ ruserpass(const char *host, char **aname, char **apass, char **aacct)
cfile = fopen(netrc, "r");
if (cfile == NULL) {
if (errno != ENOENT)
- warn("%s", netrc);
+ warn("Can't read `%s'", netrc);
return (0);
}
if (gethostname(myname, sizeof(myname)) < 0)
@@ -84,7 +109,7 @@ ruserpass(const char *host, char **aname, char **apass, char **aacct)
if ((mydomain = strchr(myname, '.')) == NULL)
mydomain = "";
next:
- while ((t = token())) switch(t) {
+ while ((t = token()) > 0) switch(t) {
case DEFAULT:
usedefault = 1;
@@ -92,7 +117,9 @@ ruserpass(const char *host, char **aname, char **apass, char **aacct)
case MACH:
if (!usedefault) {
- if (token() != ID)
+ if ((t = token()) == -1)
+ goto bad;
+ if (t != ID)
continue;
/*
* Allow match either for user's input host name
@@ -116,12 +143,15 @@ ruserpass(const char *host, char **aname, char **apass, char **aacct)
continue;
}
match:
- while ((t = token()) && t != MACH && t != DEFAULT) switch(t) {
+ while ((t = token()) > 0 &&
+ t != MACH && t != DEFAULT) switch(t) {
case LOGIN:
- if (token()) {
+ if ((t = token()) == -1)
+ goto bad;
+ if (t) {
if (*aname == NULL)
- *aname = xstrdup(tokval);
+ *aname = ftp_strdup(tokval);
else {
if (strcmp(*aname, tokval))
goto next;
@@ -132,22 +162,26 @@ ruserpass(const char *host, char **aname, char **apass, char **aacct)
if ((*aname == NULL || strcmp(*aname, "anonymous")) &&
fstat(fileno(cfile), &stb) >= 0 &&
(stb.st_mode & 077) != 0) {
- warnx("Error: .netrc file is readable by others.");
- warnx("Remove password or make file unreadable by others.");
+ warnx("Error: .netrc file is readable by others");
+ warnx("Remove password or make file unreadable by others");
goto bad;
}
- if (token() && *apass == NULL)
- *apass = xstrdup(tokval);
+ if ((t = token()) == -1)
+ goto bad;
+ if (t && *apass == NULL)
+ *apass = ftp_strdup(tokval);
break;
case ACCOUNT:
if (fstat(fileno(cfile), &stb) >= 0
&& (stb.st_mode & 077) != 0) {
- warnx("Error: .netrc file is readable by others.");
- warnx("Remove account or make file unreadable by others.");
+ warnx("Error: .netrc file is readable by others");
+ warnx("Remove account or make file unreadable by others");
goto bad;
}
- if (token() && *aacct == NULL)
- *aacct = xstrdup(tokval);
+ if ((t = token()) == -1)
+ goto bad;
+ if (t && *aacct == NULL)
+ *aacct = ftp_strdup(tokval);
break;
case MACDEF:
if (proxy) {
@@ -207,9 +241,13 @@ ruserpass(const char *host, char **aname, char **apass, char **aacct)
}
*tmp = c;
if (*tmp == '\n') {
- if (*(tmp-1) == '\0') {
- macros[macnum++].mac_end = tmp - 1;
- break;
+ if (tmp == macros[macnum].mac_start) {
+ macros[macnum++].mac_end = tmp;
+ break;
+ } else if (*(tmp - 1) == '\0') {
+ macros[macnum++].mac_end =
+ tmp - 1;
+ break;
}
*tmp = '\0';
}
@@ -222,12 +260,14 @@ ruserpass(const char *host, char **aname, char **apass, char **aacct)
}
break;
default:
- warnx("Unknown .netrc keyword %s", tokval);
+ warnx("Unknown .netrc keyword `%s'", tokval);
break;
}
goto done;
}
done:
+ if (t == -1)
+ goto bad;
(void)fclose(cfile);
return (0);
bad:
@@ -253,16 +293,26 @@ token(void)
if (c == '"') {
while ((c = getc(cfile)) != EOF && c != '"') {
if (c == '\\')
- c = getc(cfile);
+ if ((c = getc(cfile)) == EOF)
+ break;
*cp++ = c;
+ if (cp == tokval + sizeof(tokval)) {
+ warnx("Token in .netrc too long");
+ return (-1);
+ }
}
} else {
*cp++ = c;
while ((c = getc(cfile)) != EOF
&& c != '\n' && c != '\t' && c != ' ' && c != ',') {
if (c == '\\')
- c = getc(cfile);
+ if ((c = getc(cfile)) == EOF)
+ break;
*cp++ = c;
+ if (cp == tokval + sizeof(tokval)) {
+ warnx("Token in .netrc too long");
+ return (-1);
+ }
}
}
*cp = 0;
diff --git a/net/tnftp/files/src/util.c b/net/tnftp/files/src/util.c
index 6862fd4f316..add29b6c453 100644
--- a/net/tnftp/files/src/util.c
+++ b/net/tnftp/files/src/util.c
@@ -1,8 +1,8 @@
-/* NetBSD: util.c,v 1.14 2005/06/10 04:05:01 lukem Exp */
-/* from NetBSD: util.c,v 1.129 2005/06/10 00:18:47 lukem Exp */
+/* $NetBSD: util.c,v 1.1.1.6 2007/08/06 04:33:24 lukem Exp $ */
+/* from NetBSD: util.c,v 1.143 2007/05/24 05:05:19 lukem Exp */
/*-
- * Copyright (c) 1997-2005 The NetBSD Foundation, Inc.
+ * Copyright (c) 1997-2007 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -70,11 +70,43 @@
* SUCH DAMAGE.
*/
+#include "tnftp.h"
+
+#if 0 /* tnftp */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID(" NetBSD: util.c,v 1.143 2007/05/24 05:05:19 lukem Exp ");
+#endif /* not lint */
+
/*
* FTP User Program -- Misc support routines
*/
-
-#include "tnftp.h"
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <arpa/ftp.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <glob.h>
+#include <signal.h>
+#include <libgen.h>
+#include <limits.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <time.h>
+#include <tzfile.h>
+#include <unistd.h>
+
+#endif /* tnftp */
#include "ftp_var.h"
@@ -99,7 +131,7 @@ setpeer(int argc, char *argv[])
(void)another(&argc, &argv, "to");
if (argc < 2 || argc > 3) {
usage:
- fprintf(ttyout, "usage: %s host-name [port]\n", argv[0]);
+ UPRINTF("usage: %s host-name [port]\n", argv[0]);
code = -1;
return;
}
@@ -112,7 +144,7 @@ setpeer(int argc, char *argv[])
if (gatemode) {
if (gateserver == NULL || *gateserver == '\0')
- errx(1, "gateserver not defined (shouldn't happen)");
+ errx(1, "main: gateserver not defined");
host = hookup(gateserver, port);
} else
host = hookup(argv[1], port);
@@ -150,7 +182,7 @@ parse_feat(const char *line)
/*
* work-around broken ProFTPd servers that can't
- * even obey RFC 2389.
+ * even obey RFC2389.
*/
while (*line && isspace((int)*line))
line++;
@@ -177,7 +209,7 @@ getremoteinfo(void)
int overbose, i;
overbose = verbose;
- if (debug == 0)
+ if (ftp_debug == 0)
verbose = -1;
/* determine remote system type */
@@ -243,7 +275,8 @@ getremoteinfo(void)
features[FEAT_FEAT] = 1;
} else
features[FEAT_FEAT] = 0;
- if (debug) {
+#ifndef NO_DEBUG
+ if (ftp_debug) {
#define DEBUG_FEAT(x) fprintf(ttyout, "features[" #x "] = %d\n", features[(x)])
DEBUG_FEAT(FEAT_FEAT);
DEBUG_FEAT(FEAT_MDTM);
@@ -253,6 +286,7 @@ getremoteinfo(void)
DEBUG_FEAT(FEAT_TVFS);
#undef DEBUG_FEAT
}
+#endif
reply_callback = NULL;
verbose = overbose;
@@ -352,29 +386,29 @@ ftp_login(const char *host, const char *luser, const char *lpass)
{
char tmp[80];
char *user, *pass, *acct, *p;
+ char emptypass[] = "";
const char *errormsg;
int n, aflag, rval, nlen;
aflag = rval = 0;
user = pass = acct = NULL;
if (luser)
- user = xstrdup(luser);
+ user = ftp_strdup(luser);
if (lpass)
- pass = xstrdup(lpass);
+ pass = ftp_strdup(lpass);
- if (debug)
- fprintf(ttyout, "ftp_login: user `%s' pass `%s' host `%s'\n",
- user ? user : "<null>", pass ? pass : "<null>",
- host ? host : "<null>");
+ DPRINTF("ftp_login: user `%s' pass `%s' host `%s'\n",
+ user ? user : "<null>", pass ? pass : "<null>",
+ host ? host : "<null>");
/*
* Set up arguments for an anonymous FTP session, if necessary.
*/
if (anonftp) {
FREEPTR(user);
- user = xstrdup("anonymous"); /* as per RFC 1635 */
+ user = ftp_strdup("anonymous"); /* as per RFC1635 */
FREEPTR(pass);
- pass = xstrdup(getoptionvalue("anonpass"));
+ pass = ftp_strdup(getoptionvalue("anonpass"));
}
if (ruserpass(host, &user, &pass, &acct) < 0) {
@@ -394,9 +428,9 @@ ftp_login(const char *host, const char *luser, const char *lpass)
code = -1;
goto cleanup_ftp_login;
} else if (nlen == 0) {
- user = xstrdup(localname);
+ user = ftp_strdup(localname);
} else {
- user = xstrdup(tmp);
+ user = ftp_strdup(tmp);
}
}
@@ -405,7 +439,7 @@ ftp_login(const char *host, const char *luser, const char *lpass)
size_t len;
len = strlen(user) + 1 + strlen(host) + 1;
- nuser = xmalloc(len);
+ nuser = ftp_malloc(len);
(void)strlcpy(nuser, user, len);
(void)strlcat(nuser, "@", len);
(void)strlcat(nuser, host, len);
@@ -417,7 +451,9 @@ ftp_login(const char *host, const char *luser, const char *lpass)
if (n == CONTINUE) {
if (pass == NULL) {
p = getpass("Password: ");
- pass = xstrdup(p);
+ if (p == NULL)
+ p = emptypass;
+ pass = ftp_strdup(p);
memset(p, 0, strlen(p));
}
n = command("PASS %s", pass);
@@ -427,11 +463,13 @@ ftp_login(const char *host, const char *luser, const char *lpass)
aflag++;
if (acct == NULL) {
p = getpass("Account: ");
- acct = xstrdup(p);
+ if (p == NULL)
+ p = emptypass;
+ acct = ftp_strdup(p);
memset(p, 0, strlen(p));
}
if (acct[0] == '\0') {
- warnx("Login failed.");
+ warnx("Login failed");
goto cleanup_ftp_login;
}
n = command("ACCT %s", acct);
@@ -439,11 +477,11 @@ ftp_login(const char *host, const char *luser, const char *lpass)
}
if ((n != COMPLETE) ||
(!aflag && acct != NULL && command("ACCT %s", acct) != COMPLETE)) {
- warnx("Login failed.");
+ warnx("Login failed");
goto cleanup_ftp_login;
}
rval = 1;
- username = xstrdup(user);
+ username = ftp_strdup(user);
if (proxy)
goto cleanup_ftp_login;
@@ -466,7 +504,7 @@ ftp_login(const char *host, const char *luser, const char *lpass)
memset(pass, 0, strlen(pass));
FREEPTR(pass);
if (acct != NULL)
- memset(acct, 0, strlen(pass));
+ memset(acct, 0, strlen(acct));
FREEPTR(acct);
return (rval);
}
@@ -546,7 +584,7 @@ remglob(char *argv[], int doswitch, const char **errbuf)
(void)strlcat(temp, "/", sizeof(temp));
(void)strlcat(temp, TMPFILE, sizeof(temp));
if ((fd = mkstemp(temp)) < 0) {
- warn("unable to create temporary file %s", temp);
+ warn("Unable to create temporary file `%s'", temp);
return (NULL);
}
close(fd);
@@ -573,12 +611,10 @@ remglob(char *argv[], int doswitch, const char **errbuf)
(void)unlink(temp);
if (ftemp == NULL) {
if (errbuf == NULL)
- fputs(
- "can't find list of remote files, oops.\n",
- ttyout);
+ warnx("Can't find list of remote files");
else
*errbuf =
- "can't find list of remote files, oops.";
+ "Can't find list of remote files";
return (NULL);
}
}
@@ -607,16 +643,16 @@ globulize(const char *pattern)
char *p;
if (!doglob)
- return (xstrdup(pattern));
+ return (ftp_strdup(pattern));
flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_TILDE;
memset(&gl, 0, sizeof(gl));
if (glob(pattern, flags, NULL, &gl) || gl.gl_pathc == 0) {
- warnx("%s: not found", pattern);
+ warnx("Glob pattern `%s' not found", pattern);
globfree(&gl);
return (NULL);
}
- p = xstrdup(gl.gl_pathv[0]);
+ p = ftp_strdup(gl.gl_pathv[0]);
globfree(&gl);
return (p);
}
@@ -632,7 +668,7 @@ remotesize(const char *file, int noisy)
overbose = verbose;
size = -1;
- if (debug == 0)
+ if (ftp_debug == 0)
verbose = -1;
if (! features[FEAT_SIZE]) {
if (noisy)
@@ -654,7 +690,7 @@ remotesize(const char *file, int noisy)
} else {
if (r == ERROR && code == 500 && features[FEAT_SIZE] == -1)
features[FEAT_SIZE] = 0;
- if (noisy && debug == 0) {
+ if (noisy && ftp_debug == 0) {
fputs(reply_string, ttyout);
putc('\n', ttyout);
}
@@ -676,7 +712,7 @@ remotemodtime(const char *file, int noisy)
overbose = verbose;
ocode = code;
rtime = -1;
- if (debug == 0)
+ if (ftp_debug == 0)
verbose = -1;
if (! features[FEAT_MDTM]) {
if (noisy)
@@ -688,7 +724,6 @@ remotemodtime(const char *file, int noisy)
if (r == COMPLETE) {
struct tm timebuf;
char *timestr, *frac;
- int yy, mo, day, hour, min, sec;
/*
* time-val = 14DIGIT [ "." 1*DIGIT ]
@@ -720,33 +755,28 @@ remotemodtime(const char *file, int noisy)
timestr[1] = '0';
fprintf(ttyout, "Converted to `%s'\n", timestr);
}
+ memset(&timebuf, 0, sizeof(timebuf));
if (strlen(timestr) != 14 ||
- sscanf(timestr, "%04d%02d%02d%02d%02d%02d",
- &yy, &mo, &day, &hour, &min, &sec) != 6) {
+ (strptime(timestr, "%Y%m%d%H%M%S", &timebuf) == NULL)) {
bad_parse_time:
fprintf(ttyout, "Can't parse time `%s'.\n", timestr);
goto cleanup_parse_time;
}
- memset(&timebuf, 0, sizeof(timebuf));
- timebuf.tm_sec = sec;
- timebuf.tm_min = min;
- timebuf.tm_hour = hour;
- timebuf.tm_mday = day;
- timebuf.tm_mon = mo - 1;
- timebuf.tm_year = yy - TM_YEAR_BASE;
timebuf.tm_isdst = -1;
rtime = timegm(&timebuf);
if (rtime == -1) {
- if (noisy || debug != 0)
+ if (noisy || ftp_debug != 0)
goto bad_parse_time;
else
goto cleanup_parse_time;
- } else if (debug)
- fprintf(ttyout, "parsed date as: %s", ctime(&rtime));
+ } else
+ DPRINTF("parsed date `%s' as " LLF ", %s",
+ timestr, (LLT)rtime,
+ rfc2822time(localtime(&rtime)));
} else {
if (r == ERROR && code == 500 && features[FEAT_MDTM] == -1)
features[FEAT_MDTM] = 0;
- if (noisy && debug == 0) {
+ if (noisy && ftp_debug == 0) {
fputs(reply_string, ttyout);
putc('\n', ttyout);
}
@@ -759,6 +789,21 @@ remotemodtime(const char *file, int noisy)
}
/*
+ * Format tm in an RFC2822 compatible manner, with a trailing \n.
+ * Returns a pointer to a static string containing the result.
+ */
+const char *
+rfc2822time(const struct tm *tm)
+{
+ static char result[50];
+
+ if (strftime(result, sizeof(result),
+ "%a, %d %b %Y %H:%M:%S %z\n", tm) == 0)
+ errx(1, "Can't convert RFC2822 time: buffer too small");
+ return result;
+}
+
+/*
* Update global `localcwd', which contains the state of the local cwd
*/
void
@@ -767,8 +812,7 @@ updatelocalcwd(void)
if (getcwd(localcwd, sizeof(localcwd)) == NULL)
localcwd[0] = '\0';
- if (debug)
- fprintf(ttyout, "got localcwd as `%s'\n", localcwd);
+ DPRINTF("got localcwd as `%s'\n", localcwd);
}
/*
@@ -782,7 +826,7 @@ updateremotecwd(void)
overbose = verbose;
ocode = code;
- if (debug == 0)
+ if (ftp_debug == 0)
verbose = -1;
if (command("PWD") != COMPLETE)
goto badremotecwd;
@@ -800,8 +844,7 @@ updateremotecwd(void)
remotecwd[i] = *cp;
}
remotecwd[i] = '\0';
- if (debug)
- fprintf(ttyout, "got remotecwd as `%s'\n", remotecwd);
+ DPRINTF("got remotecwd as `%s'\n", remotecwd);
goto cleanupremotecwd;
badremotecwd:
remotecwd[0]='\0';
@@ -821,7 +864,7 @@ fileindir(const char *file, const char *dir)
char realdir[PATH_MAX+1];
size_t dirlen;
- /* determine parent directory of file */
+ /* determine parent directory of file */
(void)strlcpy(parentdirbuf, file, sizeof(parentdirbuf));
parentdir = dirname(parentdirbuf);
if (strcmp(parentdir, ".") == 0)
@@ -878,10 +921,12 @@ list_vertical(StringList *sl)
putc('\n', ttyout);
break;
}
- w = strlen(p);
- while (w < width) {
- w = (w + 8) &~ 7;
- (void)putc('\t', ttyout);
+ if (p) {
+ w = strlen(p);
+ while (w < width) {
+ w = (w + 8) &~ 7;
+ (void)putc('\t', ttyout);
+ }
}
}
}
@@ -1026,11 +1071,11 @@ setupsockbufsize(int sock)
if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF,
(void *)&sndbuf_size, sizeof(sndbuf_size)) == -1)
- warn("unable to set sndbuf size %d", sndbuf_size);
+ warn("Unable to set sndbuf size %d", sndbuf_size);
if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
(void *)&rcvbuf_size, sizeof(rcvbuf_size)) == -1)
- warn("unable to set rcvbuf size %d", rcvbuf_size);
+ warn("Unable to set rcvbuf size %d", rcvbuf_size);
}
/*
@@ -1186,7 +1231,7 @@ parseport(const char *port, int defport)
long nport;
char *p, *ep;
- p = xstrdup(port);
+ p = ftp_strdup(port);
nport = strtol(p, &ep, 10);
if (*ep != '\0' && ep == p) {
struct servent *svp;
@@ -1229,8 +1274,7 @@ isipv6addr(const char *addr)
rv = 1;
freeaddrinfo(res);
}
- if (debug)
- fprintf(ttyout, "isipv6addr: got %d for %s\n", rv, addr);
+ DPRINTF("isipv6addr: got %d for %s\n", rv, addr);
#endif
return (rv == 1) ? 1 : 0;
}
@@ -1285,29 +1329,65 @@ getline(FILE *stream, char *buf, size_t buflen, const char **errormsg)
return len;
}
-
/*
- * Internal version of connect(2); sets socket buffer sizes first and
+ * Internal version of connect(2); sets socket buffer sizes,
+ * binds to a specific local address (if set), and
* supports a connection timeout using a non-blocking connect(2) with
* a poll(2).
* Socket fcntl flags are temporarily updated to include O_NONBLOCK;
* these will not be reverted on connection failure.
- * Returns -1 upon failure (with errno set to the problem), or 0 on success.
+ * Returns 0 on success, or -1 upon failure (with an appropriate
+ * error message displayed.)
*/
int
-xconnect(int sock, const struct sockaddr *name, socklen_t namelen)
+ftp_connect(int sock, const struct sockaddr *name, socklen_t namelen)
{
int flags, rv, timeout, error;
socklen_t slen;
struct timeval endtime, now, td;
struct pollfd pfd[1];
+ char hname[NI_MAXHOST];
setupsockbufsize(sock);
+ if (getnameinfo(name, namelen,
+ hname, sizeof(hname), NULL, 0, NI_NUMERICHOST) != 0)
+ strlcpy(hname, "?", sizeof(hname));
+
+ if (bindai != NULL) { /* bind to specific addr */
+ struct addrinfo *ai;
+
+ for (ai = bindai; ai != NULL; ai = ai->ai_next) {
+ if (ai->ai_family == name->sa_family)
+ break;
+ }
+ if (ai == NULL)
+ ai = bindai;
+ if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
+ char bname[NI_MAXHOST];
+ int saveerr;
+
+ saveerr = errno;
+ if (getnameinfo(ai->ai_addr, ai->ai_addrlen,
+ bname, sizeof(bname), NULL, 0, NI_NUMERICHOST) != 0)
+ strlcpy(bname, "?", sizeof(bname));
+ errno = saveerr;
+ warn("Can't bind to `%s'", bname);
+ return -1;
+ }
+ }
- if ((flags = fcntl(sock, F_GETFL, 0)) == -1)
- return -1; /* get current socket flags */
- if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) == -1)
- return -1; /* set non-blocking connect */
+ /* save current socket flags */
+ if ((flags = fcntl(sock, F_GETFL, 0)) == -1) {
+ warn("Can't %s socket flags for connect to `%s'",
+ "save", hname);
+ return -1;
+ }
+ /* set non-blocking connect */
+ if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) == -1) {
+ warn("Can't set socket non-blocking for connect to `%s'",
+ hname);
+ return -1;
+ }
/* NOTE: we now must restore socket flags on successful exit */
@@ -1321,8 +1401,11 @@ xconnect(int sock, const struct sockaddr *name, socklen_t namelen)
rv = connect(sock, name, namelen); /* inititate the connection */
if (rv == -1) { /* connection error */
- if (errno != EINPROGRESS) /* error isn't "please wait" */
+ if (errno != EINPROGRESS) { /* error isn't "please wait" */
+ connecterror:
+ warn("Can't connect to `%s'", hname);
return -1;
+ }
/* connect EINPROGRESS; wait */
do {
@@ -1336,34 +1419,39 @@ xconnect(int sock, const struct sockaddr *name, socklen_t namelen)
timeout = INFTIM;
}
pfd[0].revents = 0;
- rv = xpoll(pfd, 1, timeout);
+ rv = ftp_poll(pfd, 1, timeout);
/* loop until poll ! EINTR */
} while (rv == -1 && errno == EINTR);
if (rv == 0) { /* poll (connect) timed out */
errno = ETIMEDOUT;
- return -1;
+ goto connecterror;
}
if (rv == -1) { /* poll error */
- return -1;
+ goto connecterror;
} else if (pfd[0].revents & (POLLIN|POLLOUT)) {
slen = sizeof(error); /* OK, or pending error */
if (getsockopt(sock, SOL_SOCKET, SO_ERROR,
- &error, &slen) == -1)
- return -1; /* Solaris pending error */
- if (error != 0) {
+ &error, &slen) == -1) {
+ /* Solaris pending error */
+ goto connecterror;
+ } else if (error != 0) {
errno = error; /* BSD pending error */
- return -1;
+ goto connecterror;
}
} else {
errno = EBADF; /* this shouldn't happen ... */
- return -1;
+ goto connecterror;
}
}
- if (fcntl(sock, F_SETFL, flags) == -1) /* restore socket flags */
+ if (fcntl(sock, F_SETFL, flags) == -1) {
+ /* restore socket flags */
+ warn("Can't %s socket flags for connect to `%s'",
+ "restore", hname);
return -1;
+ }
return 0;
}
@@ -1371,7 +1459,7 @@ xconnect(int sock, const struct sockaddr *name, socklen_t namelen)
* Internal version of listen(2); sets socket buffer sizes first.
*/
int
-xlisten(int sock, int backlog)
+ftp_listen(int sock, int backlog)
{
setupsockbufsize(sock);
@@ -1383,12 +1471,13 @@ xlisten(int sock, int backlog)
* on platforms without the former.
*/
int
-xpoll(struct pollfd *fds, int nfds, int timeout)
+ftp_poll(struct pollfd *fds, int nfds, int timeout)
{
-#if HAVE_POLL
+#if defined(HAVE_POLL)
return poll(fds, nfds, timeout);
-#elif HAVE_SELECT /* implement poll(2) using select(2) */
+#elif defined(HAVE_SELECT)
+ /* implement poll(2) using select(2) */
fd_set rset, wset, xset;
const int rsetflags = POLLIN | POLLRDNORM;
const int wsetflags = POLLOUT | POLLWRNORM;
@@ -1449,7 +1538,7 @@ xpoll(struct pollfd *fds, int nfds, int timeout)
* malloc() with inbuilt error checking
*/
void *
-xmalloc(size_t size)
+ftp_malloc(size_t size)
{
void *p;
@@ -1463,7 +1552,7 @@ xmalloc(size_t size)
* sl_init() with inbuilt error checking
*/
StringList *
-xsl_init(void)
+ftp_sl_init(void)
{
StringList *p;
@@ -1477,7 +1566,7 @@ xsl_init(void)
* sl_add() with inbuilt error checking
*/
void
-xsl_add(StringList *sl, char *i)
+ftp_sl_add(StringList *sl, char *i)
{
if (sl_add(sl, i) == -1)
@@ -1488,12 +1577,12 @@ xsl_add(StringList *sl, char *i)
* strdup() with inbuilt error checking
*/
char *
-xstrdup(const char *str)
+ftp_strdup(const char *str)
{
char *s;
if (str == NULL)
- errx(1, "xstrdup() called with NULL argument");
+ errx(1, "ftp_strdup: called with NULL argument");
s = strdup(str);
if (s == NULL)
err(1, "Unable to allocate memory for string copy");