-modified the ftp server so it runs in a separate thread, meaning it can now run in the background

-added autostart ftp server to the startup settings
-added a new section, the [FTP] one to the wiiflow.ini, containing settings like autostart, password, port and allow active mode transfers
-updated english.ini
This commit is contained in:
fix94.1 2013-09-05 23:52:21 +00:00
parent d53c2a22a2
commit 4d03e0e2dc
15 changed files with 287 additions and 91 deletions

View File

@ -32,6 +32,7 @@
#include "loader/sys.h" #include "loader/sys.h"
#include "homebrew/homebrew.h" #include "homebrew/homebrew.h"
#include "memory/mem2.hpp" #include "memory/mem2.hpp"
#include "network/FTP_Dir.hpp"
#include "network/http.h" #include "network/http.h"
#include "plugin/crc32.h" #include "plugin/crc32.h"
@ -123,6 +124,7 @@ void ShutdownBeforeExit(void)
while(net_get_status() == -EBUSY) while(net_get_status() == -EBUSY)
usleep(50); usleep(50);
WiFiDebugger.Close(); WiFiDebugger.Close();
ftp_endTread();
net_deinit(); net_deinit();
networkInit = false; networkInit = false;
} }

View File

@ -26,6 +26,7 @@
#define PLUGIN_DOMAIN "EMULATOR" #define PLUGIN_DOMAIN "EMULATOR"
#define HOMEBREW_DOMAIN "HOMEBREW" #define HOMEBREW_DOMAIN "HOMEBREW"
#define MUSIC_DOMAIN "MUSIC" #define MUSIC_DOMAIN "MUSIC"
#define FTP_DOMAIN "FTP"
#define AGE_LOCK_DEFAULT 13 #define AGE_LOCK_DEFAULT 13

View File

@ -23,6 +23,8 @@
#include "loader/playlog.h" #include "loader/playlog.h"
#include "loader/wbfs.h" #include "loader/wbfs.h"
#include "music/SoundHandler.hpp" #include "music/SoundHandler.hpp"
#include "network/FTP_Dir.hpp"
#include "network/ftp.h"
#include "network/gcard.h" #include "network/gcard.h"
#include "unzip/U8Archive.h" #include "unzip/U8Archive.h"
@ -148,6 +150,9 @@ CMenu::CMenu()
m_sd_dm = false; m_sd_dm = false;
m_new_dml = false; m_new_dml = false;
m_new_dm_cfg = false; m_new_dm_cfg = false;
/* ftp stuff */
m_ftp_inited = false;
m_init_ftp = false;
} }
void CMenu::init() void CMenu::init()
@ -212,8 +217,13 @@ void CMenu::init()
/* Check if we want SD Gecko */ /* Check if we want SD Gecko */
m_use_sd_logging = m_cfg.getBool("DEBUG", "sd_write_log", false); m_use_sd_logging = m_cfg.getBool("DEBUG", "sd_write_log", false);
LogToSD_SetBuffer(m_use_sd_logging); LogToSD_SetBuffer(m_use_sd_logging);
/* Check if we want FTP */
m_init_ftp = m_cfg.getBool(FTP_DOMAIN, "auto_start", false);
ftp_allow_active = m_cfg.getBool(FTP_DOMAIN, "allow_active_mode", false);
ftp_server_port = min(65535u, m_cfg.getUInt(FTP_DOMAIN, "server_port", 21));
set_ftp_password(m_cfg.getString(FTP_DOMAIN, "password", "").c_str());
/* Init Network if wanted */ /* Init Network if wanted */
init_network = (m_cfg.getBool("GENERAL", "async_network") || has_enabled_providers() || m_use_wifi_gecko); init_network = (m_cfg.getBool("GENERAL", "async_network") || has_enabled_providers() || m_use_wifi_gecko || m_init_ftp);
_netInit(); _netInit();
/* Our Wii game dir */ /* Our Wii game dir */
memset(wii_games_dir, 0, 64); memset(wii_games_dir, 0, 64);
@ -637,6 +647,8 @@ void CMenu::_netInit(void)
_initAsyncNetwork(); _initAsyncNetwork();
while(net_get_status() == -EBUSY) while(net_get_status() == -EBUSY)
usleep(100); usleep(100);
if(m_init_ftp)
m_ftp_inited = ftp_startThread();
} }
void CMenu::_setAA(int aa) void CMenu::_setAA(int aa)
@ -1175,6 +1187,7 @@ void CMenu::_buildMenus(void)
_initExplorer(); _initExplorer();
_initBoot(); _initBoot();
_initPathsMenu(); _initPathsMenu();
_initFTP();
_loadCFCfg(); _loadCFCfg();
} }
@ -2067,6 +2080,7 @@ void CMenu::_updateText(void)
_textCoverBanner(); _textCoverBanner();
_textExplorer(); _textExplorer();
_textWad(); _textWad();
_textFTP();
} }
const wstringEx CMenu::_fmt(const char *key, const wchar_t *def) const wstringEx CMenu::_fmt(const char *key, const wchar_t *def)

