arp: fix -H/-t handling.
[oweals/busybox.git] / networking / ftpd.c
index 9d43ea3a2d5d2a81ef4fb33fab00b94ecd94df38..33db964fa46c465b72bda6fa75c65adee1873ee0 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Author: Adam Tkac <vonsch@gmail.com>
  *
- * 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.
  * 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 <syslog.h>
 #include <netinet/tcp.h>
@@ -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);
@@ -525,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);
 }
@@ -534,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);
 }
 
@@ -618,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 */
@@ -632,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
@@ -808,7 +821,7 @@ handle_size_or_mdtm(int need_size)
                gmtime_r(&statbuf.st_mtime, &broken_out);
                sprintf(buf, STR(FTP_STATFILE_OK)" %04u%02u%02u%02u%02u%02u\r\n",
                        broken_out.tm_year + 1900,
-                       broken_out.tm_mon,
+                       broken_out.tm_mon + 1,
                        broken_out.tm_mday,
                        broken_out.tm_hour,
                        broken_out.tm_min,
@@ -914,6 +927,7 @@ handle_upload_common(int is_append, int is_unique)
         || fstat(local_file_fd, &statbuf) != 0
         || !S_ISREG(statbuf.st_mode)
        ) {
+               free(tempname);
                WRITE_ERR(FTP_UPLOADFAIL);
                if (local_file_fd >= 0)
                        goto close_local_and_bail;
@@ -1166,8 +1180,7 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv)
 #endif
 
        if (argv[optind]) {
-               xchdir(argv[optind]);
-               chroot(".");
+               xchroot(argv[optind]);
        }
 
        //umask(077); - admin can set umask before starting us