mirror of
https://github.com/mtheall/ftpd.git
synced 2024-11-26 19:20:31 +00:00
Add access point for Switch
This commit is contained in:
parent
852669818d
commit
709e24d458
@ -86,7 +86,7 @@ LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) \
|
||||
CC := `which ccache 2>/dev/null` $(CC)
|
||||
CXX := `which ccache 2>/dev/null` $(CXX)
|
||||
|
||||
LIBS := `$(PREFIX)pkg-config --libs libzstd` -ldeko3dd -lnx
|
||||
LIBS := `$(PREFIX)pkg-config --libs libzstd` -ldeko3d -lnx
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
|
@ -20,8 +20,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
class FtpConfig;
|
||||
@ -40,6 +43,10 @@ public:
|
||||
/// \param path_ Path to config file
|
||||
static UniqueFtpConfig load (char const *path_);
|
||||
|
||||
#ifndef NDS
|
||||
std::lock_guard<platform::Mutex> lockGuard ();
|
||||
#endif
|
||||
|
||||
/// \brief Save config
|
||||
/// \param path_ Path to config file
|
||||
bool save (char const *path_);
|
||||
@ -59,6 +66,17 @@ public:
|
||||
bool getMTime () const;
|
||||
#endif
|
||||
|
||||
#ifdef __SWITCH__
|
||||
/// \brief Whether to enable access point
|
||||
bool enableAP () const;
|
||||
|
||||
/// \brief Access point SSID
|
||||
std::string const &ssid () const;
|
||||
|
||||
/// \brief Access point passphrase
|
||||
std::string const &passphrase () const;
|
||||
#endif
|
||||
|
||||
/// \brief Set user
|
||||
/// \param user_ User
|
||||
void setUser (std::string const &user_);
|
||||
@ -81,9 +99,28 @@ public:
|
||||
void setGetMTime (bool getMTime_);
|
||||
#endif
|
||||
|
||||
#ifdef __SWITCH__
|
||||
/// \brief Set whether to enable access point
|
||||
/// \param enable_ Whether to enable access point
|
||||
void setEnableAP (bool enable_);
|
||||
|
||||
/// \brief Set access point SSID
|
||||
/// \param ssid_ SSID
|
||||
void setSSID (std::string const &ssid_);
|
||||
|
||||
/// \brief Set access point passphrase
|
||||
/// \param passphrase_ Passphrase
|
||||
void setPassphrase (std::string const &passphrase_);
|
||||
#endif
|
||||
|
||||
private:
|
||||
FtpConfig ();
|
||||
|
||||
#ifndef NDS
|
||||
/// \brief Mutex
|
||||
mutable platform::Mutex m_lock;
|
||||
#endif
|
||||
|
||||
/// \brief Username
|
||||
std::string m_user;
|
||||
|
||||
@ -97,4 +134,15 @@ private:
|
||||
/// \brief Whether to get mtime
|
||||
bool m_getMTime = true;
|
||||
#endif
|
||||
|
||||
#ifdef __SWITCH__
|
||||
/// \brief Whether to enable access point
|
||||
bool m_enableAP = false;
|
||||
|
||||
/// \brief Access point SSID
|
||||
std::string m_ssid = "ftpd";
|
||||
|
||||
/// \brief Access point passphrase
|
||||
std::string m_passphrase;
|
||||
#endif
|
||||
};
|
||||
|
@ -67,6 +67,7 @@ private:
|
||||
/// \brief Handle when network is lost
|
||||
void handleNetworkLost ();
|
||||
|
||||
#ifndef CLASSIC
|
||||
/// \brief Show menu in the current window
|
||||
void showMenu ();
|
||||
|
||||
@ -75,6 +76,7 @@ private:
|
||||
|
||||
/// \brief Show about window
|
||||
void showAbout ();
|
||||
#endif
|
||||
|
||||
/// \brief Server loop
|
||||
void loop ();
|
||||
@ -108,6 +110,12 @@ private:
|
||||
#ifndef CLASSIC
|
||||
/// \brief Whether to show settings menu
|
||||
bool m_showSettings = false;
|
||||
|
||||
#ifdef __SWITCH__
|
||||
/// \brief Whether to show access point menu
|
||||
bool m_showAP = false;
|
||||
#endif
|
||||
|
||||
/// \brief Whether to show about window
|
||||
bool m_showAbout = false;
|
||||
|
||||
@ -124,5 +132,19 @@ private:
|
||||
/// \brief getMTime setting
|
||||
bool m_getMTimeSetting;
|
||||
#endif
|
||||
|
||||
#ifdef __SWITCH__
|
||||
/// \brief Whether an error occurred enabling access point
|
||||
std::atomic<bool> m_apError = false;
|
||||
|
||||
/// \brief Enable access point setting
|
||||
bool m_enableAPSetting;
|
||||
|
||||
/// \brief Access point SSID setting
|
||||
std::string m_ssidSetting;
|
||||
|
||||
/// \brief Access point passphrase setting
|
||||
std::string m_passphraseSetting;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
@ -20,6 +20,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sockAddr.h"
|
||||
|
||||
#if defined(NDS)
|
||||
#include <nds.h>
|
||||
#elif defined(_3DS)
|
||||
@ -44,9 +46,31 @@ namespace platform
|
||||
/// \brief Initialize platform
|
||||
bool init ();
|
||||
|
||||
#ifdef __SWITCH__
|
||||
/// \brief Enable access point
|
||||
/// \param enable_ Whether to enable access point
|
||||
/// \param ssid_ SSID
|
||||
/// \param passphrase_ Passphrase
|
||||
bool enableAP (bool enable_, std::string const &ssid_, std::string const &passphrase_);
|
||||
|
||||
/// \brief Check if SSID is valid
|
||||
/// \param ssid_ SSID to check
|
||||
/// \returns empty string on success, error message on failure
|
||||
char const *validateSSID (std::string const &ssid_);
|
||||
|
||||
/// \brief Check if passphrase is valid
|
||||
/// \param passphrase_ Passphrase to check
|
||||
/// \returns empty string on success, error message on failure
|
||||
char const *validatePassphrase (std::string const &passphrase_);
|
||||
#endif
|
||||
|
||||
/// \brief Whether network is visible
|
||||
bool networkVisible ();
|
||||
|
||||
/// \brief Get network address
|
||||
/// \param[out] addr_ Network address
|
||||
bool networkAddress (SockAddr &addr_);
|
||||
|
||||
/// \brief Platform loop
|
||||
bool loop ();
|
||||
|
||||
|
@ -94,8 +94,12 @@ public:
|
||||
/// \brief Address port
|
||||
std::uint16_t port () const;
|
||||
|
||||
/// \brief Set address port
|
||||
/// \param port_ Port to set
|
||||
bool setPort (std::uint16_t port_);
|
||||
|
||||
/// \brief Address name
|
||||
/// \param buffer_
|
||||
/// \param buffer_ Buffer to hold name
|
||||
/// \param size_ Size of buffer_
|
||||
/// \retval buffer_ success
|
||||
/// \retval nullptr failure
|
||||
|
@ -165,7 +165,7 @@ void handleAPTHook (APT_HookType const type_, void *const param_)
|
||||
bool getNetworkVisibility ()
|
||||
{
|
||||
// serialize ac:u access from multiple threads
|
||||
auto lock = std::scoped_lock (s_acuFence);
|
||||
auto lock = std::lock_guard (s_acuFence);
|
||||
|
||||
// get wifi status
|
||||
std::uint32_t wifi = 0;
|
||||
@ -428,6 +428,16 @@ bool platform::networkVisible ()
|
||||
return getNetworkVisibility ();
|
||||
}
|
||||
|
||||
bool platform::networkAddress (SockAddr &addr_)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = gethostid ();
|
||||
|
||||
addr_ = addr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool platform::loop ()
|
||||
{
|
||||
if (!aptMainLoop ())
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <limits>
|
||||
#include <mutex>
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -162,6 +163,21 @@ UniqueFtpConfig FtpConfig::load (char const *const path_)
|
||||
else
|
||||
error ("Invalid value for mtime: %s\n", val.c_str ());
|
||||
}
|
||||
#endif
|
||||
#ifdef __SWITCH__
|
||||
else if (key == "ap")
|
||||
{
|
||||
if (val == "0")
|
||||
config->m_enableAP = false;
|
||||
else if (val == "1")
|
||||
config->m_enableAP = true;
|
||||
else
|
||||
error ("Invalid value for ap: %s\n", val.c_str ());
|
||||
}
|
||||
else if (key == "ssid")
|
||||
config->m_ssid = val;
|
||||
else if (key == "passphrase")
|
||||
config->m_passphrase = val;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -170,6 +186,13 @@ UniqueFtpConfig FtpConfig::load (char const *const path_)
|
||||
return config;
|
||||
}
|
||||
|
||||
#ifndef NDS
|
||||
std::lock_guard<platform::Mutex> FtpConfig::lockGuard ()
|
||||
{
|
||||
return std::lock_guard<platform::Mutex> (m_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool FtpConfig::save (char const *const path_)
|
||||
{
|
||||
if (!mkdirParent (path_))
|
||||
@ -189,6 +212,14 @@ bool FtpConfig::save (char const *const path_)
|
||||
std::fprintf (fp, "mtime=%u\n", m_getMTime);
|
||||
#endif
|
||||
|
||||
#ifdef __SWITCH__
|
||||
std::fprintf (fp, "ap=%u\n", m_enableAP);
|
||||
if (!m_ssid.empty ())
|
||||
std::fprintf (fp, "ssid=%s\n", m_ssid.c_str ());
|
||||
if (!m_passphrase.empty ())
|
||||
std::fprintf (fp, "passphrase=%s\n", m_passphrase.c_str ());
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -214,6 +245,23 @@ bool FtpConfig::getMTime () const
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __SWITCH__
|
||||
bool FtpConfig::enableAP () const
|
||||
{
|
||||
return m_enableAP;
|
||||
}
|
||||
|
||||
std::string const &FtpConfig::ssid () const
|
||||
{
|
||||
return m_ssid;
|
||||
}
|
||||
|
||||
std::string const &FtpConfig::passphrase () const
|
||||
{
|
||||
return m_passphrase;
|
||||
}
|
||||
#endif
|
||||
|
||||
void FtpConfig::setUser (std::string const &user_)
|
||||
{
|
||||
m_user = user_.substr (0, user_.find_first_of ('\0'));
|
||||
@ -255,3 +303,20 @@ void FtpConfig::setGetMTime (bool const getMTime_)
|
||||
m_getMTime = getMTime_;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __SWITCH__
|
||||
void FtpConfig::setEnableAP (bool const enable_)
|
||||
{
|
||||
m_enableAP = enable_;
|
||||
}
|
||||
|
||||
void FtpConfig::setSSID (std::string const &ssid_)
|
||||
{
|
||||
m_ssid = ssid_.substr (0, ssid_.find_first_of ('\0'));
|
||||
}
|
||||
|
||||
void FtpConfig::setPassphrase (std::string const &passphrase_)
|
||||
{
|
||||
m_passphrase = passphrase_.substr (0, passphrase_.find_first_of ('\0'));
|
||||
}
|
||||
#endif
|
||||
|
@ -36,10 +36,12 @@
|
||||
#include <sys/statvfs.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cctype>
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <mutex>
|
||||
#include <string_view>
|
||||
#include <thread>
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
@ -49,7 +51,7 @@ using namespace std::chrono_literals;
|
||||
#define LOCKED(x) \
|
||||
do \
|
||||
{ \
|
||||
auto const lock = std::scoped_lock (m_lock); \
|
||||
auto const lock = std::lock_guard (m_lock); \
|
||||
x; \
|
||||
} while (0)
|
||||
#endif
|
||||
@ -95,7 +97,7 @@ void FtpServer::draw ()
|
||||
{
|
||||
char port[7];
|
||||
#ifndef NDS
|
||||
auto lock = std::scoped_lock (m_lock);
|
||||
auto const lock = std::lock_guard (m_lock);
|
||||
#endif
|
||||
if (m_socket)
|
||||
std::sprintf (port, ":%u", m_socket->sockName ().port ());
|
||||
@ -120,7 +122,7 @@ void FtpServer::draw ()
|
||||
|
||||
{
|
||||
#ifndef NDS
|
||||
auto const lock = std::scoped_lock (s_lock);
|
||||
auto const lock = std::lock_guard (s_lock);
|
||||
#endif
|
||||
if (!s_freeSpace.empty ())
|
||||
{
|
||||
@ -134,7 +136,7 @@ void FtpServer::draw ()
|
||||
|
||||
{
|
||||
#ifndef NDS
|
||||
auto lock = std::scoped_lock (m_lock);
|
||||
auto const lock = std::lock_guard (m_lock);
|
||||
#endif
|
||||
consoleSelect (&g_sessionConsole);
|
||||
std::fputs ("\x1b[2J", stdout);
|
||||
@ -164,7 +166,7 @@ void FtpServer::draw ()
|
||||
char title[64];
|
||||
|
||||
{
|
||||
auto const serverLock = std::scoped_lock (m_lock);
|
||||
auto const serverLock = std::lock_guard (m_lock);
|
||||
std::snprintf (title,
|
||||
sizeof (title),
|
||||
STATUS_STRING " %s###ftpd",
|
||||
@ -210,7 +212,7 @@ void FtpServer::draw ()
|
||||
#endif
|
||||
|
||||
{
|
||||
auto lock = std::scoped_lock (m_lock);
|
||||
auto const lock = std::lock_guard (m_lock);
|
||||
for (auto &session : m_sessions)
|
||||
session->draw ();
|
||||
}
|
||||
@ -231,7 +233,7 @@ UniqueFtpServer FtpServer::create ()
|
||||
std::string FtpServer::getFreeSpace ()
|
||||
{
|
||||
#ifndef NDS
|
||||
auto const lock = std::scoped_lock (s_lock);
|
||||
auto const lock = std::lock_guard (s_lock);
|
||||
#endif
|
||||
return s_freeSpace;
|
||||
}
|
||||
@ -249,7 +251,7 @@ void FtpServer::updateFreeSpace ()
|
||||
auto freeSpace = fs::printSize (static_cast<std::uint64_t> (st.f_bsize) * st.f_bfree);
|
||||
|
||||
#ifndef NDS
|
||||
auto const lock = std::scoped_lock (s_lock);
|
||||
auto const lock = std::lock_guard (s_lock);
|
||||
#endif
|
||||
if (freeSpace != s_freeSpace)
|
||||
s_freeSpace = std::move (freeSpace);
|
||||
@ -262,22 +264,26 @@ std::time_t FtpServer::startTime ()
|
||||
|
||||
void FtpServer::handleNetworkFound ()
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
#if defined(NDS)
|
||||
addr.sin_addr = Wifi_GetIPInfo (nullptr, nullptr, nullptr, nullptr);
|
||||
#elif defined(_3DS) || defined(__SWITCH__)
|
||||
addr.sin_addr.s_addr = gethostid ();
|
||||
#else
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
SockAddr addr;
|
||||
if (!platform::networkAddress (addr))
|
||||
return;
|
||||
|
||||
std::uint16_t port;
|
||||
|
||||
{
|
||||
#ifndef NDS
|
||||
auto const lock = m_config->lockGuard ();
|
||||
#endif
|
||||
addr.sin_port = htons (m_config->port ());
|
||||
port = m_config->port ();
|
||||
}
|
||||
|
||||
addr.setPort (port);
|
||||
|
||||
auto socket = Socket::create ();
|
||||
if (!socket)
|
||||
return;
|
||||
|
||||
if (m_config->port () != 0 && !socket->setReuseAddress (true))
|
||||
if (port != 0 && !socket->setReuseAddress (true))
|
||||
return;
|
||||
|
||||
if (!socket->bind (addr))
|
||||
@ -290,7 +296,7 @@ void FtpServer::handleNetworkFound ()
|
||||
auto const name = sockName.name ();
|
||||
|
||||
m_name.resize (std::strlen (name) + 3 + 5);
|
||||
m_name.resize (std::sprintf (&m_name[0], "[%s]:%u", name, sockName.port ()));
|
||||
m_name.resize (std::sprintf (m_name.data (), "[%s]:%u", name, sockName.port ()));
|
||||
|
||||
info ("Started server at %s\n", m_name.c_str ());
|
||||
|
||||
@ -314,9 +320,9 @@ void FtpServer::handleNetworkLost ()
|
||||
info ("Stopped server at %s\n", m_name.c_str ());
|
||||
}
|
||||
|
||||
#ifndef CLASSIC
|
||||
void FtpServer::showMenu ()
|
||||
{
|
||||
#ifndef CLASSIC
|
||||
auto const prevShowSettings = m_showSettings;
|
||||
auto const prevShowAbout = m_showAbout;
|
||||
|
||||
@ -343,6 +349,10 @@ void FtpServer::showMenu ()
|
||||
{
|
||||
if (!prevShowSettings)
|
||||
{
|
||||
#ifndef NDS
|
||||
auto const lock = m_config->lockGuard ();
|
||||
#endif
|
||||
|
||||
m_userSetting = m_config->user ();
|
||||
m_userSetting.resize (32);
|
||||
|
||||
@ -355,7 +365,16 @@ void FtpServer::showMenu ()
|
||||
m_getMTimeSetting = m_config->getMTime ();
|
||||
#endif
|
||||
|
||||
info ("Open \"Settings\" popup\n");
|
||||
#ifdef __SWITCH__
|
||||
m_enableAPSetting = m_config->enableAP ();
|
||||
|
||||
m_ssidSetting = m_config->ssid ();
|
||||
m_ssidSetting.resize (19);
|
||||
|
||||
m_passphraseSetting = m_config->passphrase ();
|
||||
m_passphraseSetting.resize (63);
|
||||
#endif
|
||||
|
||||
ImGui::OpenPopup ("Settings");
|
||||
}
|
||||
|
||||
@ -373,7 +392,6 @@ void FtpServer::showMenu ()
|
||||
|
||||
void FtpServer::showSettings ()
|
||||
{
|
||||
#ifndef CLASSIC
|
||||
#ifdef _3DS
|
||||
auto const &io = ImGui::GetIO ();
|
||||
auto const width = io.DisplaySize.x;
|
||||
@ -388,11 +406,13 @@ void FtpServer::showSettings ()
|
||||
if (ImGui::BeginPopupModal ("Settings", nullptr, ImGuiWindowFlags_AlwaysAutoResize))
|
||||
#endif
|
||||
{
|
||||
ImGui::InputText (
|
||||
"User", &m_userSetting[0], m_userSetting.size (), ImGuiInputTextFlags_AutoSelectAll);
|
||||
ImGui::InputText ("User",
|
||||
m_userSetting.data (),
|
||||
m_userSetting.size (),
|
||||
ImGuiInputTextFlags_AutoSelectAll);
|
||||
|
||||
ImGui::InputText ("Pass",
|
||||
&m_passSetting[0],
|
||||
m_passSetting.data (),
|
||||
m_passSetting.size (),
|
||||
ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_Password);
|
||||
|
||||
@ -408,6 +428,26 @@ void FtpServer::showSettings ()
|
||||
ImGui::Checkbox ("Get mtime", &m_getMTimeSetting);
|
||||
#endif
|
||||
|
||||
#ifdef __SWITCH__
|
||||
ImGui::Checkbox ("Enable Access Point", &m_enableAPSetting);
|
||||
|
||||
ImGui::InputText ("SSID",
|
||||
m_ssidSetting.data (),
|
||||
m_ssidSetting.size (),
|
||||
ImGuiInputTextFlags_AutoSelectAll);
|
||||
auto const ssidError = platform::validateSSID (m_ssidSetting);
|
||||
if (ssidError)
|
||||
ImGui::TextColored (ImVec4 (1.0f, 0.4f, 0.4f, 1.0f), ssidError);
|
||||
|
||||
ImGui::InputText ("Passphrase",
|
||||
m_passphraseSetting.data (),
|
||||
m_passphraseSetting.size (),
|
||||
ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_Password);
|
||||
auto const passphraseError = platform::validatePassphrase (m_passphraseSetting);
|
||||
if (passphraseError)
|
||||
ImGui::TextColored (ImVec4 (1.0f, 0.4f, 0.4f, 1.0f), passphraseError);
|
||||
#endif
|
||||
|
||||
auto const apply = ImGui::Button ("Apply", ImVec2 (100, 0));
|
||||
ImGui::SameLine ();
|
||||
auto const save = ImGui::Button ("Save", ImVec2 (100, 0));
|
||||
@ -419,6 +459,10 @@ void FtpServer::showSettings ()
|
||||
m_showSettings = false;
|
||||
ImGui::CloseCurrentPopup ();
|
||||
|
||||
#ifndef NDS
|
||||
auto const lock = m_config->lockGuard ();
|
||||
#endif
|
||||
|
||||
m_config->setUser (m_userSetting);
|
||||
m_config->setPass (m_passSetting);
|
||||
m_config->setPort (m_portSetting);
|
||||
@ -427,12 +471,24 @@ void FtpServer::showSettings ()
|
||||
m_config->setGetMTime (m_getMTimeSetting);
|
||||
#endif
|
||||
|
||||
#ifdef __SWITCH__
|
||||
m_config->setEnableAP (m_enableAPSetting);
|
||||
m_config->setSSID (m_ssidSetting);
|
||||
m_config->setPassphrase (m_passphraseSetting);
|
||||
m_apError = false;
|
||||
#endif
|
||||
|
||||
UniqueSocket socket;
|
||||
LOCKED (socket = std::move (m_socket));
|
||||
}
|
||||
|
||||
if (save && !m_config->save (FTPDCONFIG))
|
||||
error ("Failed to save config\n");
|
||||
{
|
||||
#ifndef NDS
|
||||
auto const lock = m_config->lockGuard ();
|
||||
#endif
|
||||
if (save && !m_config->save (FTPDCONFIG))
|
||||
error ("Failed to save config\n");
|
||||
}
|
||||
|
||||
if (apply || save || cancel)
|
||||
{
|
||||
@ -442,13 +498,10 @@ void FtpServer::showSettings ()
|
||||
|
||||
ImGui::EndPopup ();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void FtpServer::showAbout ()
|
||||
{
|
||||
#ifndef CLASSIC
|
||||
auto const &io = ImGui::GetIO ();
|
||||
auto const width = io.DisplaySize.x;
|
||||
auto const height = io.DisplaySize.y;
|
||||
@ -539,13 +592,31 @@ void FtpServer::showAbout ()
|
||||
|
||||
ImGui::EndPopup ();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void FtpServer::loop ()
|
||||
{
|
||||
if (!m_socket)
|
||||
{
|
||||
#ifdef __SWITCH__
|
||||
if (!m_apError)
|
||||
{
|
||||
bool enable;
|
||||
std::string ssid;
|
||||
std::string passphrase;
|
||||
|
||||
{
|
||||
auto const lock = m_config->lockGuard ();
|
||||
enable = m_config->enableAP ();
|
||||
ssid = m_config->ssid ();
|
||||
passphrase = m_config->passphrase ();
|
||||
}
|
||||
|
||||
m_apError = !platform::enableAP (enable, ssid, passphrase);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (platform::networkVisible ())
|
||||
handleNetworkFound ();
|
||||
}
|
||||
@ -582,7 +653,7 @@ void FtpServer::loop ()
|
||||
{
|
||||
// remove dead sessions
|
||||
#ifndef NDS
|
||||
auto lock = std::scoped_lock (m_lock);
|
||||
auto const lock = std::lock_guard (m_lock);
|
||||
#endif
|
||||
auto it = std::begin (m_sessions);
|
||||
while (it != std::end (m_sessions))
|
||||
|
@ -50,7 +50,7 @@ using namespace std::chrono_literals;
|
||||
#define LOCKED(x) \
|
||||
do \
|
||||
{ \
|
||||
auto const lock = std::scoped_lock (m_lock); \
|
||||
auto const lock = std::lock_guard (m_lock); \
|
||||
x; \
|
||||
} while (0)
|
||||
#endif
|
||||
@ -293,10 +293,15 @@ FtpSession::FtpSession (FtpConfig &config_, UniqueSocket commandSocket_)
|
||||
m_mlstUnixMode (false),
|
||||
m_devZero (false)
|
||||
{
|
||||
if (m_config.user ().empty ())
|
||||
m_authorizedUser = true;
|
||||
if (m_config.pass ().empty ())
|
||||
m_authorizedPass = true;
|
||||
{
|
||||
#ifndef NDS
|
||||
auto const lock = m_config.lockGuard ();
|
||||
#endif
|
||||
if (m_config.user ().empty ())
|
||||
m_authorizedUser = true;
|
||||
if (m_config.pass ().empty ())
|
||||
m_authorizedPass = true;
|
||||
}
|
||||
|
||||
char buffer[32];
|
||||
std::sprintf (buffer, "Session#%p", this);
|
||||
@ -313,7 +318,7 @@ FtpSession::FtpSession (FtpConfig &config_, UniqueSocket commandSocket_)
|
||||
bool FtpSession::dead ()
|
||||
{
|
||||
#ifndef NDS
|
||||
auto const lock = std::scoped_lock (m_lock);
|
||||
auto const lock = std::lock_guard (m_lock);
|
||||
#endif
|
||||
if (m_commandSocket || m_pasvSocket || m_dataSocket)
|
||||
return false;
|
||||
@ -324,7 +329,7 @@ bool FtpSession::dead ()
|
||||
void FtpSession::draw ()
|
||||
{
|
||||
#ifndef NDS
|
||||
auto const lock = std::scoped_lock (m_lock);
|
||||
auto const lock = std::lock_guard (m_lock);
|
||||
#endif
|
||||
|
||||
#ifdef CLASSIC
|
||||
@ -610,7 +615,7 @@ void FtpSession::setState (State const state_, bool const closePasv_, bool const
|
||||
{
|
||||
{
|
||||
#ifndef NDS
|
||||
auto lock = std::scoped_lock (m_lock);
|
||||
auto lock = std::lock_guard (m_lock);
|
||||
#endif
|
||||
|
||||
m_restartPosition = 0;
|
||||
@ -1673,7 +1678,13 @@ bool FtpSession::listTransfer ()
|
||||
else if (m_xferDirMode == XferDirMode::NLST)
|
||||
getmtime = false;
|
||||
|
||||
if (getmtime && m_config.getMTime ())
|
||||
{
|
||||
auto const lock = m_config.lockGuard ();
|
||||
if (!m_config.getMTime ())
|
||||
getmtime = false;
|
||||
}
|
||||
|
||||
if (getmtime)
|
||||
{
|
||||
std::uint64_t mtime = 0;
|
||||
auto const rc = archive_getmtime (fullPath.c_str (), &mtime);
|
||||
@ -2159,13 +2170,24 @@ void FtpSession::PASS (char const *args_)
|
||||
|
||||
m_authorizedPass = false;
|
||||
|
||||
if (!m_config.user ().empty () && !m_authorizedUser)
|
||||
std::string user;
|
||||
std::string pass;
|
||||
|
||||
{
|
||||
#ifndef NDS
|
||||
auto const lock = m_config.lockGuard ();
|
||||
#endif
|
||||
user = m_config.user ();
|
||||
pass = m_config.pass ();
|
||||
}
|
||||
|
||||
if (!user.empty () && !m_authorizedUser)
|
||||
{
|
||||
sendResponse ("430 User not authorized\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_config.pass ().empty () || m_config.pass () == args_)
|
||||
if (pass.empty () || pass == args_)
|
||||
{
|
||||
m_authorizedPass = true;
|
||||
sendResponse ("230 OK\r\n");
|
||||
@ -2544,19 +2566,40 @@ void FtpSession::SITE (char const *args_)
|
||||
|
||||
if (::strcasecmp (command.c_str (), "USER") == 0)
|
||||
{
|
||||
m_config.setUser (arg);
|
||||
{
|
||||
#ifndef NDS
|
||||
auto const lock = m_config.lockGuard ();
|
||||
#endif
|
||||
m_config.setUser (arg);
|
||||
}
|
||||
|
||||
sendResponse ("200 OK\r\n");
|
||||
return;
|
||||
}
|
||||
else if (::strcasecmp (command.c_str (), "PASS") == 0)
|
||||
{
|
||||
m_config.setPass (arg);
|
||||
{
|
||||
#ifndef NDS
|
||||
auto const lock = m_config.lockGuard ();
|
||||
#endif
|
||||
m_config.setPass (arg);
|
||||
}
|
||||
|
||||
sendResponse ("200 OK\r\n");
|
||||
return;
|
||||
}
|
||||
else if (::strcasecmp (command.c_str (), "PORT") == 0)
|
||||
{
|
||||
if (!m_config.setPort (arg))
|
||||
bool error = false;
|
||||
|
||||
{
|
||||
#ifndef NDS
|
||||
auto const lock = m_config.lockGuard ();
|
||||
#endif
|
||||
error = !m_config.setPort (arg);
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
sendResponse ("550 %s\r\n", std::strerror (errno));
|
||||
return;
|
||||
@ -2569,9 +2612,19 @@ void FtpSession::SITE (char const *args_)
|
||||
else if (::strcasecmp (command.c_str (), "MTIME") == 0)
|
||||
{
|
||||
if (arg == "0")
|
||||
{
|
||||
#ifndef NDS
|
||||
auto const lock = m_config.lockGuard ();
|
||||
#endif
|
||||
m_config.setGetMTime (false);
|
||||
}
|
||||
else if (arg == "1")
|
||||
{
|
||||
#ifndef NDS
|
||||
auto const lock = m_config.lockGuard ();
|
||||
#endif
|
||||
m_config.setGetMTime (true);
|
||||
}
|
||||
else
|
||||
{
|
||||
sendResponse ("550 %s\r\n", std::strerror (EINVAL));
|
||||
@ -2581,7 +2634,16 @@ void FtpSession::SITE (char const *args_)
|
||||
#endif
|
||||
else if (::strcasecmp (command.c_str (), "SAVE") == 0)
|
||||
{
|
||||
if (!m_config.save (FTPDCONFIG))
|
||||
bool error;
|
||||
|
||||
{
|
||||
#ifndef NDS
|
||||
auto const lock = m_config.lockGuard ();
|
||||
#endif
|
||||
error = !m_config.save (FTPDCONFIG);
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
sendResponse ("550 %s\r\n", std::strerror (errno));
|
||||
return;
|
||||
@ -2730,10 +2792,21 @@ void FtpSession::USER (char const *args_)
|
||||
|
||||
m_authorizedUser = false;
|
||||
|
||||
if (m_config.user ().empty () || m_config.user () == args_)
|
||||
std::string user;
|
||||
std::string pass;
|
||||
|
||||
{
|
||||
#ifndef NDS
|
||||
auto const lock = m_config.lockGuard ();
|
||||
#endif
|
||||
user = m_config.user ();
|
||||
pass = m_config.pass ();
|
||||
}
|
||||
|
||||
if (user.empty () || user == args_)
|
||||
{
|
||||
m_authorizedUser = true;
|
||||
if (m_config.pass ().empty ())
|
||||
if (pass.empty ())
|
||||
{
|
||||
sendResponse ("230 OK\r\n");
|
||||
return;
|
||||
|
@ -169,6 +169,16 @@ bool platform::networkVisible ()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool platform::networkAddress (SockAddr &addr_)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
addr_ = addr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool platform::loop ()
|
||||
{
|
||||
bool inactive;
|
||||
|
@ -79,7 +79,7 @@ platform::Mutex s_lock;
|
||||
void drawLog ()
|
||||
{
|
||||
#ifndef NDS
|
||||
auto const lock = std::scoped_lock (s_lock);
|
||||
auto const lock = std::lock_guard (s_lock);
|
||||
#endif
|
||||
|
||||
#ifdef CLASSIC
|
||||
@ -211,7 +211,7 @@ void addLog (LogLevel const level_, char const *const fmt_, va_list ap_)
|
||||
std::vsnprintf (buffer, sizeof (buffer), fmt_, ap_);
|
||||
|
||||
#ifndef NDS
|
||||
auto const lock = std::scoped_lock (s_lock);
|
||||
auto const lock = std::lock_guard (s_lock);
|
||||
#endif
|
||||
#ifndef NDEBUG
|
||||
// std::fprintf (stderr, "%s", s_prefix[level_]);
|
||||
@ -239,7 +239,7 @@ void addLog (LogLevel const level_, std::string_view const message_)
|
||||
}
|
||||
|
||||
#ifndef NDS
|
||||
auto const lock = std::scoped_lock (s_lock);
|
||||
auto const lock = std::lock_guard (s_lock);
|
||||
#endif
|
||||
#ifndef NDEBUG
|
||||
// std::fprintf (stderr, "%s", s_prefix[level_]);
|
||||
|
@ -73,6 +73,16 @@ bool platform::networkVisible ()
|
||||
return false;
|
||||
}
|
||||
|
||||
bool platform::networkAddress (SockAddr &addr_)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr = Wifi_GetIPInfo (nullptr, nullptr, nullptr, nullptr);
|
||||
|
||||
addr_ = addr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool platform::init ()
|
||||
{
|
||||
sassert (fatInitDefault (), "Failed to initialize fat");
|
||||
|
@ -107,6 +107,26 @@ SockAddr::operator struct sockaddr const * () const
|
||||
return reinterpret_cast<struct sockaddr const *> (&m_addr);
|
||||
}
|
||||
|
||||
bool SockAddr::setPort (std::uint16_t const port_)
|
||||
{
|
||||
switch (m_addr.ss_family)
|
||||
{
|
||||
case AF_INET:
|
||||
reinterpret_cast<struct sockaddr_in *> (&m_addr)->sin_port = htons (port_);
|
||||
return true;
|
||||
|
||||
#ifndef NO_IPV6
|
||||
case AF_INET6:
|
||||
reinterpret_cast<struct sockaddr_in6 *> (&m_addr)->sin6_port = htons (port_);
|
||||
return true;
|
||||
#endif
|
||||
|
||||
default:
|
||||
std::abort ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::uint16_t SockAddr::port () const
|
||||
{
|
||||
switch (m_addr.ss_family)
|
||||
|
@ -1372,7 +1372,7 @@ void updateKeyboard (HidKeyboardState const &kbState_, ImGuiIO &io_)
|
||||
io_.KeySuper = kbState_.modifiers & HidKeyboardModifier_Gui;
|
||||
|
||||
for (int i = 0; i < 256; ++i)
|
||||
io_.KeysDown[i] = kbState_.keys[i / 64] & (1 << (i % 64));
|
||||
io_.KeysDown[i] = kbState_.keys[i / 64] & (1ul << (i % 64));
|
||||
|
||||
static enum {
|
||||
INACTIVE,
|
||||
|
@ -53,13 +53,16 @@ namespace
|
||||
/// \brief Whether to power backlight
|
||||
bool s_backlight = true;
|
||||
|
||||
/// \brief Whether access point is active
|
||||
bool s_activeAP = false;
|
||||
|
||||
/// \brief Access point SSID
|
||||
std::string s_ssid;
|
||||
|
||||
/// \brief Applet hook cookie
|
||||
AppletHookCookie s_appletHookCookie;
|
||||
|
||||
#ifdef CLASSIC
|
||||
/// \brief Host address
|
||||
in_addr_t s_addr = 0;
|
||||
#else
|
||||
#ifndef CLASSIC
|
||||
/// \brief Texture index
|
||||
enum TextureIndex
|
||||
{
|
||||
@ -294,7 +297,7 @@ void loadTextures ()
|
||||
};
|
||||
|
||||
TextureInfo textureInfos[] = {
|
||||
// clang-format off
|
||||
// clang-format off
|
||||
TextureInfo (
|
||||
"romfs:/deko3d.12x12.astc.zst", DkImageFormat_RGBA_ASTC_12x12, LOGO_WIDTH, LOGO_HEIGHT),
|
||||
TextureInfo (
|
||||
@ -315,7 +318,7 @@ void loadTextures ()
|
||||
"romfs:/wifi2_icon.rgba.zst", DkImageFormat_RGBA8_Unorm, ICON_WIDTH, ICON_HEIGHT),
|
||||
TextureInfo (
|
||||
"romfs:/wifi3_icon.rgba.zst", DkImageFormat_RGBA8_Unorm, ICON_WIDTH, ICON_HEIGHT)
|
||||
// clang-format on
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
// create memblock for transfer (large enough for the largest source file)
|
||||
@ -503,28 +506,33 @@ void drawStatus ()
|
||||
{
|
||||
TextureIndex netIcon = AIRPLANE_ICON;
|
||||
|
||||
NifmInternetConnectionType type;
|
||||
std::uint32_t wifiStrength;
|
||||
NifmInternetConnectionStatus status;
|
||||
if (R_SUCCEEDED (nifmGetInternetConnectionStatus (&type, &wifiStrength, &status)))
|
||||
if (s_activeAP)
|
||||
netIcon = WIFI3_ICON;
|
||||
else
|
||||
{
|
||||
if (type == NifmInternetConnectionType_Ethernet)
|
||||
NifmInternetConnectionType type;
|
||||
std::uint32_t wifiStrength;
|
||||
NifmInternetConnectionStatus status;
|
||||
if (R_SUCCEEDED (nifmGetInternetConnectionStatus (&type, &wifiStrength, &status)))
|
||||
{
|
||||
if (status == NifmInternetConnectionStatus_Connected)
|
||||
netIcon = ETH_ICON;
|
||||
if (type == NifmInternetConnectionType_Ethernet)
|
||||
{
|
||||
if (status == NifmInternetConnectionStatus_Connected)
|
||||
netIcon = ETH_ICON;
|
||||
else
|
||||
netIcon = ETH_NONE_ICON;
|
||||
}
|
||||
else
|
||||
netIcon = ETH_NONE_ICON;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wifiStrength >= 3)
|
||||
netIcon = WIFI3_ICON;
|
||||
else if (wifiStrength == 2)
|
||||
netIcon = WIFI3_ICON;
|
||||
else if (wifiStrength == 1)
|
||||
netIcon = WIFI3_ICON;
|
||||
else if (wifiStrength == 0)
|
||||
netIcon = WIFI_NONE_ICON;
|
||||
{
|
||||
if (wifiStrength >= 3)
|
||||
netIcon = WIFI3_ICON;
|
||||
else if (wifiStrength == 2)
|
||||
netIcon = WIFI3_ICON;
|
||||
else if (wifiStrength == 1)
|
||||
netIcon = WIFI3_ICON;
|
||||
else if (wifiStrength == 0)
|
||||
netIcon = WIFI_NONE_ICON;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -547,6 +555,15 @@ void drawStatus ()
|
||||
pos, ImGui::GetColorU32 (ImGuiCol_Text), freeSpace.c_str ());
|
||||
}
|
||||
|
||||
if (s_activeAP)
|
||||
{
|
||||
auto const size = ImGui::CalcTextSize (s_ssid.c_str ());
|
||||
auto const ssidPos = ImVec2 (
|
||||
io.DisplaySize.x - style.FramePadding.x - size.x, 3 * style.FramePadding.y + size.y);
|
||||
ImGui::GetForegroundDrawList ()->AddText (
|
||||
ssidPos, ImGui::GetColorU32 (ImGuiCol_Text), s_ssid.c_str ());
|
||||
}
|
||||
|
||||
{
|
||||
// get current timestamp
|
||||
char timeBuffer[16];
|
||||
@ -598,22 +615,154 @@ bool platform::init ()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool platform::enableAP (bool const enableAP_,
|
||||
std::string const &ssid_,
|
||||
std::string const &passphrase_)
|
||||
{
|
||||
if (s_activeAP == enableAP_)
|
||||
return true;
|
||||
|
||||
if (enableAP_)
|
||||
{
|
||||
auto const ssidError = validateSSID (ssid_);
|
||||
if (ssidError)
|
||||
{
|
||||
error ("Access Point: %s\n", ssidError);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto const passphraseError = validatePassphrase (passphrase_);
|
||||
if (passphraseError)
|
||||
{
|
||||
error ("Access Point: %s\n", passphraseError);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto rc = lp2pInitialize (Lp2pServiceType_App);
|
||||
if (R_FAILED (rc))
|
||||
{
|
||||
error ("lp2pInitialize: 0x%x\n", rc);
|
||||
return false;
|
||||
}
|
||||
|
||||
Lp2pGroupInfo groupInfo;
|
||||
lp2pCreateGroupInfo (&groupInfo);
|
||||
|
||||
// set SSID
|
||||
lp2pGroupInfoSetServiceName (&groupInfo, ssid_.c_str ());
|
||||
|
||||
// enable WPA2-PSK
|
||||
s8 flags = 0;
|
||||
lp2pGroupInfoSetFlags (&groupInfo, &flags, 1);
|
||||
|
||||
// passphrase
|
||||
rc = lp2pGroupInfoSetPassphrase (&groupInfo, passphrase_.c_str ());
|
||||
if (R_FAILED (rc))
|
||||
{
|
||||
error ("lp2pGroupInfoSetPassphrase: 0x%x\n", rc);
|
||||
lp2pExit ();
|
||||
return false;
|
||||
}
|
||||
|
||||
// create group
|
||||
rc = lp2pCreateGroup (&groupInfo);
|
||||
if (R_FAILED (rc))
|
||||
{
|
||||
error ("lp2pCreateGroup: 0x%x\n", rc);
|
||||
lp2pExit ();
|
||||
return false;
|
||||
}
|
||||
|
||||
rc = lp2pGetGroupInfo (&groupInfo);
|
||||
if (R_FAILED (rc))
|
||||
{
|
||||
error ("lp2pGetGroupInfo: 0x%x\n", rc);
|
||||
lp2pDestroyGroup ();
|
||||
lp2pExit ();
|
||||
return false;
|
||||
}
|
||||
|
||||
s_ssid = std::string ("SSID: ") + groupInfo.service_name;
|
||||
|
||||
s_activeAP = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
lp2pDestroyGroup ();
|
||||
lp2pExit ();
|
||||
s_activeAP = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
char const *platform::validateSSID (std::string const &ssid_)
|
||||
{
|
||||
auto const ssid = std::string_view (ssid_).substr (0, ssid_.find_first_of ('\0'));
|
||||
|
||||
if (ssid.size () > 19)
|
||||
return "SSID too long";
|
||||
|
||||
for (auto const &c : ssid)
|
||||
{
|
||||
if (!std::isalnum (c) && c != '-')
|
||||
return "SSID can only contain alphanumeric and -";
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char const *platform::validatePassphrase (std::string const &passphrase_)
|
||||
{
|
||||
auto const passphrase =
|
||||
std::string_view (passphrase_).substr (0, passphrase_.find_first_of ('\0'));
|
||||
|
||||
if (passphrase.size () < 8)
|
||||
return "Passphrase too short";
|
||||
else if (passphrase.size () > 63)
|
||||
return "Passphrase too long";
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool platform::networkVisible ()
|
||||
{
|
||||
if (s_activeAP)
|
||||
return true;
|
||||
|
||||
NifmInternetConnectionType type;
|
||||
std::uint32_t wifi;
|
||||
NifmInternetConnectionStatus status;
|
||||
if (R_FAILED (nifmGetInternetConnectionStatus (&type, &wifi, &status)))
|
||||
return false;
|
||||
|
||||
#ifdef CLASSIC
|
||||
if (!s_addr)
|
||||
s_addr = gethostid ();
|
||||
#endif
|
||||
|
||||
return status == NifmInternetConnectionStatus_Connected;
|
||||
}
|
||||
|
||||
bool platform::networkAddress (SockAddr &addr_)
|
||||
{
|
||||
if (s_activeAP)
|
||||
{
|
||||
Lp2pIpConfig ipConfig;
|
||||
auto const rc = lp2pGetIpConfig (&ipConfig);
|
||||
if (R_FAILED (rc))
|
||||
{
|
||||
error ("lp2pGetIpConfig: 0x%x\n", rc);
|
||||
return false;
|
||||
}
|
||||
|
||||
addr_ = *reinterpret_cast<struct sockaddr_in *> (ipConfig.ip_addr);
|
||||
return true;
|
||||
}
|
||||
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = gethostid ();
|
||||
|
||||
addr_ = addr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool platform::loop ()
|
||||
{
|
||||
if (!appletMainLoop ())
|
||||
@ -672,7 +821,7 @@ void platform::render ()
|
||||
#else
|
||||
ImGui::Render ();
|
||||
|
||||
auto &io = ImGui::GetIO ();
|
||||
auto const &io = ImGui::GetIO ();
|
||||
|
||||
if (s_width != io.DisplaySize.x || s_height != io.DisplaySize.y)
|
||||
{
|
||||
@ -726,6 +875,13 @@ void platform::exit ()
|
||||
|
||||
if (!s_backlight)
|
||||
appletSetLcdBacklightOffEnabled (false);
|
||||
|
||||
if (s_activeAP)
|
||||
{
|
||||
lp2pDestroyGroup ();
|
||||
lp2pExit ();
|
||||
s_activeAP = false;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
Reference in New Issue
Block a user