View File

@ -859,6 +859,7 @@ private:
void _initExplorer(); void _initExplorer();
void _initWad(); void _initWad();
void _initPathsMenu(); void _initPathsMenu();
void _initFTP();
// //
void _textSource(void); void _textSource(void);
void _textPluginSettings(void); void _textPluginSettings(void);
@ -889,6 +890,7 @@ private:
void _textExplorer(void); void _textExplorer(void);
void _textWad(void); void _textWad(void);
void _textPaths(void); void _textPaths(void);
void _textFTP(void);
// //
void _refreshBoot(); void _refreshBoot();
void _refreshExplorer(s8 direction = 0); void _refreshExplorer(s8 direction = 0);
@ -926,6 +928,7 @@ private:
void _hideExplorer(bool instant = false); void _hideExplorer(bool instant = false);
void _hideWad(bool instant = false); void _hideWad(bool instant = false);
void _hidePaths(bool instant = false); void _hidePaths(bool instant = false);
void _hideFTP(bool instant = false);
// //
void _showError(void); void _showError(void);
void _showMain(void); void _showMain(void);
@ -960,11 +963,14 @@ private:
void _showExplorer(void); void _showExplorer(void);
void _showWad(void); void _showWad(void);
void _showPaths(void); void _showPaths(void);
void _showFTP(void);
void _clearSources(void); void _clearSources(void);
void _updateSourceBtns(void); void _updateSourceBtns(void);
void _updatePluginText(void); void _updatePluginText(void);
void _updatePluginCheckboxes(void); void _updatePluginCheckboxes(void);
void _updateCheckboxes(void); void _updateCheckboxes(void);
void _updateFTP(void);
void _getIDCats(void); void _getIDCats(void);
void _setIDCats(void); void _setIDCats(void);
void _setBg(const TexData &tex, const TexData &lqTex); void _setBg(const TexData &tex, const TexData &lqTex);
@ -1014,7 +1020,8 @@ private:
void _PluginSettings(); void _PluginSettings();
void _CategorySettings(bool fromGameSet = false); void _CategorySettings(bool fromGameSet = false);
bool _Home(); bool _Home();
bool _HomeFTP_Loop(); void _FTP();
bool _FTP_Loop();
bool _ExitTo(); bool _ExitTo();
bool _Boot(); bool _Boot();
void _Paths(); void _Paths();
@ -1025,6 +1032,8 @@ private:
bool m_use_wifi_gecko; bool m_use_wifi_gecko;
bool m_use_sd_logging; bool m_use_sd_logging;
bool init_network; bool init_network;
bool m_init_ftp;
bool m_ftp_inited;
void _netInit(); void _netInit();
bool _loadFile(u8 * &buffer, u32 &size, const char *path, const char *file); bool _loadFile(u8 * &buffer, u32 &size, const char *path, const char *file);
int _loadIOS(u8 ios, int userIOS, string id, bool RealNAND_Channels = false); int _loadIOS(u8 ios, int userIOS, string id, bool RealNAND_Channels = false);

View File

