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,50 +1,42 @@
#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();
network_close(this->serverSocket); network_close(this->serverSocket);
mutex.unlock(); mutex.unlock();
this->serverSocket = -1; this->serverSocket = -1;
} }
DEBUG_FUNCTION_LINE("Cleaned up FTP");
} }
BOOL BackgroundThread::whileLoop() { BOOL BackgroundThread::whileLoop() {
if(this->serverSocket != -1){ if (this->serverSocket != -1) {
mutex.lock(); mutex.lock();
network_down = process_ftp_events(this->serverSocket); network_down = process_ftp_events(this->serverSocket);
mutex.unlock(); mutex.unlock();
if(network_down) { if (network_down) {
DEBUG_FUNCTION_LINE("Network is down %d", this->serverSocket); DEBUG_FUNCTION_LINE("Network is down %d", this->serverSocket);
mutex.lock(); mutex.lock();
cleanup_ftp(); cleanup_ftp();
network_close(this->serverSocket); network_close(this->serverSocket);
this->serverSocket = -1; this->serverSocket = -1;
DCFlushRange(&(this->serverSocket), 4); DCFlushRange(&(this->serverSocket), 4);
mutex.unlock(); mutex.unlock();
} }
} }

View File

@ -1,50 +1,50 @@
#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"
#define PORT 21 #define PORT 21
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

@ -42,7 +42,7 @@ misrepresented as being the original software.
#include "net.h" #include "net.h"
#include "vrt.h" #include "vrt.h"
#define UNUSED __attribute__((unused)) #define UNUSED __attribute__((unused))
#define FTP_BUFFER_SIZE 1024 #define FTP_BUFFER_SIZE 1024
#define MAX_CLIENTS 5 #define MAX_CLIENTS 5
@ -56,7 +56,7 @@ static uint8_t num_clients = 0;
static uint16_t passive_port = 1024; static uint16_t passive_port = 1024;
static char *password = NULL; static char *password = NULL;
void console_printf(const char *format, ...){ void console_printf(const char *format, ...) {
} }
typedef int32_t (*data_connection_callback)(int32_t data_socket, void *arg); typedef int32_t (*data_connection_callback)(int32_t data_socket, void *arg);
@ -76,13 +76,15 @@ 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;
}; };
typedef struct client_struct client_t; typedef struct client_struct client_t;
static client_t *clients[MAX_CLIENTS] = { NULL }; static client_t *clients[MAX_CLIENTS] = {NULL};
void set_ftp_password(char *new_password) { void set_ftp_password(char *new_password) {
if (password) if (password)
@ -92,14 +94,14 @@ void set_ftp_password(char *new_password) {
if (!password) if (!password)
return; return;
strcpy((char *)password, new_password); strcpy((char *) password, new_password);
} else { } else {
password = NULL; password = NULL;
} }
} }
static bool compare_ftp_password(char *password_attempt) { static bool compare_ftp_password(char *password_attempt) {
return !password || !strcmp((char *)password, password_attempt); return !password || !strcmp((char *) password, password_attempt);
} }
/* /*
@ -107,7 +109,7 @@ static bool compare_ftp_password(char *password_attempt) {
*/ */
static int32_t write_reply(client_t *client, uint16_t code, char *msg) { static int32_t write_reply(client_t *client, uint16_t code, char *msg) {
uint32_t msglen = 4 + strlen(msg) + CRLF_LENGTH; uint32_t msglen = 4 + strlen(msg) + CRLF_LENGTH;
char * msgbuf = (char *) malloc(msglen + 1); char *msgbuf = (char *) malloc(msglen + 1);
if (msgbuf == NULL) if (msgbuf == NULL)
return -ENOMEM; return -ENOMEM;
sprintf(msgbuf, "%u %s\r\n", code, msg); sprintf(msgbuf, "%u %s\r\n", code, msg);
@ -197,7 +199,7 @@ static int32_t ftp_SYST(client_t *client, char *rest UNUSED) {
static int32_t ftp_TYPE(client_t *client, char *rest) { static int32_t ftp_TYPE(client_t *client, char *rest) {
char representation_type[FTP_BUFFER_SIZE], param[FTP_BUFFER_SIZE]; char representation_type[FTP_BUFFER_SIZE], param[FTP_BUFFER_SIZE];
char *args[] = { representation_type, param }; char *args[] = {representation_type, param};
uint32_t num_args = split(rest, ' ', 1, args); uint32_t num_args = split(rest, ' ', 1, args);
if (num_args == 0) { if (num_args == 0) {
return write_reply(client, 501, "Syntax error in parameters."); return write_reply(client, 501, "Syntax error in parameters.");
@ -231,7 +233,7 @@ static int32_t ftp_CWD(client_t *client, char *path) {
int32_t result; int32_t result;
if (!vrt_chdir(client->cwd, path)) { if (!vrt_chdir(client->cwd, path)) {
result = write_reply(client, 250, "CWD command successful."); result = write_reply(client, 250, "CWD command successful.");
} else { } else {
result = write_reply(client, 550, strerror(errno)); result = write_reply(client, 550, strerror(errno));
} }
return result; return result;
@ -241,7 +243,7 @@ static int32_t ftp_CDUP(client_t *client, char *rest UNUSED) {
int32_t result; int32_t result;
if (!vrt_chdir(client->cwd, "..")) { if (!vrt_chdir(client->cwd, "..")) {
result = write_reply(client, 250, "CDUP command successful."); result = write_reply(client, 250, "CDUP command successful.");
} else { } else {
result = write_reply(client, 550, strerror(errno)); result = write_reply(client, 550, strerror(errno));
} }
return result; return result;
@ -287,7 +289,7 @@ static int32_t ftp_RNTO(client_t *client, char *path) {
} else { } else {
result = write_reply(client, 550, strerror( result = write_reply(client, 550, strerror(
errno)); errno));
} }
*client->pending_rename = '\0'; *client->pending_rename = '\0';
return result; return result;
@ -317,7 +319,7 @@ static int32_t ftp_PASV(client_t *client, char *rest UNUSED) {
bindAddress.sin_port = htons(passive_port++); // XXX: BUG: This will overflow eventually, with interesting results... bindAddress.sin_port = htons(passive_port++); // XXX: BUG: This will overflow eventually, with interesting results...
bindAddress.sin_addr.s_addr = htonl(INADDR_ANY); bindAddress.sin_addr.s_addr = htonl(INADDR_ANY);
int32_t result; int32_t result;
if ((result = network_bind(client->passive_socket, (struct sockaddr *)&bindAddress, sizeof(bindAddress))) < 0) { if ((result = network_bind(client->passive_socket, (struct sockaddr *) &bindAddress, sizeof(bindAddress))) < 0) {
close_passive_socket(client); close_passive_socket(client);
return write_reply(client, 520, "Unable to bind listening socket."); return write_reply(client, 520, "Unable to bind listening socket.");
} }
@ -347,7 +349,7 @@ static int32_t ftp_PORT(client_t *client, char *portspec) {
return write_reply(client, 501, "Syntax error in parameters."); return write_reply(client, 501, "Syntax error in parameters.");
} }
close_passive_socket(client); close_passive_socket(client);
uint16_t port = ((p1 &0xff) << 8) | (p2 & 0xff); uint16_t port = ((p1 & 0xff) << 8) | (p2 & 0xff);
client->address.sin_addr = sin_addr; client->address.sin_addr = sin_addr;
client->address.sin_port = htons(port); client->address.sin_port = htons(port);
console_printf("Set client address to %s:%u\n", addr_str, port); console_printf("Set client address to %s:%u\n", addr_str, port);
@ -367,7 +369,7 @@ static int32_t prepare_data_connection_active(client_t *client, data_connection_
bindAddress.sin_port = htons(SRC_PORT); bindAddress.sin_port = htons(SRC_PORT);
bindAddress.sin_addr.s_addr = htonl(INADDR_ANY); bindAddress.sin_addr.s_addr = htonl(INADDR_ANY);
int32_t result; int32_t result;
if ((result = network_bind(data_socket, (struct sockaddr *)&bindAddress, sizeof(bindAddress))) < 0) { if ((result = network_bind(data_socket, (struct sockaddr *) &bindAddress, sizeof(bindAddress))) < 0) {
network_close(data_socket); network_close(data_socket);
return result; return result;
} }
@ -389,7 +391,7 @@ static int32_t prepare_data_connection(client_t *client, void *callback, void *a
data_connection_handler handler = prepare_data_connection_active; data_connection_handler handler = prepare_data_connection_active;
if (client->passive_socket >= 0) if (client->passive_socket >= 0)
handler = prepare_data_connection_passive; handler = prepare_data_connection_passive;
result = handler(client, (data_connection_callback)callback, arg); result = handler(client, (data_connection_callback) callback, arg);
if (result < 0) { if (result < 0) {
result = write_reply(client, 520, "Closing data connection, error occurred during transfer."); result = write_reply(client, 520, "Closing data connection, error occurred during transfer.");
} else { } else {
@ -409,7 +411,7 @@ static int32_t send_nlst(int32_t data_socket, DIR_P *iter) {
struct dirent *dirent = NULL; struct dirent *dirent = NULL;
while ((dirent = vrt_readdir(iter)) != 0) { while ((dirent = vrt_readdir(iter)) != 0) {
size_t end_index = strlen(dirent->d_name); size_t end_index = strlen(dirent->d_name);
if(end_index + 2 >= MAXPATHLEN) if (end_index + 2 >= MAXPATHLEN)
continue; continue;
strcpy(filename, dirent->d_name); strcpy(filename, dirent->d_name);
filename[end_index] = CRLF[0]; filename[end_index] = CRLF[0];
@ -433,7 +435,7 @@ static int32_t send_list(int32_t data_socket, DIR_P *iter) {
while ((dirent = vrt_readdir(iter)) != 0) { while ((dirent = vrt_readdir(iter)) != 0) {
snprintf(filename, sizeof(filename), "%s/%s", iter->path, dirent->d_name); snprintf(filename, sizeof(filename), "%s/%s", iter->path, dirent->d_name);
if(stat(filename, &st) == 0) { if (stat(filename, &st) == 0) {
mtime = st.st_mtime; mtime = st.st_mtime;
size = st.st_size; size = st.st_size;
} else { } else {
@ -472,7 +474,7 @@ static int32_t ftp_LIST(client_t *client, char *path) {
// handle buggy clients that use "LIST -aL" or similar, at the expense of breaking paths that begin with '-' // handle buggy clients that use "LIST -aL" or similar, at the expense of breaking paths that begin with '-'
char flags[FTP_BUFFER_SIZE]; char flags[FTP_BUFFER_SIZE];
char rest[FTP_BUFFER_SIZE]; char rest[FTP_BUFFER_SIZE];
char *args[] = { flags, rest }; char *args[] = {flags, rest};
split(path, ' ', 1, args); split(path, ' ', 1, args);
path = rest; path = rest;
} }
@ -480,8 +482,8 @@ static int32_t ftp_LIST(client_t *client, char *path) {
path = "."; path = ".";
} }
if(path && client->cwd) { if (path && client->cwd) {
if(strcmp(path, ".") == 0 && strcmp(client->cwd, "/") == 0) { if (strcmp(path, ".") == 0 && strcmp(client->cwd, "/") == 0) {
UnmountVirtualPaths(); UnmountVirtualPaths();
MountVirtualDevices(); MountVirtualDevices();
} }
@ -628,7 +630,7 @@ typedef int32_t (*ftp_command_handler)(client_t *client, char *args);
static int32_t dispatch_to_handler(client_t *client, char *cmd_line, const char **commands, const ftp_command_handler *handlers) { static int32_t dispatch_to_handler(client_t *client, char *cmd_line, const char **commands, const ftp_command_handler *handlers) {
char cmd[FTP_BUFFER_SIZE], rest[FTP_BUFFER_SIZE]; char cmd[FTP_BUFFER_SIZE], rest[FTP_BUFFER_SIZE];
char *args[] = { cmd, rest }; char *args[] = {cmd, rest};
split(cmd_line, ' ', 1, args); split(cmd_line, ' ', 1, args);
int32_t i; int32_t i;
for (i = 0; commands[i]; i++) { for (i = 0; commands[i]; i++) {
@ -638,8 +640,9 @@ static int32_t dispatch_to_handler(client_t *client, char *cmd_line, const char
return handlers[i](client, rest); return handlers[i](client, rest);
} }
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);
@ -661,22 +664,22 @@ static int32_t ftp_UNKNOWN(client_t *client, char *rest UNUSED) {
return write_reply(client, 502, "Command not implemented."); return write_reply(client, 502, "Command not implemented.");
} }
static const char *unauthenticated_commands[] = { "USER", "PASS", "QUIT", "REIN", "NOOP", NULL }; static const char *unauthenticated_commands[] = {"USER", "PASS", "QUIT", "REIN", "NOOP", NULL};
static const ftp_command_handler unauthenticated_handlers[] = { ftp_USER, ftp_PASS, ftp_QUIT, ftp_REIN, ftp_NOOP, ftp_NEEDAUTH }; static const ftp_command_handler unauthenticated_handlers[] = {ftp_USER, ftp_PASS, ftp_QUIT, ftp_REIN, ftp_NOOP, ftp_NEEDAUTH};
static const char *authenticated_commands[] = { static const char *authenticated_commands[] = {
"USER", "PASS", "LIST", "PWD", "CWD", "CDUP", "USER", "PASS", "LIST", "PWD", "CWD", "CDUP",
"SIZE", "PASV", "PORT", "TYPE", "SYST", "MODE", "SIZE", "PASV", "PORT", "TYPE", "SYST", "MODE",
"RETR", "STOR", "APPE", "REST", "DELE", "MKD", "RETR", "STOR", "APPE", "REST", "DELE", "MKD",
"RMD", "RNFR", "RNTO", "NLST", "QUIT", "REIN", "RMD", "RNFR", "RNTO", "NLST", "QUIT", "REIN",
"SITE", "NOOP", "ALLO", NULL "SITE", "NOOP", "ALLO", NULL
}; };
static const ftp_command_handler authenticated_handlers[] = { static const ftp_command_handler authenticated_handlers[] = {
ftp_USER, ftp_PASS, ftp_LIST, ftp_PWD, ftp_CWD, ftp_CDUP, ftp_USER, ftp_PASS, ftp_LIST, ftp_PWD, ftp_CWD, ftp_CDUP,
ftp_SIZE, ftp_PASV, ftp_PORT, ftp_TYPE, ftp_SYST, ftp_MODE, ftp_SIZE, ftp_PASV, ftp_PORT, ftp_TYPE, ftp_SYST, ftp_MODE,
ftp_RETR, ftp_STOR, ftp_APPE, ftp_REST, ftp_DELE, ftp_MKD, ftp_RETR, ftp_STOR, ftp_APPE, ftp_REST, ftp_DELE, ftp_MKD,
ftp_DELE, ftp_RNFR, ftp_RNTO, ftp_NLST, ftp_QUIT, ftp_REIN, ftp_DELE, ftp_RNFR, ftp_RNTO, ftp_NLST, ftp_QUIT, ftp_REIN,
ftp_SITE, ftp_NOOP, ftp_SUPERFLUOUS, ftp_UNKNOWN ftp_SITE, ftp_NOOP, ftp_SUPERFLUOUS, ftp_UNKNOWN
}; };
/* /*
@ -746,7 +749,7 @@ static bool process_accept_events(int32_t server) {
int32_t peer; int32_t peer;
struct sockaddr_in client_address; struct sockaddr_in client_address;
int32_t addrlen = sizeof(client_address); int32_t addrlen = sizeof(client_address);
while ((peer = network_accept(server, (struct sockaddr *)&client_address, &addrlen)) != -EAGAIN) { while ((peer = network_accept(server, (struct sockaddr *) &client_address, &addrlen)) != -EAGAIN) {
if (peer < 0) { if (peer < 0) {
console_printf("Error accepting connection: [%i] %s\n", -peer, strerror(-peer)); console_printf("Error accepting connection: [%i] %s\n", -peer, strerror(-peer));
return false; return false;
@ -805,13 +808,13 @@ static void process_data_events(client_t *client) {
if (client->passive_socket >= 0) { if (client->passive_socket >= 0) {
struct sockaddr_in data_peer_address; struct sockaddr_in data_peer_address;
int32_t addrlen = sizeof(data_peer_address); int32_t addrlen = sizeof(data_peer_address);
result = network_accept(client->passive_socket, (struct sockaddr *)&data_peer_address,&addrlen); result = network_accept(client->passive_socket, (struct sockaddr *) &data_peer_address, &addrlen);
if (result >= 0) { if (result >= 0) {
client->data_socket = result; client->data_socket = result;
client->data_connection_connected = true; client->data_connection_connected = true;
} }
} else { } else {
if ((result = network_connect(client->data_socket, (struct sockaddr *)&client->address, sizeof(client->address))) < 0) { if ((result = network_connect(client->data_socket, (struct sockaddr *) &client->address, sizeof(client->address))) < 0) {
if (result == -EINPROGRESS || result == -EALREADY) if (result == -EINPROGRESS || result == -EALREADY)
result = -EAGAIN; result = -EAGAIN;
if ((result != -EAGAIN) && (result != -EISCONN)) { if ((result != -EAGAIN) && (result != -EISCONN)) {
@ -900,7 +903,7 @@ static void process_control_events(client_t *client) {
} }
console_printf("Received line longer than %u bytes, closing client.\n", FTP_BUFFER_SIZE - 1); console_printf("Received line longer than %u bytes, closing client.\n", FTP_BUFFER_SIZE - 1);
recv_loop_end: recv_loop_end:
cleanup_client(client); cleanup_client(client);
} }

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"
@ -27,15 +26,15 @@ uint32_t hostIpAddress = 0;
int iosuhaxMount = 0; int iosuhaxMount = 0;
int fsaFd = -1; int fsaFd = -1;
BackgroundThread * thread = nullptr; BackgroundThread *thread = nullptr;
/* Entry point */ /* Entry point */
ON_APPLICATION_START() { ON_APPLICATION_START() {
nn::ac::Initialize(); nn::ac::Initialize();
nn::ac::ConnectAsync(); nn::ac::ConnectAsync();
nn::ac::GetAssignedAddress(&hostIpAddress); nn::ac::GetAssignedAddress(&hostIpAddress);
WHBLogUdpInit(); WHBLogUdpInit();
//!******************************************************************* //!*******************************************************************
//! Initialize FS * //! Initialize FS *
@ -43,7 +42,7 @@ ON_APPLICATION_START() {
DEBUG_FUNCTION_LINE("IOSUHAX_Open"); DEBUG_FUNCTION_LINE("IOSUHAX_Open");
int res = IOSUHAX_Open(nullptr); int res = IOSUHAX_Open(nullptr);
if(res < 0) { if (res < 0) {
DEBUG_FUNCTION_LINE("IOSUHAX_open failed"); DEBUG_FUNCTION_LINE("IOSUHAX_open failed");
VirtualMountDevice("fs:/"); VirtualMountDevice("fs:/");
} else { } else {
@ -52,7 +51,7 @@ ON_APPLICATION_START() {
DEBUG_FUNCTION_LINE("IOSUHAX_FSA_Open"); DEBUG_FUNCTION_LINE("IOSUHAX_FSA_Open");
fsaFd = IOSUHAX_FSA_Open(); fsaFd = IOSUHAX_FSA_Open();
if(fsaFd < 0) { if (fsaFd < 0) {
DEBUG_FUNCTION_LINE("IOSUHAX_FSA_Open failed"); DEBUG_FUNCTION_LINE("IOSUHAX_FSA_Open failed");
} }
@ -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:/");
@ -87,15 +86,15 @@ ON_APPLICATION_START() {
DCFlushRange(&thread, 4); DCFlushRange(&thread, 4);
} }
void stopThread(){ void stopThread() {
BackgroundThread::destroyInstance(); BackgroundThread::destroyInstance();
} }
ON_APPLICATION_REQUESTS_EXIT(){ ON_APPLICATION_REQUESTS_EXIT() {
DEBUG_FUNCTION_LINE("Ending ftp server"); DEBUG_FUNCTION_LINE("Ending ftp server");
stopThread(); stopThread();
if(iosuhaxMount) { if (iosuhaxMount) {
IOSUHAX_sdio_disc_interface.shutdown(); IOSUHAX_sdio_disc_interface.shutdown();
IOSUHAX_usb_disc_interface.shutdown(); IOSUHAX_usb_disc_interface.shutdown();

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

@ -67,54 +67,54 @@ 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) {
int sock = socket(domain, type, protocol); int sock = socket(domain, type, protocol);
if(sock < 0) { if (sock < 0) {
int err = -wiiu_geterrno(); int err = -wiiu_geterrno();
return (err < 0) ? err : sock; return (err < 0) ? err : sock;
} }
return sock; return sock;
} }
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) {
int res = bind(s, name, namelen); int res = bind(s, name, namelen);
if(res < 0) { if (res < 0) {
int err = -wiiu_geterrno(); int err = -wiiu_geterrno();
return (err < 0) ? err : res; return (err < 0) ? err : res;
} }
return res; return res;
} }
int32_t network_listen(int32_t s,uint32_t backlog) { int32_t network_listen(int32_t s, uint32_t backlog) {
int res = listen(s, backlog); int res = listen(s, backlog);
if(res < 0) { if (res < 0) {
int err = -wiiu_geterrno(); int err = -wiiu_geterrno();
return (err < 0) ? err : res; return (err < 0) ? err : res;
} }
return res; return res;
} }
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) {
int res = accept(s, addr, addrlen); int res = accept(s, addr, addrlen);
if(res < 0) { if (res < 0) {
int err = -wiiu_geterrno(); int err = -wiiu_geterrno();
return (err < 0) ? err : res; return (err < 0) ? err : res;
} }
return res; return res;
} }
int32_t network_connect(int32_t s,struct sockaddr *addr, int32_t addrlen) { int32_t network_connect(int32_t s, struct sockaddr *addr, int32_t addrlen) {
int res = connect(s, addr, addrlen); int res = connect(s, addr, addrlen);
if(res < 0) { if (res < 0) {
int err = -wiiu_geterrno(); int err = -wiiu_geterrno();
return (err < 0) ? err : res; return (err < 0) ? err : res;
} }
return res; return res;
} }
int32_t network_read(int32_t s,void *mem,int32_t len) { int32_t network_read(int32_t s, void *mem, int32_t len) {
int res = recv(s, mem, len, 0); int res = recv(s, mem, len, 0);
if(res < 0) { if (res < 0) {
int err = -wiiu_geterrno(); int err = -wiiu_geterrno();
return (err < 0) ? err : res; return (err < 0) ? err : res;
} }
@ -125,12 +125,12 @@ uint32_t network_gethostip() {
return hostIpAddress; return hostIpAddress;
} }
int32_t network_write(int32_t s, const void *mem,int32_t len) { int32_t network_write(int32_t s, const void *mem, int32_t len) {
int32_t transfered = 0; int32_t transfered = 0;
while(len) { while (len) {
int ret = send(s, mem, len, 0); int ret = send(s, mem, len, 0);
if(ret < 0) { if (ret < 0) {
int err = -wiiu_geterrno(); int err = -wiiu_geterrno();
transfered = (err < 0) ? err : ret; transfered = (err < 0) ? err : ret;
break; break;
@ -144,7 +144,7 @@ int32_t network_write(int32_t s, const void *mem,int32_t len) {
} }
int32_t network_close(int32_t s) { int32_t network_close(int32_t s) {
if(s < 0) if (s < 0)
return -1; return -1;
return close(s); return close(s);
@ -178,7 +178,7 @@ int32_t create_server(uint16_t port) {
bindAddress.sin_addr.s_addr = htonl(INADDR_ANY); bindAddress.sin_addr.s_addr = htonl(INADDR_ANY);
int32_t ret; int32_t ret;
if ((ret = network_bind(server, (struct sockaddr *)&bindAddress, sizeof(bindAddress))) < 0) { if ((ret = network_bind(server, (struct sockaddr *) &bindAddress, sizeof(bindAddress))) < 0) {
network_close(server); network_close(server);
//gxprintf("Error binding socket: [%i] %s\n", -ret, strerror(-ret)); //gxprintf("Error binding socket: [%i] %s\n", -ret, strerror(-ret));
return ret; return ret;
@ -193,13 +193,14 @@ 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;
int32_t bytes_transferred; int32_t bytes_transferred;
set_blocking(s, true); set_blocking(s, true);
while (remaining) { while (remaining) {
try_again_with_smaller_buffer: try_again_with_smaller_buffer:
bytes_transferred = transferrer(s, buf, MIN(remaining, (int) NET_BUFFER_SIZE)); bytes_transferred = transferrer(s, buf, MIN(remaining, (int) NET_BUFFER_SIZE));
if (bytes_transferred > 0) { if (bytes_transferred > 0) {
remaining -= bytes_transferred; remaining -= bytes_transferred;
@ -222,12 +223,12 @@ try_again_with_smaller_buffer:
} }
int32_t send_exact(int32_t s, char *buf, int32_t length) { int32_t send_exact(int32_t s, char *buf, int32_t length) {
return transfer_exact(s, buf, length, (transferrer_type)network_write); return transfer_exact(s, buf, length, (transferrer_type) network_write);
} }
int32_t send_from_file(int32_t s, FILE *f) { int32_t send_from_file(int32_t s, FILE *f) {
char * buf = (char *) memalign(0x40, FREAD_BUFFER_SIZE); char *buf = (char *) memalign(0x40, FREAD_BUFFER_SIZE);
if(!buf) if (!buf)
return -1; return -1;
int32_t bytes_read; int32_t bytes_read;
@ -245,19 +246,19 @@ int32_t send_from_file(int32_t s, FILE *f) {
} }
free(buf); free(buf);
return -EAGAIN; return -EAGAIN;
end: end:
free(buf); free(buf);
return result; return result;
} }
int32_t recv_to_file(int32_t s, FILE *f) { int32_t recv_to_file(int32_t s, FILE *f) {
char * buf = (char *) memalign(0x40, NET_BUFFER_SIZE); char *buf = (char *) memalign(0x40, NET_BUFFER_SIZE);
if(!buf) if (!buf)
return -1; return -1;
int32_t bytes_read; int32_t bytes_read;
while (1) { while (1) {
try_again_with_smaller_buffer: try_again_with_smaller_buffer:
bytes_read = network_read(s, buf, NET_BUFFER_SIZE); bytes_read = network_read(s, buf, NET_BUFFER_SIZE);
if (bytes_read < 0) { if (bytes_read < 0) {
if (bytes_read == -EINVAL && NET_BUFFER_SIZE == MAX_NET_BUFFER_SIZE) { if (bytes_read == -EINVAL && NET_BUFFER_SIZE == MAX_NET_BUFFER_SIZE) {

View File

@ -43,13 +43,20 @@ extern "C"{
void initialise_network(); 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_listen(int32_t s,uint32_t backlog); int32_t network_bind(int32_t s, struct sockaddr *name, int32_t namelen);
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_listen(int32_t s, uint32_t backlog);
int32_t network_read(int32_t s,void *mem,int32_t len);
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_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

@ -4,10 +4,12 @@
#include <wut_types.h> #include <wut_types.h>
#include <mutex> #include <mutex>
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

@ -25,23 +25,20 @@
class CThread { class CThread {
public: 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
pThread = (OSThread*)memalign(8, sizeof(OSThread)); pThread = (OSThread *) memalign(8, sizeof(OSThread));
//! allocate the stack //! allocate the stack
pThreadStack = (uint8_t *) memalign(0x20, iStackSize); pThreadStack = (uint8_t *) memalign(0x20, iStackSize);
//! create the thread //! create the thread
if(pThread && pThreadStack) if (pThread && pThreadStack)
OSCreateThread(pThread, &CThread::threadCallback, 1, (char*)this, pThreadStack+iStackSize, iStackSize, iPriority, iAttributes); OSCreateThread(pThread, &CThread::threadCallback, 1, (char *) this, pThreadStack + iStackSize, iStackSize, iPriority, iAttributes);
} }
//! destructor //! destructor
@ -51,72 +48,81 @@ public:
} }
static CThread *create(CThread::Callback callback, void *callbackArg, int32_t iAttr = eAttributeNone, int32_t iPriority = 16, int32_t iStackSize = 0x8000) { static CThread *create(CThread::Callback callback, void *callbackArg, int32_t iAttr = eAttributeNone, int32_t iPriority = 16, int32_t iStackSize = 0x8000) {
return ( new CThread(iAttr, iPriority, iStackSize, callback, callbackArg) ); return (new CThread(iAttr, iPriority, iStackSize, callback, callbackArg));
} }
//! 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)
free(pThreadStack); free(pThreadStack);
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,
eAttributeAffCore0 = 0x01, eAttributeAffCore0 = 0x01,
eAttributeAffCore1 = 0x02, eAttributeAffCore1 = 0x02,
eAttributeAffCore2 = 0x04, eAttributeAffCore2 = 0x04,
eAttributeDetach = 0x08, eAttributeDetach = 0x08,
eAttributePinnedAff = 0x10 eAttributePinnedAff = 0x10
}; };
private: private:
static int threadCallback(int argc, const char **argv) { static int threadCallback(int argc, const char **argv) {
@ -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

@ -1,31 +1,31 @@
/**************************************************************************** /****************************************************************************
* Copyright (C) 2008 * Copyright (C) 2008
* Joseph Jordan <joe.ftpii@psychlaw.com.au> * Joseph Jordan <joe.ftpii@psychlaw.com.au>
* *
* Copyright (C) 2010 * Copyright (C) 2010
* by Dimok * by Dimok
* *
* This software is provided 'as-is', without any express or implied * This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any * warranty. In no event will the authors be held liable for any
* damages arising from the use of this software. * damages arising from the use of this software.
* *
* Permission is granted to anyone to use this software for any * Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and * purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions: * redistribute it freely, subject to the following restrictions:
* *
* 1. The origin of this software must not be misrepresented; you * 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use * must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product * this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required. * documentation would be appreciated but is not required.
* *
* 2. Altered source versions must be plainly marked as such, and * 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software. * must not be misrepresented as being the original software.
* *
* 3. This notice may not be removed or altered from any source * 3. This notice may not be removed or altered from any source
* distribution. * distribution.
* *
* for WiiXplorer 2010 * for WiiXplorer 2010
***************************************************************************/ ***************************************************************************/
#include <malloc.h> #include <malloc.h>
#include <string.h> #include <string.h>
#include "virtualpath.h" #include "virtualpath.h"
@ -40,42 +40,37 @@ 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;
int i = 0; int i = 0;
char name[255]; char name[255];
char alias[255]; char alias[255];
char prefix[255]; char prefix[255];
bool namestop = false; bool namestop = false;
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]; alias[i + 2] = '\0';
alias[i+2] = '\0'; }
}
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));
} }
@ -99,49 +94,48 @@ 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) {
if (!VIRTUAL_FS) { if (!VIRTUAL_FS) {
VIRTUAL_FS = (VIRTUAL_PARTITION *) malloc(sizeof(VIRTUAL_PARTITION)); VIRTUAL_FS = (VIRTUAL_PARTITION *) malloc(sizeof(VIRTUAL_PARTITION));
} }
VIRTUAL_PARTITION *tmp = realloc(VIRTUAL_FS, sizeof(VIRTUAL_PARTITION) * (MAX_VIRTUAL_FS + 1)); VIRTUAL_PARTITION *tmp = realloc(VIRTUAL_FS, sizeof(VIRTUAL_PARTITION) * (MAX_VIRTUAL_FS + 1));
if (!tmp) { if (!tmp) {
if (VIRTUAL_FS) { if (VIRTUAL_FS) {
free(VIRTUAL_FS); free(VIRTUAL_FS);
VIRTUAL_FS = 0; VIRTUAL_FS = 0;
} }
MAX_VIRTUAL_FS = 0; MAX_VIRTUAL_FS = 0;
return; return;
} }
VIRTUAL_FS = tmp; VIRTUAL_FS = tmp;
VIRTUAL_FS[MAX_VIRTUAL_FS].name = strdup(name); VIRTUAL_FS[MAX_VIRTUAL_FS].name = strdup(name);
MAX_VIRTUAL_FS++; MAX_VIRTUAL_FS++;
} }
void AddVirtualFSVOLPath(const char *name, const char *alias, const char *prefix) { void AddVirtualFSVOLPath(const char *name, const char *alias, const char *prefix) {
if (!VIRTUAL_FS_VOL) { if (!VIRTUAL_FS_VOL) {
VIRTUAL_FS_VOL = (VIRTUAL_PARTITION *) malloc(sizeof(VIRTUAL_PARTITION)); VIRTUAL_FS_VOL = (VIRTUAL_PARTITION *) malloc(sizeof(VIRTUAL_PARTITION));
} }
VIRTUAL_PARTITION *tmp = realloc(VIRTUAL_FS_VOL, sizeof(VIRTUAL_PARTITION) * (MAX_VIRTUAL_FS_VOL + 1)); VIRTUAL_PARTITION *tmp = realloc(VIRTUAL_FS_VOL, sizeof(VIRTUAL_PARTITION) * (MAX_VIRTUAL_FS_VOL + 1));
if (!tmp) { if (!tmp) {
free(VIRTUAL_FS_VOL); free(VIRTUAL_FS_VOL);
MAX_VIRTUAL_FS_VOL = 0; MAX_VIRTUAL_FS_VOL = 0;
return; return;
} }
VIRTUAL_FS_VOL = tmp; VIRTUAL_FS_VOL = tmp;
VIRTUAL_FS_VOL[MAX_VIRTUAL_FS_VOL].name = strdup(name); VIRTUAL_FS_VOL[MAX_VIRTUAL_FS_VOL].name = strdup(name);
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:/");
@ -158,45 +152,45 @@ void MountVirtualDevices()
AddVirtualFSVOLPath("content", NULL, NULL); AddVirtualFSVOLPath("content", NULL, NULL);
} }
void UnmountVirtualPaths() { void UnmountVirtualPaths() {
uint32_t i = 0; uint32_t i = 0;
for (i = 0; i < MAX_VIRTUAL_PARTITIONS; i++) { for (i = 0; i < MAX_VIRTUAL_PARTITIONS; i++) {
if (VIRTUAL_PARTITIONS[i].name) { if (VIRTUAL_PARTITIONS[i].name) {
free(VIRTUAL_PARTITIONS[i].name); free(VIRTUAL_PARTITIONS[i].name);
} }
if (VIRTUAL_PARTITIONS[i].alias) { if (VIRTUAL_PARTITIONS[i].alias) {
free(VIRTUAL_PARTITIONS[i].alias); free(VIRTUAL_PARTITIONS[i].alias);
} }
if (VIRTUAL_PARTITIONS[i].prefix) { if (VIRTUAL_PARTITIONS[i].prefix) {
free(VIRTUAL_PARTITIONS[i].prefix); free(VIRTUAL_PARTITIONS[i].prefix);
} }
} }
for (i = 0; i < MAX_VIRTUAL_FS_VOL; i++) { for (i = 0; i < MAX_VIRTUAL_FS_VOL; i++) {
if (VIRTUAL_FS_VOL[i].name) { if (VIRTUAL_FS_VOL[i].name) {
free(VIRTUAL_FS_VOL[i].name); free(VIRTUAL_FS_VOL[i].name);
} }
} }
for (i = 0; i < MAX_VIRTUAL_FS; i++) { for (i = 0; i < MAX_VIRTUAL_FS; i++) {
if (VIRTUAL_FS[i].name) { if (VIRTUAL_FS[i].name) {
free(VIRTUAL_FS[i].name); free(VIRTUAL_FS[i].name);
} }
} }
if (VIRTUAL_PARTITIONS) { if (VIRTUAL_PARTITIONS) {
free(VIRTUAL_PARTITIONS); free(VIRTUAL_PARTITIONS);
} }
if (VIRTUAL_FS_VOL) { if (VIRTUAL_FS_VOL) {
free(VIRTUAL_FS_VOL); free(VIRTUAL_FS_VOL);
} }
if (VIRTUAL_FS) { if (VIRTUAL_FS) {
free(VIRTUAL_FS); free(VIRTUAL_FS);
} }
VIRTUAL_PARTITIONS = NULL; VIRTUAL_PARTITIONS = NULL;
VIRTUAL_FS_VOL = NULL; VIRTUAL_FS_VOL = NULL;
VIRTUAL_FS = NULL; VIRTUAL_FS = NULL;
MAX_VIRTUAL_PARTITIONS = 0; MAX_VIRTUAL_PARTITIONS = 0;
MAX_VIRTUAL_FS = 0; MAX_VIRTUAL_FS = 0;
MAX_VIRTUAL_FS_VOL = 0; MAX_VIRTUAL_FS_VOL = 0;
} }

View File

@ -1,32 +1,32 @@
/**************************************************************************** /****************************************************************************
* Copyright (C) 2010 * Copyright (C) 2010
* by Dimok * by Dimok
* *
* Original VIRTUAL_PART Struct * Original VIRTUAL_PART Struct
* Copyright (C) 2008 * Copyright (C) 2008
* Joseph Jordan <joe.ftpii@psychlaw.com.au> * Joseph Jordan <joe.ftpii@psychlaw.com.au>
* *
* This software is provided 'as-is', without any express or implied * This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any * warranty. In no event will the authors be held liable for any
* damages arising from the use of this software. * damages arising from the use of this software.
* *
* Permission is granted to anyone to use this software for any * Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and * purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions: * redistribute it freely, subject to the following restrictions:
* *
* 1. The origin of this software must not be misrepresented; you * 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use * must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product * this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required. * documentation would be appreciated but is not required.
* *
* 2. Altered source versions must be plainly marked as such, and * 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software. * must not be misrepresented as being the original software.
* *
* 3. This notice may not be removed or altered from any source * 3. This notice may not be removed or altered from any source
* distribution. * distribution.
* *
* for WiiXplorer 2010 * for WiiXplorer 2010
***************************************************************************/ ***************************************************************************/
#ifndef _VIRTUALPATH_H_ #ifndef _VIRTUALPATH_H_
#define _VIRTUALPATH_H_ #define _VIRTUALPATH_H_
@ -38,26 +38,31 @@ extern "C"{
#include <stdbool.h> #include <stdbool.h>
typedef struct { typedef struct {
char *name; char *name;
char *alias; char *alias;
char *prefix; char *prefix;
bool inserted; bool inserted;
} VIRTUAL_PARTITION; } VIRTUAL_PARTITION;
extern VIRTUAL_PARTITION * VIRTUAL_PARTITIONS; extern VIRTUAL_PARTITION *VIRTUAL_PARTITIONS;
extern uint8_t MAX_VIRTUAL_PARTITIONS; extern uint8_t MAX_VIRTUAL_PARTITIONS;
extern VIRTUAL_PARTITION * VIRTUAL_FS; extern VIRTUAL_PARTITION *VIRTUAL_FS;
extern uint8_t MAX_VIRTUAL_FS; extern uint8_t MAX_VIRTUAL_FS;
extern VIRTUAL_PARTITION * VIRTUAL_FS_VOL; 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

363
src/vrt.c
View File

@ -34,67 +34,67 @@ misrepresented as being the original software.
#include "vrt.h" #include "vrt.h"
static char *virtual_abspath(char *virtual_cwd, char *virtual_path) { static char *virtual_abspath(char *virtual_cwd, char *virtual_path) {
char *path; char *path;
if (virtual_path[0] == '/') { if (virtual_path[0] == '/') {
path = virtual_path; path = virtual_path;
} else { } else {
size_t path_size = strlen(virtual_cwd) + strlen(virtual_path) + 1; size_t path_size = strlen(virtual_cwd) + strlen(virtual_path) + 1;
if (path_size > MAXPATHLEN || !(path = malloc(path_size))) return NULL; if (path_size > MAXPATHLEN || !(path = malloc(path_size))) return NULL;
strcpy(path, virtual_cwd); strcpy(path, virtual_cwd);
strcat(path, virtual_path); strcat(path, virtual_path);
} }
char *normalised_path = malloc(strlen(path) + 1); char *normalised_path = malloc(strlen(path) + 1);
if (!normalised_path) goto end; if (!normalised_path) goto end;
*normalised_path = '\0'; *normalised_path = '\0';
char *curr_dir = normalised_path; char *curr_dir = normalised_path;
uint32_t state = 0; // 0:start, 1:slash, 2:dot, 3:dotdot uint32_t state = 0; // 0:start, 1:slash, 2:dot, 3:dotdot
char *token = path; char *token = path;
while (1) { while (1) {
switch (state) { switch (state) {
case 0: case 0:
if (*token == '/') { if (*token == '/') {
state = 1; state = 1;
curr_dir = normalised_path + strlen(normalised_path); curr_dir = normalised_path + strlen(normalised_path);
strncat(normalised_path, token, 1); strncat(normalised_path, token, 1);
} }
break; break;
case 1: case 1:
if (*token == '.') state = 2; if (*token == '.') state = 2;
else if (*token != '/') state = 0; else if (*token != '/') state = 0;
break; break;
case 2: case 2:
if (*token == '/' || !*token) { if (*token == '/' || !*token) {
state = 1; state = 1;
*(curr_dir + 1) = '\0'; *(curr_dir + 1) = '\0';
} else if (*token == '.') state = 3; } else if (*token == '.') state = 3;
else state = 0; else state = 0;
break; break;
case 3: case 3:
if (*token == '/' || !*token) { if (*token == '/' || !*token) {
state = 1; state = 1;
*curr_dir = '\0'; *curr_dir = '\0';
char *prev_dir = strrchr(normalised_path, '/'); char *prev_dir = strrchr(normalised_path, '/');
if (prev_dir) curr_dir = prev_dir; if (prev_dir) curr_dir = prev_dir;
else *curr_dir = '/'; else *curr_dir = '/';
*(curr_dir + 1) = '\0'; *(curr_dir + 1) = '\0';
} else state = 0; } else state = 0;
break; break;
} }
if (!*token) break; if (!*token) break;
if (state == 0 || *token != '/') strncat(normalised_path, token, 1); if (state == 0 || *token != '/') strncat(normalised_path, token, 1);
token++; token++;
} }
uint32_t end = strlen(normalised_path); uint32_t end = strlen(normalised_path);
while (end > 1 && normalised_path[end - 1] == '/') { while (end > 1 && normalised_path[end - 1] == '/') {
normalised_path[--end] = '\x00'; normalised_path[--end] = '\x00';
} }
end: end:
if (path != virtual_path) free(path); if (path != virtual_path) free(path);
return normalised_path; return normalised_path;
} }
/* /*
@ -106,52 +106,52 @@ static char *virtual_abspath(char *virtual_cwd, char *virtual_path) {
Returns NULL to indicate that the client-visible path is invalid Returns NULL to indicate that the client-visible path is invalid
*/ */
char *to_real_path(char *virtual_cwd, char *virtual_path) { char *to_real_path(char *virtual_cwd, char *virtual_path) {
errno = ENOENT; errno = ENOENT;
if (strchr(virtual_path, ':')) { if (strchr(virtual_path, ':')) {
return NULL; // colon is not allowed in virtual path, i've decided =P return NULL; // colon is not allowed in virtual path, i've decided =P
} }
virtual_path = virtual_abspath(virtual_cwd, virtual_path); virtual_path = virtual_abspath(virtual_cwd, virtual_path);
if (!virtual_path) return NULL; if (!virtual_path) return NULL;
char *path = NULL; char *path = NULL;
char *rest = virtual_path; char *rest = virtual_path;
if (!strcmp("/", virtual_path)) { if (!strcmp("/", virtual_path)) {
// indicate vfs-root with "" // indicate vfs-root with ""
path = ""; path = "";
goto end; goto end;
} }
const char *prefix = NULL; const char *prefix = NULL;
uint32_t i; uint32_t i;
for (i = 0; i < MAX_VIRTUAL_PARTITIONS; i++) { for (i = 0; i < MAX_VIRTUAL_PARTITIONS; i++) {
VIRTUAL_PARTITION *partition = VIRTUAL_PARTITIONS + i; VIRTUAL_PARTITION *partition = VIRTUAL_PARTITIONS + i;
const char *alias = partition->alias; const char *alias = partition->alias;
size_t alias_len = strlen(alias); size_t alias_len = strlen(alias);
if (!strcasecmp(alias, virtual_path) || (!strncasecmp(alias, virtual_path, alias_len) && virtual_path[alias_len] == '/')) { if (!strcasecmp(alias, virtual_path) || (!strncasecmp(alias, virtual_path, alias_len) && virtual_path[alias_len] == '/')) {
prefix = partition->prefix; prefix = partition->prefix;
rest += alias_len; rest += alias_len;
if (*rest == '/') rest++; if (*rest == '/') rest++;
break; break;
} }
} }
if (!prefix) { if (!prefix) {
errno = ENODEV; errno = ENODEV;
goto end; goto end;
} }
size_t real_path_size = strlen(prefix) + strlen(rest) + 1; size_t real_path_size = strlen(prefix) + strlen(rest) + 1;
if (real_path_size > MAXPATHLEN) goto end; if (real_path_size > MAXPATHLEN) goto end;
path = malloc(real_path_size); path = malloc(real_path_size);
if (!path) goto end; if (!path) goto end;
strcpy(path, prefix); strcpy(path, prefix);
strcat(path, rest); strcat(path, rest);
end: end:
free(virtual_path); free(virtual_path);
return path; return path;
} }
static int checkdir(char *path) { static int checkdir(char *path) {
@ -170,101 +170,105 @@ static int checkdir(char *path) {
return -1; return -1;
} }
typedef void * (*path_func)(char *path, ...); typedef void *(*path_func)(char *path, ...);
static void *with_virtual_path(void *virtual_cwd, void *void_f, char *virtual_path, int32_t failed, ...) { static void *with_virtual_path(void *virtual_cwd, void *void_f, char *virtual_path, int32_t failed, ...) {
char *path = to_real_path(virtual_cwd, virtual_path); char *path = to_real_path(virtual_cwd, virtual_path);
if (!path || !*path) return (void *)failed; if (!path || !*path) return (void *) failed;
path_func f = (path_func)void_f; path_func f = (path_func) void_f;
va_list ap; va_list ap;
void *args[3]; void *args[3];
unsigned int num_args = 0; unsigned int num_args = 0;
va_start(ap, failed); va_start(ap, failed);
do { do {
void *arg = va_arg(ap, void *); void *arg = va_arg(ap, void *);
if (!arg) break; if (!arg) break;
args[num_args++] = arg; args[num_args++] = arg;
} while (1); } while (1);
va_end(ap); va_end(ap);
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);
return result; return result;
} }
FILE *vrt_fopen(char *cwd, char *path, char *mode) { FILE *vrt_fopen(char *cwd, char *path, char *mode) {
return with_virtual_path(cwd, fopen, path, 0, mode, NULL); return with_virtual_path(cwd, fopen, path, 0, mode, NULL);
} }
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))) {
st->st_mode = S_IFDIR;
st->st_size = 31337;
return 0;
} }
else if (!*real_path || (strcmp(path, ".") == 0) || (strlen(cwd) == 1) || ((strlen(cwd) > 1) && (strcmp(path, "..") == 0))) free(real_path);
{ return (int) with_virtual_path(cwd, stat, path, -1, st, NULL);
st->st_mode = S_IFDIR;
st->st_size = 31337;
return 0;
}
free(real_path);
return (int)with_virtual_path(cwd, stat, path, -1, st, NULL);
} }
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))) {
} return 0;
else if (!*real_path || (strcmp(path, ".") == 0) || (strlen(cwd) == 1) || ((strlen(cwd) > 1) && (strcmp(path, "..") == 0))) }
{ free(real_path);
return 0; return (int) with_virtual_path(cwd, checkdir, path, -1, NULL);
}
free(real_path);
return (int)with_virtual_path(cwd, checkdir, path, -1, NULL);
} }
int vrt_chdir(char *cwd, char *path) { int vrt_chdir(char *cwd, char *path) {
if (vrt_checkdir(cwd, path)) { if (vrt_checkdir(cwd, path)) {
return -1; return -1;
} }
char *abspath = virtual_abspath(cwd, path); char *abspath = virtual_abspath(cwd, path);
if (!abspath) { if (!abspath) {
errno = ENOMEM; errno = ENOMEM;
return -1; return -1;
} }
strcpy(cwd, abspath); strcpy(cwd, abspath);
if (cwd[1]) strcat(cwd, "/"); if (cwd[1]) strcat(cwd, "/");
free(abspath); free(abspath);
return 0; return 0;
} }
int vrt_unlink(char *cwd, char *path) { int vrt_unlink(char *cwd, char *path) {
return (int)with_virtual_path(cwd, unlink, path, -1, NULL); return (int) with_virtual_path(cwd, unlink, path, -1, NULL);
} }
int vrt_mkdir(char *cwd, char *path, mode_t mode) { int vrt_mkdir(char *cwd, char *path, mode_t mode) {
return (int)with_virtual_path(cwd, mkdir, path, -1, mode, NULL); return (int) with_virtual_path(cwd, mkdir, path, -1, mode, NULL);
} }
int vrt_rename(char *cwd, char *from_path, char *to_path) { int vrt_rename(char *cwd, char *from_path, char *to_path) {
char *real_to_path = to_real_path(cwd, to_path); char *real_to_path = to_real_path(cwd, to_path);
if (!real_to_path || !*real_to_path) return -1; if (!real_to_path || !*real_to_path) return -1;
int result = (int)with_virtual_path(cwd, rename, from_path, -1, real_to_path, NULL); int result = (int) with_virtual_path(cwd, rename, from_path, -1, real_to_path, NULL);
free(real_to_path); free(real_to_path);
return result; return result;
} }
/* /*
@ -328,11 +332,11 @@ struct dirent *vrt_readdir(DIR_P *pDir) {
DIR *iter = pDir->dir; DIR *iter = pDir->dir;
if (pDir->virt_root || pDir->virtual_fs || pDir->virtual_fs_vol) { if (pDir->virt_root || pDir->virtual_fs || pDir->virtual_fs_vol) {
int max = MAX_VIRTUAL_PARTITIONS; int max = MAX_VIRTUAL_PARTITIONS;
VIRTUAL_PARTITION * PARTITION_PTR = VIRTUAL_PARTITIONS; VIRTUAL_PARTITION *PARTITION_PTR = VIRTUAL_PARTITIONS;
if(pDir->virtual_fs){ if (pDir->virtual_fs) {
max = MAX_VIRTUAL_FS; max = MAX_VIRTUAL_FS;
PARTITION_PTR = VIRTUAL_FS; PARTITION_PTR = VIRTUAL_FS;
} else if (pDir->virtual_fs_vol){ } else if (pDir->virtual_fs_vol) {
max = MAX_VIRTUAL_FS_VOL; max = MAX_VIRTUAL_FS_VOL;
PARTITION_PTR = VIRTUAL_FS_VOL; PARTITION_PTR = VIRTUAL_FS_VOL;
} }
@ -340,9 +344,9 @@ struct dirent *vrt_readdir(DIR_P *pDir) {
VIRTUAL_PARTITION *partition = PARTITION_PTR + (int) iter->position; VIRTUAL_PARTITION *partition = PARTITION_PTR + (int) iter->position;
if (partition->inserted) { if (partition->inserted) {
iter->fileData.d_type = DT_DIR; iter->fileData.d_type = DT_DIR;
if(pDir->virtual_fs || pDir->virtual_fs_vol){ if (pDir->virtual_fs || pDir->virtual_fs_vol) {
strcpy(iter->fileData.d_name, partition->name); strcpy(iter->fileData.d_name, partition->name);
}else{ } else {
strcpy(iter->fileData.d_name, partition->alias + 1); strcpy(iter->fileData.d_name, partition->alias + 1);
} }
iter->position++; iter->position++;
@ -356,21 +360,20 @@ 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 closedir(iter->dir);
closedir(iter->dir); }
}
// root path is not allocated // root path is not allocated
if(iter->path && *iter->path != 0) if (iter->path && *iter->path != 0)
free(iter->path); free(iter->path);
free(iter); free(iter);
return 0; return 0;
} }

View File

@ -32,25 +32,32 @@ 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; uint8_t virtual_fs;
uint8_t virtual_fs; uint8_t virtual_fs_vol;
uint8_t virtual_fs_vol;
} DIR_P; } DIR_P;
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