mirror of
https://github.com/DarkStore-3DS/DarkStore.git
synced 2026-07-05 00:38:52 +00:00
Add copy & move & more error checks.
This commit is contained in:
@@ -24,4 +24,7 @@ bool returnIfExist(const std::string &path, const std::vector<std::string> &exte
|
|||||||
|
|
||||||
std::string selectFilePath(std::string selectText, const std::vector<std::string> &extensionList, int selectionMode = 1);
|
std::string selectFilePath(std::string selectText, const std::vector<std::string> &extensionList, int selectionMode = 1);
|
||||||
|
|
||||||
|
void dirCopy(DirEntry* entry, int i, const char *destinationPath, const char *sourcePath);
|
||||||
|
int fcopy(const char *sourcePath, const char *destinationPath);
|
||||||
|
|
||||||
#endif //FILE_BROWSE_HPP
|
#endif //FILE_BROWSE_HPP
|
||||||
@@ -52,6 +52,9 @@ enum ScriptState {
|
|||||||
FAILED_DOWNLOAD,
|
FAILED_DOWNLOAD,
|
||||||
SCRIPT_CANCELED,
|
SCRIPT_CANCELED,
|
||||||
SYNTAX_ERROR,
|
SYNTAX_ERROR,
|
||||||
|
COPY_ERROR,
|
||||||
|
MOVE_ERROR,
|
||||||
|
DELETE_ERROR,
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace ScriptHelper {
|
namespace ScriptHelper {
|
||||||
@@ -63,7 +66,7 @@ namespace ScriptHelper {
|
|||||||
Result downloadRelease(std::string repo, std::string file, std::string output, bool includePrereleases, bool showVersions, std::string message);
|
Result downloadRelease(std::string repo, std::string file, std::string output, bool includePrereleases, bool showVersions, std::string message);
|
||||||
Result downloadFile(std::string file, std::string output, std::string message);
|
Result downloadFile(std::string file, std::string output, std::string message);
|
||||||
|
|
||||||
void removeFile(std::string file, std::string message);
|
Result removeFile(std::string file, std::string message);
|
||||||
void installFile(std::string file, std::string message);
|
void installFile(std::string file, std::string message);
|
||||||
void extractFile(std::string file, std::string input, std::string output, std::string message);
|
void extractFile(std::string file, std::string input, std::string output, std::string message);
|
||||||
Result createFile(const char * path);
|
Result createFile(const char * path);
|
||||||
@@ -75,6 +78,9 @@ namespace ScriptHelper {
|
|||||||
void bootTitle(const std::string TitleID, bool isNAND, std::string message);
|
void bootTitle(const std::string TitleID, bool isNAND, std::string message);
|
||||||
|
|
||||||
Result prompt(std::string message);
|
Result prompt(std::string message);
|
||||||
|
|
||||||
|
Result copyFile(std::string source, std::string destination, std::string message);
|
||||||
|
Result renameFile(std::string oldName, std::string newName, std::string message);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -170,5 +170,8 @@
|
|||||||
"IS_PRERELEASE": "PreRelease: ",
|
"IS_PRERELEASE": "PreRelease: ",
|
||||||
"DOWNLOAD_ERROR": "Download Error!",
|
"DOWNLOAD_ERROR": "Download Error!",
|
||||||
"SCRIPT_CANCELED": "Script Canceled!",
|
"SCRIPT_CANCELED": "Script Canceled!",
|
||||||
"SYNTAX_ERROR": "Syntax Error!"
|
"SYNTAX_ERROR": "Syntax Error!",
|
||||||
|
"COPY_ERROR": "Copy Error!",
|
||||||
|
"MOVE_ERROR": "Move Error!",
|
||||||
|
"DELETE_ERROR": "Delete Error!"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -896,7 +896,7 @@ Result ScriptList::runFunctions(nlohmann::json &json) {
|
|||||||
if(json.at(choice).at(i).contains("file")) file = json.at(choice).at(i).at("file");
|
if(json.at(choice).at(i).contains("file")) file = json.at(choice).at(i).at("file");
|
||||||
else missing = true;
|
else missing = true;
|
||||||
if(json.at(choice).at(i).contains("message")) message = json.at(choice).at(i).at("message");
|
if(json.at(choice).at(i).contains("message")) message = json.at(choice).at(i).at("message");
|
||||||
if(!missing) ScriptHelper::removeFile(file, message);
|
if(!missing) ret = ScriptHelper::removeFile(file, message);
|
||||||
else ret = SYNTAX_ERROR;
|
else ret = SYNTAX_ERROR;
|
||||||
|
|
||||||
} else if(type == "downloadFile") {
|
} else if(type == "downloadFile") {
|
||||||
@@ -963,8 +963,12 @@ Result ScriptList::runFunctions(nlohmann::json &json) {
|
|||||||
else missing = true;
|
else missing = true;
|
||||||
promptmsg = Lang::get("DELETE_PROMPT") + "\n" + directory;
|
promptmsg = Lang::get("DELETE_PROMPT") + "\n" + directory;
|
||||||
if(!missing) {
|
if(!missing) {
|
||||||
if (Msg::promptMsg(promptmsg)) {
|
if(access(directory.c_str(), F_OK) != 0 ) {
|
||||||
removeDirRecursive(directory.c_str());
|
ret = DELETE_ERROR;
|
||||||
|
} else {
|
||||||
|
if (Msg::promptMsg(promptmsg)) {
|
||||||
|
removeDirRecursive(directory.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else ret = SYNTAX_ERROR;
|
else ret = SYNTAX_ERROR;
|
||||||
@@ -1021,12 +1025,36 @@ Result ScriptList::runFunctions(nlohmann::json &json) {
|
|||||||
std::string Message = "";
|
std::string Message = "";
|
||||||
if(json.at(choice).at(i).contains("message")) Message = json.at(choice).at(i).at("message");
|
if(json.at(choice).at(i).contains("message")) Message = json.at(choice).at(i).at("message");
|
||||||
ret = ScriptHelper::prompt(Message);
|
ret = ScriptHelper::prompt(Message);
|
||||||
|
} else if (type == "copy") {
|
||||||
|
std::string Message = "", source = "", destination = "";
|
||||||
|
bool missing = false;
|
||||||
|
if(json.at(choice).at(i).contains("source")) source = json.at(choice).at(i).at("source");
|
||||||
|
else missing = true;
|
||||||
|
if(json.at(choice).at(i).contains("destination")) destination = json.at(choice).at(i).at("destination");
|
||||||
|
else missing = true;
|
||||||
|
if(json.at(choice).at(i).contains("message")) Message = json.at(choice).at(i).at("message");
|
||||||
|
if (!missing) ret = ScriptHelper::copyFile(source, destination, Message);
|
||||||
|
else ret = SYNTAX_ERROR;
|
||||||
|
|
||||||
|
} else if (type == "move") {
|
||||||
|
std::string Message = "", oldFile = "", newFile = "";
|
||||||
|
bool missing = false;
|
||||||
|
if(json.at(choice).at(i).contains("old")) oldFile = json.at(choice).at(i).at("old");
|
||||||
|
else missing = true;
|
||||||
|
if(json.at(choice).at(i).contains("new")) newFile = json.at(choice).at(i).at("new");
|
||||||
|
else missing = true;
|
||||||
|
if(json.at(choice).at(i).contains("message")) Message = json.at(choice).at(i).at("message");
|
||||||
|
if (!missing) ret = ScriptHelper::renameFile(oldFile, newFile, Message);
|
||||||
|
else ret = SYNTAX_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ret == NONE) doneMsg();
|
if (ret == NONE) doneMsg();
|
||||||
else if (ret == FAILED_DOWNLOAD) Msg::DisplayWarnMsg(Lang::get("DOWNLOAD_ERROR"));
|
else if (ret == FAILED_DOWNLOAD) Msg::DisplayWarnMsg(Lang::get("DOWNLOAD_ERROR"));
|
||||||
else if (ret == SCRIPT_CANCELED) Msg::DisplayWarnMsg(Lang::get("SCRIPT_CANCELED"));
|
else if (ret == SCRIPT_CANCELED) Msg::DisplayWarnMsg(Lang::get("SCRIPT_CANCELED"));
|
||||||
else Msg::DisplayWarnMsg(Lang::get("SYNTAX_ERROR"));
|
else if (ret == SYNTAX_ERROR) Msg::DisplayWarnMsg(Lang::get("SYNTAX_ERROR"));
|
||||||
|
else if (ret == COPY_ERROR) Msg::DisplayWarnMsg(Lang::get("COPY_ERROR"));
|
||||||
|
else if (ret == MOVE_ERROR) Msg::DisplayWarnMsg(Lang::get("MOVE_ERROR"));
|
||||||
|
else if (ret == DELETE_ERROR) Msg::DisplayWarnMsg(Lang::get("DELETE_ERROR"));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -1228,7 +1228,7 @@ Result UniStore::execute() {
|
|||||||
if(appStoreJson.at("storeContent").at(Selection).at("script").at(i).contains("file")) file = appStoreJson.at("storeContent").at(Selection).at("script").at(i).at("file");
|
if(appStoreJson.at("storeContent").at(Selection).at("script").at(i).contains("file")) file = appStoreJson.at("storeContent").at(Selection).at("script").at(i).at("file");
|
||||||
else missing = true;
|
else missing = true;
|
||||||
if(appStoreJson.at("storeContent").at(Selection).at("script").at(i).contains("message")) message = appStoreJson.at("storeContent").at(Selection).at("script").at(i).at("message");
|
if(appStoreJson.at("storeContent").at(Selection).at("script").at(i).contains("message")) message = appStoreJson.at("storeContent").at(Selection).at("script").at(i).at("message");
|
||||||
if(!missing) ScriptHelper::removeFile(file, message);
|
if(!missing) ret = ScriptHelper::removeFile(file, message);
|
||||||
else ret = SYNTAX_ERROR;
|
else ret = SYNTAX_ERROR;
|
||||||
|
|
||||||
} else if(type == "downloadFile") {
|
} else if(type == "downloadFile") {
|
||||||
@@ -1296,8 +1296,12 @@ Result UniStore::execute() {
|
|||||||
else missing = true;
|
else missing = true;
|
||||||
promptmsg = Lang::get("DELETE_PROMPT") + "\n" + directory;
|
promptmsg = Lang::get("DELETE_PROMPT") + "\n" + directory;
|
||||||
if(!missing) {
|
if(!missing) {
|
||||||
if (Msg::promptMsg(promptmsg)) {
|
if(access(directory.c_str(), F_OK) != 0 ) {
|
||||||
removeDirRecursive(directory.c_str());
|
ret = DELETE_ERROR;
|
||||||
|
} else {
|
||||||
|
if (Msg::promptMsg(promptmsg)) {
|
||||||
|
removeDirRecursive(directory.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else ret = SYNTAX_ERROR;
|
else ret = SYNTAX_ERROR;
|
||||||
@@ -1357,12 +1361,37 @@ Result UniStore::execute() {
|
|||||||
std::string Message = "";
|
std::string Message = "";
|
||||||
if(appStoreJson.at("storeContent").at(Selection).at("script").at(i).contains("message")) Message = appStoreJson.at("storeContent").at(Selection).at("script").at(i).at("message");
|
if(appStoreJson.at("storeContent").at(Selection).at("script").at(i).contains("message")) Message = appStoreJson.at("storeContent").at(Selection).at("script").at(i).at("message");
|
||||||
ret = ScriptHelper::prompt(Message);
|
ret = ScriptHelper::prompt(Message);
|
||||||
|
|
||||||
|
} else if (type == "copy") {
|
||||||
|
std::string Message = "", source = "", destination = "";
|
||||||
|
bool missing = false;
|
||||||
|
if(appStoreJson.at("storeContent").at(Selection).at("script").at(i).contains("source")) source = appStoreJson.at("storeContent").at(Selection).at("script").at(i).at("source");
|
||||||
|
else missing = true;
|
||||||
|
if(appStoreJson.at("storeContent").at(Selection).at("script").at(i).contains("destination")) destination = appStoreJson.at("storeContent").at(Selection).at("script").at(i).at("destination");
|
||||||
|
else missing = true;
|
||||||
|
if(appStoreJson.at("storeContent").at(Selection).at("script").at(i).contains("message")) Message = appStoreJson.at("storeContent").at(Selection).at("script").at(i).at("message");
|
||||||
|
if (!missing) ret = ScriptHelper::copyFile(source, destination, Message);
|
||||||
|
else ret = SYNTAX_ERROR;
|
||||||
|
|
||||||
|
} else if (type == "move") {
|
||||||
|
std::string Message = "", oldFile = "", newFile = "";
|
||||||
|
bool missing = false;
|
||||||
|
if(appStoreJson.at("storeContent").at(Selection).at("script").at(i).contains("old")) oldFile = appStoreJson.at("storeContent").at(Selection).at("script").at(i).at("old");
|
||||||
|
else missing = true;
|
||||||
|
if(appStoreJson.at("storeContent").at(Selection).at("script").at(i).contains("new")) newFile = appStoreJson.at("storeContent").at(Selection).at("script").at(i).at("new");
|
||||||
|
else missing = true;
|
||||||
|
if(appStoreJson.at("storeContent").at(Selection).at("script").at(i).contains("message")) Message = appStoreJson.at("storeContent").at(Selection).at("script").at(i).at("message");
|
||||||
|
if (!missing) ret = ScriptHelper::renameFile(oldFile, newFile, Message);
|
||||||
|
else ret = SYNTAX_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ret == NONE) doneMsg();
|
if (ret == NONE) doneMsg();
|
||||||
else if (ret == FAILED_DOWNLOAD) Msg::DisplayWarnMsg(Lang::get("DOWNLOAD_ERROR"));
|
else if (ret == FAILED_DOWNLOAD) Msg::DisplayWarnMsg(Lang::get("DOWNLOAD_ERROR"));
|
||||||
else if (ret == SCRIPT_CANCELED) Msg::DisplayWarnMsg(Lang::get("SCRIPT_CANCELED"));
|
else if (ret == SCRIPT_CANCELED) Msg::DisplayWarnMsg(Lang::get("SCRIPT_CANCELED"));
|
||||||
else Msg::DisplayWarnMsg(Lang::get("SYNTAX_ERROR"));
|
else if (ret == SYNTAX_ERROR) Msg::DisplayWarnMsg(Lang::get("SYNTAX_ERROR"));
|
||||||
|
else if (ret == COPY_ERROR) Msg::DisplayWarnMsg(Lang::get("COPY_ERROR"));
|
||||||
|
else if (ret == MOVE_ERROR) Msg::DisplayWarnMsg(Lang::get("MOVE_ERROR"));
|
||||||
|
else if (ret == DELETE_ERROR) Msg::DisplayWarnMsg(Lang::get("DELETE_ERROR"));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -320,3 +320,100 @@ std::string selectFilePath(std::string selectText, const std::vector<std::string
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define copyBufSize 0x8000
|
||||||
|
|
||||||
|
u32 copyBuf[copyBufSize];
|
||||||
|
|
||||||
|
void dirCopy(DirEntry* entry, int i, const char *destinationPath, const char *sourcePath) {
|
||||||
|
std::vector<DirEntry> dirContents;
|
||||||
|
dirContents.clear();
|
||||||
|
if(entry->isDirectory) chdir((sourcePath + ("/" + entry->name)).c_str());
|
||||||
|
getDirectoryContents(dirContents);
|
||||||
|
if(((int)dirContents.size()) == 1) mkdir((destinationPath + ("/" + entry->name)).c_str(), 0777);
|
||||||
|
if(((int)dirContents.size()) != 1) fcopy((sourcePath + ("/" + entry->name)).c_str(), (destinationPath + ("/" + entry->name)).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
int fcopy(const char *sourcePath, const char *destinationPath) {
|
||||||
|
DIR *isDir = opendir(sourcePath);
|
||||||
|
|
||||||
|
if(isDir != NULL) {
|
||||||
|
closedir(isDir);
|
||||||
|
|
||||||
|
// Source path is a directory
|
||||||
|
chdir(sourcePath);
|
||||||
|
std::vector<DirEntry> dirContents;
|
||||||
|
getDirectoryContents(dirContents);
|
||||||
|
DirEntry* entry = &dirContents.at(1);
|
||||||
|
|
||||||
|
mkdir(destinationPath, 0777);
|
||||||
|
for(int i = 1; i < ((int)dirContents.size()); i++) {
|
||||||
|
chdir(sourcePath);
|
||||||
|
entry = &dirContents.at(i);
|
||||||
|
dirCopy(entry, i, destinationPath, sourcePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
chdir(destinationPath);
|
||||||
|
chdir("..");
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
closedir(isDir);
|
||||||
|
|
||||||
|
// Source path is a file
|
||||||
|
FILE* sourceFile = fopen(sourcePath, "rb");
|
||||||
|
off_t fsize = 0;
|
||||||
|
if(sourceFile) {
|
||||||
|
fseek(sourceFile, 0, SEEK_END);
|
||||||
|
fsize = ftell(sourceFile); // Get source file's size
|
||||||
|
fseek(sourceFile, 0, SEEK_SET);
|
||||||
|
} else {
|
||||||
|
fclose(sourceFile);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE* destinationFile = fopen(destinationPath, "wb");
|
||||||
|
//if(destinationFile) {
|
||||||
|
fseek(destinationFile, 0, SEEK_SET);
|
||||||
|
/*} else {
|
||||||
|
fclose(sourceFile);
|
||||||
|
fclose(destinationFile);
|
||||||
|
return -1;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
off_t offset = 0;
|
||||||
|
int numr;
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
scanKeys();
|
||||||
|
if(keysHeld() & KEY_B) {
|
||||||
|
// Cancel copying
|
||||||
|
fclose(sourceFile);
|
||||||
|
fclose(destinationFile);
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printf("\x1b[16;0H");
|
||||||
|
printf("Progress:\n");
|
||||||
|
printf("%i/%i Bytes ", (int)offset, (int)fsize);
|
||||||
|
|
||||||
|
// Copy file to destination path
|
||||||
|
numr = fread(copyBuf, 2, copyBufSize, sourceFile);
|
||||||
|
fwrite(copyBuf, 2, numr, destinationFile);
|
||||||
|
offset += copyBufSize;
|
||||||
|
|
||||||
|
if(offset > fsize) {
|
||||||
|
fclose(sourceFile);
|
||||||
|
fclose(destinationFile);
|
||||||
|
|
||||||
|
printf("\x1b[17;0H");
|
||||||
|
printf("%i/%i Bytes ", (int)fsize, (int)fsize);
|
||||||
|
for(int i = 0; i < 30; i++) gspWaitForVBlank();
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,12 +26,14 @@
|
|||||||
|
|
||||||
#include "download.hpp"
|
#include "download.hpp"
|
||||||
#include "extract.hpp"
|
#include "extract.hpp"
|
||||||
|
#include "fileBrowse.hpp"
|
||||||
#include "gui.hpp"
|
#include "gui.hpp"
|
||||||
#include "msg.hpp"
|
#include "msg.hpp"
|
||||||
#include "scriptHelper.hpp"
|
#include "scriptHelper.hpp"
|
||||||
#include "thread.hpp"
|
#include "thread.hpp"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "cia.h"
|
#include "cia.h"
|
||||||
@@ -96,9 +98,14 @@ Result ScriptHelper::downloadFile(std::string file, std::string output, std::str
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove a File.
|
// Remove a File.
|
||||||
void ScriptHelper::removeFile(std::string file, std::string message) {
|
Result ScriptHelper::removeFile(std::string file, std::string message) {
|
||||||
|
Result ret = NONE;
|
||||||
|
if(access(file.c_str(), F_OK) != 0 ) {
|
||||||
|
return DELETE_ERROR;
|
||||||
|
}
|
||||||
Msg::DisplayMsg(message);
|
Msg::DisplayMsg(message);
|
||||||
deleteFile(file.c_str());
|
deleteFile(file.c_str());
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Install a file.
|
// Install a file.
|
||||||
@@ -195,3 +202,29 @@ Result ScriptHelper::prompt(std::string message) {
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result ScriptHelper::copyFile(std::string source, std::string destination, std::string message) {
|
||||||
|
Result ret = NONE;
|
||||||
|
if(access(source.c_str(), F_OK) != 0 ) {
|
||||||
|
return COPY_ERROR;
|
||||||
|
}
|
||||||
|
Msg::DisplayMsg(message);
|
||||||
|
// If destination does not exist, create dirs.
|
||||||
|
if(access(destination.c_str(), F_OK) != 0 ) {
|
||||||
|
makeDirs(destination.c_str());
|
||||||
|
}
|
||||||
|
fcopy(source.c_str(), destination.c_str());
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ScriptHelper::renameFile(std::string oldName, std::string newName, std::string message) {
|
||||||
|
Result ret = NONE;
|
||||||
|
if(access(oldName.c_str(), F_OK) != 0 ) {
|
||||||
|
return MOVE_ERROR;
|
||||||
|
}
|
||||||
|
Msg::DisplayMsg(message);
|
||||||
|
// TODO: Kinda avoid that?
|
||||||
|
makeDirs(newName.c_str());
|
||||||
|
rename(oldName.c_str(), newName.c_str());
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user