@ -48,6 +48,9 @@ s16 m_bootBtnSourceOnBoot;
s16 m_bootLblMultisource; s16 m_bootLblMultisource;
s16 m_bootBtnMultisource; s16 m_bootBtnMultisource;
s16 m_bootLblFtpOnBoot;
s16 m_bootBtnFtpOnBoot;
u8 set_port = 0; u8 set_port = 0;
u8 boot_curPage = 1; u8 boot_curPage = 1;
u8 boot_Pages = 2; u8 boot_Pages = 2;
@ -99,6 +102,9 @@ static void hideBoot(bool instant, bool common)
m_btnMgr.hide(m_bootLblMultisource, instant); m_btnMgr.hide(m_bootLblMultisource, instant);
m_btnMgr.hide(m_bootBtnMultisource, instant); m_btnMgr.hide(m_bootBtnMultisource, instant);
m_btnMgr.hide(m_bootLblFtpOnBoot, instant);
m_btnMgr.hide(m_bootBtnFtpOnBoot, instant);
} }
bool CMenu::_Boot(void) bool CMenu::_Boot(void)
@ -193,6 +199,11 @@ bool CMenu::_Boot(void)
m_btnMgr.setText(m_bootBtnMultisource, m_cfg.getBool("GENERAL", "multisource") ? _t("on", L"On") : _t("off", L"Off")); m_btnMgr.setText(m_bootBtnMultisource, m_cfg.getBool("GENERAL", "multisource") ? _t("on", L"On") : _t("off", L"Off"));
m_multisource = m_cfg.getBool("GENERAL", "multisource", false); m_multisource = m_cfg.getBool("GENERAL", "multisource", false);
} }
else if (m_btnMgr.selected(m_bootBtnFtpOnBoot))
{
m_cfg.setBool(FTP_DOMAIN, "auto_start", !m_cfg.getBool(FTP_DOMAIN, "auto_start", false));
m_btnMgr.setText(m_bootBtnFtpOnBoot, m_cfg.getBool(FTP_DOMAIN, "auto_start") ? _t("on", L"On") : _t("off", L"Off"));
}
} }
} }
if(prev_load != cur_load || prev_ios != cur_ios) if(prev_load != cur_load || prev_ios != cur_ios)
@ -243,6 +254,7 @@ void CMenu::_refreshBoot()
m_btnMgr.setText(m_bootBtnCategoryOnBoot, m_cfg.getBool("GENERAL", "category_on_start") ? _t("on", L"On") : _t("off", L"Off")); m_btnMgr.setText(m_bootBtnCategoryOnBoot, m_cfg.getBool("GENERAL", "category_on_start") ? _t("on", L"On") : _t("off", L"Off"));
m_btnMgr.setText(m_bootBtnSourceOnBoot, m_cfg.getBool("GENERAL", "source_on_start") ? _t("on", L"On") : _t("off", L"Off")); m_btnMgr.setText(m_bootBtnSourceOnBoot, m_cfg.getBool("GENERAL", "source_on_start") ? _t("on", L"On") : _t("off", L"Off"));
m_btnMgr.setText(m_bootBtnMultisource, m_cfg.getBool("GENERAL", "multisource") ? _t("on", L"On") : _t("off", L"Off")); m_btnMgr.setText(m_bootBtnMultisource, m_cfg.getBool("GENERAL", "multisource") ? _t("on", L"On") : _t("off", L"Off"));
m_btnMgr.setText(m_bootBtnFtpOnBoot, m_cfg.getBool(FTP_DOMAIN, "auto_start") ? _t("on", L"On") : _t("off", L"Off"));
m_btnMgr.show(m_bootLblCategoryOnBoot); m_btnMgr.show(m_bootLblCategoryOnBoot);
m_btnMgr.show(m_bootBtnCategoryOnBoot); m_btnMgr.show(m_bootBtnCategoryOnBoot);
@ -252,6 +264,9 @@ void CMenu::_refreshBoot()
m_btnMgr.show(m_bootLblMultisource); m_btnMgr.show(m_bootLblMultisource);
m_btnMgr.show(m_bootBtnMultisource); m_btnMgr.show(m_bootBtnMultisource);
m_btnMgr.show(m_bootLblFtpOnBoot);
m_btnMgr.show(m_bootBtnFtpOnBoot);
} }
} }
@ -265,6 +280,7 @@ void CMenu::_textBoot(void)
m_btnMgr.setText(m_bootLblCategoryOnBoot, _t("cfgd7", L"Show categories on boot")); m_btnMgr.setText(m_bootLblCategoryOnBoot, _t("cfgd7", L"Show categories on boot"));
m_btnMgr.setText(m_bootLblSourceOnBoot, _t("cfgbt5", L"Show source menu on boot")); m_btnMgr.setText(m_bootLblSourceOnBoot, _t("cfgbt5", L"Show source menu on boot"));
m_btnMgr.setText(m_bootLblMultisource, _t("cfgbt6", L"Enable Multisource Features")); m_btnMgr.setText(m_bootLblMultisource, _t("cfgbt6", L"Enable Multisource Features"));
m_btnMgr.setText(m_bootLblFtpOnBoot, _t("cfgbt6", L"Start FTP Server on boot"));
m_btnMgr.setText(m_bootBtnBack, _t("cfg10", L"Back")); m_btnMgr.setText(m_bootBtnBack, _t("cfg10", L"Back"));
} }
@ -301,6 +317,9 @@ void CMenu::_initBoot(void)
m_bootLblMultisource = _addLabel("BOOT/MULTISOURCE", theme.lblFont, L"", 40, 250, 340, 56, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE); m_bootLblMultisource = _addLabel("BOOT/MULTISOURCE", theme.lblFont, L"", 40, 250, 340, 56, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE);
m_bootBtnMultisource = _addButton("BOOT/MULTISOURCE_BTN", theme.btnFont, L"", 370, 250, 230, 56, theme.btnFontColor); m_bootBtnMultisource = _addButton("BOOT/MULTISOURCE_BTN", theme.btnFont, L"", 370, 250, 230, 56, theme.btnFontColor);
m_bootLblFtpOnBoot = _addLabel("BOOT/FTP", theme.lblFont, L"", 40, 310, 340, 56, theme.lblFontColor, FTGX_JUSTIFY_LEFT | FTGX_ALIGN_MIDDLE);
m_bootBtnFtpOnBoot = _addButton("BOOT/FTP_BTN", theme.btnFont, L"", 370, 310, 230, 56, theme.btnFontColor);
_setHideAnim(m_bootLblTitle, "BOOT/TITLE", 0, -200, 0.f, 1.f); _setHideAnim(m_bootLblTitle, "BOOT/TITLE", 0, -200, 0.f, 1.f);
_setHideAnim(m_bootBtnBack, "BOOT/BACK_BTN", 0, 0, 1.f, -1.f); _setHideAnim(m_bootBtnBack, "BOOT/BACK_BTN", 0, 0, 1.f, -1.f);
_setHideAnim(m_bootLblPage, "BOOT/PAGE_BTN", 0, 0, 1.f, -1.f); _setHideAnim(m_bootLblPage, "BOOT/PAGE_BTN", 0, 0, 1.f, -1.f);
@ -329,6 +348,9 @@ void CMenu::_initBoot(void)
_setHideAnim(m_bootLblMultisource, "BOOT/MULTISOURCE", -200, 0, 1.f, 0.f); _setHideAnim(m_bootLblMultisource, "BOOT/MULTISOURCE", -200, 0, 1.f, 0.f);
_setHideAnim(m_bootBtnMultisource, "BOOT/MULTISOURCE_BTN", 200, 0, 1.f, 0.f); _setHideAnim(m_bootBtnMultisource, "BOOT/MULTISOURCE_BTN", 200, 0, 1.f, 0.f);
_setHideAnim(m_bootLblFtpOnBoot, "BOOT/FTP", -200, 0, 1.f, 0.f);
_setHideAnim(m_bootBtnFtpOnBoot, "BOOT/FTP_BTN", 200, 0, 1.f, 0.f);
hideBoot(true, true); hideBoot(true, true);
_textBoot(); _textBoot();
} }

