From 4d03e0e2dc4333884ca5d0bef36a8bbcfa2270da Mon Sep 17 00:00:00 2001 From: "fix94.1" Date: Thu, 5 Sep 2013 23:52:21 +0000 Subject: [PATCH] -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 --- source/booter/external_booter.cpp | 2 + source/defines.h | 1 + source/menu/menu.cpp | 16 +++- source/menu/menu.hpp | 11 ++- source/menu/menu_boot.cpp | 22 ++++++ source/menu/menu_download.cpp | 7 +- source/menu/menu_ftp.cpp | 119 ++++++++++++++++++++++++++++++ source/menu/menu_home.cpp | 63 +--------------- source/network/FTP_Dir.cpp | 50 +++++++++++++ source/network/FTP_Dir.hpp | 3 + source/network/ftp.c | 26 ++++--- source/network/ftp.h | 5 +- source/network/net.c | 44 ++++++++--- source/network/net.h | 4 +- wii/wiiflow/Languages/english.ini | 5 ++ 15 files changed, 287 insertions(+), 91 deletions(-) create mode 100644 source/menu/menu_ftp.cpp diff --git a/source/booter/external_booter.cpp b/source/booter/external_booter.cpp index 844e8865..a2b4df2f 100644 --- a/source/booter/external_booter.cpp +++ b/source/booter/external_booter.cpp @@ -32,6 +32,7 @@ #include "loader/sys.h" #include "homebrew/homebrew.h" #include "memory/mem2.hpp" +#include "network/FTP_Dir.hpp" #include "network/http.h" #include "plugin/crc32.h" @@ -123,6 +124,7 @@ void ShutdownBeforeExit(void) while(net_get_status() == -EBUSY) usleep(50); WiFiDebugger.Close(); + ftp_endTread(); net_deinit(); networkInit = false; } diff --git a/source/defines.h b/source/defines.h index dd940def..d1d34229 100644 --- a/source/defines.h +++ b/source/defines.h @@ -26,6 +26,7 @@ #define PLUGIN_DOMAIN "EMULATOR" #define HOMEBREW_DOMAIN "HOMEBREW" #define MUSIC_DOMAIN "MUSIC" +#define FTP_DOMAIN "FTP" #define AGE_LOCK_DEFAULT 13 diff --git a/source/menu/menu.cpp b/source/menu/menu.cpp index 13f41719..0e5b1f07 100644 --- a/source/menu/menu.cpp +++ b/source/menu/menu.cpp @@ -23,6 +23,8 @@ #include "loader/playlog.h" #include "loader/wbfs.h" #include "music/SoundHandler.hpp" +#include "network/FTP_Dir.hpp" +#include "network/ftp.h" #include "network/gcard.h" #include "unzip/U8Archive.h" @@ -148,6 +150,9 @@ CMenu::CMenu() m_sd_dm = false; m_new_dml = false; m_new_dm_cfg = false; + /* ftp stuff */ + m_ftp_inited = false; + m_init_ftp = false; } void CMenu::init() @@ -212,8 +217,13 @@ void CMenu::init() /* Check if we want SD Gecko */ m_use_sd_logging = m_cfg.getBool("DEBUG", "sd_write_log", false); 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 = (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(); /* Our Wii game dir */ memset(wii_games_dir, 0, 64); @@ -637,6 +647,8 @@ void CMenu::_netInit(void) _initAsyncNetwork(); while(net_get_status() == -EBUSY) usleep(100); + if(m_init_ftp) + m_ftp_inited = ftp_startThread(); } void CMenu::_setAA(int aa) @@ -1175,6 +1187,7 @@ void CMenu::_buildMenus(void) _initExplorer(); _initBoot(); _initPathsMenu(); + _initFTP(); _loadCFCfg(); } @@ -2067,6 +2080,7 @@ void CMenu::_updateText(void) _textCoverBanner(); _textExplorer(); _textWad(); + _textFTP(); } const wstringEx CMenu::_fmt(const char *key, const wchar_t *def) diff --git a/source/menu/menu.hpp b/source/menu/menu.hpp index ecd8bbaf..a0b21381 100644 --- a/source/menu/menu.hpp +++ b/source/menu/menu.hpp @@ -859,6 +859,7 @@ private: void _initExplorer(); void _initWad(); void _initPathsMenu(); + void _initFTP(); // void _textSource(void); void _textPluginSettings(void); @@ -889,6 +890,7 @@ private: void _textExplorer(void); void _textWad(void); void _textPaths(void); + void _textFTP(void); // void _refreshBoot(); void _refreshExplorer(s8 direction = 0); @@ -926,6 +928,7 @@ private: void _hideExplorer(bool instant = false); void _hideWad(bool instant = false); void _hidePaths(bool instant = false); + void _hideFTP(bool instant = false); // void _showError(void); void _showMain(void); @@ -960,11 +963,14 @@ private: void _showExplorer(void); void _showWad(void); void _showPaths(void); + void _showFTP(void); + void _clearSources(void); void _updateSourceBtns(void); void _updatePluginText(void); void _updatePluginCheckboxes(void); void _updateCheckboxes(void); + void _updateFTP(void); void _getIDCats(void); void _setIDCats(void); void _setBg(const TexData &tex, const TexData &lqTex); @@ -1014,7 +1020,8 @@ private: void _PluginSettings(); void _CategorySettings(bool fromGameSet = false); bool _Home(); - bool _HomeFTP_Loop(); + void _FTP(); + bool _FTP_Loop(); bool _ExitTo(); bool _Boot(); void _Paths(); @@ -1025,6 +1032,8 @@ private: bool m_use_wifi_gecko; bool m_use_sd_logging; bool init_network; + bool m_init_ftp; + bool m_ftp_inited; void _netInit(); bool _loadFile(u8 * &buffer, u32 &size, const char *path, const char *file); int _loadIOS(u8 ios, int userIOS, string id, bool RealNAND_Channels = false); diff --git a/source/menu/menu_boot.cpp b/source/menu/menu_boot.cpp index de3e3c20..6c9ddfe7 100644 --- a/source/menu/menu_boot.cpp +++ b/source/menu/menu_boot.cpp @@ -48,6 +48,9 @@ s16 m_bootBtnSourceOnBoot; s16 m_bootLblMultisource; s16 m_bootBtnMultisource; +s16 m_bootLblFtpOnBoot; +s16 m_bootBtnFtpOnBoot; + u8 set_port = 0; u8 boot_curPage = 1; 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_bootBtnMultisource, instant); + + m_btnMgr.hide(m_bootLblFtpOnBoot, instant); + m_btnMgr.hide(m_bootBtnFtpOnBoot, instant); } 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_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) @@ -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_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_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_bootBtnCategoryOnBoot); @@ -252,6 +264,9 @@ void CMenu::_refreshBoot() m_btnMgr.show(m_bootLblMultisource); 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_bootLblSourceOnBoot, _t("cfgbt5", L"Show source menu on boot")); 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")); } @@ -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_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_bootBtnBack, "BOOT/BACK_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_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); _textBoot(); } diff --git a/source/menu/menu_download.cpp b/source/menu/menu_download.cpp index 44a7f163..42d64bb4 100644 --- a/source/menu/menu_download.cpp +++ b/source/menu/menu_download.cpp @@ -404,16 +404,15 @@ s32 CMenu::_networkComplete(s32 ok, void *usrData) networkInit = ok == 0; m->m_thrdNetwork = false; - bool wifigecko = m->m_cfg.getBool("DEBUG", "wifi_gecko", false); - gprintf("NET: Network init complete, enabled wifi_gecko: %s\n", wifigecko ? "yes" : "no"); - - if(wifigecko) + gprintf("NET: Network init complete, enabled wifi_gecko: %s\n", m->m_use_wifi_gecko ? "yes" : "no"); + if(m->m_use_wifi_gecko) { const string &ip = m->m_cfg.getString("DEBUG", "wifi_gecko_ip"); u16 port = m->m_cfg.getInt("DEBUG", "wifi_gecko_port", 4405); if(ip.size() > 0 && port != 0) WiFiDebugger.Init(ip.c_str(), port); } + return 0; } diff --git a/source/menu/menu_ftp.cpp b/source/menu/menu_ftp.cpp new file mode 100644 index 00000000..d66ab3d1 --- /dev/null +++ b/source/menu/menu_ftp.cpp @@ -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 . + ****************************************************************************/ +#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")); +} + diff --git a/source/menu/menu_home.cpp b/source/menu/menu_home.cpp index 178e83b5..91a2abd4 100644 --- a/source/menu/menu_home.cpp +++ b/source/menu/menu_home.cpp @@ -18,14 +18,9 @@ #include "loader/cios.h" #include "loader/nk.h" #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_exittoLblTitle; -s16 m_homeBtnBack; s16 m_homeBtnSettings; s16 m_homeBtnReloadCache; @@ -48,19 +43,6 @@ s16 m_homeLblUser[4]; 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) { SetupInput(); @@ -139,45 +121,7 @@ bool CMenu::_Home(void) else if(m_btnMgr.selected(m_homeBtnFTP)) { _hideHome(); - /* net init as usual */ - _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); + _FTP(); _showHome(); } } @@ -336,8 +280,6 @@ void CMenu::_initHomeAndExitToMenu() 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_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); 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); - _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_homeBtnReloadCache, "HOME/RELOAD_CACHE", 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) { 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_homeBtnReloadCache, _t("home2", L"Reload Cache")); m_btnMgr.setText(m_homeBtnUpdate, _t("home3", L"Update")); diff --git a/source/network/FTP_Dir.cpp b/source/network/FTP_Dir.cpp index 6f7be4a3..5096009a 100644 --- a/source/network/FTP_Dir.cpp +++ b/source/network/FTP_Dir.cpp @@ -17,6 +17,8 @@ #include #include #include "FTP_Dir.hpp" +#include "ftp.h" +#include "net.h" #include "gecko/gecko.hpp" #include "devicemounter/DeviceHandler.hpp" #include "fileOps/fileOps.h" @@ -260,6 +262,54 @@ int ftp_delete(char *path) 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 } #endif /* __cplusplus */ diff --git a/source/network/FTP_Dir.hpp b/source/network/FTP_Dir.hpp index de4e100f..e819b7f1 100644 --- a/source/network/FTP_Dir.hpp +++ b/source/network/FTP_Dir.hpp @@ -43,6 +43,9 @@ int ftp_stat(char *file, struct stat *st); int ftp_rename(char *path, char *new_name); int ftp_delete(char *path); +bool ftp_startThread(void); +void ftp_endTread(void); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/source/network/ftp.c b/source/network/ftp.c index 15e8d7eb..b01a520e 100644 --- a/source/network/ftp.c +++ b/source/network/ftp.c @@ -20,6 +20,9 @@ #define FTP_BUFFER_SIZE 1024 #define MAX_CLIENTS 2 +bool ftp_allow_active = false; +u16 ftp_server_port = 21; + static const u16 SRC_PORT = 20; static const s32 EQUIT = 696969; static const char *CRLF = "\r\n"; @@ -54,11 +57,11 @@ typedef struct client_struct client_t; static client_t *clients[MAX_CLIENTS] = { NULL }; -void set_ftp_password(char *new_password) { - if (password) free(password); - if (new_password) { +void set_ftp_password(const char *new_password) { + if (password != NULL) free(password); + if (new_password != NULL && new_password[0] != '\0') { 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); } else { 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) { + 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; 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."); @@ -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) { s32 result = write_reply(client, 150, "Transferring data."); if (result >= 0) { - data_connection_handler handler = prepare_data_connection_active; - if (client->passive_socket >= 0) handler = prepare_data_connection_passive; - result = handler(client); + result = -1; + if(client->passive_socket >= 0) + result = prepare_data_connection_passive(client); + else if(ftp_allow_active == true) + result = prepare_data_connection_active(client); if (result < 0) { result = write_reply(client, 520, "Closing data connection, error occurred during transfer."); } else { @@ -662,7 +670,7 @@ static bool process_accept_events(s32 server) { } static void process_data_events(client_t *client) { - s32 result; + s32 result = -1; if (!client->data_connection_connected) { if (client->passive_socket >= 0) { struct sockaddr_in data_peer_address; @@ -672,7 +680,7 @@ static void process_data_events(client_t *client) { client->data_socket = result; 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 == -EINPROGRESS || result == -EALREADY) result = -EAGAIN; if (result != -EAGAIN && result != -EISCONN) gprintf("Unable to connect to client: [%i] %s\n", -result, strerror(-result)); diff --git a/source/network/ftp.h b/source/network/ftp.h index 061b2848..a7549d07 100644 --- a/source/network/ftp.h +++ b/source/network/ftp.h @@ -9,10 +9,13 @@ extern "C" { #endif /* __cplusplus */ 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); void cleanup_ftp(); +extern bool ftp_allow_active; +extern u16 ftp_server_port; + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/source/network/net.c b/source/network/net.c index 9efdd7c8..c3c01f04 100644 --- a/source/network/net.c +++ b/source/network/net.c @@ -9,6 +9,7 @@ #include #include "net.h" +#include "ftp.h" #include "FTP_Dir.hpp" #include "loader/sys.h" #include "gecko/gecko.hpp" @@ -18,6 +19,7 @@ #define FREAD_BUFFER_SIZE 32768 static u32 NET_BUFFER_SIZE = MAX_NET_BUFFER_SIZE; +s32 ftp_server = -1; s32 set_blocking(s32 s, bool blocking) { s32 flags; @@ -31,30 +33,48 @@ s32 net_close_blocking(s32 s) { return net_close(s); } -s32 create_server(u16 port) { - s32 server = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP); - if (server < 0) return -1;//die("Error creating socket", -server); - set_blocking(server, false); +bool create_server(void) { + ftp_init(); + ftp_server = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP); + if (ftp_server < 0) return false; + set_blocking(ftp_server, false); struct sockaddr_in bindAddress; memset(&bindAddress, 0, sizeof(bindAddress)); 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); s32 ret; - if ((ret = net_bind(server, (struct sockaddr *)&bindAddress, sizeof(bindAddress))) < 0) { - net_close(server); + if ((ret = net_bind(ftp_server, (struct sockaddr *)&bindAddress, sizeof(bindAddress))) < 0) { + net_close(ftp_server); + ftp_server = -1; gprintf("Error binding socket: [%i] %s\n", -ret, strerror(-ret)); - return ret; + return false; } - if ((ret = net_listen(server, 3)) < 0) { - net_close(server); + if ((ret = net_listen(ftp_server, 3)) < 0) { + net_close(ftp_server); + ftp_server = -1; 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); diff --git a/source/network/net.h b/source/network/net.h index 191767c4..e99c9b0a 100644 --- a/source/network/net.h +++ b/source/network/net.h @@ -13,7 +13,9 @@ extern "C" { void initialise_network(); s32 set_blocking(s32 s, bool blocking); 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_from_file(s32 s, FILE *f); s32 recv_to_file(s32 s, FILE *f); diff --git a/wii/wiiflow/Languages/english.ini b/wii/wiiflow/Languages/english.ini index 1711d49d..95b2508e 100644 --- a/wii/wiiflow/Languages/english.ini +++ b/wii/wiiflow/Languages/english.ini @@ -60,6 +60,8 @@ cfgbt2=Force Load cIOS cfgbt3=Force cIOS Revision cfgbt4=USB Port cfgbt5=Show source menu on boot +cfgbt6=Enable Multisource Features +cfgbt7=Start FTP Server on boot cfgc1=Exit To cfgc2=Adjust TV width cfgc3=Adjust TV height @@ -212,6 +214,7 @@ dlmsg25=Extraction must have failed! Renaming the backup to boot.dol dlmsg26=Updating cache... dlmsg27=Not enough memory! dlmsg28=Running FTP Server on %s:%u +dlmsg29=FTP Server is currently stopped. dlmsg3=Downloading from %s dlmsg4=Saving %s dlmsg5=%i/%i files downloaded @@ -243,6 +246,8 @@ errgame9=This is not a Wii or GC disc errgame10=Set USB failed: %d errneek1=Cannot launch neek2o. Verify your neek2o setup exit_to=Exit To +ftp1=Start +ftp2=Stop gameinfo1=Developer: %s gameinfo2=Publisher: %s gameinfo3=Region: %s