diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f8a523..6cc0686 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,6 +47,10 @@ find_package(ZLIB REQUIRED) option(FTPD_CLASSIC "Build ${PROJECT_NAME} classic" OFF) +if(NINTENDO_DS OR NINTENDO_WII OR NINTENDO_GAMECUBE) + set(FTPD_CLASSIC ON) +endif() + if(FTPD_CLASSIC AND (NINTENDO_SWITCH OR NINTENDO_3DS)) set(FTPD_TARGET "${PROJECT_NAME}-classic") else() @@ -86,17 +90,23 @@ if(IPO_SUPPORTED) ) endif() -if(FTPD_CLASSIC OR NINTENDO_DS) +if(FTPD_CLASSIC) target_compile_definitions(${FTPD_TARGET} PRIVATE CLASSIC) endif() -if(NINTENDO_SWITCH OR NINTENDO_3DS OR NINTENDO_DS) +if(NINTENDO_SWITCH OR NINTENDO_3DS OR NINTENDO_DS OR NINTENDO_WII OR NINTENDO_GAMECUBE) target_compile_definitions(${FTPD_TARGET} PRIVATE NO_IPV6 FTPDCONFIG="/config/${PROJECT_NAME}/${PROJECT_NAME}.cfg" ) endif() +if(NINTENDO_WII OR NINTENDO_GAMECUBE OR NINTENDO_DS) + target_compile_definitions(${FTPD_TARGET} PRIVATE HAVE_MUTEX=1 HAVE_TLS=0) +else() + target_compile_definitions(${FTPD_TARGET} PRIVATE HAVE_MUTEX=1 HAVE_TLS=1) +endif() + target_sources(${FTPD_TARGET} PRIVATE include/fs.h include/ftpConfig.h @@ -158,6 +168,7 @@ if(NINTENDO_SWITCH) target_sources(${FTPD_TARGET} PRIVATE source/switch/init.c source/switch/platform.cpp + source/common/thread.cpp ) if(FTPD_CLASSIC) @@ -362,6 +373,7 @@ elseif(NINTENDO_DS) target_sources(${FTPD_TARGET} PRIVATE source/nds/platform.cpp + source/common/thread.cpp ) nds_create_rom(${FTPD_TARGET} @@ -370,6 +382,25 @@ elseif(NINTENDO_DS) SUBTITLE2 "(c) 2025 mtheall" ICON nds/icon.bmp ) +elseif(NINTENDO_WII OR NINTENDO_GAMECUBE) + + target_link_libraries(${FTPD_TARGET} PRIVATE + fat + ) + + if(NINTENDO_GAMECUBE) + target_link_libraries(${FTPD_TARGET} PRIVATE + bba + ) + endif() + + target_sources(${FTPD_TARGET} PRIVATE + source/ogc/platform.cpp + source/common/thread.cpp + ) + + ogc_create_dol(${PROJECT_NAME}) + else() find_package(PkgConfig REQUIRED) find_package(glfw3 REQUIRED) diff --git a/include/ftpConfig.h b/include/ftpConfig.h index d92d4c2..b0c3305 100644 --- a/include/ftpConfig.h +++ b/include/ftpConfig.h @@ -48,10 +48,9 @@ class FtpConfig /// \param path_ Path to config file static UniqueFtpConfig load (gsl::not_null path_); -#ifndef __NDS__ +#if HAVE_MUTEX std::scoped_lock lockGuard (); #endif - /// \brief Save config /// \param path_ Path to config file bool save (gsl::not_null path_); @@ -139,11 +138,10 @@ class FtpConfig private: FtpConfig (); -#ifndef __NDS__ +#if HAVE_MUTEX /// \brief Mutex mutable platform::Mutex m_lock; #endif - /// \brief Username std::string m_user; diff --git a/include/ftpServer.h b/include/ftpServer.h index bf980dc..215073a 100644 --- a/include/ftpServer.h +++ b/include/ftpServer.h @@ -98,7 +98,7 @@ class FtpServer /// \brief Thread entry point void threadFunc (); -#ifndef __NDS__ +#if HAVE_MUTEX /// \brief Thread platform::Thread m_thread; diff --git a/include/ftpSession.h b/include/ftpSession.h index 7d4fa62..54aa33d 100644 --- a/include/ftpSession.h +++ b/include/ftpSession.h @@ -85,6 +85,12 @@ class FtpSession /// \brief Transfer buffersize constexpr static auto XFER_BUFFERSIZE = 8192; +#elif defined (__wii__) || defined (__gamecube__) + /// \brief Response buffer size + constexpr static auto RESPONSE_BUFFERSIZE = 8192; + + /// \brief Transfer buffersize + constexpr static auto XFER_BUFFERSIZE = 16384; #else /// \brief Response buffer size constexpr static auto RESPONSE_BUFFERSIZE = 32768; @@ -106,6 +112,11 @@ class FtpSession /// \brief Socket buffer size constexpr static auto SOCK_BUFFERSIZE = 32768; + /// \brief Amount of file position history to keep + constexpr static auto POSITION_HISTORY = 100; +#elif defined(__wii__) || defined(__gamecube__) + /// \brief Socket buffer size + constexpr static auto SOCK_BUFFERSIZE = 16384; /// \brief Amount of file position history to keep constexpr static auto POSITION_HISTORY = 100; #else @@ -246,11 +257,10 @@ class FtpSession /// \brief Transfer upload bool storeTransfer (); -#ifndef __NDS__ +#if HAVE_MUTEX /// \brief Mutex platform::Mutex m_lock; #endif - /// \brief FTP config FtpConfig &m_config; diff --git a/include/platform.h b/include/platform.h index a265136..b269ce8 100644 --- a/include/platform.h +++ b/include/platform.h @@ -32,13 +32,19 @@ #include #endif +#if defined (__wii__) || defined(__gamecube__) +#include +#include +#include +#endif + #include #include #include #include #include -#ifdef CLASSIC +#if defined(CLASSIC) extern PrintConsole g_statusConsole; extern PrintConsole g_logConsole; extern PrintConsole g_sessionConsole; @@ -113,7 +119,7 @@ struct steady_clock using steady_clock = std::chrono::steady_clock; #endif -#ifndef __NDS__ +#if HAVE_MUTEX /// \brief Platform thread class Thread { diff --git a/source/common/thread.cpp b/source/common/thread.cpp new file mode 100644 index 0000000..70ff51e --- /dev/null +++ b/source/common/thread.cpp @@ -0,0 +1,99 @@ +#include "platform.h" + +#include +#include + + +/////////////////////////////////////////////////////////////////////////// +/// \brief Platform thread pimpl +class platform::Thread::privateData_t +{ +public: + privateData_t () = default; + + /// \brief Parameterized constructor + /// \param func_ Thread entry point + privateData_t (std::function &&func_) : thread (std::move (func_)) + { + } + + /// \brief Underlying thread + std::thread thread; +}; + +/////////////////////////////////////////////////////////////////////////// +platform::Thread::~Thread () = default; + +platform::Thread::Thread () : m_d (new privateData_t ()) +{ +} + +platform::Thread::Thread (std::function &&func_) + : m_d (new privateData_t (std::move (func_))) +{ +} + +platform::Thread::Thread (Thread &&that_) : m_d (new privateData_t ()) +{ + std::swap (m_d, that_.m_d); +} + +platform::Thread &platform::Thread::operator= (Thread &&that_) +{ + std::swap (m_d, that_.m_d); + return *this; +} + +void platform::Thread::join () +{ + m_d->thread.join (); +} + +void platform::Thread::sleep (std::chrono::milliseconds const timeout_) +{ + std::this_thread::sleep_for (timeout_); +} + +/////////////////////////////////////////////////////////////////////////// +#define USE_STD_MUTEX 1 + +/// \brief Platform mutex pimpl +class platform::Mutex::privateData_t +{ +public: +#if USE_STD_MUTEX + /// \brief Underlying mutex + std::mutex mutex; +#else + /// \brief Underlying mutex + ::Mutex mutex; +#endif +}; + +/////////////////////////////////////////////////////////////////////////// +platform::Mutex::~Mutex () = default; + +platform::Mutex::Mutex () : m_d (new privateData_t ()) +{ +#if !USE_STD_MUTEX + mutexInit (&m_d->mutex); +#endif +} + +void platform::Mutex::lock () +{ +#if USE_STD_MUTEX + m_d->mutex.lock (); +#else + mutexLock (&m_d->mutex); +#endif +} + +void platform::Mutex::unlock () +{ +#if USE_STD_MUTEX + m_d->mutex.unlock (); +#else + mutexUnlock (&m_d->mutex); +#endif +} \ No newline at end of file diff --git a/source/fs.cpp b/source/fs.cpp index fc69c93..5b4fca1 100644 --- a/source/fs.cpp +++ b/source/fs.cpp @@ -40,7 +40,7 @@ #include #include -#if defined(__NDS__) || defined(__3DS__) || defined(__SWITCH__) +#if defined(__NDS__) || defined(__3DS__) || defined(__SWITCH__) || defined(__wii__) || defined (__gamecube__) #define getline __getline #endif diff --git a/source/ftpConfig.cpp b/source/ftpConfig.cpp index d2a45f6..c246bac 100644 --- a/source/ftpConfig.cpp +++ b/source/ftpConfig.cpp @@ -43,6 +43,7 @@ using stat_t = struct stat; #include #include #include +#include namespace { @@ -196,7 +197,7 @@ UniqueFtpConfig FtpConfig::load (gsl::not_null const path_) return config; } -#ifndef __NDS__ +#if HAVE_MUTEX std::scoped_lock FtpConfig::lockGuard () { return std::scoped_lock (m_lock); diff --git a/source/ftpServer.cpp b/source/ftpServer.cpp index 531bc1e..415d974 100644 --- a/source/ftpServer.cpp +++ b/source/ftpServer.cpp @@ -75,15 +75,15 @@ using statvfs_t = struct statvfs; #include using namespace std::chrono_literals; -#ifdef __NDS__ -#define LOCKED(x) x -#else +#if HAVE_MUTEX #define LOCKED(x) \ do \ { \ auto const lock = std::scoped_lock (m_lock); \ x; \ } while (0) +#else +#define LOCKED(x) x #endif namespace @@ -96,11 +96,10 @@ auto const s_startTime = std::time (nullptr); int s_tzOffset = 0; #endif -#ifndef __NDS__ +#if HAVE_MUTEX /// \brief Mutex for s_freeSpace platform::Mutex s_lock; #endif - /// \brief Free space string std::string s_freeSpace; @@ -210,7 +209,7 @@ FtpServer::~FtpServer () { m_quit = true; -#ifndef __NDS__ +#if HAVE_MUTEX m_thread.join (); #endif @@ -234,9 +233,12 @@ FtpServer::FtpServer (UniqueFtpConfig config_) m_hostnameSetting (m_config->hostname ()) #endif { + #ifndef __NDS__ mdns::setHostname (m_config->hostname ()); +#endif +#if HAVE_MUTEX m_thread = platform::Thread (std::bind (&FtpServer::threadFunc, this)); #endif @@ -249,14 +251,15 @@ FtpServer::FtpServer (UniqueFtpConfig config_) void FtpServer::draw () { -#ifdef __NDS__ - loop (); +#if HAVE_MUTEX +#else + loop(); #endif #ifdef CLASSIC { char port[7]; -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = std::scoped_lock (m_lock); #endif if (m_socket) @@ -281,7 +284,7 @@ void FtpServer::draw () } { -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = std::scoped_lock (s_lock); #endif if (!s_freeSpace.empty ()) @@ -295,7 +298,7 @@ void FtpServer::draw () } { -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = std::scoped_lock (m_lock); #endif consoleSelect (&g_sessionConsole); @@ -397,7 +400,7 @@ UniqueFtpServer FtpServer::create () std::string FtpServer::getFreeSpace () { -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = std::scoped_lock (s_lock); #endif return s_freeSpace; @@ -415,7 +418,7 @@ void FtpServer::updateFreeSpace () auto freeSpace = fs::printSize (static_cast (st.f_bsize) * st.f_bfree); -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = std::scoped_lock (s_lock); #endif if (freeSpace != s_freeSpace) @@ -443,7 +446,7 @@ void FtpServer::handleNetworkFound () std::uint16_t port; { -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = m_config->lockGuard (); #endif port = m_config->port (); @@ -525,7 +528,7 @@ void FtpServer::showMenu () if (ImGui::MenuItem ("Upload Log")) { -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = std::scoped_lock (m_lock); #endif if (!m_uploadLogCurlM) @@ -589,10 +592,10 @@ void FtpServer::showMenu () { if (!prevShowSettings) { -#ifndef __NDS__ + +#if HAVE_MUTEX auto const lock = m_config->lockGuard (); #endif - m_userSetting = m_config->user (); m_userSetting.resize (32); @@ -735,10 +738,9 @@ void FtpServer::showSettings () m_showSettings = false; ImGui::CloseCurrentPopup (); -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = m_config->lockGuard (); #endif - m_config->setUser (m_userSetting); m_config->setPass (m_passSetting); m_config->setHostname (m_hostnameSetting); @@ -764,7 +766,7 @@ void FtpServer::showSettings () if (save) { -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = m_config->lockGuard (); #endif if (!m_config->save (FTPDCONFIG)) @@ -852,7 +854,7 @@ void FtpServer::showAbout () ImGui::TreePop (); } -#if defined(__NDS__) +#if defined(__NDS__) || defined(__wii__) || defined(__gamecube__) #elif defined(__3DS__) if (ImGui::TreeNode (g_libctruVersion)) { @@ -1043,7 +1045,7 @@ void FtpServer::loop () std::vector deadSessions; { // remove dead sessions -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = std::scoped_lock (m_lock); #endif auto it = std::begin (m_sessions); @@ -1067,7 +1069,7 @@ void FtpServer::loop () if (!FtpSession::poll (m_sessions)) handleNetworkLost (); } -#ifndef __NDS__ +#if HAVE_MUTEX // avoid busy polling in background thread else platform::Thread::sleep (16ms); diff --git a/source/ftpSession.cpp b/source/ftpSession.cpp index 0070428..5d06cc2 100644 --- a/source/ftpSession.cpp +++ b/source/ftpSession.cpp @@ -55,15 +55,15 @@ using namespace std::chrono_literals; #define lstat stat #endif -#ifdef __NDS__ -#define LOCKED(x) x -#else +#if HAVE_MUTEX #define LOCKED(x) \ do \ { \ auto const lock = std::scoped_lock (m_lock); \ x; \ } while (0) +#else +#define LOCKED(x) x #endif namespace @@ -400,7 +400,7 @@ FtpSession::FtpSession (FtpConfig &config_, UniqueSocket commandSocket_) m_devZero (false) { { -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = m_config.lockGuard (); #endif if (m_config.user ().empty ()) @@ -423,7 +423,7 @@ FtpSession::FtpSession (FtpConfig &config_, UniqueSocket commandSocket_) bool FtpSession::dead () { -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = std::scoped_lock (m_lock); #endif if (m_commandSocket || m_pasvSocket || m_dataSocket) @@ -434,7 +434,7 @@ bool FtpSession::dead () void FtpSession::draw () { -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = std::scoped_lock (m_lock); #endif @@ -693,7 +693,7 @@ bool FtpSession::poll (std::vector const &sessions_) if (i.revents & (POLLIN | POLLPRI)) session->readCommand (i.revents); - if (i.revents & (POLLERR | POLLHUP)) + if (i.revents & POLLERR) session->closeCommand (); } @@ -711,7 +711,7 @@ bool FtpSession::poll (std::vector const &sessions_) if (i.revents & ~(POLLIN | POLLPRI | POLLOUT)) debug ("Data revents 0x%X\n", i.revents); - if (i.revents & (POLLERR | POLLHUP)) + if (i.revents & POLLERR) { session->sendResponse ("426 Data connection failed\r\n"); session->setState (State::COMMAND, true, true); @@ -737,7 +737,7 @@ bool FtpSession::poll (std::vector const &sessions_) debug ("Data revents 0x%X\n", i.revents); // we need to transfer data - if (i.revents & (POLLERR | POLLHUP)) + if (i.revents & POLLERR) { session->sendResponse ("426 Data connection failed\r\n"); session->setState (State::COMMAND, true, true); @@ -784,10 +784,9 @@ void FtpSession::setState (State const state_, bool const closePasv_, bool const if (state_ == State::COMMAND) { { -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = std::scoped_lock (m_lock); #endif - m_restartPosition = 0; m_fileSize = 0; m_filePosition = 0; @@ -1008,7 +1007,7 @@ int FtpSession::fillDirent (stat_t const &st_, std::string_view const path_, cha type_ = "file"; else if (S_ISDIR (st_.st_mode)) type_ = "dir"; -#if !defined(__3DS__) && !defined(__SWITCH__) +#if !defined(__3DS__) && !defined(__SWITCH__) && !defined (__wii__) && !defined (__gamecube__) else if (S_ISLNK (st_.st_mode)) type_ = "os.unix=symlink"; else if (S_ISCHR (st_.st_mode)) @@ -1191,6 +1190,12 @@ int FtpSession::fillDirent (stat_t const &st_, std::string_view const path_, cha #elif defined(__SWITCH__) auto const owner = "Switch"; auto const group = "Switch"; +#elif defined (__gamecube__) + auto const owner = "gamecube"; + auto const group = "gamecube"; +#elif defined (__wii__) + auto const owner = "wii"; + auto const group = "wii"; #else char owner[32]; char group[32]; @@ -1645,7 +1650,7 @@ void FtpSession::xferDir (char const *const args_, XferDirMode const mode_, bool void FtpSession::readCommand (int const events_) { -#ifndef __NDS__ +#if !defined(__NDS__) && !defined (__wii__) && !defined(__gamecube__) // check out-of-band data if (events_ & POLLPRI) { @@ -2791,7 +2796,7 @@ void FtpSession::PASS (char const *args_) std::string pass; { -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = m_config.lockGuard (); #endif user = m_config.user (); @@ -3194,7 +3199,7 @@ void FtpSession::SITE (char const *args_) if (compare (command, "USER") == 0) { { -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = m_config.lockGuard (); #endif m_config.setUser (std::string (arg)); @@ -3206,7 +3211,7 @@ void FtpSession::SITE (char const *args_) else if (compare (command, "PASS") == 0) { { -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = m_config.lockGuard (); #endif m_config.setPass (std::string (arg)); @@ -3220,7 +3225,7 @@ void FtpSession::SITE (char const *args_) bool error = false; { -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = m_config.lockGuard (); #endif error = !m_config.setPort (arg); @@ -3250,7 +3255,9 @@ void FtpSession::SITE (char const *args_) else if (compare (command, "HOST") == 0) { { +#if HAVE_MUTEX auto const lock = m_config.lockGuard (); +#endif m_config.setHostname (std::string (arg)); mdns::setHostname (std::string (arg)); } @@ -3262,14 +3269,14 @@ void FtpSession::SITE (char const *args_) { if (arg == "0") { -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = m_config.lockGuard (); #endif m_config.setGetMTime (false); } else if (arg == "1") { -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = m_config.lockGuard (); #endif m_config.setGetMTime (true); @@ -3286,7 +3293,7 @@ void FtpSession::SITE (char const *args_) bool error; { -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = m_config.lockGuard (); #endif error = !m_config.save (FTPDCONFIG); @@ -3451,7 +3458,7 @@ void FtpSession::USER (char const *args_) std::string pass; { -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = m_config.lockGuard (); #endif user = m_config.user (); diff --git a/source/licenses.cpp b/source/licenses.cpp index c8aecbf..2f298b0 100644 --- a/source/licenses.cpp +++ b/source/licenses.cpp @@ -28,7 +28,7 @@ #include #endif -#if !defined(__NDS__) && !defined(__3DS__) && !defined(__SWITCH__) +#if !defined(__NDS__) && !defined(__3DS__) && !defined(__SWITCH__) && !defined (__wii__) && !defined(__gamecube__) #include #endif diff --git a/source/log.cpp b/source/log.cpp index 63d85a4..362884a 100644 --- a/source/log.cpp +++ b/source/log.cpp @@ -75,7 +75,7 @@ struct Message /// \brief Log messages std::vector s_messages; -#ifndef __NDS__ +#if HAVE_MUTEX /// \brief Log lock platform::Mutex s_lock; #endif @@ -83,7 +83,7 @@ platform::Mutex s_lock; void drawLog () { -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = std::scoped_lock (s_lock); #endif @@ -157,10 +157,9 @@ void drawLog () #ifndef CLASSIC std::string getLog () { -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = std::scoped_lock (s_lock); #endif - if (s_messages.empty ()) return {}; @@ -244,18 +243,21 @@ void addLog (LogLevel const level_, char const *const fmt_, va_list ap_) #endif #ifndef __NDS__ - thread_local + #define BUFFER_SIZE 1024 +#else + #define BUFFER_SIZE 256 #endif - static char buffer[1024]; - std::vsnprintf (buffer, sizeof (buffer), fmt_, ap_); -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = std::scoped_lock (s_lock); #endif + static char buffer[BUFFER_SIZE]; + std::vsnprintf (buffer, sizeof (buffer), fmt_, ap_); + #ifndef NDEBUG - // std::fprintf (stderr, "%s", s_prefix[level_]); - // std::fputs (buffer, stderr); + std::fprintf (stderr, "%s", s_prefix[level_]); + std::fputs (buffer, stderr); #endif s_messages.emplace_back (level_, buffer); #ifdef CLASSIC @@ -278,12 +280,13 @@ void addLog (LogLevel const level_, std::string_view const message_) c = '?'; } -#ifndef __NDS__ +#if HAVE_MUTEX auto const lock = std::scoped_lock (s_lock); #endif + #ifndef NDEBUG - // std::fprintf (stderr, "%s", s_prefix[level_]); - // std::fwrite (msg.data (), 1, msg.size (), stderr); + std::fprintf (stderr, "%s", s_prefix[level_]); + std::fwrite (msg.data (), 1, msg.size (), stderr); #endif s_messages.emplace_back (level_, msg); #ifdef CLASSIC diff --git a/source/nds/platform.cpp b/source/nds/platform.cpp index 99314c4..cdb596c 100644 --- a/source/nds/platform.cpp +++ b/source/nds/platform.cpp @@ -30,6 +30,8 @@ #include #include +#include +#include #ifndef CLASSIC #error "NDS must be built in classic mode" @@ -168,3 +170,4 @@ void platform::exit () { powerOn (POWER_LCD); } + diff --git a/source/ogc/platform.cpp b/source/ogc/platform.cpp new file mode 100644 index 0000000..fbd9222 --- /dev/null +++ b/source/ogc/platform.cpp @@ -0,0 +1,130 @@ +// ftpd is a server implementation based on the following: +// - RFC 959 (https://tools.ietf.org/html/rfc959) +// - RFC 3659 (https://tools.ietf.org/html/rfc3659) +// - suggested implementation details from https://cr.yp.to/ftp/filesystem.html +// +// Copyright (C) 2020 Michael Theall +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#ifndef CLASSIC +#error "Wii and GameCube must be built in classic mode" +#endif + +#include "platform.h" + +#include "log.h" + +#include +#include + +#include +#include + +#include +#include +#include + +#ifdef __wii__ +#include +#endif + +#include + +#include +#include + +PrintConsole g_statusConsole; +PrintConsole g_logConsole; +PrintConsole g_sessionConsole; + + +static bool networkUp = false; + +namespace +{ + +static struct in_addr loc_ip, loc_netmask, loc_gateway; + +} + + +bool platform::networkVisible () +{ + return networkUp; +} + +bool platform::networkAddress (SockAddr &addr_) +{ + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_addr = loc_ip; + + addr_ = addr; + return true; +} + +bool platform::init () +{ + fatInitDefault (); + + VIDEO_Init(); +#ifdef __wii__ + WPAD_Init(); +#endif + consoleInit (&g_statusConsole); + consoleInit (&g_logConsole); + consoleInit (&g_sessionConsole); + + consoleSetWindow (&g_statusConsole, 1, 1, 80, 1); + consoleSetWindow (&g_logConsole, 1, 2, 80, 21); + consoleSetWindow (&g_sessionConsole, 1, 23, 80, 8); + consoleSelect(&g_sessionConsole); + printf(CONSOLE_ESC(46;1m) CONSOLE_ESC(2J)); + + int ret = if_configex ( &loc_ip, &loc_netmask, &loc_gateway, TRUE, 20); + if (ret>=0) { + networkUp = true; + } + + return true; +} + +bool platform::loop () +{ +#ifdef __wii__ + WPAD_ScanPads(); + + u32 pressed = WPAD_ButtonsDown(0); + + if ( pressed & WPAD_BUTTON_HOME ) return false; +#endif + return SYS_MainLoop(); +} + +void platform::render () +{ + VIDEO_WaitVSync(); +} + +void platform::exit () +{ +} + +std::string const &platform::hostname () +{ + static std::string const hostname = "wii-ftpd"; + return hostname; +} diff --git a/source/sockAddr.cpp b/source/sockAddr.cpp index 52f435e..657bb75 100644 --- a/source/sockAddr.cpp +++ b/source/sockAddr.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #ifdef __3DS__ static_assert (sizeof (sockaddr_storage) == 0x1c); @@ -370,13 +371,16 @@ char const *SockAddr::name (char *buffer_, std::size_t size_) const char const *SockAddr::name () const { -#ifdef __NDS__ - return inet_ntoa (reinterpret_cast (&m_addr)->sin_addr); +#if defined(__NDS__) + return inet_ntoa (reinterpret_cast (&m_addr)->sin_addr); #else +#if HAVE_TLS +thread_local +#endif #ifdef NO_IPV6 - thread_local static char buffer[INET_ADDRSTRLEN]; + static char buffer[INET_ADDRSTRLEN]; #else - thread_local static char buffer[INET6_ADDRSTRLEN]; + static char buffer[INET6_ADDRSTRLEN]; #endif return name (buffer, sizeof (buffer)); diff --git a/source/socket.cpp b/source/socket.cpp index ba340b1..391f2f4 100644 --- a/source/socket.cpp +++ b/source/socket.cpp @@ -83,7 +83,7 @@ UniqueSocket Socket::accept () int Socket::atMark () { -#ifdef __NDS__ +#if defined(__NDS__) || defined(__wii__) || defined(__gamecube__) errno = ENOSYS; return -1; #else @@ -163,7 +163,7 @@ bool Socket::shutdown (int const how_) bool Socket::setLinger (bool const enable_, std::chrono::seconds const time_) { -#ifdef __NDS__ +#if defined(__NDS__) || defined(__wii__) || defined(__gamecube__) (void)enable_; (void)time_; errno = ENOSYS; @@ -195,7 +195,7 @@ bool Socket::setNonBlocking (bool const nonBlocking_) auto const rc = ::ioctl (m_fd, FIONBIO, &enable); if (rc != 0) { - error ("fcntl(FIONBIO, %d): %s\n", nonBlocking_, std::strerror (errno)); + error ("iocntl(FIONBIO, %d): %s\n", nonBlocking_, std::strerror (errno)); return false; } #else diff --git a/source/switch/platform.cpp b/source/switch/platform.cpp index 4a6a41a..3471fcf 100644 --- a/source/switch/platform.cpp +++ b/source/switch/platform.cpp @@ -922,96 +922,3 @@ void platform::exit () } } -/////////////////////////////////////////////////////////////////////////// -/// \brief Platform thread pimpl -class platform::Thread::privateData_t -{ -public: - privateData_t () = default; - - /// \brief Parameterized constructor - /// \param func_ Thread entry point - privateData_t (std::function &&func_) : thread (std::move (func_)) - { - } - - /// \brief Underlying thread - std::thread thread; -}; - -/////////////////////////////////////////////////////////////////////////// -platform::Thread::~Thread () = default; - -platform::Thread::Thread () : m_d (new privateData_t ()) -{ -} - -platform::Thread::Thread (std::function &&func_) - : m_d (new privateData_t (std::move (func_))) -{ -} - -platform::Thread::Thread (Thread &&that_) : m_d (new privateData_t ()) -{ - std::swap (m_d, that_.m_d); -} - -platform::Thread &platform::Thread::operator= (Thread &&that_) -{ - std::swap (m_d, that_.m_d); - return *this; -} - -void platform::Thread::join () -{ - m_d->thread.join (); -} - -void platform::Thread::sleep (std::chrono::milliseconds const timeout_) -{ - std::this_thread::sleep_for (timeout_); -} - -/////////////////////////////////////////////////////////////////////////// -#define USE_STD_MUTEX 1 - -/// \brief Platform mutex pimpl -class platform::Mutex::privateData_t -{ -public: -#if USE_STD_MUTEX - /// \brief Underlying mutex - std::mutex mutex; -#else - /// \brief Underlying mutex - ::Mutex mutex; -#endif -}; - -/////////////////////////////////////////////////////////////////////////// -platform::Mutex::~Mutex () = default; - -platform::Mutex::Mutex () : m_d (new privateData_t ()) -{ -#if !USE_STD_MUTEX - mutexInit (&m_d->mutex); -#endif -} - -void platform::Mutex::lock () -{ -#if USE_STD_MUTEX - m_d->mutex.lock (); -#else - mutexLock (&m_d->mutex); -#endif -} - -void platform::Mutex::unlock () -{ -#if USE_STD_MUTEX - m_d->mutex.unlock (); -#else - mutexUnlock (&m_d->mutex); -#endif -}