*
* 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>
{
*(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))
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);
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);
}
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);
}
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
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,
|| 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;
#endif
if (argv[optind]) {
- xchdir(argv[optind]);
- chroot(".");
+ xchroot(argv[optind]);
}
//umask(077); - admin can set umask before starting us