From f261cf2f255b27e5ac396ac40fbe9ce9f2d31443 Mon Sep 17 00:00:00 2001 From: flb Date: Thu, 28 Jan 2021 20:26:41 +0100 Subject: [PATCH] Changed app update method --- .github/workflows/main.yml | 5 +- Makefile | 31 +---- README.md | 6 +- aiosu-forwarder/Makefile | 225 ++++++++++++++++++++++++++++++++ aiosu-forwarder/source/main.cpp | 38 ++++++ build.sh | 8 ++ include/constants.hpp | 3 + include/utils.hpp | 3 +- pack_release.sh | 4 +- resources/i18n/en-US/menus.json | 6 +- source/changelog_page.cpp | 3 + source/main.cpp | 19 --- source/tools_tab.cpp | 3 +- source/utils.cpp | 16 ++- 14 files changed, 314 insertions(+), 56 deletions(-) create mode 100644 aiosu-forwarder/Makefile create mode 100644 aiosu-forwarder/source/main.cpp create mode 100755 build.sh diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9f51348..f205f07 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,9 +13,12 @@ jobs: - name: Building aio-switch-updater run: | + pushd aiosu-forwarder + make + popd make -j$(nproc) - uses: actions/upload-artifact@master with: name: aio-switch-updater - path: aio-switch-updater*.nro + path: aio-switch-updater.nro diff --git a/Makefile b/Makefile index ba075d4..3722912 100644 --- a/Makefile +++ b/Makefile @@ -15,29 +15,6 @@ include $(DEVKITPRO)/libnx/switch_rules # SOURCES is a list of directories containing source code # DATA is a list of directories containing data files # INCLUDES is a list of directories containing header files -# ROMFS is the directory containing data to be added to RomFS, relative to the Makefile (Optional) -# -# NO_ICON: if set to anything, do not use icon. -# NO_NACP: if set to anything, no .nacp file is generated. -# APP_TITLE is the name of the app stored in the .nacp file (Optional) -# APP_AUTHOR is the author of the app stored in the .nacp file (Optional) -# APP_VERSION is the version of the app stored in the .nacp file (Optional) -# APP_TITLEID is the titleID of the app stored in the .nacp file (Optional) -# ICON is the filename of the icon (.jpg), relative to the project folder. -# If not set, it attempts to use one of the following (in this order): -# - .jpg -# - icon.jpg -# - /default_icon.jpg -# -# CONFIG_JSON is the filename of the NPDM config file (.json), relative to the project folder. -# If not set, it attempts to use one of the following (in this order): -# - .json -# - config.json -# If a JSON file is provided or autodetected, an ExeFS PFS0 (.nsp) is built instead -# of a homebrew executable (.nro). This is intended to be used for sysmodules. -# NACP building is skipped as well. -#--------------------------------------------------------------------------------- - BUILD := build SOURCES := source lib/zipper/source RESOURCES := resources @@ -45,8 +22,8 @@ DATA := data INCLUDES := include lib/zipper/include APP_TITLE := All-in-One Switch Updater APP_AUTHOR := HamletDuFromage -APP_VERSION := 1.4.3 -TARGET := $(notdir $(CURDIR))-v$(APP_VERSION) +APP_VERSION := 1.5.0 +TARGET := $(notdir $(CURDIR)) ROMFS := resources BOREALIS_PATH := lib/borealis @@ -79,7 +56,6 @@ ASFLAGS := -g $(ARCH) LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) LIBS := -lm -lcurl -lnx -lz -lmbedtls -lmbedx509 -lmbedcrypto -lstdc++fs -#LIBS := -ltwili -lm -lcurl -lnx -lz -lmbedtls -lmbedx509 -lmbedcrypto -lstdc++fs `freetype-config --libs` #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing @@ -190,6 +166,8 @@ $(ROMFS): @rm $(CURDIR)/$(ROMFS)/i18n/*/installer.json $(CURDIR)/$(ROMFS)/i18n/*/main.json $(CURDIR)/$(ROMFS)/i18n/*/popup.json @$(MAKE) -C $(CURDIR)/rcm -f $(CURDIR)/rcm/Makefile @cp $(CURDIR)/rcm/output/aio_rcm.bin $(CURDIR)/$(ROMFS)/aio_rcm.bin + #@$(MAKE) -C $(CURDIR)/aiosu-forwarder -f $(CURDIR)/aiosu-forwarder/Makefile + @cp $(CURDIR)/aiosu-forwarder/aiosu-forwarder.nro $(CURDIR)/$(ROMFS)/aiosu-forwarder.nro $(BUILD): $(ROMFS) @[ -d $@ ] || mkdir -p $@ @@ -200,6 +178,7 @@ clean: @echo clean ... ifeq ($(strip $(APP_JSON)),) @rm -fr $(BUILD) $(notdir $(CURDIR))*.nro $(notdir $(CURDIR))*.nacp $(notdir $(CURDIR))*.elf + @rm -fr $(CURDIR)/aiosu-forwarder/build $(CURDIR)/aiosu-forwarder/*.nro $(CURDIR)/aiosu-forwarder/*.nacp $(CURDIR)/aiosu-forwarder/*.elf else @rm -fr $(BUILD) $(TARGET).nsp $(TARGET).nso $(TARGET).npdm $(TARGET).elf endif diff --git a/README.md b/README.md index 4b16d05..456a7d9 100644 --- a/README.md +++ b/README.md @@ -58,10 +58,12 @@ sudo (dkp-)pacman -Sy ``` ```bash sudo (dkp-)pacman -S switch-glfw \ +switch-curl \ switch-glm \ switch-mbedtls \ switch-zlib ``` +Use [`switch-ex-curl`](https://github.com/eXhumer/switch-ex-curl) instead of `switch-curl` to use this app with an invalid SSL certificate. Clone the repository ```bash @@ -72,12 +74,14 @@ cd aio-switch-updater Compile ```bash make +``` OR +```bash make -j$(nproc) ``` ## Disclaimer -I do not own, host nor distribute any of the files that can be downloaded with this homebrew tool. At the owner's request, I will immediately remove the ability to download the problematic files. +I do not own, host nor distribute any of the files that can be downloaded with this homebrew tool. At the owner's request, I will immediately remove the ability to download any problematic file. ## Special thanks - [tiansongyu](https://github.com/tiansongyu) for bringing support for multi-language and for his Chinese translation. diff --git a/aiosu-forwarder/Makefile b/aiosu-forwarder/Makefile new file mode 100644 index 0000000..c168ec2 --- /dev/null +++ b/aiosu-forwarder/Makefile @@ -0,0 +1,225 @@ +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITPRO)),) +$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=/devkitpro") +endif + +TOPDIR ?= $(CURDIR) +include $(DEVKITPRO)/libnx/switch_rules + +#--------------------------------------------------------------------------------- +# TARGET is the name of the output +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# DATA is a list of directories containing data files +# INCLUDES is a list of directories containing header files +# ROMFS is the directory containing data to be added to RomFS, relative to the Makefile (Optional) +# +# NO_ICON: if set to anything, do not use icon. +# NO_NACP: if set to anything, no .nacp file is generated. +# APP_TITLE is the name of the app stored in the .nacp file (Optional) +# APP_AUTHOR is the author of the app stored in the .nacp file (Optional) +# APP_VERSION is the version of the app stored in the .nacp file (Optional) +# APP_TITLEID is the titleID of the app stored in the .nacp file (Optional) +# ICON is the filename of the icon (.jpg), relative to the project folder. +# If not set, it attempts to use one of the following (in this order): +# - .jpg +# - icon.jpg +# - /default_icon.jpg +# +# CONFIG_JSON is the filename of the NPDM config file (.json), relative to the project folder. +# If not set, it attempts to use one of the following (in this order): +# - .json +# - config.json +# If a JSON file is provided or autodetected, an ExeFS PFS0 (.nsp) is built instead +# of a homebrew executable (.nro). This is intended to be used for sysmodules. +# NACP building is skipped as well. +#--------------------------------------------------------------------------------- +TARGET := $(notdir $(CURDIR)) +BUILD := build +SOURCES := source +DATA := data +INCLUDES := include +APP_TITLE := aio-switch-updater forwarder +APP_AUTHOR := HamletDuFromage +APP_VERSION := 1.0 +#ROMFS := romfs + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE + +CFLAGS := -g -Wall -O2 -ffunction-sections \ + $(ARCH) $(DEFINES) + +CFLAGS += $(INCLUDE) -D__SWITCH__ + +CXXFLAGS := $(CFLAGS) -std=gnu++17 -fno-rtti -fno-exceptions + +ASFLAGS := -g $(ARCH) +LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) + +LIBS := -lnx + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(PORTLIBS) $(LIBNX) + + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +export OUTPUT := $(CURDIR)/$(TARGET) +export TOPDIR := $(CURDIR) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) +#--------------------------------------------------------------------------------- + export LD := $(CC) +#--------------------------------------------------------------------------------- +else +#--------------------------------------------------------------------------------- + export LD := $(CXX) +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- + +export OFILES_BIN := $(addsuffix .o,$(BINFILES)) +export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) +export OFILES := $(OFILES_BIN) $(OFILES_SRC) +export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES))) + +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) + +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) + +ifeq ($(strip $(CONFIG_JSON)),) + jsons := $(wildcard *.json) + ifneq (,$(findstring $(TARGET).json,$(jsons))) + export APP_JSON := $(TOPDIR)/$(TARGET).json + else + ifneq (,$(findstring config.json,$(jsons))) + export APP_JSON := $(TOPDIR)/config.json + endif + endif +else + export APP_JSON := $(TOPDIR)/$(CONFIG_JSON) +endif + +ifeq ($(strip $(ICON)),) + icons := $(wildcard *.jpg) + ifneq (,$(findstring $(TARGET).jpg,$(icons))) + export APP_ICON := $(TOPDIR)/$(TARGET).jpg + else + ifneq (,$(findstring icon.jpg,$(icons))) + export APP_ICON := $(TOPDIR)/icon.jpg + endif + endif +else + export APP_ICON := $(TOPDIR)/$(ICON) +endif + +ifeq ($(strip $(NO_ICON)),) + export NROFLAGS += --icon=$(APP_ICON) +endif + +ifeq ($(strip $(NO_NACP)),) + export NROFLAGS += --nacp=$(CURDIR)/$(TARGET).nacp +endif + +ifneq ($(APP_TITLEID),) + export NACPFLAGS += --titleid=$(APP_TITLEID) +endif + +ifneq ($(ROMFS),) + export NROFLAGS += --romfsdir=$(CURDIR)/$(ROMFS) +endif + +.PHONY: $(BUILD) clean all + +#--------------------------------------------------------------------------------- +all: $(BUILD) + +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... +ifeq ($(strip $(APP_JSON)),) + @rm -fr $(BUILD) $(TARGET).nro $(TARGET).nacp $(TARGET).elf +else + @rm -fr $(BUILD) $(TARGET).nsp $(TARGET).nso $(TARGET).npdm $(TARGET).elf +endif + + +#--------------------------------------------------------------------------------- +else +.PHONY: all + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +ifeq ($(strip $(APP_JSON)),) + +all : $(OUTPUT).nro + +ifeq ($(strip $(NO_NACP)),) +$(OUTPUT).nro : $(OUTPUT).elf $(OUTPUT).nacp +else +$(OUTPUT).nro : $(OUTPUT).elf +endif + +else + +all : $(OUTPUT).nsp + +$(OUTPUT).nsp : $(OUTPUT).nso $(OUTPUT).npdm + +$(OUTPUT).nso : $(OUTPUT).elf + +endif + +$(OUTPUT).elf : $(OFILES) + +$(OFILES_SRC) : $(HFILES_BIN) + +#--------------------------------------------------------------------------------- +# you need a rule like this for each extension you use as binary data +#--------------------------------------------------------------------------------- +%.bin.o %_bin.h : %.bin +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + @$(bin2o) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- diff --git a/aiosu-forwarder/source/main.cpp b/aiosu-forwarder/source/main.cpp new file mode 100644 index 0000000..16356cd --- /dev/null +++ b/aiosu-forwarder/source/main.cpp @@ -0,0 +1,38 @@ +#include +#include +#include + +#include + +#define PATH "/switch/aio-switch-updater/" +#define FULL_PATH "/switch/aio-switch-updater/aio-switch-updater.nro" +#define CONFIG_PATH "/config/aio-switch-updater/switch/aio-switch-updater/aio-switch-updater.nro" +#define PREFIX "/switch/aio-switch-updater/aio-switch-updater-v" +#define FORWARDER_PATH "/config/aio-switch-updater/aiosu-forwarder.nro" + + +int main(int argc, char* argv[]) + +{ + std::filesystem::create_directory(PATH); + std::filesystem::remove(FULL_PATH); + for (const auto & entry : std::filesystem::directory_iterator(PATH)){ + if(entry.path().string().find(PREFIX) != std::string::npos) { + std::filesystem::remove(entry.path().string()); + std::filesystem::remove(entry.path().string() + ".star"); + } + } + + if(std::filesystem::exists(CONFIG_PATH)){ + std::filesystem::create_directory(PATH); + std::filesystem::rename(CONFIG_PATH, FULL_PATH); + std::filesystem::remove_all("/config/aio-switch-updater/switch/aio-switch-updater/"); + rmdir("/config/aio-switch-updater/switch/aio-switch-updater/"); + rmdir("/config/aio-switch-updater/switch/"); + } + + std::filesystem::remove(FORWARDER_PATH); + + envSetNextLoad(FULL_PATH, ("\"" + std::string(FULL_PATH) + "\"").c_str()); + return 0; +} diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..73eb064 --- /dev/null +++ b/build.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +cd $DIR +pushd aiosu-forwarder +make +popd +make -j$(nproc) diff --git a/include/constants.hpp b/include/constants.hpp index e65bae0..2950683 100644 --- a/include/constants.hpp +++ b/include/constants.hpp @@ -70,6 +70,9 @@ #define SEPT_DIRECTORY_PATH "/config/aio-switch-updater/sept/" #define FW_DIRECTORY_PATH "/firmware/" +#define ROMFS_FORWARDER "romfs:/aiosu-forwarder.nro" +#define FORWARDER_PATH "/config/aio-switch-updater/aiosu-forwarder.nro" + #define LISTITEM_HEIGHT 50 diff --git a/include/utils.hpp b/include/utils.hpp index e06893c..bb0da95 100644 --- a/include/utils.hpp +++ b/include/utils.hpp @@ -42,4 +42,5 @@ int showDialogBox(std::string text, std::string opt1, std::string opt2); std::string getLatestTag(const char *url); Result CopyFile(const char src_path[FS_MAX_PATH], const char dest_path[FS_MAX_PATH]); void saveVersion(std::string version, const char* path); -std::string readVersion(const char* path); \ No newline at end of file +std::string readVersion(const char* path); +void cp(const char *to, const char *from); \ No newline at end of file diff --git a/pack_release.sh b/pack_release.sh index 70ae3bf..42f0195 100755 --- a/pack_release.sh +++ b/pack_release.sh @@ -4,5 +4,7 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" cd $DIR rm -r switch/aio-switch-updater/ mkdir -p switch/aio-switch-updater/ -ls -1 *.nro | xargs -L1 -I{} cp {} switch/aio-switch-updater/{} +cp aio-switch-updater.nro switch/aio-switch-updater/ +VERSION=$(grep "APP_VERSION :=" Makefile | cut -d' ' -f4) +cp aiosu-forwarder/aiosu-forwarder.nro switch/aio-switch-updater/aio-switch-updater-v$VERSION.nro zip -FSr aio-switch-updater.zip switch/ \ No newline at end of file diff --git a/resources/i18n/en-US/menus.json b/resources/i18n/en-US/menus.json index 60cbcf0..9b2e3d4 100644 --- a/resources/i18n/en-US/menus.json +++ b/resources/i18n/en-US/menus.json @@ -56,6 +56,8 @@ "v1_4_2_text": "\uE016 (hopefully) fixed unreliable copy of payloads.", "v1_4_3": "v1.4.3", "v1_4_3_text": "\uE016 Fixed switch not rebooting to hekate payload after updating.", + "v1_5_0": "v1.5.0", + "v1_5_0_text": "\uE016 Overhauled the app update feature.", "Ok_button": "Ok", "cheats_page.cpp":"", @@ -118,7 +120,7 @@ "firmware_text": "\uE016 Firmware dumps from 'https://darthsternie.net/switch-firmwares/'. Once downloaded, it will be extracted in '/firmware'. You can then install the update through Daybreak or ChoiDuJour.\n\uE016 Current FW: ", "currentCeatsver": "\uE016 This will download a daily updated archive of cheat codes from 'gbatemp.net'. Cheat codes for games you don't have installed won't be extracted to your SD card. You can turn off cheat updated in 'Tools->Cheat menu'.\n\uE016 Current cheats version: ", "operation_1": "sigpatches", - "list_sigpatches": "\uE016 Sigpatches allow your Switch to install and run unofficial NSP file. Make sure you pick the correct sigpatches for your setup (pure Atmosphere or Hekate+Atmosphere).", + "list_sigpatches": "\uE016 Sigpatches allow your Switch to install and run unofficial NSP file. Make sure you pick the correct sigpatches for your setup (pure Atmosphere or Hekate+Atmosphere). Reboot the console to apply patches.", "operation_2": "firmware", "list_not": "not found", "list_latest": "Latest version", @@ -185,7 +187,7 @@ "ultils_overwrite": "Do you want to overwrite existing .ini config files?", "ultis_file": "The downloaded file is not a CFW archive. This is most likely due to a broken link. If the problem persists after more than 3 hours, please open an issue on Github.", - "reboot_rcm" : "The Switch will now launch reboot to a special payload in order to finalise the install.", + "reboot_rcm" : "The Switch will now reboot to a special payload in order to finalise the install.", "hekate_dialogue" : "Do you want to also download Hekate?\nIf not, the Switch will now launch reboot to a special payload in order to finalise the install.", "Yes" : "Yes", "No" : "No", diff --git a/source/changelog_page.cpp b/source/changelog_page.cpp index 0d113ff..9f710c6 100644 --- a/source/changelog_page.cpp +++ b/source/changelog_page.cpp @@ -70,6 +70,9 @@ ChangelogPage::ChangelogPage() : AppletFrame(true, true) verTitles.push_back("menus/v1_4_3"_i18n ); changes.push_back("menus/v1_4_3_text"_i18n ); + verTitles.push_back("menus/v1_5_0"_i18n ); + changes.push_back("menus/v1_5_0_text"_i18n ); + int nbVersions = verTitles.size(); items.reserve(nbVersions); for(int i = nbVersions -1 ; i >= 0; i--){ diff --git a/source/main.cpp b/source/main.cpp index f5b7fe6..d7331b2 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -54,25 +54,6 @@ int main(int argc, char* argv[]) romfsInit(); createTree(CONFIG_PATH); - std::string appName = std::string(argv[0]).substr(5); - bool star = false; - //if(1){ - if(appName.find(APP_PATH) != std::string::npos){ - for(auto& p : std::filesystem::directory_iterator(APP_PATH)){ - if(p.path().extension().string() == ".nro" && p.path().string() != appName){ - std::cout << p.path().string() << std::endl; - std::filesystem::remove(p.path()); - } - if(p.path().extension().string() == ".star"){ - std::filesystem::remove(p.path()); - star = true; - } - } - } - if(star) { - std::ofstream starFile(std::string(APP_PATH) + ".aio-switch-updater-v" + APP_VERSION + ".nro.star", std::ofstream::out); - } - brls::Logger::setLogLevel(brls::LogLevel::DEBUG); brls::Logger::debug("Start"); diff --git a/source/tools_tab.cpp b/source/tools_tab.cpp index f41a2de..16823d2 100644 --- a/source/tools_tab.cpp +++ b/source/tools_tab.cpp @@ -1,5 +1,5 @@ #include "tools_tab.hpp" - + namespace i18n = brls::i18n; using namespace i18n::literals; ToolsTab::ToolsTab(std::string tag) : brls::List() @@ -123,6 +123,7 @@ ToolsTab::ToolsTab(std::string tag) : brls::List() cleanUp->setHeight(LISTITEM_HEIGHT); this->addView(cleanUp); + //tag = "1.TEST"; if(!tag.empty() && tag != APP_VERSION){ updateApp = new brls::ListItem("menus/tool_update"_i18n + tag +")"); std::string text("menus/tool_DownLoad"_i18n + std::string(APP_URL)); diff --git a/source/utils.cpp b/source/utils.cpp index a6f9a9c..8e4569f 100644 --- a/source/utils.cpp +++ b/source/utils.cpp @@ -173,10 +173,9 @@ void extractArchive(archiveType type, std::string tag){ } break; case app: - extract(APP_FILENAME); - nroPath += "aio-switch-updater-v" + tag + ".nro"; - //nroPath += "aio-switch-updater-vTEST.nro"; - envSetNextLoad(nroPath.c_str(), ("\"" + nroPath + "\"").c_str()); + extract(APP_FILENAME, CONFIG_PATH); + cp(ROMFS_FORWARDER, FORWARDER_PATH); + envSetNextLoad(FORWARDER_PATH, ("\"" + std::string(FORWARDER_PATH) + "\"").c_str()); romfsExit(); brls::Application::quit(); break; @@ -282,6 +281,15 @@ std::string getLatestTag(const char *url){ } } +void cp(const char *from, const char *to){ + std::ifstream src(from, std::ios::binary); + std::ofstream dst(to, std::ios::binary); + + if (src.good() && dst.good()) { + dst << src.rdbuf(); +} +} + Result CopyFile(const char src_path[FS_MAX_PATH], const char dest_path[FS_MAX_PATH]) { FsFileSystem *fs; Result ret = 0;