mirror of
https://github.com/wiiu-env/ftpiiu_plugin.git
synced 2024-11-17 18:29:19 +01:00
Use sdmc_dev
Enable UTF8
This commit is contained in:
parent
f1be81814c
commit
0ba3844ad8
442
source/ftp.c
442
source/ftp.c
@ -1,29 +1,25 @@
|
||||
#include "ftp.h"
|
||||
#include <arpa/inet.h>
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <malloc.h>
|
||||
#include <netinet/in.h>
|
||||
#include <poll.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#ifdef _3DS
|
||||
#include <3ds.h>
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#define lstat stat
|
||||
#endif
|
||||
#include "console.h"
|
||||
|
||||
#ifndef _3DS
|
||||
#define Errno() errno
|
||||
#define closesocket(x) close(x)
|
||||
#endif
|
||||
#define POLL_UNKNOWN (~(POLLIN|POLLOUT))
|
||||
|
||||
#define XFER_BUFFERSIZE 4096
|
||||
@ -51,6 +47,7 @@ FTP_DECLARE(MKD);
|
||||
FTP_DECLARE(MODE);
|
||||
FTP_DECLARE(NLST);
|
||||
FTP_DECLARE(NOOP);
|
||||
FTP_DECLARE(OPTS);
|
||||
FTP_DECLARE(PASS);
|
||||
FTP_DECLARE(PASV);
|
||||
FTP_DECLARE(PORT);
|
||||
@ -108,15 +105,11 @@ struct ftp_session_t
|
||||
size_t buffersize; /*! persistent buffer size between callbacks */
|
||||
uint64_t filepos; /*! persistent file position between callbacks */
|
||||
uint64_t filesize; /*! persistent file size between callbacks */
|
||||
#ifdef _3DS
|
||||
Handle fd; /*! persistent handle between callbacks */
|
||||
#else
|
||||
union
|
||||
{
|
||||
DIR *dp; /*! persistent open directory pointer between callbacks */
|
||||
int fd; /*! persistent open file descriptor between callbacks */
|
||||
};
|
||||
#endif
|
||||
};
|
||||
|
||||
/*! ftp command descriptor */
|
||||
@ -141,6 +134,7 @@ static ftp_command_t ftp_commands[] =
|
||||
FTP_COMMAND(MODE),
|
||||
FTP_COMMAND(NLST),
|
||||
FTP_COMMAND(NOOP),
|
||||
FTP_COMMAND(OPTS),
|
||||
FTP_COMMAND(PASS),
|
||||
FTP_COMMAND(PASV),
|
||||
FTP_COMMAND(PORT),
|
||||
@ -165,16 +159,6 @@ static ftp_command_t ftp_commands[] =
|
||||
/*! number of ftp commands */
|
||||
static const size_t num_ftp_commands = sizeof(ftp_commands)/sizeof(ftp_commands[0]);
|
||||
|
||||
#ifdef _3DS
|
||||
static inline int Errno(void)
|
||||
{
|
||||
int err = SOC_GetErrno();
|
||||
if(err < 0)
|
||||
return -err;
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! compare ftp command descriptors
|
||||
*
|
||||
* @param[in] p1 left side of comparison (ftp_command_t*)
|
||||
@ -198,34 +182,6 @@ ftp_command_cmp(const void *p1,
|
||||
#ifdef _3DS
|
||||
/*! SOC service buffer */
|
||||
static u32 *SOC_buffer = NULL;
|
||||
|
||||
/*! SDMC archive */
|
||||
static FS_archive sdmcArchive =
|
||||
{
|
||||
.id = ARCH_SDMC,
|
||||
.lowPath =
|
||||
{
|
||||
.type = PATH_EMPTY,
|
||||
.size = 1,
|
||||
.data = (u8*)"",
|
||||
},
|
||||
};
|
||||
|
||||
/*! convert 3DS dirent name to ASCII
|
||||
*
|
||||
* TODO: add support for non-ASCII characters
|
||||
*
|
||||
* @param[in] dst output buffer
|
||||
* @param[in] src input buffer
|
||||
*/
|
||||
static void
|
||||
convert_name(char *dst,
|
||||
const u16 *src)
|
||||
{
|
||||
while(*src)
|
||||
*dst++ = *src++;
|
||||
*dst = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! server listen address */
|
||||
@ -233,9 +189,9 @@ static struct sockaddr_in serv_addr;
|
||||
/*! listen file descriptor */
|
||||
static int listenfd = -1;
|
||||
/*! current data port */
|
||||
in_port_t data_port = DATA_PORT;
|
||||
static in_port_t data_port = DATA_PORT;
|
||||
/*! list of ftp sessions */
|
||||
ftp_session_t *sessions = NULL;
|
||||
static ftp_session_t *sessions = NULL;
|
||||
|
||||
/*! Allocate a new data port
|
||||
*
|
||||
@ -267,14 +223,14 @@ ftp_set_socket_nonblocking(int fd)
|
||||
flags = fcntl(fd, F_GETFL, 0);
|
||||
if(flags == -1)
|
||||
{
|
||||
console_print(RED "fcntl: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "fcntl: %d %s\n" RESET, errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
|
||||
if(rc != 0)
|
||||
{
|
||||
console_print(RED "fcntl: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "fcntl: %d %s\n" RESET, errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -299,7 +255,7 @@ ftp_closesocket(int fd, int connected)
|
||||
rc = getpeername(fd, (struct sockaddr*)&addr, &addrlen);
|
||||
if(rc != 0)
|
||||
{
|
||||
console_print(RED "getpeername: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "getpeername: %d %s\n" RESET, errno, strerror(errno));
|
||||
console_print(YELLOW "closing connection to fd=%d\n" RESET, fd);
|
||||
}
|
||||
else
|
||||
@ -309,13 +265,13 @@ ftp_closesocket(int fd, int connected)
|
||||
/* shutdown connection */
|
||||
rc = shutdown(fd, SHUT_RDWR);
|
||||
if(rc != 0)
|
||||
console_print(RED "shutdown: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "shutdown: %d %s\n" RESET, errno, strerror(errno));
|
||||
}
|
||||
|
||||
/* close socket */
|
||||
rc = closesocket(fd);
|
||||
rc = close(fd);
|
||||
if(rc != 0)
|
||||
console_print(RED "closesocket: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "close: %d %s\n" RESET, errno, strerror(errno));
|
||||
}
|
||||
|
||||
/*! close command socket on ftp session
|
||||
@ -367,21 +323,12 @@ ftp_session_close_data(ftp_session_t *session)
|
||||
static void
|
||||
ftp_session_close_file(ftp_session_t *session)
|
||||
{
|
||||
#ifdef _3DS
|
||||
Result ret;
|
||||
|
||||
ret = FSFILE_Close(session->fd);
|
||||
if(ret != 0)
|
||||
console_print(RED "FSFILE_Close: 0x%08X\n" RESET, (unsigned int)ret);
|
||||
session->fd = -1;
|
||||
#else
|
||||
int rc;
|
||||
|
||||
rc = close(session->fd);
|
||||
if(rc != 0)
|
||||
console_print(RED "close: %d %s\n" RESET, errno, strerror(errno));
|
||||
session->fd = -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*! open file for reading for ftp session
|
||||
@ -393,30 +340,6 @@ ftp_session_close_file(ftp_session_t *session)
|
||||
static int
|
||||
ftp_session_open_file_read(ftp_session_t *session)
|
||||
{
|
||||
#ifdef _3DS
|
||||
Result ret;
|
||||
u64 size;
|
||||
|
||||
/* open file in read mode */
|
||||
ret = FSUSER_OpenFile(NULL, &session->fd, sdmcArchive,
|
||||
FS_makePath(PATH_CHAR, session->buffer),
|
||||
FS_OPEN_READ, FS_ATTRIBUTE_NONE);
|
||||
if(ret != 0)
|
||||
{
|
||||
console_print(RED "FSUSER_OpenFile: 0x%08X\n" RESET, (unsigned int)ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get the file size */
|
||||
ret = FSFILE_GetSize(session->fd, &size);
|
||||
if(ret != 0)
|
||||
{
|
||||
console_print(RED "FSFILE_GetSize: 0x%08X\n" RESET, (unsigned int)ret);
|
||||
ftp_session_close_file(session);
|
||||
return -1;
|
||||
}
|
||||
session->filesize = size;
|
||||
#else
|
||||
int rc;
|
||||
struct stat st;
|
||||
|
||||
@ -437,7 +360,6 @@ ftp_session_open_file_read(ftp_session_t *session)
|
||||
return -1;
|
||||
}
|
||||
session->filesize = st.st_size;
|
||||
#endif
|
||||
|
||||
/* reset file position */
|
||||
/* TODO: support REST command */
|
||||
@ -455,28 +377,9 @@ ftp_session_open_file_read(ftp_session_t *session)
|
||||
static ssize_t
|
||||
ftp_session_read_file(ftp_session_t *session)
|
||||
{
|
||||
#ifdef _3DS
|
||||
Result ret;
|
||||
u32 bytes;
|
||||
|
||||
/* read file at current position */
|
||||
ret = FSFILE_Read(session->fd, &bytes, session->filepos,
|
||||
session->buffer, sizeof(session->buffer));
|
||||
if(ret != 0)
|
||||
{
|
||||
console_print(RED "FSFILE_Read: 0x%08X\n" RESET, (unsigned int)ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* adjust file position */
|
||||
session->filepos += bytes;
|
||||
|
||||
return bytes;
|
||||
#else
|
||||
ssize_t rc;
|
||||
|
||||
/* read file at current position */
|
||||
/* TODO: maybe use pread? */
|
||||
rc = read(session->fd, session->buffer, sizeof(session->buffer));
|
||||
if(rc < 0)
|
||||
{
|
||||
@ -488,7 +391,6 @@ ftp_session_read_file(ftp_session_t *session)
|
||||
session->filepos += rc;
|
||||
|
||||
return rc;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*! open file for writing for ftp session
|
||||
@ -502,27 +404,6 @@ ftp_session_read_file(ftp_session_t *session)
|
||||
static int
|
||||
ftp_session_open_file_write(ftp_session_t *session)
|
||||
{
|
||||
#ifdef _3DS
|
||||
Result ret;
|
||||
|
||||
/* open file in write and create mode */
|
||||
ret = FSUSER_OpenFile(NULL, &session->fd, sdmcArchive,
|
||||
FS_makePath(PATH_CHAR, session->buffer),
|
||||
FS_OPEN_WRITE|FS_OPEN_CREATE, FS_ATTRIBUTE_NONE);
|
||||
if(ret != 0)
|
||||
{
|
||||
console_print(RED "FSUSER_OpenFile: 0x%08X\n" RESET, (unsigned int)ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* truncate file */
|
||||
ret = FSFILE_SetSize(session->fd, 0);
|
||||
if(ret != 0)
|
||||
{
|
||||
console_print(RED "FSFILE_SetSize: 0x%08X\n" RESET, (unsigned int)ret);
|
||||
ftp_session_close_file(session);
|
||||
}
|
||||
#else
|
||||
/* open file in write and create mode with truncation */
|
||||
session->fd = open(session->buffer, O_WRONLY|O_CREAT|O_TRUNC, 0644);
|
||||
if(session->fd < 0)
|
||||
@ -530,7 +411,6 @@ ftp_session_open_file_write(ftp_session_t *session)
|
||||
console_print(RED "open '%s': %d %s\n" RESET, session->buffer, errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* reset file position */
|
||||
/* TODO: support REST command */
|
||||
@ -548,32 +428,9 @@ ftp_session_open_file_write(ftp_session_t *session)
|
||||
static ssize_t
|
||||
ftp_session_write_file(ftp_session_t *session)
|
||||
{
|
||||
#ifdef _3DS
|
||||
Result ret;
|
||||
u32 bytes;
|
||||
|
||||
/* write to file at current position */
|
||||
ret = FSFILE_Write(session->fd, &bytes, session->filepos,
|
||||
session->buffer + session->bufferpos,
|
||||
session->buffersize - session->bufferpos,
|
||||
FS_WRITE_FLUSH);
|
||||
if(ret != 0)
|
||||
{
|
||||
console_print(RED "FSFILE_Write: 0x%08X\n" RESET, (unsigned int)ret);
|
||||
return -1;
|
||||
}
|
||||
else if(bytes == 0)
|
||||
console_print(RED "FSFILE_Write: wrote 0 bytes\n" RESET);
|
||||
|
||||
/* adjust file position */
|
||||
session->filepos += bytes;
|
||||
|
||||
return bytes;
|
||||
#else
|
||||
ssize_t rc;
|
||||
|
||||
/* write to file at current position */
|
||||
/* TODO: maybe use writev? */
|
||||
rc = write(session->fd, session->buffer + session->bufferpos,
|
||||
session->buffersize - session->bufferpos);
|
||||
if(rc < 0)
|
||||
@ -588,7 +445,6 @@ ftp_session_write_file(ftp_session_t *session)
|
||||
session->filepos += rc;
|
||||
|
||||
return rc;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*! close current working directory for ftp session
|
||||
@ -598,15 +454,6 @@ ftp_session_write_file(ftp_session_t *session)
|
||||
static void
|
||||
ftp_session_close_cwd(ftp_session_t *session)
|
||||
{
|
||||
#ifdef _3DS
|
||||
Result ret;
|
||||
|
||||
/* close open directory handle */
|
||||
ret = FSDIR_Close(session->fd);
|
||||
if(ret != 0)
|
||||
console_print(RED "FSDIR_Close: 0x%08X\n" RESET, (unsigned int)ret);
|
||||
session->fd = -1;
|
||||
#else
|
||||
int rc;
|
||||
|
||||
/* close open directory pointer */
|
||||
@ -614,7 +461,6 @@ ftp_session_close_cwd(ftp_session_t *session)
|
||||
if(rc != 0)
|
||||
console_print(RED "closedir: %d %s\n" RESET, errno, strerror(errno));
|
||||
session->dp = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*! open current working directory for ftp session
|
||||
@ -626,18 +472,6 @@ ftp_session_close_cwd(ftp_session_t *session)
|
||||
static int
|
||||
ftp_session_open_cwd(ftp_session_t *session)
|
||||
{
|
||||
#ifdef _3DS
|
||||
Result ret;
|
||||
|
||||
/* open current working directory */
|
||||
ret = FSUSER_OpenDirectory(NULL, &session->fd, sdmcArchive,
|
||||
FS_makePath(PATH_CHAR, session->cwd));
|
||||
if(ret != 0)
|
||||
{
|
||||
console_print(RED "FSUSER_OpenDirectory: 0x%08X\n" RESET, (unsigned int)ret);
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
/* open current working directory */
|
||||
session->dp = opendir(session->cwd);
|
||||
if(session->dp == NULL)
|
||||
@ -645,7 +479,6 @@ ftp_session_open_cwd(ftp_session_t *session)
|
||||
console_print(RED "opendir '%s': %d %s\n" RESET, session->cwd, errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -715,7 +548,10 @@ ftp_send_response(ftp_session_t *session,
|
||||
|
||||
/* print response code and message to buffer */
|
||||
va_start(ap, fmt);
|
||||
rc = sprintf(buffer, "%d ", code);
|
||||
if(code != 211)
|
||||
rc = sprintf(buffer, "%d ", code);
|
||||
else
|
||||
rc = sprintf(buffer, "%d- ", code);
|
||||
rc += vsnprintf(buffer+rc, sizeof(buffer)-rc, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
@ -731,7 +567,7 @@ ftp_send_response(ftp_session_t *session,
|
||||
console_print(GREEN "%s" RESET, buffer);
|
||||
rc = send(session->cmd_fd, buffer, to_send, 0);
|
||||
if(rc < 0)
|
||||
console_print(RED "send: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "send: %d %s\n" RESET, errno, strerror(errno));
|
||||
else if(rc != to_send)
|
||||
console_print(RED "only sent %u/%u bytes\n" RESET,
|
||||
(unsigned int)rc, (unsigned int)to_send);
|
||||
@ -742,8 +578,6 @@ ftp_send_response(ftp_session_t *session,
|
||||
/*! destroy ftp session
|
||||
*
|
||||
* @param[in] session ftp session
|
||||
*
|
||||
* @returns next session in list
|
||||
*/
|
||||
static ftp_session_t*
|
||||
ftp_session_destroy(ftp_session_t *session)
|
||||
@ -793,7 +627,7 @@ ftp_session_new(int listen_fd)
|
||||
new_fd = accept(listen_fd, (struct sockaddr*)&addr, &addrlen);
|
||||
if(new_fd < 0)
|
||||
{
|
||||
console_print(RED "accept: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "accept: %d %s\n" RESET, errno, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -840,7 +674,7 @@ ftp_session_new(int listen_fd)
|
||||
rc = getsockname(new_fd, (struct sockaddr*)&session->pasv_addr, &addrlen);
|
||||
if(rc != 0)
|
||||
{
|
||||
console_print(RED "getsockname: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "getsockname: %d %s\n" RESET, errno, strerror(errno));
|
||||
ftp_send_response(session, 451, "Failed to get connection info\r\n");
|
||||
ftp_session_destroy(session);
|
||||
return;
|
||||
@ -879,7 +713,7 @@ ftp_session_accept(ftp_session_t *session)
|
||||
new_fd = accept(session->pasv_fd, (struct sockaddr*)&addr, &addrlen);
|
||||
if(new_fd < 0)
|
||||
{
|
||||
console_print(RED "accept: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "accept: %d %s\n" RESET, errno, strerror(errno));
|
||||
ftp_session_set_state(session, COMMAND_STATE);
|
||||
ftp_send_response(session, 425, "Failed to establish connection\r\n");
|
||||
return -1;
|
||||
@ -928,7 +762,7 @@ ftp_session_connect(ftp_session_t *session)
|
||||
session->data_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(session->data_fd < 0)
|
||||
{
|
||||
console_print(RED "socket: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "socket: %d %s\n" RESET, errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -937,7 +771,7 @@ ftp_session_connect(ftp_session_t *session)
|
||||
sizeof(session->peer_addr));
|
||||
if(rc != 0)
|
||||
{
|
||||
console_print(RED "connect: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "connect: %d %s\n" RESET, errno, strerror(errno));
|
||||
ftp_closesocket(session->data_fd, 0);
|
||||
session->data_fd = -1;
|
||||
return -1;
|
||||
@ -973,7 +807,7 @@ ftp_session_read_command(ftp_session_t *session)
|
||||
if(rc < 0)
|
||||
{
|
||||
/* error retrieving command */
|
||||
console_print(RED "recv: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "recv: %d %s\n" RESET, errno, strerror(errno));
|
||||
ftp_session_close_cmd(session);
|
||||
return;
|
||||
}
|
||||
@ -1064,7 +898,7 @@ ftp_session_poll(ftp_session_t *session)
|
||||
/* poll the selected socket */
|
||||
rc = poll(&pollinfo, 1, 0);
|
||||
if(rc < 0)
|
||||
console_print(RED "poll: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "poll: %d %s\n" RESET, errno, strerror(errno));
|
||||
else if(rc > 0)
|
||||
{
|
||||
if(pollinfo.revents != 0)
|
||||
@ -1142,15 +976,6 @@ ftp_init(void)
|
||||
goto fs_fail;
|
||||
}
|
||||
|
||||
/* open SDMC archive */
|
||||
ret = FSUSER_OpenArchive(NULL, &sdmcArchive);
|
||||
if(ret != 0)
|
||||
{
|
||||
console_print(RED "FSUSER_OpenArchive: 0x%08X\n" RESET, (unsigned int)ret);
|
||||
goto archive_fail;
|
||||
}
|
||||
|
||||
#if ENABLE_LOGGING
|
||||
/* initialize sdmc_dev */
|
||||
ret = sdmcInit();
|
||||
if(ret != 0)
|
||||
@ -1159,6 +984,7 @@ ftp_init(void)
|
||||
goto sdmc_fail;
|
||||
}
|
||||
|
||||
#if ENABLE_LOGGING
|
||||
/* open log file */
|
||||
FILE *fp = freopen("/ftbrony.log", "wb", stderr);
|
||||
if(fp == NULL)
|
||||
@ -1196,7 +1022,7 @@ ftp_init(void)
|
||||
listenfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(listenfd < 0)
|
||||
{
|
||||
console_print(RED "socket: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "socket: %d %s\n" RESET, errno, strerror(errno));
|
||||
ftp_exit();
|
||||
return -1;
|
||||
}
|
||||
@ -1216,7 +1042,7 @@ ftp_init(void)
|
||||
rc = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
|
||||
if(rc != 0)
|
||||
{
|
||||
console_print(RED "setsockopt: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "setsockopt: %d %s\n" RESET, errno, strerror(errno));
|
||||
ftp_exit();
|
||||
return -1;
|
||||
}
|
||||
@ -1227,7 +1053,7 @@ ftp_init(void)
|
||||
rc = bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
|
||||
if(rc != 0)
|
||||
{
|
||||
console_print(RED "bind: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "bind: %d %s\n" RESET, errno, strerror(errno));
|
||||
ftp_exit();
|
||||
return -1;
|
||||
}
|
||||
@ -1236,7 +1062,7 @@ ftp_init(void)
|
||||
rc = listen(listenfd, 5);
|
||||
if(rc != 0)
|
||||
{
|
||||
console_print(RED "listen: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "listen: %d %s\n" RESET, errno, strerror(errno));
|
||||
ftp_exit();
|
||||
return -1;
|
||||
}
|
||||
@ -1256,7 +1082,7 @@ ftp_init(void)
|
||||
rc = getsockname(listenfd, (struct sockaddr*)&serv_addr, &addrlen);
|
||||
if(rc != 0)
|
||||
{
|
||||
console_print(RED "getsockname: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "getsockname: %d %s\n" RESET, errno, strerror(errno));
|
||||
ftp_exit();
|
||||
return -1;
|
||||
}
|
||||
@ -1264,7 +1090,7 @@ ftp_init(void)
|
||||
rc = gethostname(hostname, sizeof(hostname));
|
||||
if(rc != 0)
|
||||
{
|
||||
console_print(RED "gethostname: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "gethostname: %d %s\n" RESET, errno, strerror(errno));
|
||||
ftp_exit();
|
||||
return -1;
|
||||
}
|
||||
@ -1291,17 +1117,12 @@ ftruncate_fail:
|
||||
console_print(RED "fclose: 0x%08X\n" RESET, errno);
|
||||
|
||||
stderr_fail:
|
||||
#endif
|
||||
ret = sdmcExit();
|
||||
if(ret != 0)
|
||||
console_print(RED "sdmcExit: 0x%08X\n" RESET, (unsigned int)ret);
|
||||
|
||||
sdmc_fail:
|
||||
#endif
|
||||
ret = FSUSER_CloseArchive(NULL, &sdmcArchive);
|
||||
if(ret != 0)
|
||||
console_print(RED "FSUSER_CloseArchive: 0x%08X\n" RESET, (unsigned int)ret);
|
||||
|
||||
archive_fail:
|
||||
ret = fsExit();
|
||||
if(ret != 0)
|
||||
console_print(RED "fsExit: 0x%08X\n" RESET, (unsigned int)ret);
|
||||
@ -1365,7 +1186,10 @@ ftp_loop(void)
|
||||
|
||||
rc = poll(&pollinfo, 1, 0);
|
||||
if(rc < 0)
|
||||
console_print(RED "poll: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
{
|
||||
console_print(RED "poll: %d %s\n" RESET, errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
else if(rc > 0)
|
||||
{
|
||||
if(pollinfo.revents & POLLIN)
|
||||
@ -1479,47 +1303,10 @@ build_path(ftp_session_t *session,
|
||||
static int
|
||||
list_transfer(ftp_session_t *session)
|
||||
{
|
||||
#ifdef _3DS
|
||||
Result ret;
|
||||
#endif
|
||||
ssize_t rc;
|
||||
|
||||
if(session->bufferpos == session->buffersize)
|
||||
{
|
||||
#ifdef _3DS
|
||||
FS_dirent dent;
|
||||
u32 entries;
|
||||
char name[256];
|
||||
|
||||
ret = FSDIR_Read(session->fd, &entries, 1, &dent);
|
||||
if(ret != 0)
|
||||
{
|
||||
console_print(RED "FSDIR_Read: 0x%08X\n" RESET, (unsigned int)ret);
|
||||
ftp_session_close_cwd(session);
|
||||
ftp_session_set_state(session, COMMAND_STATE);
|
||||
ftp_send_response(session, 450, "failed to read directory\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(entries == 0)
|
||||
{
|
||||
ftp_session_close_cwd(session);
|
||||
ftp_session_set_state(session, COMMAND_STATE);
|
||||
ftp_send_response(session, 226, "OK\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
convert_name(name, dent.name);
|
||||
if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
|
||||
return 0;
|
||||
|
||||
session->buffersize =
|
||||
sprintf(session->buffer,
|
||||
"%crwxrwxrwx 1 3DS 3DS %llu Jan 1 1970 %s\r\n",
|
||||
dent.isDirectory ? 'd' : '-',
|
||||
dent.fileSize,
|
||||
name);
|
||||
#else
|
||||
struct stat st;
|
||||
struct dirent *dent = readdir(session->dp);
|
||||
if(dent == NULL)
|
||||
@ -1533,8 +1320,12 @@ list_transfer(ftp_session_t *session)
|
||||
if(strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0)
|
||||
return 0;
|
||||
|
||||
snprintf(session->buffer, sizeof(session->buffer),
|
||||
"%s/%s", session->cwd, dent->d_name);
|
||||
if(strcmp(session->cwd, "/") == 0)
|
||||
snprintf(session->buffer, sizeof(session->buffer),
|
||||
"/%s", dent->d_name);
|
||||
else
|
||||
snprintf(session->buffer, sizeof(session->buffer),
|
||||
"%s/%s", session->cwd, dent->d_name);
|
||||
rc = lstat(session->buffer, &st);
|
||||
if(rc != 0)
|
||||
{
|
||||
@ -1552,7 +1343,6 @@ list_transfer(ftp_session_t *session)
|
||||
S_ISLNK(st.st_mode) ? 'l' : '-',
|
||||
(unsigned long long)st.st_size,
|
||||
dent->d_name);
|
||||
#endif
|
||||
session->bufferpos = 0;
|
||||
}
|
||||
|
||||
@ -1562,9 +1352,9 @@ list_transfer(ftp_session_t *session)
|
||||
{
|
||||
if(rc < 0)
|
||||
{
|
||||
if(Errno() == EWOULDBLOCK)
|
||||
if(errno == EWOULDBLOCK)
|
||||
return -1;
|
||||
console_print(RED "send: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "send: %d %s\n" RESET, errno, strerror(errno));
|
||||
}
|
||||
else
|
||||
console_print(YELLOW "send: %d %s\n" RESET, ECONNRESET, strerror(ECONNRESET));
|
||||
@ -1608,9 +1398,9 @@ retrieve_transfer(ftp_session_t *session)
|
||||
{
|
||||
if(rc < 0)
|
||||
{
|
||||
if(Errno() == EWOULDBLOCK)
|
||||
if(errno == EWOULDBLOCK)
|
||||
return -1;
|
||||
console_print(RED "send: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "send: %d %s\n" RESET, errno, strerror(errno));
|
||||
}
|
||||
else
|
||||
console_print(YELLOW "send: %d %s\n" RESET, ECONNRESET, strerror(ECONNRESET));
|
||||
@ -1637,9 +1427,9 @@ store_transfer(ftp_session_t *session)
|
||||
{
|
||||
if(rc < 0)
|
||||
{
|
||||
if(Errno() == EWOULDBLOCK)
|
||||
if(errno == EWOULDBLOCK)
|
||||
return -1;
|
||||
console_print(RED "recv: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "recv: %d %s\n" RESET, errno, strerror(errno));
|
||||
}
|
||||
|
||||
ftp_session_close_file(session);
|
||||
@ -1723,19 +1513,6 @@ FTP_DECLARE(CWD)
|
||||
return ftp_send_response(session, 553, "%s\r\n", strerror(errno));
|
||||
|
||||
{
|
||||
#ifdef _3DS
|
||||
Result ret;
|
||||
Handle fd;
|
||||
|
||||
ret = FSUSER_OpenDirectory(NULL, &fd, sdmcArchive,
|
||||
FS_makePath(PATH_CHAR, session->buffer));
|
||||
if(ret != 0)
|
||||
return ftp_send_response(session, 553, "not a directory\r\n");
|
||||
|
||||
ret = FSDIR_Close(fd);
|
||||
if(ret != 0)
|
||||
console_print(RED "FSDIR_Close: 0x%08X\n" RESET, (unsigned int)ret);
|
||||
#else
|
||||
struct stat st;
|
||||
int rc;
|
||||
|
||||
@ -1748,7 +1525,6 @@ FTP_DECLARE(CWD)
|
||||
|
||||
if(!S_ISDIR(st.st_mode))
|
||||
return ftp_send_response(session, 553, "not a directory\r\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
strncpy(session->cwd, session->buffer, sizeof(session->cwd));
|
||||
@ -1758,11 +1534,7 @@ FTP_DECLARE(CWD)
|
||||
|
||||
FTP_DECLARE(DELE)
|
||||
{
|
||||
#ifdef _3DS
|
||||
Result ret;
|
||||
#else
|
||||
int rc;
|
||||
#endif
|
||||
int rc;
|
||||
|
||||
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
|
||||
|
||||
@ -1771,21 +1543,12 @@ FTP_DECLARE(DELE)
|
||||
if(build_path(session, args) != 0)
|
||||
return ftp_send_response(session, 553, "%s\r\n", strerror(errno));
|
||||
|
||||
#ifdef _3DS
|
||||
ret = FSUSER_DeleteFile(NULL, sdmcArchive, FS_makePath(PATH_CHAR, session->buffer));
|
||||
if(ret != 0)
|
||||
{
|
||||
console_print(RED "FSUSER_DeleteFile: 0x%08X\n" RESET, (unsigned int)ret);
|
||||
return ftp_send_response(session, 550, "failed to delete file\r\n");
|
||||
}
|
||||
#else
|
||||
rc = unlink(session->buffer);
|
||||
if(rc != 0)
|
||||
{
|
||||
console_print(RED "unlink: %d %s\n" RESET, errno, strerror(errno));
|
||||
return ftp_send_response(session, 550, "failed to delete file\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
return ftp_send_response(session, 250, "OK\r\n");
|
||||
}
|
||||
@ -1796,7 +1559,7 @@ FTP_DECLARE(FEAT)
|
||||
|
||||
ftp_session_set_state(session, COMMAND_STATE);
|
||||
|
||||
return ftp_send_response(session, 211, "\r\n");
|
||||
return ftp_send_response(session, 211, "\r\n UTF8\r\n211 End\r\n");
|
||||
}
|
||||
|
||||
FTP_DECLARE(LIST)
|
||||
@ -1849,11 +1612,7 @@ FTP_DECLARE(LIST)
|
||||
|
||||
FTP_DECLARE(MKD)
|
||||
{
|
||||
#ifdef _3DS
|
||||
Result ret;
|
||||
#else
|
||||
int rc;
|
||||
#endif
|
||||
int rc;
|
||||
|
||||
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
|
||||
|
||||
@ -1862,21 +1621,12 @@ FTP_DECLARE(MKD)
|
||||
if(build_path(session, args) != 0)
|
||||
return ftp_send_response(session, 553, "%s\r\n", strerror(errno));
|
||||
|
||||
#ifdef _3DS
|
||||
ret = FSUSER_CreateDirectory(NULL, sdmcArchive, FS_makePath(PATH_CHAR, session->buffer));
|
||||
if(ret != 0)
|
||||
{
|
||||
console_print(RED "FSUSER_OpenDirectory: 0x%08X\n" RESET, (unsigned int)ret);
|
||||
return ftp_send_response(session, 550, "failed to create directory\r\n");
|
||||
}
|
||||
#else
|
||||
rc = mkdir(session->buffer, 0755);
|
||||
if(rc != 0)
|
||||
{
|
||||
console_print(RED "mkdir: %d %s\n" RESET, errno, strerror(errno));
|
||||
return ftp_send_response(session, 550, "failed to create directory\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
return ftp_send_response(session, 250, "OK\r\n");
|
||||
}
|
||||
@ -1909,6 +1659,20 @@ FTP_DECLARE(NOOP)
|
||||
return ftp_send_response(session, 200, "OK\r\n");
|
||||
}
|
||||
|
||||
FTP_DECLARE(OPTS)
|
||||
{
|
||||
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
|
||||
|
||||
ftp_session_set_state(session, COMMAND_STATE);
|
||||
|
||||
if(strcasecmp(args, "UTF8") == 0
|
||||
|| strcasecmp(args, "UTF8 ON") == 0
|
||||
|| strcasecmp(args, "UTF8 NLST") == 0)
|
||||
return ftp_send_response(session, 200, "OK\r\n");
|
||||
|
||||
return ftp_send_response(session, 504, "invalid argument\r\n");
|
||||
}
|
||||
|
||||
FTP_DECLARE(PASS)
|
||||
{
|
||||
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
|
||||
@ -1936,7 +1700,7 @@ FTP_DECLARE(PASV)
|
||||
session->pasv_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(session->pasv_fd < 0)
|
||||
{
|
||||
console_print(RED "socket: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "socket: %d %s\n" RESET, errno, strerror(errno));
|
||||
return ftp_send_response(session, 451, "\r\n");
|
||||
}
|
||||
|
||||
@ -1951,7 +1715,7 @@ FTP_DECLARE(PASV)
|
||||
sizeof(session->pasv_addr));
|
||||
if(rc != 0)
|
||||
{
|
||||
console_print(RED "bind: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "bind: %d %s\n" RESET, errno, strerror(errno));
|
||||
ftp_session_close_pasv(session);
|
||||
return ftp_send_response(session, 451, "\r\n");
|
||||
}
|
||||
@ -1959,7 +1723,7 @@ FTP_DECLARE(PASV)
|
||||
rc = listen(session->pasv_fd, 5);
|
||||
if(rc != 0)
|
||||
{
|
||||
console_print(RED "listen: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "listen: %d %s\n" RESET, errno, strerror(errno));
|
||||
ftp_session_close_pasv(session);
|
||||
return ftp_send_response(session, 451, "\r\n");
|
||||
}
|
||||
@ -1971,7 +1735,7 @@ FTP_DECLARE(PASV)
|
||||
&addrlen);
|
||||
if(rc != 0)
|
||||
{
|
||||
console_print(RED "getsockname: %d %s\n" RESET, Errno(), strerror(Errno()));
|
||||
console_print(RED "getsockname: %d %s\n" RESET, errno, strerror(errno));
|
||||
ftp_session_close_pasv(session);
|
||||
return ftp_send_response(session, 451, "\r\n");
|
||||
}
|
||||
@ -2171,11 +1935,7 @@ FTP_DECLARE(RETR)
|
||||
|
||||
FTP_DECLARE(RMD)
|
||||
{
|
||||
#ifdef _3DS
|
||||
Result ret;
|
||||
#else
|
||||
int rc;
|
||||
#endif
|
||||
int rc;
|
||||
|
||||
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
|
||||
|
||||
@ -2184,34 +1944,20 @@ FTP_DECLARE(RMD)
|
||||
if(build_path(session, args) != 0)
|
||||
return ftp_send_response(session, 553, "%s\r\n", strerror(errno));
|
||||
|
||||
#ifdef _3DS
|
||||
ret = FSUSER_DeleteDirectory(NULL, sdmcArchive, FS_makePath(PATH_CHAR, session->buffer));
|
||||
if(ret != 0)
|
||||
{
|
||||
console_print(RED "FSUSER_DeleteDirectory: 0x%08X\n" RESET, (unsigned int)ret);
|
||||
return ftp_send_response(session, 550, "failed to delete directory\r\n");
|
||||
}
|
||||
#else
|
||||
rc = rmdir(session->buffer);
|
||||
if(rc != 0)
|
||||
{
|
||||
console_print(RED "rmdir: %d %s\n" RESET, errno, strerror(errno));
|
||||
return ftp_send_response(session, 550, "failed to delete directory\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
return ftp_send_response(session, 250, "OK\r\n");
|
||||
}
|
||||
|
||||
FTP_DECLARE(RNFR)
|
||||
{
|
||||
#ifdef _3DS
|
||||
Result ret;
|
||||
Handle fd;
|
||||
#else
|
||||
int rc;
|
||||
struct stat st;
|
||||
#endif
|
||||
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
|
||||
|
||||
ftp_session_set_state(session, COMMAND_STATE);
|
||||
@ -2219,35 +1965,12 @@ FTP_DECLARE(RNFR)
|
||||
if(build_path(session, args) != 0)
|
||||
return ftp_send_response(session, 553, "%s\r\n", strerror(errno));
|
||||
|
||||
#ifdef _3DS
|
||||
ret = FSUSER_OpenFile(NULL, &fd, sdmcArchive,
|
||||
FS_makePath(PATH_CHAR, session->buffer),
|
||||
FS_OPEN_READ, FS_ATTRIBUTE_NONE);
|
||||
if(ret != 0)
|
||||
{
|
||||
ret = FSUSER_OpenDirectory(NULL, &fd, sdmcArchive,
|
||||
FS_makePath(PATH_CHAR, session->buffer));
|
||||
if(ret == 0)
|
||||
ret = FSDIR_Close(fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = FSFILE_Close(fd);
|
||||
}
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
console_print(RED "no such file or directory\n" RESET);
|
||||
return ftp_send_response(session, 450, "no such file or directory\r\n");
|
||||
}
|
||||
#else
|
||||
rc = lstat(session->buffer, &st);
|
||||
if(rc != 0)
|
||||
{
|
||||
console_print(RED "lstat: %d %s\n" RESET, errno, strerror(errno));
|
||||
return ftp_send_response(session, 450, "no such file or directory\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
session->flags |= SESSION_RENAME;
|
||||
|
||||
@ -2256,11 +1979,7 @@ FTP_DECLARE(RNFR)
|
||||
|
||||
FTP_DECLARE(RNTO)
|
||||
{
|
||||
#ifdef _3DS
|
||||
Result ret;
|
||||
#else
|
||||
int rc;
|
||||
#endif
|
||||
int rc;
|
||||
char buffer[XFER_BUFFERSIZE];
|
||||
|
||||
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
|
||||
@ -2277,27 +1996,12 @@ FTP_DECLARE(RNTO)
|
||||
if(build_path(session, args) != 0)
|
||||
return ftp_send_response(session, 554, "%s\r\n", strerror(errno));
|
||||
|
||||
#ifdef _3DS
|
||||
ret = FSUSER_RenameFile(NULL,
|
||||
sdmcArchive, FS_makePath(PATH_CHAR, buffer),
|
||||
sdmcArchive, FS_makePath(PATH_CHAR, session->buffer));
|
||||
if(ret != 0)
|
||||
ret = FSUSER_RenameDirectory(NULL,
|
||||
sdmcArchive, FS_makePath(PATH_CHAR, buffer),
|
||||
sdmcArchive, FS_makePath(PATH_CHAR, session->buffer));
|
||||
if(ret != 0)
|
||||
{
|
||||
console_print(RED "FSUSER_RenameFile/Directory: 0x%08X\n" RESET, (unsigned int)ret);
|
||||
return ftp_send_response(session, 550, "failed to rename file/directory\r\n");
|
||||
}
|
||||
#else
|
||||
rc = rename(buffer, session->buffer);
|
||||
if(rc != 0)
|
||||
{
|
||||
console_print(RED "rename: %d %s\n" RESET, errno, strerror(errno));
|
||||
return ftp_send_response(session, 550, "failed to rename file/directory\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
return ftp_send_response(session, 250, "OK\r\n");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user