View File

@ -404,16 +404,15 @@ s32 CMenu::_networkComplete(s32 ok, void *usrData)
networkInit = ok == 0; networkInit = ok == 0;
m->m_thrdNetwork = false; m->m_thrdNetwork = false;
bool wifigecko = m->m_cfg.getBool("DEBUG", "wifi_gecko", false); gprintf("NET: Network init complete, enabled wifi_gecko: %s\n", m->m_use_wifi_gecko ? "yes" : "no");
gprintf("NET: Network init complete, enabled wifi_gecko: %s\n", wifigecko ? "yes" : "no"); if(m->m_use_wifi_gecko)
if(wifigecko)
{ {
const string &ip = m->m_cfg.getString("DEBUG", "wifi_gecko_ip"); const string &ip = m->m_cfg.getString("DEBUG", "wifi_gecko_ip");
u16 port = m->m_cfg.getInt("DEBUG", "wifi_gecko_port", 4405); u16 port = m->m_cfg.getInt("DEBUG", "wifi_gecko_port", 4405);
if(ip.size() > 0 && port != 0) if(ip.size() > 0 && port != 0)
WiFiDebugger.Init(ip.c_str(), port); WiFiDebugger.Init(ip.c_str(), port);
} }
return 0; return 0;
} }

119
source/menu/menu_ftp.cpp Normal file
View File

@ -0,0 +1,119 @@
/****************************************************************************
* Copyright (C) 2013 FIX94
*
* 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 <http://www.gnu.org/licenses/>.
****************************************************************************/
#include "menu.hpp"
#include "network/net.h"
#include "network/ftp.h"
#include "network/http.h"
#include "network/gcard.h"
#include "network/FTP_Dir.hpp"
s16 m_ftpBtnBack;
s16 m_ftpBtnToggle;
void CMenu::_updateFTP(void)
{
if(m_ftp_inited == true)
{
in_addr addr;
addr.s_addr = net_gethostip();
m_btnMgr.setText(m_wbfsLblDialog, wfmt(_fmt("dlmsg28", L"Running FTP Server on %s:%d"), inet_ntoa(addr), ftp_server_port));
m_btnMgr.setText(m_ftpBtnToggle, _t("ftp2", L"Stop"));
}
else
{
m_btnMgr.setText(m_wbfsLblDialog, _t("dlmsg29", L"FTP Server is currently stopped."));
m_btnMgr.setText(m_ftpBtnToggle, _t("ftp1", L"Start"));
}
}
void CMenu::_FTP(void)
{
_showFTP();
_updateFTP();
m_btnMgr.show(m_wbfsLblDialog);
while(!m_exit)
{
_mainLoopCommon();
if(BTN_HOME_PRESSED || BTN_B_PRESSED)
break;
else if(BTN_A_PRESSED)
{
if(m_btnMgr.selected(m_ftpBtnBack))
break;
else if(m_btnMgr.selected(m_ftpBtnToggle))
{
gprintf("%d\n", m_ftp_inited);
if(m_ftp_inited == true)
{
ftp_endTread();
m_init_ftp = false;
m_ftp_inited = false;
init_network = (m_cfg.getBool("GENERAL", "async_network") || has_enabled_providers() || m_use_wifi_gecko);
}
else
{
m_init_ftp = true;
init_network = true;
if(networkInit == false)
{
gprintf("no net init yet\n");
_netInit();
}
else
{
gprintf("net already inited, just start server\n");
m_ftp_inited = ftp_startThread();
}
}
_updateFTP();
}
}
}
m_btnMgr.hide(m_wbfsLblDialog);
_hideFTP();
}
void CMenu::_showFTP(void)
{
m_btnMgr.show(m_ftpBtnToggle);
m_btnMgr.show(m_ftpBtnBack);
}
void CMenu::_hideFTP(bool instant)
{
m_btnMgr.hide(m_ftpBtnToggle, instant);
m_btnMgr.hide(m_ftpBtnBack, instant);
}
void CMenu::_initFTP(void)
{
m_ftpBtnToggle = _addButton("FTP/TOGGLE_BTN", theme.btnFont, L"", 20, 400, 200, 56, theme.btnFontColor);
m_ftpBtnBack = _addButton("FTP/BACK_BTN", theme.btnFont, L"", 420, 400, 200, 56, theme.btnFontColor);
_setHideAnim(m_ftpBtnToggle, "FTP/TOGGLE_BTN", 0, 0, 1.f, -1.f);
_setHideAnim(m_ftpBtnBack, "FTP/BACK_BTN", 0, 0, 1.f, -1.f);
_textFTP();
_hideFTP(true);
}
void CMenu::_textFTP(void)
{
m_btnMgr.setText(m_ftpBtnToggle, L"");
m_btnMgr.setText(m_ftpBtnBack, _t("cfg10", L"Back"));
}

