Add log upload to hastebin

This commit is contained in:
Michael Theall 2022-10-03 21:52:19 -05:00
parent 16c59354da
commit 1db3c48ee4
14 changed files with 369 additions and 42 deletions

View File

@ -0,0 +1,74 @@
-----BEGIN CERTIFICATE-----
MIIFNzCCBN6gAwIBAgIQDY30H+7eX+UAL96D4Q4pCTAKBggqhkjOPQQDAjBKMQsw
CQYDVQQGEwJVUzEZMBcGA1UEChMQQ2xvdWRmbGFyZSwgSW5jLjEgMB4GA1UEAxMX
Q2xvdWRmbGFyZSBJbmMgRUNDIENBLTMwHhcNMjIwNzA2MDAwMDAwWhcNMjMwNzA2
MjM1OTU5WjB1MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQG
A1UEBxMNU2FuIEZyYW5jaXNjbzEZMBcGA1UEChMQQ2xvdWRmbGFyZSwgSW5jLjEe
MBwGA1UEAxMVc25pLmNsb3VkZmxhcmVzc2wuY29tMFkwEwYHKoZIzj0CAQYIKoZI
zj0DAQcDQgAEYORbsKsnHR3Fgl5NnfC69t+zjW+thQ8/EsuWWyfJ/BceQF8t1h26
EN6BRaMb1c5UTpX1tI5JMgaXxXpFtESRI6OCA3kwggN1MB8GA1UdIwQYMBaAFKXO
N+rrsHUOlGeItEX62SQQh5YfMB0GA1UdDgQWBBQQcujrZ4f9+4Oh6nEzkQZ52Dku
zzA+BgNVHREENzA1gg4qLmhhc3RlYmluLmNvbYIVc25pLmNsb3VkZmxhcmVzc2wu
Y29tggxoYXN0ZWJpbi5jb20wDgYDVR0PAQH/BAQDAgeAMB0GA1UdJQQWMBQGCCsG
AQUFBwMBBggrBgEFBQcDAjB7BgNVHR8EdDByMDegNaAzhjFodHRwOi8vY3JsMy5k
aWdpY2VydC5jb20vQ2xvdWRmbGFyZUluY0VDQ0NBLTMuY3JsMDegNaAzhjFodHRw
Oi8vY3JsNC5kaWdpY2VydC5jb20vQ2xvdWRmbGFyZUluY0VDQ0NBLTMuY3JsMD4G
A1UdIAQ3MDUwMwYGZ4EMAQICMCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuZGln
aWNlcnQuY29tL0NQUzB2BggrBgEFBQcBAQRqMGgwJAYIKwYBBQUHMAGGGGh0dHA6
Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBABggrBgEFBQcwAoY0aHR0cDovL2NhY2VydHMu
ZGlnaWNlcnQuY29tL0Nsb3VkZmxhcmVJbmNFQ0NDQS0zLmNydDAMBgNVHRMBAf8E
AjAAMIIBfwYKKwYBBAHWeQIEAgSCAW8EggFrAWkAdgDoPtDaPvUGNTLnVyi8iWvJ
A9PL0RFr7Otp4Xd9bQa9bgAAAYHRAkxAAAAEAwBHMEUCIAhr5wFeEo8D3dOu+FYr
8vljOnpEIvMuNJjB6iBOcuXWAiEA6pI8/KK1U9Ig+xlAsKsol7+btAokI6OzNxfN
VOVM3KQAdgA1zxkbv7FsV78PrUxtQsu7ticgJlHqP+Eq76gDwzvWTAAAAYHRAkxs
AAAEAwBHMEUCIDIOIZDfw+ITXL6KvYGCJJx8yxDk2uiMy9ixN3XIG6AKAiEArbT1
OhUlElPkGlwHWvcDXRnT24tKxP9WteDcCUD9W8QAdwC3Pvsk35xNunXyOcW6WPRs
XfxCz3qfNcSeHQmBJe20mQAAAYHRAkx3AAAEAwBIMEYCIQCptt9MYfIgiomqP9Xb
nXD2h3RK/11gtOTCzv+/qGKF9QIhANApIgtpOEeTIbXPXFJQBScB0NksARcRcBby
uoI1A2Y/MAoGCCqGSM49BAMCA0cAMEQCIFwUBWYQxZT+B0ItToj+mkoVTO1mDQox
ruuJ/G4Jmh4dAiA4ar4ImAlk4uptLNoZzxbc1m8CyHB2siaCDv3Lf7QktA==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDzTCCArWgAwIBAgIQCjeHZF5ftIwiTv0b7RQMPDANBgkqhkiG9w0BAQsFADBa
MQswCQYDVQQGEwJJRTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJl
clRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTIw
MDEyNzEyNDgwOFoXDTI0MTIzMTIzNTk1OVowSjELMAkGA1UEBhMCVVMxGTAXBgNV
BAoTEENsb3VkZmxhcmUsIEluYy4xIDAeBgNVBAMTF0Nsb3VkZmxhcmUgSW5jIEVD
QyBDQS0zMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEua1NZpkUC0bsH4HRKlAe
nQMVLzQSfS2WuIg4m4Vfj7+7Te9hRsTJc9QkT+DuHM5ss1FxL2ruTAUJd9NyYqSb
16OCAWgwggFkMB0GA1UdDgQWBBSlzjfq67B1DpRniLRF+tkkEIeWHzAfBgNVHSME
GDAWgBTlnVkwgkdYzKz6CFQ2hns6tQRN8DAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0l
BBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8CAQAwNAYI
KwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j
b20wOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL09t
bmlyb290MjAyNS5jcmwwbQYDVR0gBGYwZDA3BglghkgBhv1sAQEwKjAoBggrBgEF
BQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzALBglghkgBhv1sAQIw
CAYGZ4EMAQIBMAgGBmeBDAECAjAIBgZngQwBAgMwDQYJKoZIhvcNAQELBQADggEB
AAUkHd0bsCrrmNaF4zlNXmtXnYJX/OvoMaJXkGUFvhZEOFp3ArnPEELG4ZKk40Un
+ABHLGioVplTVI+tnkDB0A+21w0LOEhsUCxJkAZbZB2LzEgwLt4I4ptJIsCSDBFe
lpKU1fwg3FZs5ZKTv3ocwDfjhUkV+ivhdDkYD7fa86JXWGBPzI6UAPxGezQxPk1H
goE6y/SJXQ7vTQ1unBuCJN0yJV0ReFEQPaA1IwQvZW+cwdFD19Ae8zFnWSfda9J1
CZMRJCQUzym+5iPDuI9yP+kHyCREU3qzuWFloUwOxkgAyXVjBYdwRVKD05WdRerw
6DEdfgkfCv4+3ao8XnTSrLE=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
-----END CERTIFICATE-----

