Formatting and cleanup

This commit is contained in:
Maschell 2021-09-24 19:49:11 +02:00
parent f4dd784456
commit 9f784cbf1b
16 changed files with 548 additions and 528 deletions

View File

@ -1,28 +1,21 @@
#include "BackgroundThread.hpp" #include "BackgroundThread.hpp"
#include <malloc.h> #include <cstring>
#include <stdio.h>
#include <string.h>
#include <coreinit/cache.h>
#include <utils/logger.h>
#include "ftp.h" #include "ftp.h"
#include "net.h" #include "net.h"
BackgroundThread *BackgroundThread::instance = nullptr; BackgroundThread *BackgroundThread::instance = nullptr;
BackgroundThread::BackgroundThread() : BackgroundThreadWrapper(BackgroundThread::getPriority()) { BackgroundThread::BackgroundThread() : BackgroundThreadWrapper(BackgroundThread::getPriority()) {
DEBUG_FUNCTION_LINE("Create new Server"); DEBUG_FUNCTION_LINE("Start FTP Server");
mutex.lock(); mutex.lock();
this->serverSocket = create_server(PORT); this->serverSocket = create_server(PORT);
DCFlushRange(&(this->serverSocket), 4); DCFlushRange(&(this->serverSocket), 4);
mutex.unlock(); mutex.unlock();
DEBUG_FUNCTION_LINE("handle %d", this->serverSocket);
CThread::resumeThread(); CThread::resumeThread();
} }
BackgroundThread::~BackgroundThread() { BackgroundThread::~BackgroundThread() {
DEBUG_FUNCTION_LINE("Clean up FTP"); DEBUG_FUNCTION_LINE("Shutting down FTP Server");
if (this->serverSocket != -1) { if (this->serverSocket != -1) {
mutex.lock(); mutex.lock();
cleanup_ftp(); cleanup_ftp();
@ -30,7 +23,6 @@ BackgroundThread::~BackgroundThread() {
mutex.unlock(); mutex.unlock();
this->serverSocket = -1; this->serverSocket = -1;
} }
DEBUG_FUNCTION_LINE("Cleaned up FTP");
} }
BOOL BackgroundThread::whileLoop() { BOOL BackgroundThread::whileLoop() {

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include "utils/BackgroundThreadWrapper.hpp" #include "utils/BackgroundThreadWrapper.hpp"
#include <coreinit/cache.h> #include <coreinit/cache.h>
#include "utils/logger.h" #include "utils/logger.h"
@ -8,43 +9,42 @@
class BackgroundThread : BackgroundThreadWrapper { class BackgroundThread : BackgroundThreadWrapper {
public: public:
static BackgroundThread *getInstance() { static BackgroundThread *getInstance() {
DCFlushRange(&instance, sizeof(instance)); DCFlushRange(&instance, sizeof(BackgroundThread));
ICInvalidateRange(&instance, sizeof(instance)); ICInvalidateRange(&instance, sizeof(BackgroundThread));
if(instance == NULL) { if (instance == nullptr) {
instance = new BackgroundThread(); instance = new BackgroundThread();
DCFlushRange(&instance, sizeof(instance)); DCFlushRange(&instance, sizeof(BackgroundThread));
ICInvalidateRange(&instance, sizeof(instance)); ICInvalidateRange(&instance, sizeof(BackgroundThread));
} }
return instance; return instance;
} }
static void destroyInstance() { static void destroyInstance() {
DCFlushRange(&instance, sizeof(instance)); DCFlushRange(&instance, sizeof(BackgroundThread));
ICInvalidateRange(&instance, sizeof(instance)); ICInvalidateRange(&instance, sizeof(BackgroundThread));
DEBUG_FUNCTION_LINE("Instance is %08X\n", instance); DEBUG_FUNCTION_LINE("Instance is %08X\n", instance);
OSSleepTicks(OSSecondsToTicks(1)); OSSleepTicks(OSSecondsToTicks(1));
if(instance != NULL) { if (instance != nullptr) {
delete instance; delete instance;
instance = NULL; instance = nullptr;
DCFlushRange(&instance, sizeof(instance)); DCFlushRange(&instance, sizeof(BackgroundThread));
ICInvalidateRange(&instance, sizeof(instance)); ICInvalidateRange(&instance, sizeof(BackgroundThread));
} }
} }
BackgroundThread(); BackgroundThread();
virtual ~BackgroundThread(); ~BackgroundThread() override;
private: private:
static int32_t getPriority() { static int32_t getPriority() {
return 16; return 16;
} }
virtual BOOL whileLoop(); BOOL whileLoop() override;
static BackgroundThread *instance; static BackgroundThread *instance;
int serverSocket = -1; int serverSocket = -1;
int network_down = 0; int network_down = 0;
}; };

View File

@ -76,7 +76,9 @@ struct client_struct {
bool data_connection_connected; bool data_connection_connected;
data_connection_callback data_callback; data_connection_callback data_callback;
void *data_connection_callback_arg; void *data_connection_callback_arg;
void (*data_connection_cleanup)(void *arg); void (*data_connection_cleanup)(void *arg);
uint64_t data_connection_timer; uint64_t data_connection_timer;
}; };
@ -639,7 +641,8 @@ static int32_t dispatch_to_handler(client_t *client, char *cmd_line, const char
} }
static const char *site_commands[] = {"LOADER", "CLEAR", "CHMOD", "PASSWD", "NOPASSWD", "EJECT", "MOUNT", "UNMOUNT", "LOAD", NULL}; static const char *site_commands[] = {"LOADER", "CLEAR", "CHMOD", "PASSWD", "NOPASSWD", "EJECT", "MOUNT", "UNMOUNT", "LOAD", NULL};
static const ftp_command_handler site_handlers[] = { ftp_SITE_LOADER, ftp_SITE_CLEAR, ftp_SITE_CHMOD, ftp_SITE_PASSWD, ftp_SITE_NOPASSWD, ftp_SITE_EJECT, ftp_SITE_MOUNT, ftp_SITE_UNMOUNT, ftp_SITE_LOAD, ftp_SITE_UNKNOWN }; static const ftp_command_handler site_handlers[] = {ftp_SITE_LOADER, ftp_SITE_CLEAR, ftp_SITE_CHMOD, ftp_SITE_PASSWD, ftp_SITE_NOPASSWD, ftp_SITE_EJECT, ftp_SITE_MOUNT, ftp_SITE_UNMOUNT,
ftp_SITE_LOAD, ftp_SITE_UNKNOWN};
static int32_t ftp_SITE(client_t *client, char *cmd_line) { static int32_t ftp_SITE(client_t *client, char *cmd_line) {
return dispatch_to_handler(client, cmd_line, site_commands, site_handlers); return dispatch_to_handler(client, cmd_line, site_commands, site_handlers);

View File

@ -29,11 +29,15 @@ misrepresented as being the original software.
#ifdef __cplusplus #ifdef __cplusplus
extern "C"{ extern "C"{
#endif #endif
#include <stdbool.h> #include <stdbool.h>
void accept_ftp_client(int32_t server); void accept_ftp_client(int32_t server);
void set_ftp_password(char *new_password); void set_ftp_password(char *new_password);
bool process_ftp_events(int32_t server); bool process_ftp_events(int32_t server);
void cleanup_ftp(); void cleanup_ftp();
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -8,7 +8,6 @@
#include <coreinit/cache.h> #include <coreinit/cache.h>
#include "utils/logger.h" #include "utils/logger.h"
#include <whb/log_udp.h> #include <whb/log_udp.h>
#include <whb/libmanager.h>
#include "virtualpath.h" #include "virtualpath.h"
#include "BackgroundThread.hpp" #include "BackgroundThread.hpp"
@ -63,9 +62,9 @@ ON_APPLICATION_START() {
mount_fs("storage_odd_updates", fsaFd, "/dev/odd02", "/vol/storage_odd_updates"); mount_fs("storage_odd_updates", fsaFd, "/dev/odd02", "/vol/storage_odd_updates");
mount_fs("storage_odd_content", fsaFd, "/dev/odd03", "/vol/storage_odd_content"); mount_fs("storage_odd_content", fsaFd, "/dev/odd03", "/vol/storage_odd_content");
mount_fs("storage_odd_content2", fsaFd, "/dev/odd04", "/vol/storage_odd_content2"); mount_fs("storage_odd_content2", fsaFd, "/dev/odd04", "/vol/storage_odd_content2");
mount_fs("storage_slc", fsaFd, NULL, "/vol/system"); mount_fs("storage_slc", fsaFd, nullptr, "/vol/system");
mount_fs("storage_mlc", fsaFd, NULL, "/vol/storage_mlc01"); mount_fs("storage_mlc", fsaFd, nullptr, "/vol/storage_mlc01");
mount_fs("storage_usb", fsaFd, NULL, "/vol/storage_usb01"); mount_fs("storage_usb", fsaFd, nullptr, "/vol/storage_usb01");
VirtualMountDevice("fs:/"); VirtualMountDevice("fs:/");
VirtualMountDevice("slccmpt01:/"); VirtualMountDevice("slccmpt01:/");

View File

@ -5,6 +5,7 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include <stdint.h> #include <stdint.h>
#include "net.h" #include "net.h"

View File

@ -193,6 +193,7 @@ int32_t create_server(uint16_t port) {
} }
typedef int32_t (*transferrer_type)(int32_t s, void *mem, int32_t len); typedef int32_t (*transferrer_type)(int32_t s, void *mem, int32_t len);
static int32_t transfer_exact(int32_t s, char *buf, int32_t length, transferrer_type transferrer) { static int32_t transfer_exact(int32_t s, char *buf, int32_t length, transferrer_type transferrer) {
int32_t result = 0; int32_t result = 0;
int32_t remaining = length; int32_t remaining = length;

View File

@ -44,12 +44,19 @@ void initialise_network();
#endif #endif
int32_t network_socket(uint32_t domain, uint32_t type, uint32_t protocol); int32_t network_socket(uint32_t domain, uint32_t type, uint32_t protocol);
int32_t network_bind(int32_t s, struct sockaddr *name, int32_t namelen); int32_t network_bind(int32_t s, struct sockaddr *name, int32_t namelen);
int32_t network_listen(int32_t s, uint32_t backlog); int32_t network_listen(int32_t s, uint32_t backlog);
int32_t network_accept(int32_t s, struct sockaddr *addr, int32_t *addrlen); int32_t network_accept(int32_t s, struct sockaddr *addr, int32_t *addrlen);
int32_t network_connect(int32_t s, struct sockaddr *, int32_t); int32_t network_connect(int32_t s, struct sockaddr *, int32_t);
int32_t network_read(int32_t s, void *mem, int32_t len); int32_t network_read(int32_t s, void *mem, int32_t len);
int32_t network_close(int32_t s); int32_t network_close(int32_t s);
uint32_t network_gethostip(); uint32_t network_gethostip();
int32_t set_blocking(int32_t s, bool blocking); int32_t set_blocking(int32_t s, bool blocking);

View File

@ -1,28 +1,22 @@
#include "BackgroundThreadWrapper.hpp" #include "BackgroundThreadWrapper.hpp"
#include <string.h>
#include <coreinit/cache.h> #include <coreinit/cache.h>
BackgroundThreadWrapper::BackgroundThreadWrapper(int32_t priority) : CThread(CThread::eAttributeAffCore2, priority, 0x100000) { BackgroundThreadWrapper::BackgroundThreadWrapper(int32_t priority) : CThread(CThread::eAttributeAffCore2, priority, 0x100000) {
} }
BackgroundThreadWrapper::~BackgroundThreadWrapper() { BackgroundThreadWrapper::~BackgroundThreadWrapper() {
exitThread = 1; exitThread = 1;
DCFlushRange((void *) &exitThread, 4); DCFlushRange((void *) &exitThread, 4);
DEBUG_FUNCTION_LINE("Exit thread");
} }
void BackgroundThreadWrapper::executeThread() { void BackgroundThreadWrapper::executeThread() {
while (true) { while (true) {
if (exitThread) { if (exitThread) {
DEBUG_FUNCTION_LINE("We want to exit");
break; break;
} }
if (!whileLoop()) { if (!whileLoop()) {
break; break;
} }
} }
DEBUG_FUNCTION_LINE("Exit!");
} }

View File

@ -7,7 +7,9 @@
class BackgroundThreadWrapper : public CThread { class BackgroundThreadWrapper : public CThread {
public: public:
explicit BackgroundThreadWrapper(int32_t priority); explicit BackgroundThreadWrapper(int32_t priority);
~BackgroundThreadWrapper() override; ~BackgroundThreadWrapper() override;
protected: protected:
[[nodiscard]] BOOL shouldExit() const { [[nodiscard]] BOOL shouldExit() const {
return (exitThread == 1); return (exitThread == 1);
@ -16,6 +18,7 @@ protected:
void setThreadPriority(int32_t priority) override { void setThreadPriority(int32_t priority) override {
CThread::setThreadPriority(priority); CThread::setThreadPriority(priority);
} }
std::recursive_mutex mutex; std::recursive_mutex mutex;
private: private:
void executeThread() override; void executeThread() override;

View File

@ -28,11 +28,8 @@ public:
typedef void (*Callback)(CThread *thread, void *arg); typedef void (*Callback)(CThread *thread, void *arg);
//! constructor //! constructor
CThread(int32_t iAttr, int32_t iPriority = 16, int32_t iStackSize = 0x8000, CThread::Callback callback = NULL, void *callbackArg = NULL) explicit CThread(int32_t iAttr, int32_t iPriority = 16, int32_t iStackSize = 0x8000, CThread::Callback callback = nullptr, void *callbackArg = nullptr)
: pThread(NULL) : pThread(nullptr), pThreadStack(nullptr), pCallback(callback), pCallbackArg(callbackArg) {
, pThreadStack(NULL)
, pCallback(callback)
, pCallbackArg(callbackArg) {
//! save attribute assignment //! save attribute assignment
iAttributes = iAttr; iAttributes = iAttr;
//! allocate the thread //! allocate the thread
@ -55,50 +52,58 @@ public:
} }
//! Get thread ID //! Get thread ID
virtual void* getThread() const { [[nodiscard]] virtual void *getThread() const {
return pThread; return pThread;
} }
//! Thread entry function //! Thread entry function
virtual void executeThread(void) { virtual void executeThread() {
if (pCallback) if (pCallback)
pCallback(this, pCallbackArg); pCallback(this, pCallbackArg);
} }
//! Suspend thread //! Suspend thread
virtual void suspendThread(void) { virtual void suspendThread() {
if (isThreadSuspended()) return; if (isThreadSuspended()) return;
if (pThread) OSSuspendThread(pThread); if (pThread) OSSuspendThread(pThread);
} }
//! Resume thread //! Resume thread
virtual void resumeThread(void) { virtual void resumeThread() {
if (!isThreadSuspended()) return; if (!isThreadSuspended()) return;
if (pThread) OSResumeThread(pThread); if (pThread) OSResumeThread(pThread);
} }
//! Set thread priority //! Set thread priority
virtual void setThreadPriority(int prio) { virtual void setThreadPriority(int prio) {
if (pThread) OSSetThreadPriority(pThread, prio); if (pThread) OSSetThreadPriority(pThread, prio);
} }
//! Check if thread is suspended //! Check if thread is suspended
virtual BOOL isThreadSuspended(void) const { [[nodiscard]] virtual BOOL isThreadSuspended() const {
if (pThread) return OSIsThreadSuspended(pThread); if (pThread) return OSIsThreadSuspended(pThread);
return false; return false;
} }
//! Check if thread is terminated //! Check if thread is terminated
virtual BOOL isThreadTerminated(void) const { [[nodiscard]] virtual BOOL isThreadTerminated() const {
if (pThread) return OSIsThreadTerminated(pThread); if (pThread) return OSIsThreadTerminated(pThread);
return false; return false;
} }
//! Check if thread is running //! Check if thread is running
virtual BOOL isThreadRunning(void) const { [[nodiscard]] virtual BOOL isThreadRunning() const {
return !isThreadSuspended() && !isThreadRunning(); return !isThreadSuspended() && !isThreadRunning();
} }
//! Shutdown thread //! Shutdown thread
virtual void shutdownThread(void) { virtual void shutdownThread() {
//! wait for thread to finish //! wait for thread to finish
if (pThread && !(iAttributes & eAttributeDetach)) { if (pThread && !(iAttributes & eAttributeDetach)) {
if (isThreadSuspended()) if (isThreadSuspended())
resumeThread(); resumeThread();
OSJoinThread(pThread, NULL); OSJoinThread(pThread, nullptr);
} }
//! free the thread stack buffer //! free the thread stack buffer
if (pThreadStack) if (pThreadStack)
@ -106,9 +111,10 @@ public:
if (pThread) if (pThread)
free(pThread); free(pThread);
pThread = NULL; pThread = nullptr;
pThreadStack = NULL; pThreadStack = nullptr;
} }
//! Thread attributes //! Thread attributes
enum eCThreadAttributes { enum eCThreadAttributes {
eAttributeNone = 0x07, eAttributeNone = 0x07,
@ -124,6 +130,7 @@ private:
((CThread *) argv)->executeThread(); ((CThread *) argv)->executeThread();
return 0; return 0;
} }
int iAttributes; int iAttributes;
OSThread *pThread; OSThread *pThread;
uint8_t *pThreadStack; uint8_t *pThreadStack;

View File

@ -16,7 +16,7 @@ extern "C" {
#define DEBUG_FUNCTION_LINE(FMT, ARGS...)do { \ #define DEBUG_FUNCTION_LINE(FMT, ARGS...)do { \
WHBLogPrintf("[%23s]%30s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \ WHBLogPrintf("[%23s]%30s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \
} while (0); } while (0)
#define DEBUG_FUNCTION_LINE_WRITE(FMT, ARGS...)do { \ #define DEBUG_FUNCTION_LINE_WRITE(FMT, ARGS...)do { \
WHBLogWritef("[%23s]%30s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \ WHBLogWritef("[%23s]%30s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \

View File

@ -40,8 +40,7 @@ VIRTUAL_PARTITION *VIRTUAL_FS = NULL;
uint8_t MAX_VIRTUAL_FS_VOL = 0; uint8_t MAX_VIRTUAL_FS_VOL = 0;
VIRTUAL_PARTITION *VIRTUAL_FS_VOL = NULL; VIRTUAL_PARTITION *VIRTUAL_FS_VOL = NULL;
void VirtualMountDevice(const char * path) void VirtualMountDevice(const char *path) {
{
if (!path) if (!path)
return; return;
@ -53,13 +52,11 @@ void VirtualMountDevice(const char * path)
alias[0] = '/'; alias[0] = '/';
do do {
{
if (path[i] == ':') if (path[i] == ':')
namestop = true; namestop = true;
if(!namestop) if (!namestop) {
{
name[i] = path[i]; name[i] = path[i];
name[i + 1] = '\0'; name[i + 1] = '\0';
alias[i + 1] = path[i]; alias[i + 1] = path[i];
@ -69,13 +66,11 @@ void VirtualMountDevice(const char * path)
prefix[i] = path[i]; prefix[i] = path[i];
prefix[i + 1] = '\0'; prefix[i + 1] = '\0';
i++; i++;
} } while (path[i - 1] != '/');
while(path[i-1] != '/');
AddVirtualPath(name, alias, prefix); AddVirtualPath(name, alias, prefix);
} }
void AddVirtualPath(const char *name, const char *alias, const char *prefix) void AddVirtualPath(const char *name, const char *alias, const char *prefix) {
{
if (!VIRTUAL_PARTITIONS) { if (!VIRTUAL_PARTITIONS) {
VIRTUAL_PARTITIONS = (VIRTUAL_PARTITION *) malloc(sizeof(VIRTUAL_PARTITION)); VIRTUAL_PARTITIONS = (VIRTUAL_PARTITION *) malloc(sizeof(VIRTUAL_PARTITION));
} }
@ -140,8 +135,7 @@ void AddVirtualPath(const char *name, const char *alias, const char *prefix)
MAX_VIRTUAL_FS_VOL++; MAX_VIRTUAL_FS_VOL++;
} }
void MountVirtualDevices() void MountVirtualDevices() {
{
VirtualMountDevice("fs:/"); VirtualMountDevice("fs:/");
VirtualMountDevice("slccmpt01:/"); VirtualMountDevice("slccmpt01:/");
VirtualMountDevice("storage_odd_tickets:/"); VirtualMountDevice("storage_odd_tickets:/");

View File

@ -54,10 +54,15 @@ extern VIRTUAL_PARTITION * VIRTUAL_FS_VOL;
extern uint8_t MAX_VIRTUAL_FS_VOL; extern uint8_t MAX_VIRTUAL_FS_VOL;
void VirtualMountDevice(const char *devicepath); void VirtualMountDevice(const char *devicepath);
void AddVirtualPath(const char *name, const char *alias, const char *prefix); void AddVirtualPath(const char *name, const char *alias, const char *prefix);
void AddVirtualFSPath(const char *name, const char *alias, const char *prefix); void AddVirtualFSPath(const char *name, const char *alias, const char *prefix);
void AddVirtualFSVOLPath(const char *name, const char *alias, const char *prefix); void AddVirtualFSVOLPath(const char *name, const char *alias, const char *prefix);
void MountVirtualDevices(); void MountVirtualDevices();
void UnmountVirtualPaths(); void UnmountVirtualPaths();
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -190,11 +190,21 @@ static void *with_virtual_path(void *virtual_cwd, void *void_f, char *virtual_pa
void *result; void *result;
switch (num_args) { switch (num_args) {
case 0: result = f(path); break; case 0:
case 1: result = f(path, args[0]); break; result = f(path);
case 2: result = f(path, args[0], args[1]); break; break;
case 3: result = f(path, args[0], args[1], args[2]); break; case 1:
default: result = (void *)failed; break; result = f(path, args[0]);
break;
case 2:
result = f(path, args[0], args[1]);
break;
case 3:
result = f(path, args[0], args[1], args[2]);
break;
default:
result = (void *) failed;
break;
} }
free(path); free(path);
@ -207,12 +217,9 @@ FILE *vrt_fopen(char *cwd, char *path, char *mode) {
int vrt_stat(char *cwd, char *path, struct stat *st) { int vrt_stat(char *cwd, char *path, struct stat *st) {
char *real_path = to_real_path(cwd, path); char *real_path = to_real_path(cwd, path);
if (!real_path) if (!real_path) {
{
return -1; return -1;
} } else if (!*real_path || (strcmp(path, ".") == 0) || (strlen(cwd) == 1) || ((strlen(cwd) > 1) && (strcmp(path, "..") == 0))) {
else if (!*real_path || (strcmp(path, ".") == 0) || (strlen(cwd) == 1) || ((strlen(cwd) > 1) && (strcmp(path, "..") == 0)))
{
st->st_mode = S_IFDIR; st->st_mode = S_IFDIR;
st->st_size = 31337; st->st_size = 31337;
return 0; return 0;
@ -223,12 +230,9 @@ int vrt_stat(char *cwd, char *path, struct stat *st) {
static int vrt_checkdir(char *cwd, char *path) { static int vrt_checkdir(char *cwd, char *path) {
char *real_path = to_real_path(cwd, path); char *real_path = to_real_path(cwd, path);
if (!real_path) if (!real_path) {
{
return -1; return -1;
} } else if (!*real_path || (strcmp(path, ".") == 0) || (strlen(cwd) == 1) || ((strlen(cwd) > 1) && (strcmp(path, "..") == 0))) {
else if (!*real_path || (strcmp(path, ".") == 0) || (strlen(cwd) == 1) || ((strlen(cwd) > 1) && (strcmp(path, "..") == 0)))
{
return 0; return 0;
} }
free(real_path); free(real_path);
@ -358,8 +362,7 @@ struct dirent *vrt_readdir(DIR_P *pDir) {
int vrt_closedir(DIR_P *iter) { int vrt_closedir(DIR_P *iter) {
if (!iter) return -1; if (!iter) return -1;
if(iter->dir) if (iter->dir) {
{
if (iter->virt_root) if (iter->virt_root)
free(iter->dir); free(iter->dir);
else else

View File

@ -32,8 +32,7 @@ extern "C"{
#include <stdio.h> #include <stdio.h>
#include <sys/dirent.h> #include <sys/dirent.h>
typedef struct typedef struct {
{
DIR *dir; DIR *dir;
char *path; char *path;
uint8_t virt_root; uint8_t virt_root;
@ -44,13 +43,21 @@ typedef struct
char *to_real_path(char *virtual_cwd, char *virtual_path); char *to_real_path(char *virtual_cwd, char *virtual_path);
FILE *vrt_fopen(char *cwd, char *path, char *mode); FILE *vrt_fopen(char *cwd, char *path, char *mode);
int vrt_stat(char *cwd, char *path, struct stat *st); int vrt_stat(char *cwd, char *path, struct stat *st);
int vrt_chdir(char *cwd, char *path); int vrt_chdir(char *cwd, char *path);
int vrt_unlink(char *cwd, char *path); int vrt_unlink(char *cwd, char *path);
int vrt_mkdir(char *cwd, char *path, mode_t mode); int vrt_mkdir(char *cwd, char *path, mode_t mode);
int vrt_rename(char *cwd, char *from_path, char *to_path); int vrt_rename(char *cwd, char *from_path, char *to_path);
DIR_P *vrt_opendir(char *cwd, char *path); DIR_P *vrt_opendir(char *cwd, char *path);
struct dirent *vrt_readdir(DIR_P *iter); struct dirent *vrt_readdir(DIR_P *iter);
int vrt_closedir(DIR_P *iter); int vrt_closedir(DIR_P *iter);
#ifdef __cplusplus #ifdef __cplusplus