View File

@ -18,14 +18,9 @@
#include "loader/cios.h" #include "loader/cios.h"
#include "loader/nk.h" #include "loader/nk.h"
#include "const_str.hpp" #include "const_str.hpp"
#include "network/net.h"
#include "network/ftp.h"
#include "network/http.h"
#include "network/FTP_Dir.hpp"
s16 m_homeLblTitle; s16 m_homeLblTitle;
s16 m_exittoLblTitle; s16 m_exittoLblTitle;
s16 m_homeBtnBack;
s16 m_homeBtnSettings; s16 m_homeBtnSettings;
s16 m_homeBtnReloadCache; s16 m_homeBtnReloadCache;
@ -48,19 +43,6 @@ s16 m_homeLblUser[4];
TexData m_homeBg; TexData m_homeBg;
bool CMenu::_HomeFTP_Loop(void)
{
_mainLoopCommon();
if(BTN_HOME_PRESSED || BTN_B_PRESSED)
return true;
else if(BTN_A_PRESSED)
{
if(m_btnMgr.selected(m_homeBtnBack))
return true;
}
return false;
}
bool CMenu::_Home(void) bool CMenu::_Home(void)
{ {
SetupInput(); SetupInput();
@ -139,45 +121,7 @@ bool CMenu::_Home(void)
else if(m_btnMgr.selected(m_homeBtnFTP)) else if(m_btnMgr.selected(m_homeBtnFTP))
{ {
_hideHome(); _hideHome();
/* net init as usual */ _FTP();
_initAsyncNetwork();
m_btnMgr.show(m_wbfsLblDialog);
m_btnMgr.show(m_homeBtnBack);
m_btnMgr.setText(m_wbfsLblDialog, _t("dlmsg1", L"Initializing network..."));
bool cancel = false;
while(!m_exit && m_thrdNetwork == true && net_get_status() == -EBUSY)
{
if(_HomeFTP_Loop())
{
cancel = true;
break;
}
}
if(networkInit == false || cancel == true)
{
m_btnMgr.hide(m_wbfsLblDialog);
m_btnMgr.hide(m_homeBtnBack);
break;
}
/* start server finally */
ftp_init();
in_addr addr;
u32 ip = net_gethostip();
addr.s_addr = ip;
u16 m_ftp_port = 21;
int server = create_server(m_ftp_port);
m_btnMgr.setText(m_wbfsLblDialog, wfmt(_fmt("dlmsg28", L"Running FTP Server on %s:%u"), inet_ntoa(addr), m_ftp_port));
while(!m_exit)
{
if(_HomeFTP_Loop())
break;
process_ftp_events(server);
}
/* cleanup and closing */
cleanup_ftp();
net_close(server);
m_btnMgr.hide(m_wbfsLblDialog);
m_btnMgr.hide(m_homeBtnBack);
_showHome(); _showHome();
} }
} }
@ -336,8 +280,6 @@ void CMenu::_initHomeAndExitToMenu()
m_homeBg = _texture("HOME/BG", "texture", theme.bg, false); m_homeBg = _texture("HOME/BG", "texture", theme.bg, false);
m_homeLblTitle = _addTitle("HOME/TITLE", theme.titleFont, L"", 20, 30, 600, 60, theme.titleFontColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE); m_homeLblTitle = _addTitle("HOME/TITLE", theme.titleFont, L"", 20, 30, 600, 60, theme.titleFontColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE);
m_homeBtnBack = _addButton("HOME/BACK_BTN", theme.btnFont, L"", 420, 400, 200, 56, theme.btnFontColor);
_setHideAnim(m_homeLblTitle, "HOME/TITLE", 0, 0, -2.f, 0.f); _setHideAnim(m_homeLblTitle, "HOME/TITLE", 0, 0, -2.f, 0.f);
m_homeBtnSettings = _addButton("HOME/SETTINGS", theme.btnFont, L"", 60, 100, 250, 56, theme.btnFontColor); m_homeBtnSettings = _addButton("HOME/SETTINGS", theme.btnFont, L"", 60, 100, 250, 56, theme.btnFontColor);
@ -352,8 +294,6 @@ void CMenu::_initHomeAndExitToMenu()
m_homeLblBattery = _addLabel("HOME/BATTERY", theme.btnFont, L"", 0, 420, 640, 56, theme.btnFontColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE, theme.btnTexC); m_homeLblBattery = _addLabel("HOME/BATTERY", theme.btnFont, L"", 0, 420, 640, 56, theme.btnFontColor, FTGX_JUSTIFY_CENTER | FTGX_ALIGN_MIDDLE, theme.btnTexC);
_setHideAnim(m_homeBtnBack, "HOME/BACK_BTN", 0, 0, 1.f, -1.f);
_setHideAnim(m_homeBtnSettings, "HOME/SETTINGS", 0, 0, -2.f, 0.f); _setHideAnim(m_homeBtnSettings, "HOME/SETTINGS", 0, 0, -2.f, 0.f);
_setHideAnim(m_homeBtnReloadCache, "HOME/RELOAD_CACHE", 0, 0, -2.f, 0.f); _setHideAnim(m_homeBtnReloadCache, "HOME/RELOAD_CACHE", 0, 0, -2.f, 0.f);
_setHideAnim(m_homeBtnUpdate, "HOME/UPDATE", 0, 0, -2.f, 0.f); _setHideAnim(m_homeBtnUpdate, "HOME/UPDATE", 0, 0, -2.f, 0.f);
@ -392,7 +332,6 @@ void CMenu::_initHomeAndExitToMenu()
void CMenu::_textHome(void) void CMenu::_textHome(void)
{ {
m_btnMgr.setText(m_homeLblTitle, VERSION_STRING); m_btnMgr.setText(m_homeLblTitle, VERSION_STRING);
m_btnMgr.setText(m_homeBtnBack, _t("cfg10", L"Back"));
m_btnMgr.setText(m_homeBtnSettings, _t("home1", L"Settings")); m_btnMgr.setText(m_homeBtnSettings, _t("home1", L"Settings"));
m_btnMgr.setText(m_homeBtnReloadCache, _t("home2", L"Reload Cache")); m_btnMgr.setText(m_homeBtnReloadCache, _t("home2", L"Reload Cache"));
m_btnMgr.setText(m_homeBtnUpdate, _t("home3", L"Update")); m_btnMgr.setText(m_homeBtnUpdate, _t("home3", L"Update"));

View File

@ -17,6 +17,8 @@
#include <string.h> #include <string.h>
#include <sys/errno.h> #include <sys/errno.h>
#include "FTP_Dir.hpp" #include "FTP_Dir.hpp"
#include "ftp.h"
#include "net.h"
#include "gecko/gecko.hpp" #include "gecko/gecko.hpp"
#include "devicemounter/DeviceHandler.hpp" #include "devicemounter/DeviceHandler.hpp"
#include "fileOps/fileOps.h" #include "fileOps/fileOps.h"
@ -260,6 +262,54 @@ int ftp_delete(char *path)
return ret; return ret;
} }
lwp_t ftpThrdPtr = LWP_THREAD_NULL;
volatile bool ftpThrd_running = false;
bool end_ftp = false;
s32 cur_server_num = -1;
void *ftp_loopThrd(void *nothing)
{
while(end_ftp == false)
{
process_ftp_events(cur_server_num);
usleep(100);
}
ftpThrd_running = false;
return nothing;
}
bool ftp_startThread(void)
{
ftp_endTread();
if(create_server() == false)
return false;
cur_server_num = get_server_num();
if(cur_server_num < 0)
return false;
end_ftp = false;
ftpThrd_running = true;
LWP_CreateThread(&ftpThrdPtr, ftp_loopThrd, NULL, NULL, 0, 64);
return true;
}
void ftp_endTread(void)
{
if(ftpThrdPtr == LWP_THREAD_NULL)
return;
if(LWP_ThreadIsSuspended(ftpThrdPtr))
LWP_ResumeThread(ftpThrdPtr);
end_ftp = true;
while(ftpThrd_running)
usleep(50);
LWP_JoinThread(ftpThrdPtr, NULL);
ftpThrdPtr = LWP_THREAD_NULL;
end_server();
cur_server_num = -1;
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

View File

@ -43,6 +43,9 @@ int ftp_stat(char *file, struct stat *st);
int ftp_rename(char *path, char *new_name); int ftp_rename(char *path, char *new_name);
int ftp_delete(char *path); int ftp_delete(char *path);
bool ftp_startThread(void);
void ftp_endTread(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

View File

@ -20,6 +20,9 @@
#define FTP_BUFFER_SIZE 1024 #define FTP_BUFFER_SIZE 1024
#define MAX_CLIENTS 2 #define MAX_CLIENTS 2
bool ftp_allow_active = false;
u16 ftp_server_port = 21;
static const u16 SRC_PORT = 20; static const u16 SRC_PORT = 20;
static const s32 EQUIT = 696969; static const s32 EQUIT = 696969;
static const char *CRLF = "\r\n"; static const char *CRLF = "\r\n";
@ -54,11 +57,11 @@ 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(const char *new_password) {
if (password) free(password); if (password != NULL) free(password);
if (new_password) { if (new_password != NULL && new_password[0] != '\0') {
password = malloc(strlen(new_password) + 1); password = malloc(strlen(new_password) + 1);
if (!password) return;//die("Unable to allocate memory for password", errno); if (password == NULL) return;//die("Unable to allocate memory for password", errno);
strcpy((char *)password, new_password); strcpy((char *)password, new_password);
} else { } else {
password = NULL; password = NULL;
@ -298,6 +301,9 @@ static s32 ftp_PASV(client_t *client, char *rest __attribute__((unused))) {
} }
static s32 ftp_PORT(client_t *client, char *portspec) { static s32 ftp_PORT(client_t *client, char *portspec) {
if(ftp_allow_active == false) /* port is only used for active clients */
return write_reply(client, 502, "Command not implemented.");
u32 h1, h2, h3, h4, p1, p2; u32 h1, h2, h3, h4, p1, p2;
if (sscanf(portspec, "%3u,%3u,%3u,%3u,%3u,%3u", &h1, &h2, &h3, &h4, &p1, &p2) < 6) { if (sscanf(portspec, "%3u,%3u,%3u,%3u,%3u,%3u", &h1, &h2, &h3, &h4, &p1, &p2) < 6) {
return write_reply(client, 501, "Syntax error in parameters."); return write_reply(client, 501, "Syntax error in parameters.");
@ -347,9 +353,11 @@ static s32 prepare_data_connection_passive(client_t *client) {
static s32 prepare_data_connection(client_t *client, void *callback, void *arg, void *cleanup) { static s32 prepare_data_connection(client_t *client, void *callback, void *arg, void *cleanup) {
s32 result = write_reply(client, 150, "Transferring data."); s32 result = write_reply(client, 150, "Transferring data.");
if (result >= 0) { if (result >= 0) {
data_connection_handler handler = prepare_data_connection_active; result = -1;
if (client->passive_socket >= 0) handler = prepare_data_connection_passive; if(client->passive_socket >= 0)
result = handler(client); result = prepare_data_connection_passive(client);
else if(ftp_allow_active == true)
result = prepare_data_connection_active(client);
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 {
@ -662,7 +670,7 @@ static bool process_accept_events(s32 server) {
} }
static void process_data_events(client_t *client) { static void process_data_events(client_t *client) {
s32 result; s32 result = -1;
if (!client->data_connection_connected) { if (!client->data_connection_connected) {
if (client->passive_socket >= 0) { if (client->passive_socket >= 0) {
struct sockaddr_in data_peer_address; struct sockaddr_in data_peer_address;
@ -672,7 +680,7 @@ static void process_data_events(client_t *client) {
client->data_socket = result; client->data_socket = result;
client->data_connection_connected = true; client->data_connection_connected = true;
} }
} else { } else if(ftp_allow_active == true) {
if ((result = net_connect(client->data_socket, (struct sockaddr *)&client->address, sizeof(client->address))) < 0) { if ((result = net_connect(client->data_socket, (struct sockaddr *)&client->address, sizeof(client->address))) < 0) {
if (result == -EINPROGRESS || result == -EALREADY) result = -EAGAIN; if (result == -EINPROGRESS || result == -EALREADY) result = -EAGAIN;
if (result != -EAGAIN && result != -EISCONN) gprintf("Unable to connect to client: [%i] %s\n", -result, strerror(-result)); if (result != -EAGAIN && result != -EISCONN) gprintf("Unable to connect to client: [%i] %s\n", -result, strerror(-result));

View File

@ -9,10 +9,13 @@ extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
void accept_ftp_client(s32 server); void accept_ftp_client(s32 server);
void set_ftp_password(char *new_password); void set_ftp_password(const char *new_password);
bool process_ftp_events(s32 server); bool process_ftp_events(s32 server);
void cleanup_ftp(); void cleanup_ftp();
extern bool ftp_allow_active;
extern u16 ftp_server_port;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

View File

@ -9,6 +9,7 @@
#include <sys/fcntl.h> #include <sys/fcntl.h>
#include "net.h" #include "net.h"
#include "ftp.h"
#include "FTP_Dir.hpp" #include "FTP_Dir.hpp"
#include "loader/sys.h" #include "loader/sys.h"
#include "gecko/gecko.hpp" #include "gecko/gecko.hpp"
@ -18,6 +19,7 @@
#define FREAD_BUFFER_SIZE 32768 #define FREAD_BUFFER_SIZE 32768
static u32 NET_BUFFER_SIZE = MAX_NET_BUFFER_SIZE; static u32 NET_BUFFER_SIZE = MAX_NET_BUFFER_SIZE;
s32 ftp_server = -1;
s32 set_blocking(s32 s, bool blocking) { s32 set_blocking(s32 s, bool blocking) {
s32 flags; s32 flags;
@ -31,30 +33,48 @@ s32 net_close_blocking(s32 s) {
return net_close(s); return net_close(s);
} }
s32 create_server(u16 port) { bool create_server(void) {
s32 server = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP); ftp_init();
if (server < 0) return -1;//die("Error creating socket", -server); ftp_server = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
set_blocking(server, false); if (ftp_server < 0) return false;
set_blocking(ftp_server, false);
struct sockaddr_in bindAddress; struct sockaddr_in bindAddress;
memset(&bindAddress, 0, sizeof(bindAddress)); memset(&bindAddress, 0, sizeof(bindAddress));
bindAddress.sin_family = AF_INET; bindAddress.sin_family = AF_INET;
bindAddress.sin_port = htons(port); bindAddress.sin_port = htons(ftp_server_port);
bindAddress.sin_addr.s_addr = htonl(INADDR_ANY); bindAddress.sin_addr.s_addr = htonl(INADDR_ANY);
s32 ret; s32 ret;
if ((ret = net_bind(server, (struct sockaddr *)&bindAddress, sizeof(bindAddress))) < 0) { if ((ret = net_bind(ftp_server, (struct sockaddr *)&bindAddress, sizeof(bindAddress))) < 0) {
net_close(server); net_close(ftp_server);
ftp_server = -1;
gprintf("Error binding socket: [%i] %s\n", -ret, strerror(-ret)); gprintf("Error binding socket: [%i] %s\n", -ret, strerror(-ret));
return ret; return false;
} }
if ((ret = net_listen(server, 3)) < 0) { if ((ret = net_listen(ftp_server, 3)) < 0) {
net_close(server); net_close(ftp_server);
ftp_server = -1;
gprintf("Error listening on socket: [%i] %s\n", -ret, strerror(-ret)); gprintf("Error listening on socket: [%i] %s\n", -ret, strerror(-ret));
return ret; return false;
} }
gprintf("FTP Server started\n");
return true;
}
return server; void end_server(void)
{
if(ftp_server < 0)
return;
cleanup_ftp();
net_close(ftp_server);
ftp_server = -1;
gprintf("FTP Server ended\n");
}
s32 get_server_num(void)
{
return ftp_server;
} }
typedef s32 (*transferrer_type)(s32 s, void *mem, s32 len); typedef s32 (*transferrer_type)(s32 s, void *mem, s32 len);

View File

@ -13,7 +13,9 @@ extern "C" {
void initialise_network(); void initialise_network();
s32 set_blocking(s32 s, bool blocking); s32 set_blocking(s32 s, bool blocking);
s32 net_close_blocking(s32 s); s32 net_close_blocking(s32 s);
s32 create_server(u16 port); bool create_server(void);
s32 get_server_num(void);
void end_server(void);
s32 send_exact(s32 s, char *buf, s32 length); s32 send_exact(s32 s, char *buf, s32 length);
s32 send_from_file(s32 s, FILE *f); s32 send_from_file(s32 s, FILE *f);
s32 recv_to_file(s32 s, FILE *f); s32 recv_to_file(s32 s, FILE *f);

View File

@ -60,6 +60,8 @@ cfgbt2=Force Load cIOS
cfgbt3=Force cIOS Revision cfgbt3=Force cIOS Revision
cfgbt4=USB Port cfgbt4=USB Port
cfgbt5=Show source menu on boot cfgbt5=Show source menu on boot
cfgbt6=Enable Multisource Features
cfgbt7=Start FTP Server on boot
cfgc1=Exit To cfgc1=Exit To
cfgc2=Adjust TV width cfgc2=Adjust TV width
cfgc3=Adjust TV height cfgc3=Adjust TV height
@ -212,6 +214,7 @@ dlmsg25=Extraction must have failed! Renaming the backup to boot.dol
dlmsg26=Updating cache... dlmsg26=Updating cache...
dlmsg27=Not enough memory! dlmsg27=Not enough memory!
dlmsg28=Running FTP Server on %s:%u dlmsg28=Running FTP Server on %s:%u
dlmsg29=FTP Server is currently stopped.
dlmsg3=Downloading from %s dlmsg3=Downloading from %s
dlmsg4=Saving %s dlmsg4=Saving %s
dlmsg5=%i/%i files downloaded dlmsg5=%i/%i files downloaded
@ -243,6 +246,8 @@ errgame9=This is not a Wii or GC disc
errgame10=Set USB failed: %d errgame10=Set USB failed: %d
errneek1=Cannot launch neek2o. Verify your neek2o setup errneek1=Cannot launch neek2o. Verify your neek2o setup
exit_to=Exit To exit_to=Exit To
ftp1=Start
ftp2=Stop
gameinfo1=Developer: %s gameinfo1=Developer: %s
gameinfo2=Publisher: %s gameinfo2=Publisher: %s
gameinfo3=Region: %s gameinfo3=Region: %s