View File

@ -52,7 +52,7 @@ RSF_FILE := meta/ftpd-classic-cia.rsf
endif
APP_DESCRIPTION := v$(VERSION)
APP_AUTHOR := (c) 2021 Michael Theall, Dave Murphy, TuxSH
APP_AUTHOR := (c) 2022 Michael Theall, Dave Murphy, TuxSH
ICON := meta/icon.png
BNR_IMAGE := meta/banner.png
@ -72,9 +72,10 @@ CFLAGS += $(INCLUDE) -DARM11 -D__3DS__ \
-DSTATUS_STRING="\"ftpd v$(VERSION)\"" \
-DIMGUI_DISABLE_INCLUDE_IMCONFIG_H=1 \
-DNO_IPV6 -DFTPDCONFIG="\"/config/ftpd/ftpd.cfg\"" \
-DANTI_ALIAS=1
-DANTI_ALIAS=1 \
`curl-config --cflags`
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++2a
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) $(OPTIMIZE)
@ -82,7 +83,7 @@ LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) $(OPTIMIZE)
CC := `which ccache 2>/dev/null` $(CC)
CXX := `which ccache 2>/dev/null` $(CXX)
LIBS := -lcitro3d -lctru -lm
LIBS := `curl-config --libs` -lcitro3d -lctru -lm
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing

View File

