This commit was generated by cvs2svn to compensate for changes in r116424,

which included commits to RCS files with non-trunk default branches.
This commit is contained in:
Mike Heffner 2003-06-16 02:36:38 +00:00
commit fa65375d6b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=116425
18 changed files with 4706 additions and 557 deletions

View File

@ -0,0 +1,64 @@
diff -ru src.orig/cmds.c src/cmds.c
--- src.orig/cmds.c Sun Jun 15 22:11:43 2003
+++ src/cmds.c Sun Jun 15 21:46:37 2003
@@ -131,6 +131,7 @@
#include <string.h>
#include <time.h>
#include <unistd.h>
+#include <libutil.h>
#include "ftp_var.h"
#include "version.h"
diff -ru src.orig/fetch.c src/fetch.c
--- src.orig/fetch.c Sun Jun 15 22:11:43 2003
+++ src/fetch.c Sun Jun 15 21:46:53 2003
@@ -69,6 +69,7 @@
#include <string.h>
#include <unistd.h>
#include <time.h>
+#include <libutil.h>
#include "ftp_var.h"
#include "version.h"
Only in src: ftp.cat1
diff -ru src.orig/progressbar.c src/progressbar.c
--- src.orig/progressbar.c Sun Jun 15 22:11:43 2003
+++ src/progressbar.c Sun Jun 15 21:50:48 2003
@@ -50,6 +50,7 @@
*/
#include <sys/types.h>
#include <sys/param.h>
+#include <sys/time.h>
#include <err.h>
#include <errno.h>
@@ -57,10 +58,12 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
-#include <tzfile.h>
#include <unistd.h>
#include "progressbar.h"
+
+#define SECSPERHOUR 60
+#define SECSPERDAY ((long)60 * 60 * 24)
#if !defined(NO_PROGRESS)
/*
diff -ru src.orig/util.c src/util.c
--- src.orig/util.c Sun Jun 15 22:11:44 2003
+++ src/util.c Sun Jun 15 21:51:31 2003
@@ -101,10 +101,11 @@
#include <string.h>
#include <termios.h>
#include <time.h>
-#include <tzfile.h>
#include <unistd.h>
#include "ftp_var.h"
+
+#define TM_YEAR_BASE 1900
/*
* Connect to peer server and auto-login, if possible.

3500
contrib/lukemftp/diffout Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,26 @@
# $NetBSD: Makefile,v 1.26 2003/01/21 16:08:06 jhawk Exp $
# from: @(#)Makefile 8.2 (Berkeley) 4/3/94
PROG= ftp
SRCS= cmds.c cmdtab.c complete.c domacro.c fetch.c ftp.c main.c \
progressbar.c ruserpass.c util.c
# Uncomment the following to provide defaults for gate-ftp operation
#
#CPPFLAGS+=-DGATE_SERVER=\"ftp-gw.host\" # -DGATE_PORT=21
.if defined(SMALLPROG)
CPPFLAGS+=-DNO_EDITCOMPLETE -DNO_ABOUT
.else
LDADD+= -ledit -ltermcap
DPADD+= ${LIBEDIT} ${LIBTERMCAP}
.endif
.if !defined(SMALLPROG) || defined(SMALLPROG_INET6)
CPPFLAGS+= -DINET6
.endif
cmds.o fetch.o: version.h
main.o: ftp_var.h
.include <bsd.prog.mk>

View File

@ -1,4 +1,4 @@
/* $NetBSD: cmds.c,v 1.98 2002/06/05 10:20:46 lukem Exp $ */
/* $NetBSD: cmds.c,v 1.100 2002/11/30 03:10:55 lukem Exp $ */
/*-
* Copyright (c) 1996-2002 The NetBSD Foundation, Inc.
@ -102,11 +102,36 @@
* SUCH DAMAGE.
*/
#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.100 2002/11/30 03:10:55 lukem Exp $");
#endif
#endif /* not lint */
/*
* FTP User Program -- Command Routines.
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <arpa/ftp.h>
#include "lukemftp.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>
#include <libutil.h>
#include "ftp_var.h"
#include "version.h"
@ -1008,7 +1033,7 @@ setgate(int argc, char *argv[])
gatemode = 0;
else {
if (argc == 3)
gateport = strdup(argv[2]);
gateport = xstrdup(argv[2]);
(void)strlcpy(gsbuf, argv[1], sizeof(gsbuf));
gateserver = gsbuf;
gatemode = 1;

View File

@ -1,4 +1,4 @@
/* $NetBSD: cmdtab.c,v 1.39 2000/11/15 00:10:59 lukem Exp $ */
/* $NetBSD: cmdtab.c,v 1.40 2002/07/29 04:24:47 lukem Exp $ */
/*-
* Copyright (c) 1996-2000 The NetBSD Foundation, Inc.
@ -69,8 +69,16 @@
* SUCH DAMAGE.
*/
#include "lukemftp.h"
#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.40 2002/07/29 04:24:47 lukem Exp $");
#endif
#endif /* not lint */
#include <stdio.h>
#include "ftp_var.h"
/*
@ -123,7 +131,7 @@ char nmaphelp[] = "set templates for default file name mapping";
char ntranshelp[] = "set translation table for default file name mapping";
char optshelp[] = "show or set options for remote commands";
char pagehelp[] = "view a remote file through your pager";
char passivehelp[] = "enter passive transfer mode";
char passivehelp[] = "toggle use of passive transfer mode";
char plshelp[] = "list contents of remote path through your pager";
char pmlsdhelp[] = "list contents of remote directory in a machine "
"parsable form through your pager";

View File

@ -36,11 +36,23 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: complete.c,v 1.38 2000/05/01 10:35:17 lukem Exp $");
#endif /* not lint */
/*
* FTP user program - command and file completion routines
*/
#include "lukemftp.h"
#include <sys/stat.h>
#include <ctype.h>
#include <err.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ftp_var.h"

View File

@ -33,7 +33,18 @@
* SUCH DAMAGE.
*/
#include "lukemftp.h"
#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.19 2002/02/01 05:04:43 itojun Exp $");
#endif
#endif /* not lint */
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "ftp_var.h"

View File

