diff --git a/inc/file.h b/inc/file.h index 84d552d..ffb7a44 100644 --- a/inc/file.h +++ b/inc/file.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "fsfile.h" #include "data.h" @@ -32,6 +33,9 @@ namespace fs //Same as above, but commits data to 'dev' after every file is closed void copyDirToDirCommit(const std::string& from, const std::string& to, const std::string& dev); + //Copies unzfile to 'to' + void copyZipToDir(unzFile *unz, const std::string& to, const std::string& dev); + //deletes file void delfile(const std::string& path); //Recursively deletes 'path' diff --git a/inc/ui.h b/inc/ui.h index 9241b24..9d7265a 100644 --- a/inc/ui.h +++ b/inc/ui.h @@ -49,7 +49,7 @@ namespace ui //Strings for file mode menu extern std::string advMenuStr[6]; //Strings for extras menu - extern std::string exMenuStr[10]; + extern std::string exMenuStr[11]; //Strings for options menu extern std::string optMenuStr[13]; //Strings for options explanations diff --git a/src/file.cpp b/src/file.cpp index 24bf921..9398c6d 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "file.h" @@ -40,154 +41,17 @@ static struct } } sortDirList; -typedef struct -{ - std::string from, to, dev; - uint64_t *pos; - bool fin; -} copyArgs; - -static copyArgs *copyArgsCreate(const std::string& _f, const std::string& _t, const std::string& _dev, uint64_t *_p) -{ - copyArgs *ret = new copyArgs; - ret->from = _f; - ret->to = _t; - ret->dev = _dev; - ret->pos = _p; - ret->fin = false; - return ret; -} - -static void copyfile_t(void *a) -{ - copyArgs *args = (copyArgs *)a; - - FILE *f = fopen(args->from.c_str(), "rb"); - FILE *t = fopen(args->to.c_str(), "wb"); - if(f == NULL || t == NULL) - { - fclose(f); - fclose(t); - args->fin = true; - return; - } - - size_t read = 0; - unsigned char *buff = new unsigned char[BUFF_SIZE]; - while((read = fread(buff, 1, BUFF_SIZE, f))) - { - fwrite(buff, 1, read, t); - *args->pos += read; - } - delete[] buff; - fclose(f); - fclose(t); - - args->fin = true; -} - -static void copyfileFS_t(void *a) -{ - copyArgs *args = (copyArgs *)a; - - FSFILE *f = fsfopen(args->from.c_str(), FsOpenMode_Read); - FSFILE *t = fsfopen(args->to.c_str(), FsOpenMode_Write); - if(f == NULL || t == NULL) - { - fsfclose(f); - fsfclose(t); - args->fin = true; - return; - } - - size_t read = 0; - unsigned char *buff = new unsigned char[BUFF_SIZE]; - while((read = fsfread(buff, 1, BUFF_SIZE, f))) - { - fsfwrite(buff, 1, read, t); - *args->pos += read; - } - delete[] buff; - fsfclose(f); - fsfclose(t); - - args->fin = true; -} - -static void copyfileCommit_t(void *a) -{ - copyArgs *args = (copyArgs *)a; - - FILE *f = fopen(args->from.c_str(), "rb"); - FILE *t = fopen(args->to.c_str(), "wb"); - if(f == NULL || t == NULL) - { - fclose(f); - fclose(t); - args->fin = true; - return; - } - - size_t read = 0; - unsigned char *buff = new unsigned char[BUFF_SIZE]; - while((read = fread(buff, 1, BUFF_SIZE, f))) - { - fwrite(buff, 1, read, t); - *args->pos += read; - } - delete[] buff; - fclose(f); - fclose(t); - - fsdevCommitDevice(args->dev.c_str()); - - args->fin = true; -} - -static void copyfileCommitFS_t(void *a) -{ - copyArgs *args = (copyArgs *)a; - - FSFILE *f = fsfopen(args->from.c_str(), FsOpenMode_Read); - FSFILE *t = fsfopen(args->to.c_str(), FsOpenMode_Write); - if(f == NULL || t == NULL) - { - fsfclose(f); - fsfclose(t); - args->fin = true; - return; - } - - size_t read = 0; - unsigned char *buff = new unsigned char[BUFF_SIZE]; - while((read = fsfread(buff, 1, BUFF_SIZE, f))) - { - fsfwrite(buff, 1, read, t); - *args->pos += read; - } - delete[] buff; - fsfclose(f); - fsfclose(t); - - fsdevCommitDevice(args->dev.c_str()); - - args->fin = true; -} - static void mkdirRec(const std::string& _p) { //skip first slash size_t pos = _p.find('/', 0) + 1; while((pos = _p.find('/', pos)) != _p.npos) { - std::string create; - create.assign(_p.begin(), _p.begin() + pos); - mkdir(create.c_str(), 777); + mkdir(_p.substr(0, pos).c_str(), 777); ++pos; } } - void fs::init() { if(fs::fileExists("sdmc:/switch/jksv_dir.txt")) @@ -381,48 +245,52 @@ int fs::dataFile::getNextValueInt() void fs::copyFile(const std::string& from, const std::string& to) { - Thread cpyThread; - uint64_t gProg = 0; - copyArgs *thr = copyArgsCreate(from, to, "", &gProg); + uint8_t *buff = new uint8_t[BUFF_SIZE]; + ui::progBar prog(fs::fsize(from)); if(data::directFsCmd) - threadCreate(&cpyThread, copyfileFS_t, thr, NULL, 0x4000, 0x2B, 1); - else - threadCreate(&cpyThread, copyfile_t, thr, NULL, 0x4000, 0x2B, 1); - - ui::progBar fileProg(fsize(from)); - threadStart(&cpyThread); - while(!thr->fin) { - fileProg.update(*thr->pos); - gfxBeginFrame(); - fileProg.draw(from, ui::copyHead); - gfxEndFrame(); + FSFILE *in = fsfopen(from.c_str(), FsOpenMode_Read); + FSFILE *out = fsfopen(to.c_str(), FsOpenMode_Write); + + size_t readIn = 0; + while((readIn = fsfread(buff, 1, BUFF_SIZE, in)) > 0) + { + fsfwrite(buff, 1, readIn, out); + + prog.update(fsftell(in)); + gfxBeginFrame(); + prog.draw(from, ui::copyHead); + gfxEndFrame(); + } + fsfclose(in); + fsfclose(out); } - threadClose(&cpyThread); - delete thr; + else + { + FILE *in = fopen(from.c_str(), "rb"); + FILE *out = fopen(to.c_str(), "wb"); + + size_t readIn = 0; + while((readIn = fread(buff, 1, BUFF_SIZE, in)) > 0) + { + fwrite(buff, 1, readIn, out); + + prog.update(ftell(in)); + gfxBeginFrame(); + prog.draw(from, ui::copyHead); + gfxEndFrame(); + } + fclose(in); + fclose(out); + } + delete[] buff; } void fs::copyFileCommit(const std::string& from, const std::string& to, const std::string& dev) { - Thread cpyThread; - uint64_t gProg = 0; - copyArgs *thr = copyArgsCreate(from, to, dev, &gProg); - if(data::directFsCmd) - threadCreate(&cpyThread, copyfileCommitFS_t, thr, NULL, 0x4000, 0x2B, 1); - else - threadCreate(&cpyThread, copyfileCommit_t, thr, NULL, 0x4000, 0x2B, 1); - - ui::progBar fileProg(fsize(from)); - threadStart(&cpyThread); - while(!thr->fin) - { - fileProg.update(*thr->pos); - gfxBeginFrame(); - fileProg.draw(from, ui::copyHead); - gfxEndFrame(); - } - threadClose(&cpyThread); - delete thr; + fs::copyFile(from, to); + if(R_FAILED(fsdevCommitDevice(dev.c_str()))) + ui::showMessage("*Error*", "Error committing file to device."); } void fs::copyDirToDir(const std::string& from, const std::string& to) @@ -455,14 +323,21 @@ void fs::copyDirToDir(const std::string& from, const std::string& to) void copyFileToZip(const std::string& from, zipFile *to) { + ui::progBar prog(fs::fsize(from)); FILE *cpy = fopen(from.c_str(), "rb"); - size_t readIn = 0; + size_t readIn = 0, offset = 0; uint8_t *inBuff= new uint8_t[BUFF_SIZE]; while((readIn = fread(inBuff, 1, BUFF_SIZE, cpy)) > 0) { if(zipWriteInFileInZip(*to, inBuff, readIn) != 0) - ui::showMessage("fail", "here"); + ui::showMessage("Failed", "zipWriteInFileInZip"); + + offset += readIn; + prog.update(offset); + gfxBeginFrame(); + prog.draw(from, ui::copyHead); + gfxEndFrame(); } delete[] inBuff; @@ -492,6 +367,59 @@ void fs::copyDirToZip(const std::string& from, zipFile *to) } } +void fs::copyZipToDir(unzFile *unz, const std::string& to, const std::string& dev) +{ + char filename[FS_MAX_PATH]; + uint8_t *buff = new uint8_t[BUFF_SIZE]; + int readIn = 0; + unz_file_info info; + do + { + unzGetCurrentFileInfo(*unz, &info, filename, FS_MAX_PATH, NULL, 0, NULL, 0); + unzOpenCurrentFile(*unz); + std::string path = to + filename; + mkdirRec(path.substr(0, path.find_last_of('/') + 1)); + ui::progBar prog(info.uncompressed_size); + size_t done = 0; + if(data::directFsCmd) + { + FSFILE *out = fsfopen(path.c_str(), FsOpenMode_Write); + while((readIn = unzReadCurrentFile(*unz, buff, BUFF_SIZE)) > 0) + { + done += readIn; + fsfwrite(buff, 1, readIn, out); + prog.update(done); + + gfxBeginFrame(); + prog.draw(filename, ui::copyHead); + gfxEndFrame(); + } + fsfclose(out); + } + else + { + FILE *out = fopen(path.c_str(), "wb"); + while((readIn = unzReadCurrentFile(*unz, buff, BUFF_SIZE)) > 0) + { + done += readIn; + fwrite(buff, 1, readIn, out); + prog.update(done); + + gfxBeginFrame(); + prog.draw(filename, ui::copyHead); + gfxEndFrame(); + } + fclose(out); + } + unzCloseCurrentFile(*unz); + if(R_FAILED(fsdevCommitDevice(dev.c_str()))) + ui::showMessage("*Error*", "Error committing file to device."); + } + while(unzGoToNextFile(*unz) != UNZ_END_OF_LIST_OF_FILE); + + delete[] buff; +} + void fs::copyDirToDirCommit(const std::string& from, const std::string& to, const std::string& dev) { dirList list(from); diff --git a/src/ui.cpp b/src/ui.cpp index 37b2472..f7018ea 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -67,7 +67,7 @@ std::string ui::confEraseNand = "*WARNING*: This *will* erase the save data for std::string ui::confEraseFolder = "*WARNING*: This *will* delete the current save data for #%s# *from your system*! Are you sure you want to continue?"; std::string ui::noSavesFound = "No saves found for #%s#!"; std::string ui::advMenuStr[6] = { "Copy to ", "Delete", "Rename", "Make Dir", "Properties", "Close" }; -std::string ui::exMenuStr[10] = { "SD to SD Browser", "BIS: PRODINFOF", "BIS: SAFE", "BIS: SYSTEM", "BIS: USER", "Remove Update", "Terminate Process", "Mount System Save", "Rescan Titles", "Mount Process RomFS" }; +std::string ui::exMenuStr[11] = { "SD to SD Browser", "BIS: PRODINFOF", "BIS: SAFE", "BIS: SYSTEM", "BIS: USER", "Remove Update", "Terminate Process", "Mount System Save", "Rescan Titles", "Mount Process RomFS", "Backup JKSV Folder" }; std::string ui::optMenuStr[13] = { "Include Dev Sv: ", "AutoBackup: ", "Overclock: ", "Hold to Delete: ", "Hold to Restore: ", "Hold to Overwrite: ", "Force Mount: ", "Account Sys. Saves: ", "Write to Sys. Saves: ", "Text UI Mode: ", "Direct FS Cmd: ", "Skip User Select: ", "Export to ZIP: " }; std::string ui::optMenuExp[13] = { diff --git a/src/ui/fldrsel.cpp b/src/ui/fldrsel.cpp index 4f67378..7f2fa02 100644 --- a/src/ui/fldrsel.cpp +++ b/src/ui/fldrsel.cpp @@ -25,14 +25,14 @@ void ui::folderMenuPrepare(data::user& usr, data::titledata& dat) void ui::createNewBackup(const uint64_t& held) { - std::string folder; + std::string out; if(held & KEY_R) - folder = data::curUser.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD); + out = data::curUser.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD); else if(held & KEY_L) - folder = data::curUser.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YDM); + out = data::curUser.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YDM); else if(held & KEY_ZL) - folder = data::curUser.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_HOYSTE); + out = data::curUser.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_HOYSTE); else { const std::string dict[] = @@ -46,21 +46,18 @@ void ui::createNewBackup(const uint64_t& held) data::curData.getTitleSafe(), util::generateAbbrev(data::curData) }; - folder = util::getStringInput("", "Enter a folder name", 64, 8, dict); + out = util::getStringInput("", "Enter a name", 64, 8, dict); } - if(!folder.empty()) + if(!out.empty()) { - std::string path = data::curData.getPath() + "/" + folder; + std::string path = data::curData.getPath() + "/" + out; if(data::zip) { path += ".zip"; - zipFile cpyTo = zipOpen(path.c_str(), 0); - if(cpyTo != NULL) - { - fs::copyDirToZip("sv:/", &cpyTo); - zipClose(cpyTo, ""); - } + zipFile zip = zipOpen(path.c_str(), 0); + fs::copyDirToZip("sv:/", &zip); + zipClose(zip, NULL); } else { @@ -68,7 +65,6 @@ void ui::createNewBackup(const uint64_t& held) path += "/"; fs::copyDirToDir("sv:/", path); } - folderMenuPrepare(data::curUser, data::curData); } } @@ -77,63 +73,95 @@ void ui::overwriteBackup(unsigned ind) { fs::dirList list(data::curData.getPath()); - std::string folderName = list.getItem(ind); - if(confirm(data::holdOver, ui::confOverwrite.c_str(), folderName.c_str())) + std::string itemName = list.getItem(ind); + if(confirm(data::holdOver, ui::confOverwrite.c_str(), itemName.c_str())) { - std::string toPath = data::curData.getPath() + folderName + "/"; - //Delete and recreate - fs::delDir(toPath); - mkdir(toPath.c_str(), 777); - - std::string root = "sv:/"; - - fs::copyDirToDir(root, toPath); + if(list.isDir(ind)) + { + std::string toPath = data::curData.getPath() + itemName + "/"; + //Delete and recreate + fs::delDir(toPath); + mkdir(toPath.c_str(), 777); + fs::copyDirToDir("sv:/", toPath); + } + else + { + std::string toPath = data::curData.getPath() + itemName; + fs::delfile(toPath); + zipFile zip = zipOpen(toPath.c_str(), 0); + fs::copyDirToZip("sv:/", &zip); + zipClose(zip, NULL); + } } } void ui::restoreBackup(unsigned ind) { - if((data::curData.getType() != FsSaveDataType_System || data::sysSaveWrite) && folderMenu.getSelected() > 0) + fs::dirList list(data::curData.getPath()); + std::string folderName = list.getItem(ind); + if((data::curData.getType() != FsSaveDataType_System || data::sysSaveWrite) && folderMenu.getSelected() > 0 && confirm(data::holdRest, ui::confRestore.c_str(), folderName.c_str())) { - fs::dirList list(data::curData.getPath()); - - std::string folderName = list.getItem(ind); - if(confirm(data::holdRest, ui::confRestore.c_str(), folderName.c_str())) + if(data::autoBack) { - if(data::autoBack) + switch(data::zip) { - std::string autoFolder = data::curData.getPath() + "/AUTO - " + data::curUser.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_ASC); - mkdir(autoFolder.c_str(), 777); - autoFolder += "/"; + case true: + { + std::string autoZip = data::curData.getPath() + "/AUTO " + data::curUser.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + ".zip"; + zipFile zip = zipOpen(autoZip.c_str(), 0); + fs::copyDirToZip("sv:/", &zip); + zipClose(zip, NULL); + } + break; - std::string root = "sv:/"; - fs::copyDirToDir(root, autoFolder); + case false: + { + std::string autoFolder = data::curData.getPath() + "/AUTO - " + data::curUser.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD); + mkdir(autoFolder.c_str(), 777); + autoFolder += "/"; + fs::copyDirToDir("sv:/", autoFolder); + } + break; } + } + if(!list.isDir(ind)) + { + std::string path = data::curData.getPath() + list.getItem(ind); + unzFile unz = unzOpen(path.c_str()); + fs::copyZipToDir(&unz, "sv:/", "sv"); + unzClose(unz); + } + else + { std::string fromPath = data::curData.getPath() + folderName + "/"; - std::string root = "sv:/"; - - fs::delDir(root); + fs::delDir("sv:/"); fsdevCommitDevice("sv"); - fs::copyDirToDirCommit(fromPath, root, "sv"); - - //Rescan init folder menu if autobak to show changes - if(data::autoBack) - folderMenuPrepare(data::curUser, data::curData); + fs::copyDirToDirCommit(fromPath, "sv:/", "sv"); } } + if(data::autoBack) + folderMenuPrepare(data::curUser, data::curData); } void ui::deleteBackup(unsigned ind) { fs::dirList list(data::curData.getPath()); - std::string folderName = list.getItem(folderMenu.getSelected() - 1); - if(ui::confirmDelete(folderName)) + std::string itemName = list.getItem(folderMenu.getSelected() - 1); + if(ui::confirmDelete(itemName)) { - std::string delPath = data::curData.getPath() + folderName + "/"; - fs::delDir(delPath); + if(list.isDir(ind)) + { + std::string delPath = data::curData.getPath() + itemName + "/"; + fs::delDir(delPath); + } + else + { + std::string delPath = data::curData.getPath() + itemName; + fs::delfile(delPath); + } } folderMenuPrepare(data::curUser, data::curData); diff --git a/src/ui/txtui.cpp b/src/ui/txtui.cpp index 462a77f..b6787a6 100644 --- a/src/ui/txtui.cpp +++ b/src/ui/txtui.cpp @@ -196,7 +196,7 @@ void ui::exMenuPrep() { exMenu.reset(); exMenu.setParams(76, 98, 310); - for(unsigned i = 0; i < 10; i++) + for(unsigned i = 0; i < 11; i++) exMenu.addOpt(ui::exMenuStr[i]); } @@ -320,6 +320,19 @@ void ui::updateExMenu(const uint64_t& down, const uint64_t& held) } } break; + + case 10: + { + fs::logClose(); + remove(std::string(fs::getWorkDir() + "log.txt").c_str()); + std::string zipName = "JKSV - " + util::getDateTime(util::DATE_FMT_ASC) + ".zip"; + zipFile jksv = zipOpen(std::string("sdmc:/" + zipName).c_str(), 0); + fs::copyDirToZip(fs::getWorkDir(), &jksv); + zipClose(jksv, NULL); + rename(std::string("sdmc:/" + zipName).c_str(), std::string(fs::getWorkDir() + zipName).c_str()); + fs::logOpen(); + } + break; } } else if(down & KEY_B)