@ -12,10 +12,11 @@ CPPFLAGS := -g -Wall -pthread -Iinclude -Isource/linux \
-DSTATUS_STRING="\"ftpd v$(VERSION)\"" \
-DIMGUI_DISABLE_INCLUDE_IMCONFIG_H=1 \
-DIMGUI_IMPL_OPENGL_LOADER_GLAD=1 \
-DFTPDCONFIG="\"ftpd.cfg\""
-DFTPDCONFIG="\"ftpd.cfg\"" \
`curl-config --cflags`
CFLAGS := $(CPPFLAGS)
CXXFLAGS := $(CPPFLAGS) -std=gnu++17
LDFLAGS := -pthread `pkg-config --libs gl glfw3` -ldl
CXXFLAGS := $(CPPFLAGS) -std=gnu++2a
LDFLAGS := -pthread `curl-config --libs` `pkg-config --libs gl glfw3` -ldl
.PHONY: all clean

View File

@ -35,7 +35,7 @@ NITRO :=
# These set the information text in the nds file
GAME_TITLE := ftpd classic
GAME_SUBTITLE1 := v$(VERSION)
GAME_SUBTITLE2 := (c) 2021 mtheall
GAME_SUBTITLE2 := (c) 2022 mtheall
#---------------------------------------------------------------------------------
# options for code generation
@ -48,7 +48,7 @@ CFLAGS := -g -Wall $(OPTIMIZE) \
-DSTATUS_STRING="\"ftpd v$(VERSION)\"" \
-DIMGUI_DISABLE_INCLUDE_IMCONFIG_H=1 \
-DNO_IPV6 -DCLASSIC -DFTPDCONFIG="\"/config/ftpd/ftpd.cfg\""
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++2a
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) $(OPTIMIZE)

View File

