(from RFC 2389).
add support for MLST & MLSD (machine parseble listings) with 'mlst', 'mlsd'
and 'pmlsd' (mlsd |$PAGER) commands. (from draft-ietf-ftpext-mlst-11)
rename remotesyst() to getremoteinfo(), and modify to parse the result from
FEAT (if supported), and take into account the support for the various
extensions such as MDTM, SIZE, REST (STREAM), MLSD, and FEAT/OPTS.
put each feature into one of the following categories:
- known to work (explicit FEAT)
- unknown but assume works until explicit failure, when it's
then tagged as `known not to work'.
- known not to work (FEAT succeeded but didn't return anything,
or was unknown and then explicit failure)
assign results into features[] matrix.
add support to getreply() so that an optional callback will be called
for each line received from the server except for the first and last.
this is used in FEAT (and MLST) parsing.
modify various commands to check if REST (STREAM), MDTM and SIZE are
explicitly or implicitly supported before using.
fix `syst' when verbose is off.
minor knf (indent goto labels by one space, etc).
simply various command usage handlers by assuming that argv != NULL except
for quit() and disconnect().
- ftp(1): treats IPv4 mapped destination as IPv4 peer, not native IPv6 peer.
this does not support network with SIIT translator.
- rshd(8)/rlogind(8): rejects accesses from IPv4 mapped peer, to avoid
possible abuse of IPv4 mapped addr (rshd/rlogind use source address-based
auth so it is important to check the condition).
Now that after many years on not caring we find certain popular
ftp servers are starting to obey RFC959 to the letter of the law
and will only return a list of filenames (not directories or
other filetypes) in the output of `NLST', then `LIST' is more useful
in this case. (Note that the aforementioned pedanticness means that
filename completion isn't as useful as it could be...)
Fixes [bin/8937] by David A. Gatwood <dgatwood@deepspace.mklinux.org>
for listings of the current working directory; some ftp servers don't
like `NLST .'.
[noted by Giles Lean <giles@nemeton.com.au>]
* recvrequest(): treat remote=="" as remote==NULL when calling command().
(to support the above change)
* support `[user@]' in `[user@]host' and `[user@]host[:][path]'.
[based on idea (and initial code) from David Maxwell <david@fundy.ca>]
* `idle' may be invoked without any args
* reformat some comments
* reformat usage string in program and man page
* call updateremotepwd() after successful login, not after successful connect
* always call setsockopt(, IPPROTO_IP, IP_TOS, ) (et al); using #if
defined(IPPROTO_IP) doesn't work on certain foreign systems where
enums instead of #defines are used...
[noted by Matthias Pfaller <leo@dachau.marco.de>]
EL_RPROMPT support i added to editline(3).
- allow $FTPPROMPT and $FTPRPROMPT to override defaults for the relevant
prompts
- move `%' formatting code from prompt() to expandbuf().
- implement `%.' and `%c', similar to the same % codes in tcsh(1)
(functionality I added to tcsh nearly 6 years ago), except that `%.'
always does `...trailing' and `%c' always does `/<x>trailing'.
- unknown `%foo' codes get printed as `%foo'
to contain the remote working directory.
- add `set prompt', a user configurable prompt. (defaults to `ftp> ').
the following escape characters a la tcsh(1) are supported: %/, %m,
%M, and %n.
- add global var `username'; used by prompt code
- fix a couple of minor memory leaks
- bump version
- add `usage'; displays the usage of a command.
implemented by calling the c_handler() with argc = 0, argv = "funcname".
- add `passive auto'; does the same as $FTPMODE=auto.
- add `set [option value]'; display all options, or set an option to a value.
- add `unset option'; unset an option.
- add getoptionvalue() to retrieve an option's value, and replace a few
global variables with calls to this.
- implement cleanuppeer(), which resets various bits of state back to
`disconnected'. call in disconnect() and lostpeer().
- support completing on `options'.
- improve recovery after a SIGINT may have closed the connection.
XXX: there's still a couple to fix
other stuff:
- various consistency fixes in the man page.
- ensure that the command usage strings in the code and man page match reality.
- mput/mget: check that the connection still exists before each xfer.
- minor cosmetic changes in confirm().
- set code correctly in sizecmd() and modtime()
- don't need \n in err() strings.
- change lostpeer to take an argument (rather than casting (sig_t)lostpeer
in signal handlers)
- knf and whitespace police.
* confirm(): move from util.c to cmds.c. display mnemonic string in its prompt.
add support for `q' (terminate current xfer), `?' (show help list)
* in various signal handlers, output a linefeed only if fromatty.
* if fgets(stdin) returned NULL (i.e, EOF), clearerr(stdin) because you don't
want future fgets to fail. this is not done for the fgets() in the main
command loop, since ftp will quit at that point.
* unless ftp is invoked with -a, don't retain the anonftp setting between
hosts (`ftp somehost:' sets anonftp, but you don't want that to `stick'
if you close that connection and open a new one).
prints out info if bytes > 0). only set the handler if SIGINFO is defined
* hijack SIGQUIT to be the same as SIGINFO (foreign ports have this, and it's
annoying to have SIGQUIT dump core on netbsd when it prints info on other
systems)
* in {recv,send}request(), factor a lot of duplicated code out into a
`cleanup' section at the end
* rework shell() a bit
* implement xsignal_restart(), which only sets the SA_RESTART flag if
specifically requested
* xsignal() is now a wrapper to xsignal_restart(). INFO, USR1, USR2 and WINCH
are restartable, ALRM, INT, PIPE and QUIT are not.
* improve getreply()'s timeout code to take advantage of the above.
other changes:
* improve wording of how globbing works for `classic' URLs (host:path).
suggested by John Refling <johnr@imageworks.com> in relation to PRs
[bin/8519] and [bin/8520]
* always compile in the `edit' command even if NO_EDITCOMPLETE defined.
it's just a no-op in the latter case, which is more consistent to
the users.
* always compile in about: support (i.e, remove NO_ABOUT).
i'm entitled to some vanity in this program...
* clean up some whitespace
the disabled state can be overridden by toggling epsv4.
(I got sick of the errors about EPSV not being supported on almost
every server I connect to. This way we retain support for epsv4, but
it's not so whiny after the first failure...)
lpage page local files
pdir as dir, but through your $PAGER
pls as ls, but through your $PAGER
* implement docase() (a la dotrans() et al) and use appropriately, rototilling
some duplicated code
* globulize(): modify to return a pointer to the strdup()ed result in all cases,
and hack the code that calls it to take this into account
* replace strcpy() and strncpy() with strlcpy()
* put(), getit(): use some aptly named local vars instead of argv[...]
* delint
* document the above three commands
* rototill the way the sndbuf and rcvbuf work. remove resetsockbufsize()
* use the appropriate socket buffer size as the size of the buffer that
the read()/write() loops use. speeds up things in some cases.
the an empty directory (e.g, between `some' and `path' in
`ftp://host/some//path'), then execute `CWD ' (without a path).
This command will probably fail on rfc 959 compliant servers, so
issue a warning in this case and bail. [noted by cgd].
(i wonder if the people who wrote rfc 1738 actually realised that this
requirement appears to contravene the spec for `cwd' in rfc 959 ?)
* replace isurl() with isipv6addr(), and use appropriately. fixes
auto-login with `classic ftp URLs' (e.g, `ftp somehost:')
* cleanup and rework some of the ipv6 stuff in parse_url()
* prevent potential coredump in fetch_ftp() when parsing `;type=X'
* KNF a few lines
* fix a couple of comments
* cleanup the man page a bit
this is mainly for (hypothetical) ftp server which disconnect clients
that use EPSV/EPRT. I've never seen any ftp server like this, but
epsv4 command may be of use when such an ftp server is found.
features:
---------
* transfer rate throttling with the new `rate' command. syntax:
rate direction [max [incr]]
where direction is `all', `get' or `put'.
if max is not supplied, the current settings are displayed.
if max is supplied, then transfers in the given direction will
be throttled to this value.
if incr is supplied, the increment for the `on-the-fly' scaling
will be set to that, otherwise `1024' is used.
currently implemented for binary get, binary put, and url fetches.
not yet supported for ascii get or put, or local file copies.
* on-the-fly scaling of the throttle based on signals:
- SIGUSR1 raises the throttle rate by the increment for that direction
- SIGUSR2 lowers the throttle rate by the increment for that direction
* -T dir,max[,incr] option to set rate from the command line
* `k', `m', `g' suffix support for bytecounts in the `hash', `rate',
`rcvbuf' and `sndbuf' commands)
bug fixes and code mods:
------------------------
* fix up ftp_login() so that ruserpass() is always called, even for
command-line url fetches.
* implement strsuftoi(), which parses a given number into a int with
suffix support. replaces getsockbufsize()
* implement parserate(), which does the argv parsing for -T and rate
* save and restore errno in signal handlers (may not be necessary, but
it doesn't hurt)
notes:
------
the rate command has had reasonable testing, but I'd like feedback
if it doesn't do the right thing, especially from people on slower
(i.e, modem) links.
I haven't tested the rate throttle against a http server which does
`transfer-encoding: chunked' because I couldn't find a server to
test against.
the latter only seemed to work for TIS Gauntlet and not TIS fwtk.
thanks to simonb@netbsd.org for testing this. fixes [bin/5556].
* if EOF (e.g, ^D) is entered at a username/password/account prompt which
happens to use fgets(), exit the login rather than treating EOF as CR.
* don't use the comma operator where separate statements are valid
* always use snprintf to copy stuff into malloced buffers, just in case
typos creep in and mean that the buffer ends up being overflowed
elements, which are used for the initial authentication attempt (if
requested by the server). in the case of $http_proxy, use the values
for proxy authentication.
- the path is split on `/', and each directory is CWD-ed into separately.
(from [standards/7484] by Alan Barrett <apb@iafrica.com>)
- support a trailing `;type=X' suffix, where X is a,i, or d. (d isn't
implemented, but it is recognised)
- the only non-compliant behaviour is that empty directories sections
(e.g `//') aren't run as `CWD ' - as a lot of ftpds don't like that.
Instead, treat this as a no-op.
* don't support globbing for ftp urls, since that's technically not
RFC compliant.
* fix a couple of man-page nits
* fix fetch_ftp() so that hcode parsing is not done for file:// urls
(a } in the wrong place, and code at the wrong indent level...)
* change outfile to being a global (so it gets correctly reset)
* change parse_url to not remove leading '/' for non ftp urls.
whilst this is not totally rfc1738 compliant, other code kinda
assumes this is the case, and it doesn't hurt
* parse_url()
- only look for user[:pass] for an ftp url (per rfc1738)
- strip leading /'s in an ftp url. (almost per rfc 1738)
* fetch_url()
- decode a copy of the path and use that to build local filenames
- send port in http Host: header (suggested by cgd@netbsd.org)
* fetch_ftp()
- url_decode() the user, pass and path
- fix splitting of path into dir & file (partially from [bin/7073])
- don't bother caching the last host; it can cause problems when
using ftp:// transfers, or when the user changes between xfers
* improve documentation of auto-fetched url arguments (especially regarding
escape sequences in ftp:// urls)
* some whitespace & copyright updates
this should fix [bin/7073] William O Ferry <woferry@warp.wofme.com>,
as well as the metaissues raised in that PR.
* set setvbuf(ttyout, NULL, _IOLBF, 0) and remove a bunch of fflush(ttyout).
* use fwrite() instead of write() for progressmeter (don't intermix stdio
with non stdio ops)
* in autofetch mode, don't attempt to 'cd /' on first xfer (only on
subsequent xfers), as some ftp daemons don't permit that.
[noted by dbj@netbsd.org].
XXX: code could be smarter (but a lot more complicated to boot); this
works for now.
* support $no_proxy, which is a comma or space separated list of
host[:port] elements for which proxying is to be disabled.
(asked for by cgd in [bin/5027])
* if $FTPANONPASS is defined, use that as the anon ftp password
(instead of "`whoami`@")
* allow http URL's without a filename as long as an output file
is specified.
other stuff:
* implement parse_url(), which breaks up a URL into its bits, and use.
* simplify url_get() and auto_fetch() to use parse_url() and to not
modify the supplied URL or a copy of it.
* implement xmalloc() and xstrdup(); error-checked malloc()/strdup()
* add more consistency to messages, quoting strings in output as `%s'
* parse Last-Modified: HTTP headers for date, and change time of
retrieved file if parsing succeeded
* support file:/// and file://localhost/ URLs
* in url_get(), re-write byte moving code to consistently use fread()
and fwrite(), and check errors at end with ferror()
* add about:* easter-egg (#ifndef SMALL :-)
* default to passive with active fallback. $FTPMODE modifies this behaviour.
-A forces active connection.
* support '-o outfile' for auto-fetched files. outfile can be a file,
`-' (for stdout), or '|command' (to output each file through command).
* support '-r waittime', which retries the connection after waittime seconds
if it fails.
* fix 'page file' when restart is non-zero.
* try all ip-addresses of a host in a http fetch (as the normal ftp fetch
does).
XXX: a ``broken pipe'' error sometimes occurs with -o '|command';
i haven't tracked this down yet.