* fix RATE{GET,PUT} under some situations when the client is slower than
the server (something i missed when migrating the rate limiting code
i wrote in ftp(1) to ftpd(8))
* document what units RATE{GET,PUT} use
* implement closedataconn() and use appropriately (including in mlsd())
* only put leading space in front of MLST output (not MLSD output)
* MLSD: only output pdir and cdir entries when the type fact is requested.
* change error code for giving MLSD a non-directory from 550 to 501
* remove MLSx Type fact support for UNIX.* for now; it's not standardised yet.
* do a check_login when MLSD and MLST are given no args
* detect & complain about null facts in OPTS MLST
* cache getgroups() at login instead of calling each time in fact_perm()
other mods:
* implement cprintf(); as per fprintf() but increments total_bytes{,_out}
* implement CPUTC(); as per putc() but increments total_bytes{,_out}
* implement base64_encode()
* fact_unique() display base64 encoding of dev_t and ino_t rather than
hex output; should scale if size of those changes
* change reply() so that a negative code acts as the initial line in a reply,
code == 0 prefixes the line with 4 spaces, and code > 0 works as before.
deprecate lreply(code, ) and lreply(0, ) in favour of reply(-code, ) and
reply(0, ) respectively.
* use cprintf() and CPUTC() appropriately (often instead of printf(),
lreply(-2, ) or lreply(-1, ).
now we actually account for the data sent by MLST and MLSD.
* remove DEBUG support for sending MLSD output to control connection instead
of data connection (my ftp client now supports MLSD :-)
* implement draft-ietf-ftpext-mlst-10 commands, especially MLST and MLSD.
we already supported SIZE and MDTM. add the appropriate FEAT output lines.
* migrate a lot of the command code from ftpcmd.y and ftpd.c to cmds.c
* make dataconn(), feat(), lookup(), opts() and sizecmd() public
* modify struct tab so that it has a `flags' instead of `implemented' element,
and remove the `hasopts' element. If flags == 1, the command is implemented.
if flags == 2, the command is implemented and takes options
* add macros ISDOTDIR(x) (is x ".") and ISDOTDOTDIR(x) (is x "..")
* modify lreply() so that lreply(-2, ...) just outputs the given info without
a prefix or trailing \r\n. this saves doing b = printf(); total_* += b;
* enhance statcmd(). still needs work in the LPRT status stuff.
* crank version
Problem noted in [bin/9642] by Takahiro Kambe <taca@sky.yamashina.kyoto.jp>,
(part of which already had been solved by itojun a while ago), and provided
patch covered most of the fixes needed. (Thanks Takahiro!)
- Consistently indent goto labels by one space.
of the port range used by passive connections. based on work in [bin/9158]
from Takahiro Kambe <taca@sky.yamashina.kyoto.jp>
* change the way global variables are defined and extern-ed to be more
consistent.
* add connection limits (`limit' keyword in ftpd.conf)
* move initialisation of curclass from parse_conf() to new function
init_curclass()
* implement count_users(), which determines the number of users in a given
class. a file - /var/run/ftpd.pids-<class> - is used to store a list
of pids in use (effectively an array of pid_t's), and its size is reduced
as necessary.
* new % modifiers in format_file:
%c class
%M maximum connection count
%N current connection count
* always end_login()s, even for refused connections
bugs fixed:
* remove \n from %T output
* fix some inconsistencies in the man pages
* ensure that both `ftp' *and* `anonymous' are allowed in ftpusers.
(this was accidently broken in a recent commit to be ``or'' not ``and'')
* use MAXPATHLEN not MAXPATHLEN+1
* crank copyright date on modified files
* crank version
the name advertised to the client, even if ftpd can determine it from
the ip address that ftpd is bound to. requested by mrg.
* remove -4/-6; they were effectively no-ops since itojun's change in 1.75.
* crank version
* use .Dv and .Tn in the man pages as appropriate
* KNF a bit
The following were inspired by similar changes in openbsd, but may
have additional improvements by me:
* add more check_login tests to the parser rules
* nuke a few memory leaks in the parser rules
* clear passwords before free()ing them, for safety
* don't display \r\n in setproctitle() output
* add support for -U, which enables managing /var/run/utmp entries for
connections. solves [bin/2217] by Jason Downs <downsj@teeny.org>
* fix oob handling for STAT command
* use SIG_ERR instead of -1
as (useful for virtual ftp servers in conjunction with inetd.conf(5)'s
ability to bind to a specific address).
if this option is used, add `hostname' to the syslog messages.
* improve documentation of command-line options
* don't allow class names of `all' or `none' in ftpusers
userglob [allow|deny]
to
userglob[@host] [allow|deny [classname]]
where class is a userdefined classname.
- if host is given it may either be a CIDR address (e.g, `1.2.3.0/24') or a
hostglob (e.g, `*.foo.com'), and the remote host is matched against that.
- if classname is given, use that to match entries in ftpd.conf (defaults
to `guest' for `anonymous'/`ftp' logins, `chroot' for users found in
/etc/ftpchroot, and `real' for everyone else.
* implement new /etc/ftpd.conf directives:
classtype classname type set type of classname to GUEST, CHROOT, or REAL
motd classname file file to use instead of /etc/motd
rateget classname rate set rateget throttle to rate
rateput classname rate set rateput throttle to rate
upload classname allow/deny uploads (STOU, STOR, APPE). if
denied, also acts as `modify deny'.
* implement new `SITE' commands:
RATEGET as per /etc/ftpd.conf rateget, but cannot exceed that
RATEPUT as per /etc/ftpd.conf rateput, but cannot exceed that
* implement format_file(), which outputs a file to the user, parsing %
escapes. use to print /etc/ftpwelcome, /etc/motd, and the `display' file.
* implement strsuftoi() (from ftp(1)), which parses a number and
optional suffix (for use with rateget, etc)
* don't bother seteuid(0) ; bind(...) ; seteuid(pw->pw_uid), since
we don't need reserved ports (at wasn't getting them anyway).
* update & reorder copyrights
* use strlcpy() as appropriate
the string tokenisation must be performed by the caller (which is
generally easy because it's almost always a static command).
* change do_conversion() to return a char *argv[] instead of char *cmd.
tokenisation of the command is done internally.
* change retrieve() to take char *argv[] instead of char *cmd.
(to take advantage of the above changes). fixes [bin/8173]
* use fparseln() instead of fgetln()
* store conversions in listed order (rather than reverse order)
* use stringlists instead of handrolling code to manage an argv.
(this was broken in the last commit). problem noticed by simonb@
* don't display the stderr output of the internal ls.
* modify usage of lreply so that generally only one `XXX-' code per
`block' is displayed; the rest of the lines have four spaces instead.
i find this easier to read.
* fix a couple places where byte accounting wasn't correct
* implement xferstats. full stats are displayed for `STAT', and a
summary is displayed upon exit (and syslogged). inspired by wu-ftpd.
* wrap data xfers in {send,receive}_data with alarm() timeouts. this
should remove the majority of the `hanging ftpd' problems that
people were still seeing. inspired by wu-ftpd.
* link with ../../bin/ls, so that bin/ls is not required under a
chroot()ed area for `LIST' to work. based on [bin/4497] from
"Soren S. Jorvang" <soren@t.dk>
* migrate code from util.c into ftpd.c, so that it doesn't conflict
with ls' util.c.
* remove man page comment about ~ftp/bin/ls being necessary.
* bump version to 7.2.0.
* syslog xfer time with xfer stats.
* if appropriate, syslog error message with command.
internal code stuff:
* change arguments of various functions from `char *' to `const char *'.
* define PLURAL(x) macro, which returns `' if x == 1, `s' otherwise.
use macro appropriately
* lreply(): a code of -1 means ``send line as is''. a code of 0
means ``send line with 4 space prefix''. don't print a space after
the `-' for any other code.
* logcmd(): add `const struct timeval *elapsed' and `const char *error'
for more flexible error reporting
solution with less code replication. use realpath() in logcmd() so
that all logged filenames are sane.
* support `REST STREAM' in `FEAT' reply (from draft-ietf-ftpext-mlst-05)
* in 'HELP', suffix unimplemented commands with `-' instead of `*'; the
former is easier to differentiate from `+'.
* deprecate curdir() now that logcmd() doesn't use it.
* ensure all filename buffers are at least MAXPATHLEN+1 in size.
* move jmp_buf errcatch out of extern.h, removing need to #include <setjmp.h>
in every file.
* implement FEAT and OPTS from RFC2389. FEAT returns SIZE and MDTM.
OPTS only works on NOOP (as a test).
* extend format of /etc/ftpchroot similar to /etc/ftpusers; each entry
can take an optional trailing `yes' or `no' which indicates if
chroot should be done (defaults to `yes').
based on patches from Ty Sarna <tsarna@endicor.com> in [bin/4769]
cleanups/bugs:
* reorder and reformat entries in yacc parser to match cmdtab[].
add a blank line between each rule.
* add short hasopts and char *options to struct tab, to support OPTS.
* deprecate upper(); use strcasecmp() instead of strcmp()
* remove unnecessary for (;;) { } in yylex();
* replace copy() and sgetsave() with xstrdup()
* fix a couple of `hasyyerrored = 1' that were accidently removed.
problem; move `hasyyerrored' state flag out of yylex() so that
check_{login,modify} can also set it.
* check result of check_login for PORT command
* set initial timeout before the "setjmp(); for(;;) yyparse()",
otherwise an invalid command after login incorrectly sets the timeout
to 5 minutes (rather than what was set in ftpd.conf)
* replace (char *)0 with NULL
* move yyerror() from ftpd.c to ftpcmd.y
* remove need for -Dunix, by using the version string from ftpd.c
(instead of `BSD-199506')
* move all extern-ed vars into extern.h
- ensure hostname from gethostname() is nul-terminated in all cases
- minor KNF
- use MAXHOSTNAMELEN over various other values/defines
- be safe will buffers that hold hostnames
the user at the end of a transfer.
this generates a file in /tmp, so anonymous requires a
writable ~ftp/tmp, which you may not want to do (because it may
allow people to unwanted upload files).
XXX: a better method of storing the stderr output would be nice, but
is a lot more effort to implement. this feature can at least be
used temporarily whilst debugging why an ftp conversion doesn't
work.