@ -37,7 +37,7 @@ include $(DEVKITPRO)/libnx/switch_rules
# of a homebrew executable (.nro). This is intended to be used for sysmodules.
# NACP building is skipped as well.
#---------------------------------------------------------------------------------
APP_AUTHOR := (c) 2021 Michael Theall, Dave Murphy, TuxSH
APP_AUTHOR := (c) 2022 Michael Theall, Dave Murphy, TuxSH
ICON := meta/ftpd.jpg
APP_VERSION := $(VERSION)
@ -75,9 +75,10 @@ CFLAGS += $(INCLUDE) -D__SWITCH__ \
-DSTATUS_STRING="\"ftpd v$(VERSION)\"" \
-DIMGUI_DISABLE_INCLUDE_IMCONFIG_H=1 \
-DFTPDCONFIG="\"/config/ftpd/ftpd.cfg\"" \
`$(PREFIX)pkg-config --cflags libzstd`
`$(PREFIX)pkg-config --cflags libzstd` \
`curl-config --cflags`
CXXFLAGS := $(CFLAGS) -std=gnu++17 -fno-exceptions -fno-rtti
CXXFLAGS := $(CFLAGS) -std=gnu++2a -fno-exceptions -fno-rtti
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) \
@ -86,7 +87,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` -ldeko3d -lnx
LIBS := `curl-config --libs` `$(PREFIX)pkg-config --libs libzstd` -ldeko3d -lnx
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing

View File

@ -3,7 +3,7 @@
// - RFC 3659 (https://tools.ietf.org/html/rfc3659)
// - suggested implementation details from https://cr.yp.to/ftp/filesystem.html
//
// Copyright (C) 2020 Michael Theall
// Copyright (C) 2022 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
@ -44,7 +44,7 @@ public:
static UniqueFtpConfig load (char const *path_);
#ifndef NDS
std::lock_guard<platform::Mutex> lockGuard ();
std::scoped_lock<platform::Mutex> lockGuard ();
#endif
/// \brief Save config

View File

@ -3,7 +3,7 @@
// - RFC 3659 (https://tools.ietf.org/html/rfc3659)
// - suggested implementation details from https://cr.yp.to/ftp/filesystem.html
//
// Copyright (C) 2020 Michael Theall
// Copyright (C) 2022 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
@ -25,6 +25,10 @@
#include "platform.h"
#include "socket.h"
#ifndef CLASSIC
#include <curl/curl.h>
#endif
#include <atomic>
#include <chrono>
#include <cstdint>
@ -107,6 +111,20 @@ private:
/// \brief Whether thread should quit
std::atomic<bool> m_quit;
#ifndef CLASSIC
/// \brief Log upload cURL context
CURLM *m_uploadLogCurlM = nullptr;
/// \brief Log upload mime context
curl_mime *m_uploadLogMime = nullptr;
/// \brief Log upload cURL context
std::atomic<CURL *> m_uploadLogCurl = nullptr;
/// \brief Log upload data
std::string m_uploadLogData;
/// \brief Log upload result
std::string m_uploadLogResult;
#endif
#ifndef CLASSIC
/// \brief Whether to show settings menu
bool m_showSettings = false;

View File

@ -3,7 +3,7 @@
// - RFC 3659 (https://tools.ietf.org/html/rfc3659)
// - suggested implementation details from https://cr.yp.to/ftp/filesystem.html
//
// Copyright (C) 2020 Michael Theall
// Copyright (C) 2022 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
@ -37,6 +37,11 @@ enum LogLevel
/// \brief Draw log
void drawLog ();
#ifndef CLASSIC
/// \brief Get log
std::string getLog ();
#endif
/// \brief Add debug message to bound log
/// \param fmt_ Message format
__attribute__ ((format (printf, 1, 2))) void debug (char const *fmt_, ...);

View File

@ -168,7 +168,7 @@ void handleAPTHook (APT_HookType const type_, void *const param_)
bool getNetworkVisibility ()
{
// serialize ac:u access from multiple threads
auto lock = std::lock_guard (s_acuFence);
auto const lock = std::scoped_lock (s_acuFence);
// get wifi status
std::uint32_t wifi = 0;

View File

@ -3,7 +3,7 @@
// - RFC 3659 (https://tools.ietf.org/html/rfc3659)
// - suggested implementation details from https://cr.yp.to/ftp/filesystem.html
//
// Copyright (C) 2021 Michael Theall
// Copyright (C) 2022 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
@ -187,9 +187,9 @@ UniqueFtpConfig FtpConfig::load (char const *const path_)
}
#ifndef NDS
std::lock_guard<platform::Mutex> FtpConfig::lockGuard ()
std::scoped_lock<platform::Mutex> FtpConfig::lockGuard ()
{
return std::lock_guard<platform::Mutex> (m_lock);
return std::scoped_lock<platform::Mutex> (m_lock);
}
#endif

View File

@ -3,7 +3,7 @@
// - RFC 3659 (https://tools.ietf.org/html/rfc3659)
// - suggested implementation details from https://cr.yp.to/ftp/filesystem.html
//
// Copyright (C) 2021 Michael Theall
// Copyright (C) 2022 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
@ -52,7 +52,7 @@ using namespace std::chrono_literals;
#define LOCKED(x) \
do \
{ \
auto const lock = std::lock_guard (m_lock); \
auto const lock = std::scoped_lock (m_lock); \
x; \
} while (0)
#endif
@ -69,6 +69,86 @@ platform::Mutex s_lock;
/// \brief Free space string
std::string s_freeSpace;
#ifndef CLASSIC
#ifndef NDEBUG
std::string printable (char *const data_, std::size_t const size_)
{
std::string result;
result.reserve (size_);
for (std::size_t i = 0; i < size_; ++i)
{
if (std::isprint (data_[i]) || std::isspace (data_[i]))
result.push_back (data_[i]);
else
{
char buffer[5];
std::snprintf (buffer, sizeof (buffer), "%%%02u", static_cast<unsigned char> (data_[i]));
result += buffer;
}
}
return result;
}
int curlDebug (CURL *const handle_, curl_infotype const type_, char *const data_, std::size_t const size_, void *const user_)
{
(void)user_;
auto const text = printable (data_, size_);
switch (type_)
{
case CURLINFO_TEXT:
info ("== Info: %s", text.c_str ());
break;
case CURLINFO_HEADER_OUT:
info ("=> Send header: %s", text.c_str ());
break;
case CURLINFO_DATA_OUT:
info ("=> Send data: %s", text.c_str ());
break;
case CURLINFO_SSL_DATA_OUT:
info ("=> Send SSL data: %s", text.c_str ());
break;
case CURLINFO_HEADER_IN:
info ("<= Receive header: %s", text.c_str ());
break;
case CURLINFO_DATA_IN:
info ("<= Receive data: %s", text.c_str ());
break;
case CURLINFO_SSL_DATA_IN:
info ("<= Receive SSL data: %s", text.c_str ());
break;
default:
break;
}
return 0;
}
#endif
std::size_t curlCallback (void *const contents_, std::size_t const size_, std::size_t const count_, void *const user_)
{
auto const total = size_ * count_;
auto const start = static_cast<char*> (contents_);
auto const end = start + total;
auto &result = *static_cast<std::string*> (user_);
result.insert (std::end (result), start, end);
return total;
}
#endif
}
///////////////////////////////////////////////////////////////////////////
@ -79,6 +159,18 @@ FtpServer::~FtpServer ()
#ifndef NDS
m_thread.join ();
#endif
#ifndef CLASSIC
if (m_uploadLogCurl)
{
curl_multi_remove_handle (m_uploadLogCurlM, m_uploadLogCurl);
curl_easy_cleanup (m_uploadLogCurl);
curl_mime_free (m_uploadLogMime);
}
if (m_uploadLogCurlM)
curl_multi_cleanup (m_uploadLogCurlM);
#endif
}
FtpServer::FtpServer (UniqueFtpConfig config_) : m_config (std::move (config_)), m_quit (false)
@ -98,7 +190,7 @@ void FtpServer::draw ()
{
char port[7];
#ifndef NDS
auto const lock = std::lock_guard (m_lock);
auto const lock = std::scoped_lock (m_lock);
#endif
if (m_socket)
std::sprintf (port, ":%u", m_socket->sockName ().port ());
@ -123,7 +215,7 @@ void FtpServer::draw ()
{
#ifndef NDS
auto const lock = std::lock_guard (s_lock);
auto const lock = std::scoped_lock (s_lock);
#endif
if (!s_freeSpace.empty ())
{
@ -137,7 +229,7 @@ void FtpServer::draw ()
{
#ifndef NDS
auto const lock = std::lock_guard (m_lock);
auto const lock = std::scoped_lock (m_lock);
#endif
consoleSelect (&g_sessionConsole);
std::fputs ("\x1b[2J", stdout);
@ -167,7 +259,7 @@ void FtpServer::draw ()
char title[64];
{
auto const serverLock = std::lock_guard (m_lock);
auto const serverLock = std::scoped_lock (m_lock);
std::snprintf (title,
sizeof (title),
STATUS_STRING " %s###ftpd",
@ -213,7 +305,7 @@ void FtpServer::draw ()
#endif
{
auto const lock = std::lock_guard (m_lock);
auto const lock = std::scoped_lock (m_lock);
for (auto &session : m_sessions)
session->draw ();
}
@ -234,7 +326,7 @@ UniqueFtpServer FtpServer::create ()
std::string FtpServer::getFreeSpace ()
{
#ifndef NDS
auto const lock = std::lock_guard (s_lock);
auto const lock = std::scoped_lock (s_lock);
#endif
return s_freeSpace;
}
@ -252,7 +344,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::lock_guard (s_lock);
auto const lock = std::scoped_lock (s_lock);
#endif
if (freeSpace != s_freeSpace)
s_freeSpace = std::move (freeSpace);
@ -330,7 +422,7 @@ void FtpServer::showMenu ()
if (ImGui::BeginMenuBar ())
{
#if defined(__3DS__) || defined(__SWITCH__)
if (ImGui::BeginMenu (u8"Menu \xee\x80\x83")) // Y Button
if (ImGui::BeginMenu ("Menu \xee\x80\x83")) // Y Button
#else
if (ImGui::BeginMenu ("Menu"))
#endif
@ -338,6 +430,58 @@ void FtpServer::showMenu ()
if (ImGui::MenuItem ("Settings"))
m_showSettings = true;
if (ImGui::MenuItem ("Upload Log"))
{
#ifndef NDS
auto const lock = std::scoped_lock (m_lock);
#endif
if (!m_uploadLogCurlM)
m_uploadLogCurlM = curl_multi_init ();
if (m_uploadLogCurlM && !m_uploadLogCurl.load (std::memory_order_relaxed))
{
m_uploadLogData = getLog ();
auto const handle = curl_easy_init ();
#ifdef __3DS__
// 3DS CA fails peer verification, so add CA here
curl_easy_setopt (handle, CURLOPT_CAINFO, "romfs:/sni.cloudflaressl.com.ca");
#endif
#ifndef NDEBUG
curl_easy_setopt (handle, CURLOPT_DEBUGFUNCTION, &curlDebug);
curl_easy_setopt (handle, CURLOPT_DEBUGDATA, nullptr);
curl_easy_setopt (handle, CURLOPT_VERBOSE, 1L);
#endif
// write result into string
m_uploadLogResult.clear ();
curl_easy_setopt (handle, CURLOPT_WRITEFUNCTION, &curlCallback);
curl_easy_setopt (handle, CURLOPT_WRITEDATA, &m_uploadLogResult);
// set headers
static char contentType[] = "Content-Type: multipart/form-data";
static curl_slist const headers = { contentType, nullptr };
curl_easy_setopt (handle, CURLOPT_URL, "https://hastebin.com/documents");
curl_easy_setopt (handle, CURLOPT_HTTPHEADER, &headers);
// set form data
auto const mime = curl_mime_init (handle);
auto const part = curl_mime_addpart (mime);
curl_mime_name (part, "data");
curl_mime_data (part, m_uploadLogData.data (), m_uploadLogData.size ());
curl_easy_setopt (handle, CURLOPT_MIMEPOST, mime);
// add to multi handle
curl_multi_add_handle (m_uploadLogCurlM, handle);
// signal network thread to process
m_uploadLogMime = mime;
m_uploadLogCurl.store (handle, std::memory_order_relaxed);
}
}
if (ImGui::MenuItem ("About"))
m_showAbout = true;
@ -666,6 +810,49 @@ void FtpServer::loop ()
handleNetworkFound ();
}
#ifndef CLASSIC
{
auto const lock = std::scoped_lock (m_lock);
if (m_uploadLogCurl.load (std::memory_order_relaxed))
{
int busy = 0;
auto const mc = curl_multi_perform (m_uploadLogCurlM, &busy);
if (mc != CURLM_OK)
{
error ("curl_multi_perform: %d %s\n", mc, curl_multi_strerror (mc));
curl_multi_remove_handle (m_uploadLogCurlM, m_uploadLogCurl);
curl_easy_cleanup (m_uploadLogCurl);
curl_mime_free (m_uploadLogMime);
m_uploadLogMime = nullptr;
m_uploadLogCurl.store (nullptr, std::memory_order_relaxed);
}
else
{
int count = 0;
auto const msg = curl_multi_info_read (m_uploadLogCurlM, &count);
if (msg && msg->msg == CURLMSG_DONE && msg->easy_handle == m_uploadLogCurl)
{
if (msg->data.result != CURLE_OK)
info ("cURL finished with status %d\n", msg->data.result);
if (m_uploadLogResult.starts_with ("{\"key\":\""))
{
auto const key = m_uploadLogResult.substr (8, 10);
info ("https://hastebin.com/%s\n", key.c_str ());
}
curl_multi_remove_handle (m_uploadLogCurlM, m_uploadLogCurl);
curl_easy_cleanup (m_uploadLogCurl);
curl_mime_free (m_uploadLogMime);
m_uploadLogMime = nullptr;
m_uploadLogCurl.store (nullptr, std::memory_order_relaxed);
}
}
}
}
#endif
// poll listen socket
if (m_socket)
{
@ -698,7 +885,7 @@ void FtpServer::loop ()
{
// remove dead sessions
#ifndef NDS
auto const lock = std::lock_guard (m_lock);
auto const lock = std::scoped_lock (m_lock);
#endif
auto it = std::begin (m_sessions);
while (it != std::end (m_sessions))

View File

@ -3,7 +3,7 @@
// - RFC 3659 (https://tools.ietf.org/html/rfc3659)
// - suggested implementation details from https://cr.yp.to/ftp/filesystem.html
//
// Copyright (C) 2020 Michael Theall
// Copyright (C) 2022 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
@ -50,7 +50,7 @@ using namespace std::chrono_literals;
#define LOCKED(x) \
do \
{ \
auto const lock = std::lock_guard (m_lock); \
auto const lock = std::scoped_lock (m_lock); \
x; \
} while (0)
#endif
@ -318,7 +318,7 @@ FtpSession::FtpSession (FtpConfig &config_, UniqueSocket commandSocket_)
bool FtpSession::dead ()
{
#ifndef NDS
auto const lock = std::lock_guard (m_lock);
auto const lock = std::scoped_lock (m_lock);
#endif
if (m_commandSocket || m_pasvSocket || m_dataSocket)
return false;
@ -329,7 +329,7 @@ bool FtpSession::dead ()
void FtpSession::draw ()
{
#ifndef NDS
auto const lock = std::lock_guard (m_lock);
auto const lock = std::scoped_lock (m_lock);
#endif
#ifdef CLASSIC
@ -615,7 +615,7 @@ void FtpSession::setState (State const state_, bool const closePasv_, bool const
{
{
#ifndef NDS
auto lock = std::lock_guard (m_lock);
auto const lock = std::scoped_lock (m_lock);
#endif
m_restartPosition = 0;

View File

@ -3,7 +3,7 @@
// - RFC 3659 (https://tools.ietf.org/html/rfc3659)
// - suggested implementation details from https://cr.yp.to/ftp/filesystem.html
//
// Copyright (C) 2020 Michael Theall
// Copyright (C) 2022 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
@ -25,6 +25,7 @@
#include "imgui.h"
#include <mutex>
#include <ranges>
#include <vector>
namespace
@ -79,7 +80,7 @@ platform::Mutex s_lock;
void drawLog ()
{
#ifndef NDS
auto const lock = std::lock_guard (s_lock);
auto const lock = std::scoped_lock (s_lock);
#endif
#ifdef CLASSIC
@ -149,6 +150,39 @@ void drawLog ()
#endif
}
#ifndef CLASSIC
std::string getLog ()
{
#ifndef NDS
auto const lock = std::scoped_lock (s_lock);
#endif
if (s_messages.empty ())
return {};
std::vector<Message const *> stack;
stack.reserve (s_messages.size ());
std::size_t size = 0;
for (auto const &msg : s_messages | std::views::reverse)
{
if (size + msg.message.size () > 1024 * 1024)
break;
size += msg.message.size ();
stack.emplace_back (&msg);
}
std::string log;
log.reserve (size);
for (auto const &msg : stack | std::views::reverse)
log += msg->message;
return log;
}
#endif
void debug (char const *const fmt_, ...)
{
#ifndef NDEBUG
@ -211,7 +245,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::lock_guard (s_lock);
auto const lock = std::scoped_lock (s_lock);
#endif
#ifndef NDEBUG
// std::fprintf (stderr, "%s", s_prefix[level_]);
@ -239,7 +273,7 @@ void addLog (LogLevel const level_, std::string_view const message_)
}
#ifndef NDS
auto const lock = std::lock_guard (s_lock);
auto const lock = std::scoped_lock (s_lock);
#endif
#ifndef NDEBUG
// std::fprintf (stderr, "%s", s_prefix[level_]);

View File

@ -3,7 +3,7 @@
// - RFC 3659 (https://tools.ietf.org/html/rfc3659)
// - suggested implementation details from https://cr.yp.to/ftp/filesystem.html
//
// Copyright (C) 2020 Michael Theall
// Copyright (C) 2022 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
@ -24,12 +24,17 @@
#include "imgui.h"
#ifndef CLASSIC
#include <curl/curl.h>
#endif
#include <cstdio>
#include <cstdlib>
int main (int argc_, char *argv_[])
{
#ifndef CLASSIC
curl_global_init (CURL_GLOBAL_ALL);
IMGUI_CHECKVERSION ();
ImGui::CreateContext ();
#endif
@ -65,5 +70,6 @@ int main (int argc_, char *argv_[])
#ifndef CLASSIC
ImGui::DestroyContext ();
curl_global_cleanup ();
#endif
}