@ -1,7 +1,7 @@
/* $NetBSD: extern.h,v 1.60 2000/10/11 14:46:03 is Exp $ */
/* $NetBSD: extern.h,v 1.61 2003/01/21 16:08:07 jhawk Exp $ */
/*-
* Copyright (c) 1996-2000 The NetBSD Foundation, Inc.
* Copyright (c) 1996-2003 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@ -110,7 +110,6 @@ void abortpt(int);
void abortxfer(int);
void account(int, char **);
void ai_unmapped(struct addrinfo *);
void alarmtimer(int);
int another(int *, char ***, const char *);
int auto_fetch(int, char **);
int auto_put(int, char **, const char *);
@ -123,7 +122,7 @@ void cmdabort(int);
void cmdtimeout(int);
void cmdscanner(void);
int command(const char *, ...)
;
__attribute__((__format__(__printf__, 1, 2)));
#ifndef NO_EDITCOMPLETE
unsigned char complete(EditLine *, int);
void controlediting(void);
@ -183,14 +182,11 @@ void newer(int, char **);
void page(int, char **);
int parseport(const char *, int);
int parserate(int, char **, int);
void progressmeter(int);
char *prompt(void);
void proxabort(int);
void proxtrans(const char *, const char *, const char *);
void psabort(int);
void psummary(int);
void pswitch(int);
void ptransfer(int);
void put(int, char **);
void pwd(int, char **);
void quit(int, char **);
@ -263,5 +259,3 @@ void *xmalloc(size_t);
StringList *xsl_init(void);
void xsl_add(StringList *, char *);
char *xstrdup(const char *);
sigfunc xsignal(int, sigfunc);
sigfunc xsignal_restart(int, sigfunc, int);

View File

@ -1,7 +1,7 @@
/* $NetBSD: fetch.c,v 1.136 2002/06/05 10:20:48 lukem Exp $ */
/* $NetBSD: fetch.c,v 1.141 2003/05/14 14:31:00 wiz Exp $ */
/*-
* Copyright (c) 1997-2002 The NetBSD Foundation, Inc.
* Copyright (c) 1997-2003 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@ -39,11 +39,37 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: fetch.c,v 1.141 2003/05/14 14:31:00 wiz Exp $");
#endif /* not lint */
/*
* FTP User Program -- Command line file retrieval
*/
#include "lukemftp.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>
#include <libutil.h>
#include "ftp_var.h"
#include "version.h"
@ -155,7 +181,7 @@ auth_url(const char *challenge, char **response, const char *guser,
*response = (char *)xmalloc(rlen);
(void)strlcpy(*response, scheme, rlen);
len = strlcat(*response, " ", rlen);
base64_encode(clear, clen, *response + len);
base64_encode(clear, clen, (u_char *)*response + len);
memset(clear, 0, clen);
rval = 0;
@ -235,12 +261,12 @@ url_decode(char *url)
* XXX: this is not totally RFC 1738 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
* host and the url-path removed, but any additional leading slashes
* in the url-path are retained (because they imply that we should
* 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).
*
* Examples:
* input url output path
* input URL output path
* --------- -----------
* "ftp://host" NULL
* "http://host/" NULL
@ -484,7 +510,8 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
rval = fetch_ftp(url);
goto cleanup_fetch_url;
}
warnx("Invalid URL (no file after directory) `%s'", url);
warnx("no file after directory (you must specify an "
"output file) `%s'", url);
goto cleanup_fetch_url;
} else {
if (debug)
@ -1741,7 +1768,7 @@ auto_put(int argc, char **argv, const char *uploadserver)
}
}
if (debug)
fprintf(ttyout, "auto_put: url `%s' argv[2] `%s'\n",
fprintf(ttyout, "auto_put: URL `%s' argv[2] `%s'\n",
path, uargv[2] ? uargv[2] : "<null>");
/* connect and cwd */

View File

@ -1,6 +1,6 @@
.\" $NetBSD: ftp.1,v 1.83 2002/06/05 10:20:48 lukem Exp $
.\" $NetBSD: ftp.1,v 1.94 2003/05/14 14:31:00 wiz Exp $
.\"
.\" Copyright (c) 1996-2002 The NetBSD Foundation, Inc.
.\" Copyright (c) 1996-2003 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
@ -68,7 +68,7 @@
.\"
.\" @(#)ftp.1 8.3 (Berkeley) 10/9/94
.\"
.Dd May 18, 2002
.Dd January 20, 2003
.Dt FTP 1
.Os
.Sh NAME
@ -76,7 +76,7 @@
.Nd
Internet file transfer program
.Sh SYNOPSIS
.Nm ""
.Nm
.Op Fl 46AadefginpRtvV
.Bk -words
.Op Fl N Ar netrc
@ -88,46 +88,81 @@ Internet file transfer program
.Op Fl P Ar port
.Ek
.Bk -words
.Op Fl q Ar quittime
.Ek
.Bk -words
.Op Fl r Ar retry
.Ek
.Bk -words
.\" [-T dir,max[,inc]]
.Oo
.Fl T
.Fl T Xo
.Sm off
.Xo
.Ar dir ,
.Ar max
.Op , Ar inc
.Xc
.Sm on
.Xc
.Oc
.Ek
.Bk -words
.\" [[user@]host [port]]
.Oo
[\fIuser\fR@]\fIhost\fR
.Oo Ar user Ns Li \&@ Oc Ns Ar host
.Op Ar port
.Oc
.Ek
.Bk -words
[\fIuser\fR@]\fIhost\fR:[\fIpath\fR][/]
.\" [[user@]host:[path][/]]
.Sm off
.Oo
.Op Ar user Li \&@
.Ar host Li \&:
.Op Ar path
.Op Li /
.Oc
.Sm on
.Ek
.Bk -words
.Op file:///\fIpath\fR
.\" [file:///path]
.Sm off
.Oo
.Li file:/// Ar path
.Oc
.Sm on
.Ek
.Bk -words
.Op ftp://[\fIuser\fR[:\fIpassword\fR]@]\fIhost\fR[:\fIport\fR]/\fIpath\fR[/]
.\" [ftp://[user[:password]@]host[:port]/path[/]]
.Sm off
.Oo
.Li ftp://
.Oo Ar user
.Op Li \&: Ar password
.Li \&@ Oc
.Ar host Oo Li \&: Ar port Oc
.Li / Ar path
.Op Li /
.Op Li ;type= Ar X
.Oc
.Sm on
.Ek
.Bk -words
.Op http://[\fIuser\fR[:\fIpassword\fR]@]\fIhost\fR[:\fIport\fR]/\fIpath\fR
.\" [http://[user[:password]@]host[:port]/path]
.Sm off
.Oo
.Li http://
.Oo Ar user
.Op Li \&: Ar password
.Li \&@ Oc
.Ar host Oo Li \&: Ar port Oc
.Li / Ar path
.Oc
.Sm on
.Ek
.Op Ar \&.\&.\&.
.Nm ""
.Fl u Ar url
.\".Ar ftp://[\fIuser\fR[:\fIpassword\fR]@]\fIhost\fR[:\fIport\fR]/\fIpath\fR[/[file]]
.\"|
.\".Ar [\fIuser\fR@]\fIhost\fR:[\fIpath\fR][/[\fIfile\fR]]
.Nm
.Bk -words
file
.Fl u Ar URL Ar file
.Ek
.Op Ar \&.\&.\&.
.Sh DESCRIPTION
@ -243,6 +278,10 @@ Sets the port number to
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
Restart all non-proxied auto-fetches.
.It Fl t
@ -266,11 +305,11 @@ bytes/second.
Refer to
.Ic rate
for more information.
.It Fl u Ar url file Op \&.\&.\&.
.It Fl u Ar URL file Op \&.\&.\&.
Upload files on the command line to
.Ar url
.Ar URL
where
.Ar url
.Ar URL
is one of the ftp URL types as supported by auto-fetch
(with an optional target filename for single file uploads), and
.Ar file
@ -869,7 +908,7 @@ will attempt to contact an
.Tn FTP
server at that port.
If the
.Ic auto-login
.Ic "set auto-login"
option is on (default),
.Nm
will also attempt to automatically log the user in to
@ -882,10 +921,10 @@ Retrieve
and display with the program specified by the
.Ic "set pager"
option.
.It Ic passive Op Ic auto
.It Ic passive Op Cm auto
Toggle passive mode (if no arguments are given).
If
.Ic auto
.Cm auto
is given, act as if
.Ev FTPMODE
is set to
@ -896,14 +935,17 @@ will send a
.Dv PASV
command for all data connections instead of a
.Dv PORT
command. The
command.
The
.Dv PASV
command requests that the remote server open a port for the data connection
and return the address of that port. The remote server listens on that
port and the client connects to it. When using the more traditional
and return the address of that port.
The remote server listens on that port and the client connects to it.
When using the more traditional
.Dv PORT
command, the client listens on a port and sends that address to the remote
server, who connects back to it. Passive mode is useful when using
server, who connects back to it.
Passive mode is useful when using
.Nm
through a gateway router or host that controls the directionality of
traffic.
@ -965,34 +1007,34 @@ will delete all files.
.Pp
When prompting is on, the following commands are available at a prompt:
.Bl -tag -width 2n -offset indent
.It Ic a
.It Cm a
Answer
.Sq yes
to the current file, and automatically answer
.Sq yes
to any remaining files for the current command.
.It Ic n
.It Cm n
Answer
.Sq no ,
and do not transfer the file.
.It Ic p
.It Cm p
Answer
.Sq yes
to the current file, and turn off prompt mode
(as is
.Dq prompt off
had been given).
.It Ic q
.It Cm q
Terminate the current operation.
.It Ic y
.It Cm y
Answer
.Sq yes ,
and transfer the file.
.It Ic ?
.It Cm ?
Display a help message.
.El
.Pp
Any other reponse will answer
Any other response will answer
.Sq yes
to the current file.
.It Ic proxy Ar ftp-command
@ -1072,11 +1114,11 @@ is 0, disable the throttle.
.Ar direction
may be one of:
.Bl -tag -width "all" -offset indent -compact
.It Ic all
.It Cm all
Both directions.
.It Ic get
.It Cm get
Incoming transfers.
.It Ic put
.It Cm put
Outgoing transfers.
.El
.Pp
@ -1240,7 +1282,7 @@ for certain
implementations which do ignore
.Dv PORT
commands but, incorrectly, indicate they've been accepted.
.It Ic set Op Ar "option value"
.It Ic set Op Ar option Ar value
Set
.Ar option
to
@ -1252,25 +1294,25 @@ and
are not given, display all of the options and their values.
The currently supported options are:
.Bl -tag -width "http_proxy" -offset indent
.It anonpass
.It Cm anonpass
Defaults to
.Ev $FTPANONPASS
.It ftp_proxy
.It Cm ftp_proxy
Defaults to
.Ev $ftp_proxy .
.It http_proxy
.It Cm http_proxy
Defaults to
.Ev $http_proxy .
.It no_proxy
.It Cm no_proxy
Defaults to
.Ev $no_proxy .
.It pager
.It Cm pager
Defaults to
.Ev $PAGER .
.It prompt
.It Cm prompt
Defaults to
.Ev $FTPPROMPT .
.It rprompt
.It Cm rprompt
Defaults to
.Ev $FTPRPROMPT .
.El
@ -1415,13 +1457,14 @@ support an optional suffix on the argument which changes the
interpretation of the argument.
Supported suffixes are:
.Bl -tag -width 3n -offset indent -compact
.It b
Causes no modification. (Optional)
.It k
.It Li b
Causes no modification.
(Optional)
.It Li k
Kilo; multiply the argument by 1024
.It m
.It Li m
Mega; multiply the argument by 1048576
.It g
.It Li g
Giga; multiply the argument by 1073741824
.El
.Pp
@ -1447,7 +1490,15 @@ on the command line.
.Pp
The following formats are valid syntax for an auto-fetch element:
.Bl -tag -width "FOO "
.It [user@]host:[path][/]
.\" [user@]host:[path][/]
.It Xo
.Sm off
.Op Ar user Li \&@
.Ar host Li \&:
.Op Ar path
.Op Li /
.Sm on
.Xc
.Dq Classic
.Tn FTP
format.
@ -1471,7 +1522,19 @@ of
in the current directory.
Otherwise, the full remote name is used as the local name,
relative to the local root directory.
.It ftp://[user[:password]@]host[:port]/path[/][;type=X]
.\" ftp://[user[:password]@]host[:port]/path[/][;type=X]
.It Xo
.Sm off
.Li ftp://
.Oo Ar user
.Op Li \&: Ar password
.Li \&@ Oc
.Ar host Oo Li \&: Ar port Oc
.Li / Ar path
.Op Li /
.Op Li ;type= Ar X
.Sm on
.Xc
An
.Tn FTP
URL, retrieved using the
@ -1493,15 +1556,94 @@ In this case, use
.Ar password
if supplied, otherwise prompt the user for one.
.Pp
If a suffix of
.Sq ;type=A
or
.Sq ;type=I
is supplied, then the transfer type will take place as
ascii or binary (respectively).
The default transfer type is binary.
.Pp
In order to be compliant with
.Cm RFC 1738 ,
.Nm
strips the leading
.Sq /
from
interprets the
.Ar path
part of an
.Dq ftp://
auto-fetch URL as follows:
.Bl -bullet
.It
The
.Sq Li /
immediately after the
.Ar host Ns Oo Li \&: Ns Ar port Oc
is interpreted as a separator before the
.Ar path ,
resulting in a transfer relative from the default login directory of
the user.
and not as part of the
.Ar path
itself.
.It
The
.Ar path
is interpreted as a
.So Li / Sc Ns -separated
list of name components.
For all but the last such component,
.Nm
performs the equivalent of a
.Ic cd
command.
For the last path component,
.Nm
performs the equivalent of a
.Ic get
command.
.It
Empty name components,
which result from
.Sq Li //
within the
.Ar path ,
or from an extra
.Sq Li /
at the beginning of the
.Ar path ,
will cause the equivalent of a
.Ic cd
command without a directory name.
This is unlikely to be useful.
.It
Any
.Sq Li \&% Ns Ar XX
codes within the path components are decoded, with
.Ar XX
representing a character code in hexadecimal.
This decoding takes place after the
.Ar path
has been split into components,
but before each component is used in the equivalent of a
.Ic cd
or
.Ic get
command.
Some often-used codes are
.Sq Li \&%2F
(which represents
.Sq Li / )
and
.Sq Li \&%7E
(which represents
.Sq Li ~ ) .
.El
.Pp
The above interpretation has the following consequences:
.Bl -bullet
.It
The path is interpreted relative to the
default login directory of the specified user or of the
.Sq anonymous
user.
If the
.Pa /
directory is required, use a leading path of
@ -1519,15 +1661,57 @@ with the password
.Sq mypass ,
use
.Dq ftp://myname:mypass@localhost/%2fetc/motd
.Pp
If a suffix of
.Sq ;type=A
or
.Sq ;type=I
is supplied, then the transfer type will take place as
ascii or binary (respectively).
The default transfer type is binary.
.It http://[user[:password]@]host[:port]/path
.It
The exact
.Ic cd
and
.Ic get
commands can be controlled by careful choice of
where to use
.Sq /
and where to use
.Sq %2F
(or
.Sq %2f ) .
For example, the following URLs correspond to the
equivalents of the indicated commands:
.Bl -tag -width "ftp://host/%2Fdir1%2Fdir2%2Ffile"
.It ftp://host/dir1/dir2/file
.Dq "cd dir1" ,
.Dq "cd dir2" ,
.Dq "get file" .
.It ftp://host/%2Fdir1/dir2/file
.Dq "cd /dir1" ,
.Dq "cd dir2" ,
.Dq "get file" .
.It ftp://host/dir1%2Fdir2/file
.Dq "cd dir1/dir2" ,
.Dq "get file" .
.It ftp://host/%2Fdir1%2Fdir2/file
.Dq "cd /dir1/dir2" ,
.Dq "get file" .
.It ftp://host/dir1%2Fdir2%2Ffile
.Dq "get dir1/dir2/file" .
.It ftp://host/%2Fdir1%2Fdir2%2Ffile
.Dq "get /dir1/dir2/file" .
.El
.It
You must have appropriate access permission for each of the
intermediate directories that is used in the equivalent of a
.Ic cd
command.
.El
.\" http://[user[:password]@]host[:port]/path
.It Xo
.Sm off
.Li http://
.Oo Ar user
.Op Li \&: Ar password
.Li \&@ Oc
.Ar host Oo Li \&: Ar port Oc
.Li / Ar path
.Sm on
.Xc
An
.Tn HTTP
URL, retrieved using the
@ -1540,16 +1724,22 @@ is defined, it is used as a URL to an
proxy server.
If
.Tn HTTP
authorisation is required to retrieve
authorization is required to retrieve
.Ar path ,
and
.Sq user
(and optionally
.Sq password )
is in the URL, use them for the first attempt to authenticate.
.It file:///path
.\" file:///path
.It Xo
.Sm off
.Li file:/// Ar path
.Sm on
.Xc
A local URL, copied from
.Ar /path .
.Pa / Ns Ar path
on the local host.
.El
.Pp
Unless noted otherwise above, and
@ -1736,7 +1926,7 @@ mode transfers.
.Nm
supports only the default values for the remaining
file transfer parameters:
.Ic mode ,
.Ic mode ,
.Ic form ,
and
.Ic struct .
@ -1841,6 +2031,14 @@ If a macro named
.Ic init
is defined, it is automatically executed as the last step in the
auto-login process.
For example,
.Bd -literal -offset indent
default
macdef init
epsv4 off
.Ed
.Pp
followed by a blank line.
.El
.Sh COMMAND LINE EDITING
.Nm
@ -1888,9 +2086,20 @@ command.
The following formatting sequences are replaced by the given
information:
.Bl -tag -width "%% " -offset indent
.It %/
.It Li \&%/
The current remote working directory.
.It %c[[0]\fIn\fR], %.[[0]\fIn\fR]
.\" %c[[0]n], %.[[0]n]
.It Xo
.Sm off
.Li \&%c
.Op Oo Li 0 Oc Ar n
.Sm on
.No ,
.Sm off
.Li \&%.
.Op Oo Li 0 Oc Ar n
.Sm on
.Xc
The trailing component of the current remote working directory, or
.Em n
trailing components if a digit
@ -1902,21 +2111,28 @@ begins with
.Sq 0 ,
the number of skipped components precede the trailing component(s) in
the format
.Dq /\fI\*[Lt]skipped\*[Gt]\fRtrailing
.\" ``/<number>trailing''
.Do
.Sm off
.Li / Li \*[Lt] Va number Li \*[Gt]
.Va trailing
.Sm on
.Dc
(for
.Sq %c )
.Sq \&%c )
or
.Dq ...trailing
.\" ``...trailing''
.Dq Li \&... Ns Va trailing
(for
.Sq %. ) .
.It %M
.Sq \&%. ) .
.It Li \&%M
The remote host name.
.It %m
.It Li \&%m
The remote host name, up to the first
.Sq \&. .
.It %n
.It Li \&%n
The remote user name.
.It %%
.It Li \&%%
A single
.Sq % .
.El
@ -1934,15 +2150,15 @@ Defaults to
Overrides the default operation mode.
Support values are:
.Bl -tag -width "passive"
.It active
.It Cm active
active mode
.Tn FTP
only
.It auto
.It Cm auto
automatic determination of passive or active (this is the default)
.It gate
.It Cm gate
gate-ftp mode
.It passive
.It Cm passive
passive mode
.Tn FTP
only
@ -2028,6 +2244,21 @@ proxying is not to be used.
Each entry may have an optional trailing ":port", which restricts
the matching to connections to that port.
.El
.Sh EXTENDED PASSIVE MODE AND FIREWALLS
Some firewall configurations do not allow
.Nm
to use extended passive mode.
If you find that even a simple
.Ic ls
appears to hang after printing a message such as this:
.Pp
.Dl 229 Entering Extended Passive Mode (|||58551|)
.Pp
then you will need to disable extended passive mode with
.Ic epsv4 off .
See the above section
.Sx The .netrc File
for an example of how to make this automatic.
.Sh SEE ALSO
.Xr getservbyname 3 ,
.Xr editrc 5 ,
@ -2061,7 +2292,9 @@ and other enhancements over the standard
were implemented in
.Nx 1.3
and later releases
by Luke Mewburn \*[Lt]lukem@netbsd.org\*[Gt].
by
.An Luke Mewburn
.Aq lukem@NetBSD.org .
.Pp
IPv6 support was added by the WIDE/KAME project
(but may not be present in all non-NetBSD versions of this program, depending

View File

@ -98,10 +98,41 @@
* SUCH DAMAGE.
*/
#include "lukemftp.h"
#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.120 2002/06/05 10:20:49 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 <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <stdarg.h>
#ifndef USE_SELECT
#include <poll.h>
#endif
#include "ftp_var.h"
volatile int abrtflag = 0;

View File

@ -1,7 +1,7 @@
/* $NetBSD: ftp_var.h,v 1.62 2001/12/26 09:40:16 lukem Exp $ */
/* $NetBSD: ftp_var.h,v 1.64 2003/01/21 16:08:07 jhawk Exp $ */
/*-
* Copyright (c) 1996-2001 The NetBSD Foundation, Inc.
* Copyright (c) 1996-2003 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@ -111,14 +111,20 @@
#define NO_PROGRESS
#endif
#include <sys/param.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <setjmp.h>
#include <stringlist.h>
#ifndef NO_EDITCOMPLETE
#include <histedit.h>
#endif /* !NO_EDITCOMPLETE */
typedef void (*sigfunc)(int);
#include "extern.h"
#include "progressbar.h"
/*
* Format of command table.
@ -175,7 +181,6 @@ enum {
#define HASHBYTES 1024 /* default mark for `hash' command */
#define DEFAULTINCR 1024 /* default increment for `rate' command */
#define STALLTIME 5 /* # of seconds of no xfer before "stalling" */
#define FTP_PORT 21 /* default if ! getservbyname("ftp/tcp") */
#define HTTP_PORT 80 /* default if ! getservbyname("http/tcp") */
@ -204,9 +209,7 @@ GLOBAL int trace; /* trace packets exchanged */
GLOBAL int hash; /* print # for each buffer transferred */
GLOBAL int mark; /* number of bytes between hashes */
GLOBAL int sendport; /* use PORT/LPRT cmd for each data connection */
GLOBAL int verbose; /* print messages coming back from server */
GLOBAL int connected; /* 1 = connected to server, -1 = logged in */
GLOBAL int fromatty; /* input is from a terminal */
GLOBAL int interactive; /* interactively prompt on m* cmds */
GLOBAL int confirmrest; /* confirm rest of current m* cmd */
GLOBAL int debug; /* debugging level */
@ -223,7 +226,6 @@ GLOBAL int mcase; /* map upper to lower case for mget names */
GLOBAL int ntflag; /* use ntin ntout tables for name translation */
GLOBAL int mapflag; /* use mapin mapout templates on file names */
GLOBAL int preserve; /* preserve modification time on files */
GLOBAL int progress; /* display transfer progress bar */
GLOBAL int code; /* return/reply code for ftp command */
GLOBAL int crflag; /* if 1, strip car. rets. on ascii gets */
GLOBAL int passivemode; /* passive mode enabled */
@ -252,9 +254,7 @@ GLOBAL int rate_get_incr; /* increment for get xfer rate */
GLOBAL int rate_put; /* maximum put xfer rate */
GLOBAL int rate_put_incr; /* increment for put xfer rate */
GLOBAL int retry_connect; /* seconds between retrying connection */
GLOBAL int ttywidth; /* width of tty */
GLOBAL char *tmpdir; /* temporary directory */
GLOBAL FILE *ttyout; /* stdout, or stderr if retrieving to stdout */
GLOBAL int epsv4; /* use EPSV/EPRT on IPv4 connections */
GLOBAL int epsv4bad; /* EPSV doesn't work on the current server */
GLOBAL int editing; /* command line editing enabled */
@ -268,10 +268,7 @@ GLOBAL size_t cursor_argc; /* location of cursor in margv */
GLOBAL size_t cursor_argo; /* offset of cursor in margv[cursor_argc] */
#endif /* !NO_EDITCOMPLETE */
GLOBAL off_t bytes; /* current # of bytes read */
GLOBAL off_t filesize; /* size of file being transferred */
GLOBAL char *direction; /* direction transfer is occurring */
GLOBAL off_t restart_point; /* offset to restart transfer */
GLOBAL char *hostname; /* name of host connected to */
GLOBAL int unix_server; /* server is unix, can use binary for ascii */
@ -287,8 +284,6 @@ GLOBAL char *gateport; /* port number to use for gateftp connections */
GLOBAL char *outfile; /* filename to output URLs to */
GLOBAL int restartautofetch; /* restart auto-fetch */
GLOBAL sigjmp_buf toplevel; /* non-local goto stuff for cmd scanner */
GLOBAL char line[FTPBUFLEN]; /* input line buffer */
GLOBAL char *stringbase; /* current scan point in line buffer */
GLOBAL char argbuf[FTPBUFLEN]; /* argument storage buffer */
@ -336,29 +331,7 @@ extern struct option optiontab[];
#endif
#ifdef NO_LONG_LONG
# define LLF "%ld"
# define LLFP(x) "%" x "ld"
# define LLT long
# define ULLF "%lu"
# define ULLFP(x) "%" x "lu"
# define ULLT unsigned long
# define STRTOLL(x,y,z) strtol(x,y,z)
#else
#if HAVE_PRINTF_QD
# define LLF "%qd"
# define LLFP(x) "%" x "qd"
# define LLT long long
# define ULLF "%qu"
# define ULLFP(x) "%" x "qu"
# define ULLT unsigned long long
# define STRTOLL(x,y,z) strtoll(x,y,z)
#else
# 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
# define STRTOLL(x,y,z) strtoll(x,y,z)
#endif
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.82 2002/06/05 13:51:54 lukem Exp $ */
/* $NetBSD: main.c,v 1.84 2003/05/14 14:31:00 wiz Exp $ */
/*-
* Copyright (c) 1996-2002 The NetBSD Foundation, Inc.
@ -98,11 +98,36 @@
* SUCH DAMAGE.
*/
#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.84 2003/05/14 14:31:00 wiz Exp $");
#endif
#endif /* not lint */
/*
* FTP User Program -- Command Interface.
*/
#include <sys/types.h>
#include <sys/socket.h>
#include "lukemftp.h"
#include <err.h>
#include <errno.h>
#include <netdb.h>
#include <paths.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <locale.h>
#define GLOBAL /* force GLOBAL decls in ftp_var.h to be declared */
#include "ftp_var.h"
@ -123,9 +148,7 @@ main(int argc, char *argv[])
char *cp, *ep, *anonuser, *anonpass, *upload_path;
int dumbterm, s, len, isupload;
#if 0 /* XXX */
setlocale(LC_ALL, "");
#endif
setprogname(argv[0]);
ftpport = "ftp";
@ -258,7 +281,7 @@ main(int argc, char *argv[])
}
}
while ((ch = getopt(argc, argv, "46AadefginN:o:pP:r:RtT:u:vV")) != -1) {
while ((ch = getopt(argc, argv, "46AadefginN:o:pP:q:r:RtT:u:vV")) != -1) {
switch (ch) {
case '4':
family = AF_INET;
@ -330,6 +353,12 @@ main(int argc, char *argv[])
ftpport = optarg;
break;
case 'q':
quit_time = strtol(optarg, &ep, 10);
if (quit_time < 1 || *ep != '\0')
errx(1, "bad quit value: %s", optarg);
break;
case 'r':
retry_connect = strtol(optarg, &ep, 10);
if (retry_connect < 1 || *ep != '\0')
@ -1003,6 +1032,6 @@ usage(void)
" [-T dir,max[,inc][[user@]host [port]]] [host:path[/]]\n"
" [file:///file] [ftp://[user[:pass]@]host[:port]/path[/]]\n"
" [http://[user[:pass]@]host[:port]/path] [...]\n"
" %s -u url file [...]\n", progname, progname);
" %s -u URL file [...]\n", progname, progname);
exit(1);
}

