From 0ba3844ad807f4fd59b1aaf0e417af93f4a5e4b7 Mon Sep 17 00:00:00 2001 From: mtheall Date: Wed, 19 Aug 2015 13:25:34 -0500 Subject: [PATCH] Use sdmc_dev Enable UTF8 --- source/ftp.c | 442 +++++++++------------------------------------------ 1 file changed, 73 insertions(+), 369 deletions(-) diff --git a/source/ftp.c b/source/ftp.c index 756e790..bbb3170 100644 --- a/source/ftp.c +++ b/source/ftp.c @@ -1,29 +1,25 @@ #include "ftp.h" #include #include +#include #include #include #include #include #include #include +#include #include #include -#include #include +#include #include #ifdef _3DS #include <3ds.h> -#else -#include -#include +#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"); }