mirror of
https://github.com/J-D-K/JKSV.git
synced 2026-03-22 01:34:13 -05:00
299 lines
5.7 KiB
C++
299 lines
5.7 KiB
C++
#include <fstream>
|
|
#include <cstdio>
|
|
#include <switch.h>
|
|
#include <dirent.h>
|
|
#include <unistd.h>
|
|
|
|
#include "file.h"
|
|
#include "util.h"
|
|
#include "sys.h"
|
|
#include "ui.h"
|
|
#include "gfx.h"
|
|
|
|
#define BUFF_SIZE 512 * 1024
|
|
|
|
namespace fs
|
|
{
|
|
bool mountSave(data::user& usr, data::titledata& open)
|
|
{
|
|
FsFileSystem sv;
|
|
Result res = 0;
|
|
|
|
if(open.getType() == FsSaveDataType_SaveData)
|
|
{
|
|
res = fsMount_SaveData(&sv, open.getID(), usr.getUID());
|
|
if(R_FAILED(res))
|
|
return false;
|
|
|
|
int r = fsdevMountDevice("sv", sv);
|
|
if(r == -1)
|
|
return false;
|
|
}
|
|
else if(sys::sysSave && open.getType() == FsSaveDataType_SystemSaveData)
|
|
{
|
|
res = fsMount_SystemSaveData(&sv, open.getID());
|
|
if(R_FAILED(res))
|
|
return false;
|
|
|
|
int r = fsdevMountDevice("sv", sv);
|
|
if(r == -1)
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
dirList::dirList(const std::string& _path)
|
|
{
|
|
path = _path;
|
|
d = opendir(path.c_str());
|
|
|
|
while((ent = readdir(d)))
|
|
{
|
|
item.push_back(ent->d_name);
|
|
}
|
|
|
|
closedir(d);
|
|
}
|
|
|
|
void dirList::reassign(const std::string& _path)
|
|
{
|
|
path = _path;
|
|
|
|
d = opendir(path.c_str());
|
|
|
|
item.clear();
|
|
|
|
while((ent = readdir(d)))
|
|
{
|
|
item.push_back(ent->d_name);
|
|
}
|
|
|
|
closedir(d);
|
|
}
|
|
|
|
void dirList::rescan()
|
|
{
|
|
item.clear();
|
|
d = opendir(path.c_str());
|
|
|
|
while((ent = readdir(d)))
|
|
{
|
|
item.push_back(ent->d_name);
|
|
}
|
|
|
|
closedir(d);
|
|
}
|
|
|
|
std::string dirList::getItem(int index)
|
|
{
|
|
return item[index];
|
|
}
|
|
|
|
bool dirList::isDir(int index)
|
|
{
|
|
std::string fullPath = path + item[index];
|
|
struct stat s;
|
|
if(stat(fullPath.c_str(), &s) == 0)
|
|
{
|
|
if(S_ISDIR(s.st_mode))
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
unsigned dirList::getCount()
|
|
{
|
|
return item.size();
|
|
}
|
|
|
|
void copyFile(const std::string& from, const std::string& to)
|
|
{
|
|
std::fstream f(from, std::ios::in | std::ios::binary);
|
|
std::fstream t(to, std::ios::out | std::ios::binary);
|
|
|
|
f.seekg(0, f.end);
|
|
size_t fileSize = f.tellg();
|
|
f.seekg(0, f.beg);
|
|
|
|
uint8_t *buff = new uint8_t[BUFF_SIZE];
|
|
ui::progBar prog(fileSize);
|
|
|
|
std::string copyString = "Copying " + from + "...";
|
|
copyString = util::getWrappedString(copyString, 64, 1136);
|
|
for(unsigned i = 0; i < fileSize; )
|
|
{
|
|
f.read((char *)buff, BUFF_SIZE);
|
|
t.write((char *)buff, f.gcount());
|
|
|
|
i += f.gcount();
|
|
prog.update(i);
|
|
|
|
prog.draw(copyString);
|
|
|
|
gfx::handleBuffs();
|
|
}
|
|
|
|
delete[] buff;
|
|
|
|
f.close();
|
|
t.close();
|
|
}
|
|
|
|
void copyFileCommit(const std::string& from, const std::string& to, const std::string& dev)
|
|
{
|
|
std::fstream f(from, std::ios::in | std::ios::binary);
|
|
std::fstream t(to, std::ios::out | std::ios::binary);
|
|
|
|
f.seekg(0, f.end);
|
|
size_t fileSize = f.tellg();
|
|
f.seekg(0, f.beg);
|
|
|
|
uint8_t *buff = new uint8_t[BUFF_SIZE];
|
|
ui::progBar prog(fileSize);
|
|
|
|
std::string copyString = "Copying " + from + "...";
|
|
copyString = util::getWrappedString(copyString, 64, 1136);
|
|
for(unsigned i = 0; i < fileSize; )
|
|
{
|
|
f.read((char *)buff, BUFF_SIZE);
|
|
t.write((char *)buff, f.gcount());
|
|
|
|
i += f.gcount();
|
|
prog.update(i);
|
|
|
|
prog.draw(copyString);
|
|
|
|
gfx::handleBuffs();
|
|
}
|
|
|
|
delete[] buff;
|
|
|
|
f.close();
|
|
t.close();
|
|
|
|
Result res = fsdevCommitDevice(dev.c_str());
|
|
if(R_FAILED(res))
|
|
ui::showError("Error committing file to device", res);
|
|
}
|
|
|
|
void copyDirToDir(const std::string& from, const std::string& to)
|
|
{
|
|
dirList list(from);
|
|
|
|
for(unsigned i = 0; i < list.getCount(); i++)
|
|
{
|
|
if(list.isDir(i))
|
|
{
|
|
std::string newFrom = from + list.getItem(i) + "/";
|
|
std::string newTo = to + list.getItem(i);
|
|
mkdir(newTo.c_str(), 0777);
|
|
newTo += "/";
|
|
|
|
copyDirToDir(newFrom, newTo);
|
|
}
|
|
else
|
|
{
|
|
std::string fullFrom = from + list.getItem(i);
|
|
std::string fullTo = to + list.getItem(i);
|
|
|
|
copyFile(fullFrom, fullTo);
|
|
}
|
|
}
|
|
}
|
|
|
|
void copyDirToDirCommit(const std::string& from, const std::string& to, const std::string& dev)
|
|
{
|
|
dirList list(from);
|
|
|
|
for(unsigned i = 0; i < list.getCount(); i++)
|
|
{
|
|
if(list.isDir(i))
|
|
{
|
|
std::string newFrom = from + list.getItem(i) + "/";
|
|
std::string newTo = to + list.getItem(i);
|
|
mkdir(newTo.c_str(), 0777);
|
|
newTo += "/";
|
|
|
|
copyDirToDirCommit(newFrom, newTo, dev);
|
|
}
|
|
else
|
|
{
|
|
std::string fullFrom = from + list.getItem(i);
|
|
std::string fullTo = to + list.getItem(i);
|
|
|
|
copyFileCommit(fullFrom, fullTo, dev);
|
|
}
|
|
}
|
|
}
|
|
|
|
void delDir(const std::string& path)
|
|
{
|
|
dirList list(path);
|
|
for(unsigned i = 0; i < list.getCount(); i++)
|
|
{
|
|
if(list.isDir(i))
|
|
{
|
|
std::string newPath = path + "/" + list.getItem(i) + "/";
|
|
delDir(newPath);
|
|
|
|
std::string delPath = path + list.getItem(i);
|
|
rmdir(delPath.c_str());
|
|
}
|
|
else
|
|
{
|
|
std::string delPath = path + list.getItem(i);
|
|
std::remove(delPath.c_str());
|
|
}
|
|
}
|
|
|
|
rmdir(path.c_str());
|
|
}
|
|
|
|
void dumpAllUserSaves(data::user& u)
|
|
{
|
|
for(unsigned i = 0; i < u.titles.size(); i++)
|
|
{
|
|
if(fs::mountSave(u, u.titles[i]))
|
|
{
|
|
util::makeTitleDir(u, u.titles[i]);
|
|
|
|
//sdmc:/JKSV/[title]/[user] - [date]/
|
|
std::string outPath = util::getTitleDir(u, u.titles[i]) + u.getUsernameSafe() + " - " + util::getDateTime();
|
|
mkdir(outPath.c_str(), 777);
|
|
outPath += "/";
|
|
|
|
std::string root = "sv:/";
|
|
|
|
fs::copyDirToDir(root, outPath);
|
|
|
|
fsdevUnmountDevice("sv");
|
|
}
|
|
}
|
|
}
|
|
|
|
std::string getFileProps(const std::string& _path)
|
|
{
|
|
std::string ret = "";
|
|
std::fstream get(_path, std::ios::in | std::ios::binary);
|
|
if(get.is_open())
|
|
{
|
|
//Size
|
|
get.seekg(0, get.end);
|
|
unsigned fileSize = get.tellg();
|
|
get.seekg(0, get.beg);
|
|
|
|
get.close();
|
|
|
|
//Probably add more later
|
|
|
|
char tmp[256];
|
|
std::sprintf(tmp, "Path: \"%s\"\nSize: %u", _path.c_str(), fileSize);
|
|
|
|
ret = tmp;
|
|
}
|
|
return ret;
|
|
}
|
|
}
|