mirror of
https://github.com/DarkStore-3DS/DarkStore.git
synced 2026-07-03 00:39:02 +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);
|
||||
|
||||
void dirCopy(DirEntry* entry, int i, const char *destinationPath, const char *sourcePath);
|
||||
int fcopy(const char *sourcePath, const char *destinationPath);
|
||||
|
||||
#endif //FILE_BROWSE_HPP
|
||||
@@ -52,6 +52,9 @@ enum ScriptState {
|
||||
FAILED_DOWNLOAD,
|
||||
SCRIPT_CANCELED,
|
||||
SYNTAX_ERROR,
|
||||
COPY_ERROR,
|
||||
MOVE_ERROR,
|
||||
DELETE_ERROR,
|
||||
};
|
||||
|
||||
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 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 extractFile(std::string file, std::string input, std::string output, std::string message);
|
||||
Result createFile(const char * path);
|
||||
@@ -75,6 +78,9 @@ namespace ScriptHelper {
|
||||
void bootTitle(const std::string TitleID, bool isNAND, 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
|
||||
@@ -170,5 +170,8 @@
|
||||
"IS_PRERELEASE": "PreRelease: ",
|
||||
"DOWNLOAD_ERROR": "Download Error!",
|
||||
"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");
|
||||
else missing = true;
|
||||
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 if(type == "downloadFile") {
|
||||
@@ -963,8 +963,12 @@ Result ScriptList::runFunctions(nlohmann::json &json) {
|
||||
else missing = true;
|
||||
promptmsg = Lang::get("DELETE_PROMPT") + "\n" + directory;
|
||||
if(!missing) {
|
||||
if (Msg::promptMsg(promptmsg)) {
|
||||
removeDirRecursive(directory.c_str());
|
||||
if(access(directory.c_str(), F_OK) != 0 ) {
|
||||
ret = DELETE_ERROR;
|
||||
} else {
|
||||
if (Msg::promptMsg(promptmsg)) {
|
||||
removeDirRecursive(directory.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
else ret = SYNTAX_ERROR;
|
||||
@@ -1021,12 +1025,36 @@ Result ScriptList::runFunctions(nlohmann::json &json) {
|
||||
std::string Message = "";
|
||||
if(json.at(choice).at(i).contains("message")) Message = json.at(choice).at(i).at("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();
|
||||
else if (ret == FAILED_DOWNLOAD) Msg::DisplayWarnMsg(Lang::get("DOWNLOAD_ERROR"));
|
||||
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;
|
||||
}
|
||||
@@ -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");
|
||||
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) ScriptHelper::removeFile(file, message);
|
||||
if(!missing) ret = ScriptHelper::removeFile(file, message);
|
||||
else ret = SYNTAX_ERROR;
|
||||
|
||||
} else if(type == "downloadFile") {
|
||||
@@ -1296,8 +1296,12 @@ Result UniStore::execute() {
|
||||
else missing = true;
|
||||
promptmsg = Lang::get("DELETE_PROMPT") + "\n" + directory;
|
||||
if(!missing) {
|
||||
if (Msg::promptMsg(promptmsg)) {
|
||||
removeDirRecursive(directory.c_str());
|
||||
if(access(directory.c_str(), F_OK) != 0 ) {
|
||||
ret = DELETE_ERROR;
|
||||
} else {
|
||||
if (Msg::promptMsg(promptmsg)) {
|
||||
removeDirRecursive(directory.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
else ret = SYNTAX_ERROR;
|
||||
@@ -1357,12 +1361,37 @@ Result UniStore::execute() {
|
||||
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");
|
||||
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();
|
||||
else if (ret == FAILED_DOWNLOAD) Msg::DisplayWarnMsg(Lang::get("DOWNLOAD_ERROR"));
|
||||
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;
|
||||
}
|
||||
@@ -319,4 +319,101 @@ 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 "extract.hpp"
|
||||
#include "fileBrowse.hpp"
|
||||
#include "gui.hpp"
|
||||
#include "msg.hpp"
|
||||
#include "scriptHelper.hpp"
|
||||
#include "thread.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <unistd.h>
|
||||
|
||||
extern "C" {
|
||||
#include "cia.h"
|
||||
@@ -96,9 +98,14 @@ Result ScriptHelper::downloadFile(std::string file, std::string output, std::str
|
||||
}
|
||||
|
||||
// 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);
|
||||
deleteFile(file.c_str());
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Install a file.
|
||||
@@ -194,4 +201,30 @@ Result ScriptHelper::prompt(std::string message) {
|
||||
ret = SCRIPT_CANCELED;
|
||||
}
|
||||
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