Skip to content

Commit

Permalink
Nx add gc mount, Nx save zip upload, Nx romfs mount, Nx bis storage m…
Browse files Browse the repository at this point in the history
…ount
  • Loading branch information
ITotalJustice committed Dec 10, 2024
1 parent db4fe21 commit 20bb627
Show file tree
Hide file tree
Showing 20 changed files with 2,113 additions and 405 deletions.
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -253,12 +253,15 @@ if (NINTENDO_SWITCH)
src/platform/nx/vfs/vfs_nx_root.c
src/platform/nx/vfs/vfs_nx_fs.c
src/platform/nx/vfs/vfs_nx_save.c
src/platform/nx/vfs/vfs_nx_storage.c
src/platform/nx/vfs/vfs_nx_gc.c
src/platform/nx/utils.c
src/log/log.c
)

add_executable(ftpexe
src/platform/nx/main.c
src/platform/nx/vfs/vfs_nx_stdio.c
src/platform/nx/vfs/vfs_nx_hdd.c
${NX_SRC}
)
Expand Down
91 changes: 32 additions & 59 deletions src/ftpsrv.c
Original file line number Diff line number Diff line change
Expand Up @@ -605,29 +605,27 @@ static enum FTP_FILE_TRANSFER_STATE ftp_file_data_transfer_progress(struct FtpSe
} else {
n = socket_send(session->data_sock, g_ftp.data_buf, n, 0);
if (n < 0) {
if (errno != EWOULDBLOCK && errno != EAGAIN) {
return FTP_FILE_TRANSFER_STATE_ERROR;
} else {
ftp_vfs_seek(&transfer->file_vfs, transfer->offset);
if (errno == EWOULDBLOCK || errno == EAGAIN) {
ftp_vfs_seek(&transfer->file_vfs, g_ftp.data_buf, 0, transfer->offset);
return FTP_FILE_TRANSFER_STATE_BLOCKING;
} else {
return FTP_FILE_TRANSFER_STATE_ERROR;
}
} else {
transfer->offset += (size_t)n;
if (n != read) {
ftp_vfs_seek(&transfer->file_vfs, transfer->offset);
ftp_vfs_seek(&transfer->file_vfs, g_ftp.data_buf, n, transfer->offset);
return FTP_FILE_TRANSFER_STATE_BLOCKING;
} else if (read < sizeof(g_ftp.data_buf)) {
return FTP_FILE_TRANSFER_STATE_FINISHED;
}
}
}
} else {
n = socket_recv(session->data_sock, g_ftp.data_buf, sizeof(g_ftp.data_buf), 0);
if (n < 0) {
if (errno != EWOULDBLOCK && errno != EAGAIN) {
return FTP_FILE_TRANSFER_STATE_ERROR;
} else {
if (errno == EWOULDBLOCK || errno == EAGAIN) {
return FTP_FILE_TRANSFER_STATE_BLOCKING;
} else {
return FTP_FILE_TRANSFER_STATE_ERROR;
}
} else if (n == 0) {
return FTP_FILE_TRANSFER_STATE_FINISHED;
Expand Down Expand Up @@ -912,8 +910,13 @@ static void ftp_cmd_MODE(struct FtpSession* session, const char* data) {
}
}

// RETR <SP> <pathname> <CRLF> | 125, 150, (110), 226, 250, 425, 426, 451, 450, 550, 500, 501, 421, 530
static void ftp_cmd_RETR(struct FtpSession* session, const char* data) {
static void ftp_open_file(struct FtpSession* session, const char* data, enum FtpVfsOpenMode open_mode, enum FTP_TRANSFER_MODE transfer_mode, int error_code) {
session->transfer.offset = 0;
if (session->server_marker > 0) {
session->transfer.offset = session->server_marker;
session->server_marker = 0;
}

struct Pathname pathname = {0};
int rc = snprintf(pathname.s, sizeof(pathname), "%s", data);

Expand All @@ -923,70 +926,40 @@ static void ftp_cmd_RETR(struct FtpSession* session, const char* data) {
struct Pathname fullpath = {0};
rc = build_fullpath(session, &fullpath, pathname);
if (rc < 0) {
ftp_client_msg(session, 550, "Requested action not taken.");
ftp_client_msg(session, error_code, "Requested action not taken.");
} else {
rc = ftp_vfs_open(&session->transfer.file_vfs, fullpath.s, FtpVfsOpenMode_READ);
rc = ftp_vfs_open(&session->transfer.file_vfs, fullpath.s, open_mode);
if (rc < 0) {
ftp_client_msg(session, 550, "Requested action not taken, %s Failed to open path: %s.", strerror(errno), fullpath.s);
ftp_client_msg(session, error_code, "Requested action not taken, %s Failed to open path: %s.", strerror(errno), fullpath.s);
} else {
struct stat st = {0};
rc = ftp_vfs_fstat(&session->transfer.file_vfs, fullpath.s, &st);
if (session->transfer.offset) {
rc = ftp_vfs_seek(&session->transfer.file_vfs, NULL, 0, session->transfer.offset);
}

if (rc < 0) {
ftp_client_msg(session, 550, "Requested action not taken, %s. Failed to fstat path: %s", strerror(errno), fullpath.s);
ftp_vfs_close(&session->transfer.file_vfs);
ftp_client_msg(session, 550, "Requested action not taken, %s. Failed to fseek path: %s", strerror(errno), fullpath.s);
} else {
session->transfer.offset = 0;
session->transfer.size = st.st_size;

if (session->server_marker > 0) {
session->transfer.offset = session->server_marker;
rc = ftp_vfs_seek(&session->transfer.file_vfs, session->transfer.offset);
session->server_marker = 0;
}

if (rc < 0) {
ftp_client_msg(session, 550, "Requested action not taken, %s. Failed to fseek path: %s", strerror(errno), fullpath.s);
} else {
ftp_data_open(session, FTP_TRANSFER_MODE_RETR);
}
ftp_data_open(session, transfer_mode);
}
}
}
}
}

// RETR <SP> <pathname> <CRLF> | 125, 150, (110), 226, 250, 425, 426, 451, 450, 550, 500, 501, 421, 530
static void ftp_cmd_RETR(struct FtpSession* session, const char* data) {
ftp_open_file(session, data, FtpVfsOpenMode_READ, FTP_TRANSFER_MODE_RETR, 550);
}

// STOR <SP> <pathname> <CRLF> | 125, 150, (110), 226, 250, 425, 426, 451, 551, 552, 532, 450, 452, 553, 500, 501, 421, 530
static void ftp_cmd_STOR(struct FtpSession* session, const char* data) {
struct Pathname pathname = {0};
int rc = snprintf(pathname.s, sizeof(pathname), "%s", data);

if (rc <= 0 || rc >= sizeof(pathname)) {
ftp_client_msg(session, 501, "Syntax error in parameters or arguments.");
} else {
enum FtpVfsOpenMode flags = FtpVfsOpenMode_WRITE;
if (session->server_marker == -1) {
flags = FtpVfsOpenMode_APPEND;
session->server_marker = 0;
}

struct Pathname fullpath = {0};
rc = build_fullpath(session, &fullpath, pathname);
if (rc < 0) {
ftp_client_msg(session, 551, "Requested action aborted: page type unknown, %s.", strerror(errno));
} else {
rc = ftp_vfs_open(&session->transfer.file_vfs, fullpath.s, flags);
if (rc < 0) {
ftp_client_msg(session, 551, "Requested action aborted: page type unknown, %s. Failed to open path: %s", strerror(errno), fullpath.s);
} else {
ftp_data_open(session, FTP_TRANSFER_MODE_STOR);
}
}
}
ftp_open_file(session, data, FtpVfsOpenMode_WRITE, FTP_TRANSFER_MODE_STOR, 551);
}

// APPE <SP> <pathname> <CRLF> | 125, 150, (110), 226, 250, 425, 426, 451, 551, 552, 532, 450, 550, 452, 553, 500, 501, 502, 421, 530
static void ftp_cmd_APPE(struct FtpSession* session, const char* data) {
session->server_marker = -1;
ftp_cmd_STOR(session, data);
ftp_open_file(session, data, FtpVfsOpenMode_APPEND, FTP_TRANSFER_MODE_STOR, 551);
}

// ALLO <SP> <decimal-integer> <CRLF> | 200, 202, 500, 501, 504, 421, 530
Expand Down
5 changes: 2 additions & 3 deletions src/ftpsrv_vfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,13 @@ struct FtpVfsDirEntry;
int ftp_vfs_open(struct FtpVfsFile* f, const char* path, enum FtpVfsOpenMode mode);
int ftp_vfs_read(struct FtpVfsFile* f, void* buf, size_t size);
int ftp_vfs_write(struct FtpVfsFile* f, const void* buf, size_t size);
int ftp_vfs_seek(struct FtpVfsFile* f, size_t off);
int ftp_vfs_fstat(struct FtpVfsFile* f, const char* path, struct stat* st);
// buf and size is the amount of data sent.
int ftp_vfs_seek(struct FtpVfsFile* f, const void* buf, size_t size, size_t off);
int ftp_vfs_close(struct FtpVfsFile* f);
int ftp_vfs_isfile_open(struct FtpVfsFile* f);

int ftp_vfs_opendir(struct FtpVfsDir* f, const char* path);
const char* ftp_vfs_readdir(struct FtpVfsDir* f, struct FtpVfsDirEntry* entry);
int ftp_vfs_dirstat(struct FtpVfsDir* f, const struct FtpVfsDirEntry* entry, const char* path, struct stat* st);
int ftp_vfs_dirlstat(struct FtpVfsDir* f, const struct FtpVfsDirEntry* entry, const char* path, struct stat* st);
int ftp_vfs_closedir(struct FtpVfsDir* f);
int ftp_vfs_isdir_open(struct FtpVfsDir* f);
Expand Down
30 changes: 5 additions & 25 deletions src/platform/nx/vfs/vfs_nx_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -473,10 +473,6 @@ int vfs_fs_internal_seek(struct VfsFsFile* f, size_t off) {
return 0;
}

int vfs_fs_internal_fstat(FsFileSystem* fs, struct VfsFsFile* f, const char nxpath[static FS_MAX_PATH], struct stat* st) {
return fstat_internal(fs, &f->fd, nxpath, st);
}

int vfs_fs_internal_close(struct VfsFsFile* f) {
if (!vfs_fs_internal_isfile_open(f)) {
return -1;
Expand Down Expand Up @@ -529,7 +525,7 @@ const char* vfs_fs_internal_readdir(struct VfsFsDir* f, struct VfsFsDirEntry* en
return entry->buf.name;
}

int vfs_fs_internal_dirstat(FsFileSystem* fs, struct VfsFsDir* f, const struct VfsFsDirEntry* entry, const char nxpath[static FS_MAX_PATH], struct stat* st) {
int vfs_fs_internal_dirlstat(FsFileSystem* fs, struct VfsFsDir* f, const struct VfsFsDirEntry* entry, const char nxpath[static FS_MAX_PATH], struct stat* st) {
memset(st, 0, sizeof(*st));
st->st_nlink = 1;

Expand All @@ -551,10 +547,6 @@ int vfs_fs_internal_dirstat(FsFileSystem* fs, struct VfsFsDir* f, const struct V
return 0;
}

int vfs_fs_internal_dirlstat(FsFileSystem* fs, struct VfsFsDir* f, const struct VfsFsDirEntry* entry, const char nxpath[static FS_MAX_PATH], struct stat* st) {
return vfs_fs_internal_dirstat(fs, f, entry, nxpath, st);
}

int vfs_fs_internal_closedir(struct VfsFsDir* f) {
if (!vfs_fs_internal_isdir_open(f)) {
return -1;
Expand Down Expand Up @@ -668,21 +660,11 @@ static int vfs_fs_write(void* user, const void* buf, size_t size) {
return vfs_fs_internal_write(f, buf, size);
}

static int vfs_fs_seek(void* user, size_t off) {
static int vfs_fs_seek(void* user, const void* buf, size_t size, size_t off) {
struct VfsFsFile* f = user;
return vfs_fs_internal_seek(f, off);
}

static int vfs_fs_fstat(void* user, const char* path, struct stat* st) {
struct VfsFsFile* f = user;
FsFileSystem* fs = NULL;
char nxpath[FS_MAX_PATH];
if (fsdev_wrapTranslatePath(path, &fs, nxpath)) {
return -1;
}
return fstat_internal(fs, &f->fd, nxpath, st);
}

static int vfs_fs_isfile_open(void* user) {
struct VfsFsFile* f = user;
return vfs_fs_internal_isfile_open(f);
Expand Down Expand Up @@ -712,15 +694,15 @@ const char* vfs_fs_readdir(void* user, void* user_entry) {
return vfs_fs_internal_readdir(f, entry);
}

static int vfs_fs_dirstat(void* user, const void* user_entry, const char* path, struct stat* st) {
static int vfs_fs_dirlstat(void* user, const void* user_entry, const char* path, struct stat* st) {
struct VfsFsDir* f = user;
const struct VfsFsDirEntry* entry = user_entry;
FsFileSystem* fs = NULL;
char nxpath[FS_MAX_PATH];
if (fsdev_wrapTranslatePath(path, &fs, nxpath)) {
return -1;
}
return vfs_fs_internal_dirstat(fs, f, entry, nxpath, st);
return vfs_fs_internal_dirlstat(fs, f, entry, nxpath, st);
}

static int vfs_fs_isdir_open(void* user) {
Expand Down Expand Up @@ -792,13 +774,11 @@ const FtpVfs g_vfs_fs = {
.read = vfs_fs_read,
.write = vfs_fs_write,
.seek = vfs_fs_seek,
.fstat = vfs_fs_fstat,
.close = vfs_fs_close,
.isfile_open = vfs_fs_isfile_open,
.opendir = vfs_fs_opendir,
.readdir = vfs_fs_readdir,
.dirstat = vfs_fs_dirstat,
.dirlstat = vfs_fs_dirstat,
.dirlstat = vfs_fs_dirlstat,
.closedir = vfs_fs_closedir,
.isdir_open = vfs_fs_isdir_open,
.stat = vfs_fs_stat,
Expand Down
2 changes: 0 additions & 2 deletions src/platform/nx/vfs/vfs_nx_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,11 @@ int vfs_fs_internal_open(FsFileSystem* fs, struct VfsFsFile* f, const char nxpat
int vfs_fs_internal_read(struct VfsFsFile* f, void* buf, size_t size);
int vfs_fs_internal_write(struct VfsFsFile* f, const void* buf, size_t size);
int vfs_fs_internal_seek(struct VfsFsFile* f, size_t off);
int vfs_fs_internal_fstat(FsFileSystem* fs, struct VfsFsFile* f, const char nxpath[static FS_MAX_PATH], struct stat* st);
int vfs_fs_internal_close(struct VfsFsFile* f);
int vfs_fs_internal_isfile_open(struct VfsFsFile* f);

int vfs_fs_internal_opendir(FsFileSystem* fs, struct VfsFsDir* f, const char nxpath[static FS_MAX_PATH]);
const char* vfs_fs_internal_readdir(struct VfsFsDir* f, struct VfsFsDirEntry* entry);
int vfs_fs_internal_dirstat(FsFileSystem* fs, struct VfsFsDir* f, const struct VfsFsDirEntry* entry, const char nxpath[static FS_MAX_PATH], struct stat* st);
int vfs_fs_internal_dirlstat(FsFileSystem* fs, struct VfsFsDir* f, const struct VfsFsDirEntry* entry, const char nxpath[static FS_MAX_PATH], struct stat* st);
int vfs_fs_internal_closedir(struct VfsFsDir* f);
int vfs_fs_internal_isdir_open(struct VfsFsDir* f);
Expand Down
Loading

0 comments on commit 20bb627

Please sign in to comment.