X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=networking%2Fftpd.c;h=e38138c0a85b1b4d8ef0e753597ab323c5113ae9;hb=1f56e51ca1d96b70635eb1b9df1d1ab0edd98a72;hp=186ff50cebf9c90d1e602bbf3818bf4952e39688;hpb=98a4c7cf3d799ab953cb77e8b34597c73e3e7335;p=oweals%2Fbusybox.git diff --git a/networking/ftpd.c b/networking/ftpd.c index 186ff50ce..e38138c0a 100644 --- a/networking/ftpd.c +++ b/networking/ftpd.c @@ -4,7 +4,7 @@ * * Author: Adam Tkac * - * Licensed under GPLv2, see file LICENSE in this tarball for details. + * Licensed under GPLv2, see file LICENSE in this source tree. * * Only subset of FTP protocol is implemented but vast majority of clients * should not have any problem. @@ -12,6 +12,22 @@ * You have to run this daemon via inetd. */ +//usage:#define ftpd_trivial_usage +//usage: "[-wvS] [-t N] [-T N] [DIR]" +//usage:#define ftpd_full_usage "\n\n" +//usage: "Anonymous FTP server\n" +//usage: "\n" +//usage: "ftpd should be used as an inetd service.\n" +//usage: "ftpd's line for inetd.conf:\n" +//usage: " 21 stream tcp nowait root ftpd ftpd /files/to/serve\n" +//usage: "It also can be ran from tcpsvd:\n" +//usage: " tcpsvd -vE 0.0.0.0 21 ftpd /files/to/serve\n" +//usage: "\n -w Allow upload" +//usage: "\n -v Log errors to stderr. -vv: verbose log" +//usage: "\n -S Log errors to syslog. -SS: verbose log" +//usage: "\n -t,-T Idle and absolute timeouts" +//usage: "\n DIR Change root to this directory" + #include "libbb.h" #include #include @@ -206,7 +222,7 @@ cmdio_write_error(unsigned status) { *(uint32_t *) G.msg_err = status; xwrite(STDOUT_FILENO, G.msg_err, sizeof("NNN " MSG_ERR) - 1); - if (G.verbose > 1) + if (G.verbose > 0) verbose_log(G.msg_err); } #define WRITE_ERR(a) cmdio_write_error(STRNUM32sp(a)) @@ -416,7 +432,7 @@ bind_for_passive_mode(void) G.pasv_listen_fd = fd = xsocket(G.local_addr->u.sa.sa_family, SOCK_STREAM, 0); setsockopt_reuseaddr(fd); - set_nport(G.local_addr, 0); + set_nport(&G.local_addr->u.sa, 0); xbind(fd, &G.local_addr->u.sa, G.local_addr->len); xlisten(fd, 1); getsockname(fd, &G.local_addr->u.sa, &G.local_addr->len); @@ -461,21 +477,6 @@ handle_epsv(void) free(response); } -/* libbb candidate */ -static -len_and_sockaddr* get_peer_lsa(int fd) -{ - len_and_sockaddr *lsa; - socklen_t len = 0; - - if (getpeername(fd, NULL, &len) != 0) - return NULL; - lsa = xzalloc(LSA_LEN_SIZE + len); - lsa->len = len; - getpeername(fd, &lsa->u.sa, &lsa->len); - return lsa; -} - static void handle_port(void) { @@ -540,7 +541,7 @@ handle_port(void) G.port_addr = xdotted2sockaddr(raw, port); #else G.port_addr = get_peer_lsa(STDIN_FILENO); - set_nport(G.port_addr, htons(port)); + set_nport(&G.port_addr->u.sa, htons(port)); #endif WRITE_OK(FTP_PORTOK); } @@ -549,7 +550,7 @@ static void handle_rest(void) { /* When ftp_arg == NULL simply restart from beginning */ - G.restart_pos = G.ftp_arg ? xatoi_u(G.ftp_arg) : 0; + G.restart_pos = G.ftp_arg ? xatoi_positive(G.ftp_arg) : 0; WRITE_OK(FTP_RESTOK); } @@ -633,10 +634,10 @@ popen_ls(const char *opt) argv[4] = NULL; /* Improve compatibility with non-RFC conforming FTP clients - * which send e.g. "LIST -l", "LIST -la". + * which send e.g. "LIST -l", "LIST -la", "LIST -aL". * See https://bugs.kde.org/show_bug.cgi?id=195578 */ if (ENABLE_FEATURE_FTPD_ACCEPT_BROKEN_LIST - && G.ftp_arg && G.ftp_arg[0] == '-' && G.ftp_arg[1] == 'l' + && G.ftp_arg && G.ftp_arg[0] == '-' ) { const char *tmp = strchr(G.ftp_arg, ' '); if (tmp) /* skip the space */ @@ -647,10 +648,7 @@ popen_ls(const char *opt) xpiped_pair(outfd); /*fflush_all(); - so far we dont use stdio on output */ - pid = BB_MMU ? fork() : vfork(); - if (pid < 0) - bb_perror_msg_and_die(BB_MMU ? "fork" : "vfork"); - + pid = BB_MMU ? xfork() : xvfork(); if (pid == 0) { /* child */ #if !BB_MMU @@ -981,17 +979,23 @@ handle_stou(void) static uint32_t cmdio_get_cmd_and_arg(void) { - size_t len; + int len; uint32_t cmdval; char *cmd; alarm(G.timeout); free(G.ftp_cmd); - len = 8 * 1024; /* Paranoia. Peer may send 1 gigabyte long cmd... */ - G.ftp_cmd = cmd = xmalloc_fgets_str_len(stdin, "\r\n", &len); - if (!cmd) - exit(0); + { + /* Paranoia. Peer may send 1 gigabyte long cmd... */ + /* Using separate len_on_stk instead of len optimizes + * code size (allows len to be in CPU register) */ + size_t len_on_stk = 8 * 1024; + G.ftp_cmd = cmd = xmalloc_fgets_str_len(stdin, "\r\n", &len_on_stk); + if (!cmd) + exit(0); + len = len_on_stk; + } /* De-escape telnet: 0xff,0xff => 0xff */ /* RFC959 says that ABOR, STAT, QUIT may be sent even during @@ -1127,9 +1131,9 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv) opts = getopt32(argv, "l1vS" IF_FEATURE_FTP_WRITE("w") "t:T:", &G.timeout, &abs_timeout, &G.verbose, &verbose_S); if (opts & (OPT_l|OPT_1)) { /* Our secret backdoor to ls */ -/* TODO: pass -n? It prevents user/group resolution, whicj may not work in chroot anyway */ +/* TODO: pass -n? It prevents user/group resolution, which may not work in chroot anyway */ /* TODO: pass -A? It shows dot files */ -/* TODO: pass --group-directories-first? would be nice, but ls don't do that yet */ +/* TODO: pass --group-directories-first? would be nice, but ls doesn't do that yet */ xchdir(argv[2]); argv[2] = (char*)"--"; /* memset(&G, 0, sizeof(G)); - ls_main does it */