View File

@ -0,0 +1,463 @@
/* $NetBSD: progressbar.c,v 1.3 2003/02/28 09:53:49 lukem Exp $ */
/*-
* Copyright (c) 1997-2003 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Luke Mewburn.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
* NASA Ames Research Center.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: progressbar.c,v 1.3 2003/02/28 09:53:49 lukem Exp $");
#endif /* not lint */
/*
* FTP User Program -- Misc support routines
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#include <err.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include "progressbar.h"
#define SECSPERHOUR 60
#define SECSPERDAY ((long)60 * 60 * 24)
#if !defined(NO_PROGRESS)
/*
* return non-zero if we're the current foreground process
*/
int
foregroundproc(void)
{
static pid_t pgrp = -1;
if (pgrp == -1)
pgrp = getpgrp();
return (tcgetpgrp(fileno(ttyout)) == pgrp);
}
#endif /* !defined(NO_PROGRESS) */
#ifndef NO_PROGRESS
static void updateprogressmeter(int);
/*
* SIGALRM handler to update the progress meter
*/
static void
updateprogressmeter(int dummy)
{
int oerrno = errno;
progressmeter(0);
errno = oerrno;
}
#endif /* NO_PROGRESS */
/*
* List of order of magnitude prefixes.
* The last is `P', as 2^64 = 16384 Petabytes
*/
static const char prefixes[] = " KMGTP";
/*
* Display a transfer progress bar if progress is non-zero.
* SIGALRM is hijacked for use by this function.
* - Before the transfer, set filesize to size of file (or -1 if unknown),
* and call with flag = -1. This starts the once per second timer,
* and a call to updateprogressmeter() upon SIGALRM.
* - During the transfer, updateprogressmeter will call progressmeter
* with flag = 0
* - After the transfer, call with flag = 1
*/
static struct timeval start;
static struct timeval lastupdate;
#define BUFLEFT (sizeof(buf) - len)
void
progressmeter(int flag)
{
static off_t lastsize;
off_t cursize;
struct timeval now, wait;
#ifndef NO_PROGRESS
struct timeval td;
off_t abbrevsize, bytespersec;
double elapsed;
int ratio, barlength, i, len, remaining;
/*
* Work variables for progress bar.
*
* XXX: if the format of the progress bar changes
* (especially the number of characters in the
* `static' portion of it), be sure to update
* these appropriately.
*/
char buf[256]; /* workspace for progress bar */
#define BAROVERHEAD 43 /* non `*' portion of progress bar */
/*
* stars should contain at least
* sizeof(buf) - BAROVERHEAD entries
*/
static const char stars[] =
"*****************************************************************************"
"*****************************************************************************"
"*****************************************************************************";
#endif
if (flag == -1) {
(void)gettimeofday(&start, NULL);
lastupdate = start;
lastsize = restart_point;
}
(void)gettimeofday(&now, NULL);
cursize = bytes + restart_point;
timersub(&now, &lastupdate, &wait);
if (cursize > lastsize) {
lastupdate = now;
lastsize = cursize;
wait.tv_sec = 0;
} else {
#ifndef STANDALONE_PROGRESS
if (quit_time > 0 && wait.tv_sec > quit_time) {
len = snprintf(buf, sizeof(buf), "\r\n%s: "
"transfer aborted because stalled for %lu sec.\r\n",
getprogname(), (unsigned long)wait.tv_sec);
(void)write(fileno(ttyout), buf, len);
(void)xsignal(SIGALRM, SIG_DFL);
alarmtimer(0);
siglongjmp(toplevel, 1);
}
#endif /* !STANDALONE_PROGRESS */
}
/*
* Always set the handler even if we are not the foreground process.
*/
#ifdef STANDALONE_PROGRESS
if (progress) {
#else
if (quit_time > 0 || progress) {
#endif /* !STANDALONE_PROGRESS */
if (flag == -1) {
(void)xsignal_restart(SIGALRM, updateprogressmeter, 1);
alarmtimer(1); /* set alarm timer for 1 Hz */
} else if (flag == 1) {
(void)xsignal(SIGALRM, SIG_DFL);
alarmtimer(0);
}
}
#ifndef NO_PROGRESS
if (!progress)
return;
len = 0;
/*
* print progress bar only if we are foreground process.
*/
if (! foregroundproc())
return;
len += snprintf(buf + len, BUFLEFT, "\r");
if (filesize > 0) {
ratio = (int)((double)cursize * 100.0 / (double)filesize);
ratio = MAX(ratio, 0);
ratio = MIN(ratio, 100);
len += snprintf(buf + len, BUFLEFT, "%3d%% ", ratio);
/*
* calculate the length of the `*' bar, ensuring that
* the number of stars won't exceed the buffer size
*/
barlength = MIN(sizeof(buf) - 1, ttywidth) - BAROVERHEAD;
if (barlength > 0) {
i = barlength * ratio / 100;
len += snprintf(buf + len, BUFLEFT,
"|%.*s%*s|", i, stars, barlength - i, "");
}
}
abbrevsize = cursize;
for (i = 0; abbrevsize >= 100000 && i < sizeof(prefixes); i++)
abbrevsize >>= 10;
len += snprintf(buf + len, BUFLEFT, " " LLFP("5") " %c%c ",
(LLT)abbrevsize,
prefixes[i],
i == 0 ? ' ' : 'B');
timersub(&now, &start, &td);
elapsed = td.tv_sec + (td.tv_usec / 1000000.0);
bytespersec = 0;
if (bytes > 0) {
bytespersec = bytes;
if (elapsed > 0.0)
bytespersec /= elapsed;
}
for (i = 1; bytespersec >= 1024000 && i < sizeof(prefixes); i++)
bytespersec >>= 10;
len += snprintf(buf + len, BUFLEFT,
" " LLFP("3") ".%02d %cB/s ",
(LLT)(bytespersec / 1024),
(int)((bytespersec % 1024) * 100 / 1024),
prefixes[i]);
if (filesize > 0) {
if (bytes <= 0 || elapsed <= 0.0 || cursize > filesize) {
len += snprintf(buf + len, BUFLEFT, " --:-- ETA");
} else if (wait.tv_sec >= STALLTIME) {
len += snprintf(buf + len, BUFLEFT, " - stalled -");
} else {
remaining = (int)
((filesize - restart_point) / (bytes / elapsed) -
elapsed);
if (remaining >= 100 * SECSPERHOUR)
len += snprintf(buf + len, BUFLEFT,
" --:-- ETA");
else {
i = remaining / SECSPERHOUR;
if (i)
len += snprintf(buf + len, BUFLEFT,
"%2d:", i);
else
len += snprintf(buf + len, BUFLEFT,
" ");
i = remaining % SECSPERHOUR;
len += snprintf(buf + len, BUFLEFT,
"%02d:%02d ETA", i / 60, i % 60);
}
}
}
if (flag == 1)
len += snprintf(buf + len, BUFLEFT, "\n");
(void)write(fileno(ttyout), buf, len);
#endif /* !NO_PROGRESS */
}
#ifndef STANDALONE_PROGRESS
/*
* Display transfer statistics.
* Requires start to be initialised by progressmeter(-1),
* direction to be defined by xfer routines, and filesize and bytes
* to be updated by xfer routines
* If siginfo is nonzero, an ETA is displayed, and the output goes to stderr
* instead of ttyout.
*/
void
ptransfer(int siginfo)
{
struct timeval now, td, wait;
double elapsed;
off_t bytespersec;
int remaining, hh, i, len;
char buf[256]; /* Work variable for transfer status. */
if (!verbose && !progress && !siginfo)
return;
(void)gettimeofday(&now, NULL);
timersub(&now, &start, &td);
elapsed = td.tv_sec + (td.tv_usec / 1000000.0);
bytespersec = 0;
if (bytes > 0) {
bytespersec = bytes;
if (elapsed > 0.0)
bytespersec /= elapsed;
}
len = 0;
len += snprintf(buf + len, BUFLEFT, LLF " byte%s %s in ",
(LLT)bytes, bytes == 1 ? "" : "s", direction);
remaining = (int)elapsed;
if (remaining > SECSPERDAY) {
int days;
days = remaining / SECSPERDAY;
remaining %= SECSPERDAY;
len += snprintf(buf + len, BUFLEFT,
"%d day%s ", days, days == 1 ? "" : "s");
}
hh = remaining / SECSPERHOUR;
remaining %= SECSPERHOUR;
if (hh)
len += snprintf(buf + len, BUFLEFT, "%2d:", hh);
len += snprintf(buf + len, BUFLEFT,
"%02d:%02d ", remaining / 60, remaining % 60);
for (i = 1; bytespersec >= 1024000 && i < sizeof(prefixes); i++)
bytespersec >>= 10;
len += snprintf(buf + len, BUFLEFT, "(" LLF ".%02d %cB/s)",
(LLT)(bytespersec / 1024),
(int)((bytespersec % 1024) * 100 / 1024),
prefixes[i]);
if (siginfo && bytes > 0 && elapsed > 0.0 && filesize >= 0
&& bytes + restart_point <= filesize) {
remaining = (int)((filesize - restart_point) /
(bytes / elapsed) - elapsed);
hh = remaining / SECSPERHOUR;
remaining %= SECSPERHOUR;
len += snprintf(buf + len, BUFLEFT, " ETA: ");
if (hh)
len += snprintf(buf + len, BUFLEFT, "%2d:", hh);
len += snprintf(buf + len, BUFLEFT, "%02d:%02d",
remaining / 60, remaining % 60);
timersub(&now, &lastupdate, &wait);
if (wait.tv_sec >= STALLTIME)
len += snprintf(buf + len, BUFLEFT, " (stalled)");
}
len += snprintf(buf + len, BUFLEFT, "\n");
(void)write(siginfo ? STDERR_FILENO : fileno(ttyout), buf, len);
}
/*
* SIG{INFO,QUIT} handler to print transfer stats if a transfer is in progress
*/
void
psummary(int notused)
{
int oerrno = errno;
if (bytes > 0) {
if (fromatty)
write(fileno(ttyout), "\n", 1);
ptransfer(1);
}
errno = oerrno;
}
#endif /* !STANDALONE_PROGRESS */
/*
* Set the SIGALRM interval timer for wait seconds, 0 to disable.
*/
void
alarmtimer(int wait)
{
struct itimerval itv;
itv.it_value.tv_sec = wait;
itv.it_value.tv_usec = 0;
itv.it_interval = itv.it_value;
setitimer(ITIMER_REAL, &itv, NULL);
}
/*
* Install a POSIX signal handler, allowing the invoker to set whether
* the signal should be restartable or not
*/
sigfunc
xsignal_restart(int sig, sigfunc func, int restartable)
{
struct sigaction act, oact;
act.sa_handler = func;
sigemptyset(&act.sa_mask);
#if defined(SA_RESTART) /* 4.4BSD, Posix(?), SVR4 */
act.sa_flags = restartable ? SA_RESTART : 0;
#elif defined(SA_INTERRUPT) /* SunOS 4.x */
act.sa_flags = restartable ? 0 : SA_INTERRUPT;
#else
#error "system must have SA_RESTART or SA_INTERRUPT"
#endif
if (sigaction(sig, &act, &oact) < 0)
return (SIG_ERR);
return (oact.sa_handler);
}
/*
* Install a signal handler with the `restartable' flag set dependent upon
* which signal is being set. (This is a wrapper to xsignal_restart())
*/
sigfunc
xsignal(int sig, sigfunc func)
{
int restartable;
/*
* Some signals print output or change the state of the process.
* There should be restartable, so that reads and writes are
* not affected. Some signals should cause program flow to change;
* these signals should not be restartable, so that the system call
* will return with EINTR, and the program will go do something
* different. If the signal handler calls longjmp() or siglongjmp(),
* it doesn't matter if it's restartable.
*/
switch(sig) {
#ifdef SIGINFO
case SIGINFO:
#endif
case SIGQUIT:
case SIGUSR1:
case SIGUSR2:
case SIGWINCH:
restartable = 1;
break;
case SIGALRM:
case SIGINT:
case SIGPIPE:
restartable = 0;
break;
default:
/*
* 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);
}
return(xsignal_restart(sig, func, restartable));
}

View File

@ -0,0 +1,99 @@
/* $NetBSD: progressbar.h,v 1.3 2003/02/28 09:53:49 lukem Exp $ */
/*-
* Copyright (c) 1996-2003 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Luke Mewburn.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef STANDALONE_PROGRESS
#include <setjmp.h>
#endif /* !STANDALONE_PROGRESS */
#ifndef GLOBAL
#define GLOBAL extern
#endif
#define STALLTIME 5 /* # of seconds of no xfer before "stalling" */
typedef void (*sigfunc)(int);
GLOBAL FILE *ttyout; /* stdout, or stderr if retrieving to stdout */
GLOBAL int progress; /* display transfer progress bar */
GLOBAL int ttywidth; /* width of tty */
GLOBAL off_t bytes; /* current # of bytes read */
GLOBAL off_t filesize; /* size of file being transferred */
GLOBAL off_t restart_point; /* offset to restart transfer */
#ifndef STANDALONE_PROGRESS
GLOBAL int fromatty; /* input is from a terminal */
GLOBAL int verbose; /* print messages coming back from server */
GLOBAL int quit_time; /* maximum time to wait if stalled */
GLOBAL char *direction; /* direction transfer is occurring */
GLOBAL sigjmp_buf toplevel; /* non-local goto stuff for cmd scanner */
#endif /* !STANDALONE_PROGRESS */
int foregroundproc(void);
void alarmtimer(int);
void progressmeter(int);
sigfunc xsignal(int, sigfunc);
sigfunc xsignal_restart(int, sigfunc, int);
#ifndef STANDALONE_PROGRESS
void psummary(int);
void ptransfer(int);
#endif /* !STANDALONE_PROGRESS */
#ifdef NO_LONG_LONG
# define LLF "%ld"
# define LLFP(x) "%" x "ld"
# define LLT long
# define ULLF "%lu"
# define ULLFP(x) "%" x "lu"
# define ULLT unsigned long
#else
# 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

View File

@ -33,7 +33,26 @@
* SUCH DAMAGE.
*/
#include "lukemftp.h"
#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.28 2000/11/15 00:11: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>
#include "ftp_var.h"

View File

@ -1,7 +1,7 @@
/* $NetBSD: util.c,v 1.107 2002/06/05 10:20:50 lukem Exp $ */
/* $NetBSD: util.c,v 1.112 2003/06/15 13:49:46 lukem Exp $ */
/*-
* Copyright (c) 1997-2002 The NetBSD Foundation, Inc.
* Copyright (c) 1997-2003 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@ -73,14 +73,40 @@
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: util.c,v 1.112 2003/06/15 13:49:46 lukem Exp $");
#endif /* not lint */
/*
* FTP User Program -- Misc support routines
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/ftp.h>
#include "lukemftp.h"
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <glob.h>
#include <signal.h>
#include <limits.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <time.h>
#include <unistd.h>
#include "ftp_var.h"
#define TM_YEAR_BASE 1900
/*
* Connect to peer server and auto-login, if possible.
*/
@ -775,303 +801,6 @@ updateremotepwd(void)
code = ocode;
}
#ifndef NO_PROGRESS
/*
* return non-zero if we're the current foreground process
*/
int
foregroundproc(void)
{
static pid_t pgrp = -1;
if (pgrp == -1)
#if GETPGRP_VOID
pgrp = getpgrp();
#else /* ! GETPGRP_VOID */
pgrp = getpgrp(0);
#endif /* ! GETPGRP_VOID */
return (tcgetpgrp(fileno(ttyout)) == pgrp);
}
static void updateprogressmeter(int);
/*
* SIGALRM handler to update the progress meter
*/
static void
updateprogressmeter(int dummy)
{
int oerrno = errno;
progressmeter(0);
errno = oerrno;
}
#endif /* NO_PROGRESS */
/*
* List of order of magnitude prefixes.
* The last is `P', as 2^64 = 16384 Petabytes
*/
static const char prefixes[] = " KMGTP";
/*
* Display a transfer progress bar if progress is non-zero.
* SIGALRM is hijacked for use by this function.
* - Before the transfer, set filesize to size of file (or -1 if unknown),
* and call with flag = -1. This starts the once per second timer,
* and a call to updateprogressmeter() upon SIGALRM.
* - During the transfer, updateprogressmeter will call progressmeter
* with flag = 0
* - After the transfer, call with flag = 1
*/
static struct timeval start;
static struct timeval lastupdate;
#define BUFLEFT (sizeof(buf) - len)
void
progressmeter(int flag)
{
static off_t lastsize;
#ifndef NO_PROGRESS
struct timeval now, td, wait;
off_t cursize, abbrevsize, bytespersec;
double elapsed;
int ratio, barlength, i, len, remaining;
/*
* Work variables for progress bar.
*
* XXX: if the format of the progress bar changes
* (especially the number of characters in the
* `static' portion of it), be sure to update
* these appropriately.
*/
char buf[256]; /* workspace for progress bar */
#define BAROVERHEAD 43 /* non `*' portion of progress bar */
/*
* stars should contain at least
* sizeof(buf) - BAROVERHEAD entries
*/
const char stars[] =
"*****************************************************************************"
"*****************************************************************************"
"*****************************************************************************";
#endif
if (flag == -1) {
(void)gettimeofday(&start, NULL);
lastupdate = start;
lastsize = restart_point;
}
#ifndef NO_PROGRESS
if (!progress)
return;
len = 0;
/*
* print progress bar only if we are foreground process.
*/
if (! foregroundproc())
return;
(void)gettimeofday(&now, NULL);
cursize = bytes + restart_point;
timersub(&now, &lastupdate, &wait);
if (cursize > lastsize) {
lastupdate = now;
lastsize = cursize;
wait.tv_sec = 0;
}
len += snprintf(buf + len, BUFLEFT, "\r");
if (filesize > 0) {
ratio = (int)((double)cursize * 100.0 / (double)filesize);
ratio = MAX(ratio, 0);
ratio = MIN(ratio, 100);
len += snprintf(buf + len, BUFLEFT, "%3d%% ", ratio);
/*
* calculate the length of the `*' bar, ensuring that
* the number of stars won't exceed the buffer size
*/
barlength = MIN(sizeof(buf) - 1, ttywidth) - BAROVERHEAD;
if (barlength > 0) {
i = barlength * ratio / 100;
len += snprintf(buf + len, BUFLEFT,
"|%.*s%*s|", i, stars, barlength - i, "");
}
}
abbrevsize = cursize;
for (i = 0; abbrevsize >= 100000 && i < sizeof(prefixes); i++)
abbrevsize >>= 10;
len += snprintf(buf + len, BUFLEFT, " " LLFP("5") " %c%c ",
(LLT)abbrevsize,
prefixes[i],
i == 0 ? ' ' : 'B');
timersub(&now, &start, &td);
elapsed = td.tv_sec + (td.tv_usec / 1000000.0);
bytespersec = 0;
if (bytes > 0) {
bytespersec = bytes;
if (elapsed > 0.0)
bytespersec /= elapsed;
}
for (i = 1; bytespersec >= 1024000 && i < sizeof(prefixes); i++)
bytespersec >>= 10;
len += snprintf(buf + len, BUFLEFT,
" " LLFP("3") ".%02d %cB/s ",
(LLT)(bytespersec / 1024),
(int)((bytespersec % 1024) * 100 / 1024),
prefixes[i]);
if (filesize > 0) {
if (bytes <= 0 || elapsed <= 0.0 || cursize > filesize) {
len += snprintf(buf + len, BUFLEFT, " --:-- ETA");
} else if (flag == 1) {
i = elapsed / SECSPERHOUR;
if (i)
len += snprintf(buf + len, BUFLEFT, "%2d:", i);
else
len += snprintf(buf + len, BUFLEFT, " ");
i = (int)elapsed % SECSPERHOUR;
len += snprintf(buf + len, BUFLEFT,
"%02d:%02d ", i / 60, i % 60);
} else if (wait.tv_sec >= STALLTIME) {
len += snprintf(buf + len, BUFLEFT, " - stalled -");
} else {
remaining = (int)
((filesize - restart_point) / (bytes / elapsed) -
elapsed);
if (remaining >= 100 * SECSPERHOUR)
len += snprintf(buf + len, BUFLEFT,
" --:-- ETA");
else {
i = remaining / SECSPERHOUR;
if (i)
len += snprintf(buf + len, BUFLEFT,
"%2d:", i);
else
len += snprintf(buf + len, BUFLEFT,
" ");
i = remaining % SECSPERHOUR;
len += snprintf(buf + len, BUFLEFT,
"%02d:%02d ETA", i / 60, i % 60);
}
}
}
if (flag == 1)
len += snprintf(buf + len, BUFLEFT, "\n");
(void)write(fileno(ttyout), buf, len);
if (flag == -1) {
(void)xsignal_restart(SIGALRM, updateprogressmeter, 1);
alarmtimer(1); /* set alarm timer for 1 Hz */
} else if (flag == 1) {
(void)xsignal(SIGALRM, SIG_DFL);
alarmtimer(0);
}
#endif /* !NO_PROGRESS */
}
/*
* Display transfer statistics.
* Requires start to be initialised by progressmeter(-1),
* direction to be defined by xfer routines, and filesize and bytes
* to be updated by xfer routines
* If siginfo is nonzero, an ETA is displayed, and the output goes to stderr
* instead of ttyout.
*/
void
ptransfer(int siginfo)
{
struct timeval now, td, wait;
double elapsed;
off_t bytespersec;
int remaining, hh, i, len;
char buf[256]; /* Work variable for transfer status. */
if (!verbose && !progress && !siginfo)
return;
(void)gettimeofday(&now, NULL);
timersub(&now, &start, &td);
elapsed = td.tv_sec + (td.tv_usec / 1000000.0);
bytespersec = 0;
if (bytes > 0) {
bytespersec = bytes;
if (elapsed > 0.0)
bytespersec /= elapsed;
}
len = 0;
len += snprintf(buf + len, BUFLEFT, LLF " byte%s %s in ",
(LLT)bytes, bytes == 1 ? "" : "s", direction);
remaining = (int)elapsed;
if (remaining > SECSPERDAY) {
int days;
days = remaining / SECSPERDAY;
remaining %= SECSPERDAY;
len += snprintf(buf + len, BUFLEFT,
"%d day%s ", days, days == 1 ? "" : "s");
}
hh = remaining / SECSPERHOUR;
remaining %= SECSPERHOUR;
if (hh)
len += snprintf(buf + len, BUFLEFT, "%2d:", hh);
len += snprintf(buf + len, BUFLEFT,
"%02d:%02d ", remaining / 60, remaining % 60);
for (i = 1; bytespersec >= 1024000 && i < sizeof(prefixes); i++)
bytespersec >>= 10;
len += snprintf(buf + len, BUFLEFT, "(" LLF ".%02d %cB/s)",
(LLT)(bytespersec / 1024),
(int)((bytespersec % 1024) * 100 / 1024),
prefixes[i]);
if (siginfo && bytes > 0 && elapsed > 0.0 && filesize >= 0
&& bytes + restart_point <= filesize) {
remaining = (int)((filesize - restart_point) /
(bytes / elapsed) - elapsed);
hh = remaining / SECSPERHOUR;
remaining %= SECSPERHOUR;
len += snprintf(buf + len, BUFLEFT, " ETA: ");
if (hh)
len += snprintf(buf + len, BUFLEFT, "%2d:", hh);
len += snprintf(buf + len, BUFLEFT, "%02d:%02d",
remaining / 60, remaining % 60);
timersub(&now, &lastupdate, &wait);
if (wait.tv_sec >= STALLTIME)
len += snprintf(buf + len, BUFLEFT, " (stalled)");
}
len += snprintf(buf + len, BUFLEFT, "\n");
(void)write(siginfo ? STDERR_FILENO : fileno(ttyout), buf, len);
}
/*
* SIG{INFO,QUIT} handler to print transfer stats if a transfer is in progress
*/
void
psummary(int notused)
{
int oerrno = errno;
if (bytes > 0) {
if (fromatty)
write(fileno(ttyout), "\n", 1);
ptransfer(1);
}
errno = oerrno;
}
/*
* List words in stringlist, vertically arranged
@ -1157,20 +886,6 @@ crankrate(int sig)
}
/*
* Set the SIGALRM interval timer for wait seconds, 0 to disable.
*/
void
alarmtimer(int wait)
{
struct itimerval itv;
itv.it_value.tv_sec = wait;
itv.it_value.tv_usec = 0;
itv.it_interval = itv.it_value;
setitimer(ITIMER_REAL, &itv, NULL);
}
/*
* Setup or cleanup EditLine structures
*/
@ -1389,7 +1104,8 @@ formatbuf(char *buf, size_t len, const char *src)
case 'M':
case 'm':
for (p2 = connected ? hostname : "-"; *p2; p2++) {
for (p2 = connected && username ? username : "-";
*p2 ; p2++) {
if (op == 'm' && *p2 == '.')
break;
ADDBUF(*p2);
@ -1553,84 +1269,3 @@ xstrdup(const char *str)
err(1, "Unable to allocate memory for string copy");
return (s);
}
/*
* Install a POSIX signal handler, allowing the invoker to set whether
* the signal should be restartable or not
*/
sigfunc
xsignal_restart(int sig, sigfunc func, int restartable)
{
#ifdef ultrix /* XXX: this is lame - how do we test sigvec vs. sigaction? */
struct sigvec vec, ovec;
vec.sv_handler = func;
sigemptyset(&vec.sv_mask);
vec.sv_flags = 0;
if (sigvec(sig, &vec, &ovec) < 0)
return (SIG_ERR);
return (ovec.sv_handler);
#else /* ! ultrix */
struct sigaction act, oact;
act.sa_handler = func;
sigemptyset(&act.sa_mask);
#if defined(SA_RESTART) /* 4.4BSD, Posix(?), SVR4 */
act.sa_flags = restartable ? SA_RESTART : 0;
#elif defined(SA_INTERRUPT) /* SunOS 4.x */
act.sa_flags = restartable ? 0 : SA_INTERRUPT;
#else
#error "system must have SA_RESTART or SA_INTERRUPT"
#endif
if (sigaction(sig, &act, &oact) < 0)
return (SIG_ERR);
return (oact.sa_handler);
#endif /* ! ultrix */
}
/*
* Install a signal handler with the `restartable' flag set dependent upon
* which signal is being set. (This is a wrapper to xsignal_restart())
*/
sigfunc
xsignal(int sig, sigfunc func)
{
int restartable;
/*
* Some signals print output or change the state of the process.
* There should be restartable, so that reads and writes are
* not affected. Some signals should cause program flow to change;
* these signals should not be restartable, so that the system call
* will return with EINTR, and the program will go do something
* different. If the signal handler calls longjmp() or siglongjmp(),
* it doesn't matter if it's restartable.
*/
switch(sig) {
#ifdef SIGINFO
case SIGINFO:
#endif
case SIGQUIT:
case SIGUSR1:
case SIGUSR2:
case SIGWINCH:
restartable = 1;
break;
case SIGALRM:
case SIGINT:
case SIGPIPE:
restartable = 0;
break;
default:
/*
* 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);
}
return(xsignal_restart(sig, func, restartable));
}

View File

@ -1,6 +1,6 @@
/* $NetBSD: version.h,v 1.29 2002/06/05 10:20:51 lukem Exp $ */
/* $NetBSD: version.h,v 1.31 2003/06/15 13:49:46 lukem Exp $ */
/*-
* Copyright (c) 1999-2002 The NetBSD Foundation, Inc.
* Copyright (c) 1999-2003 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@ -40,5 +40,5 @@
#endif
#ifndef FTP_VERSION
#define FTP_VERSION "20020605"
#define FTP_VERSION "20030615"
#endif