Rework backups

This commit is contained in:
Pk11 2022-01-14 18:50:35 -06:00
parent fc13fbeb89
commit 6d8fb9ca44
6 changed files with 168 additions and 134 deletions

View File

@ -1,5 +1,7 @@
#include "install.h"
#include "main.h" #include "main.h"
#include "menu.h" #include "menu.h"
#include "rom.h"
#include "storage.h" #include "storage.h"
#include "message.h" #include "message.h"
#include "nand/nandio.h" #include "nand/nandio.h"
@ -13,8 +15,8 @@ enum {
}; };
static void generateList(Menu* m); static void generateList(Menu* m);
static void printItem(Menu* m);
static int subMenu(); static int subMenu();
static void restore(Menu* m);
static bool delete(Menu* m); static bool delete(Menu* m);
void backupMenu() void backupMenu()
@ -43,6 +45,7 @@ void backupMenu()
generateList(m); generateList(m);
printMenu(m); printMenu(m);
printItem(m);
} }
if (keysDown() & KEY_B || m->itemCount <= 0) if (keysDown() & KEY_B || m->itemCount <= 0)
@ -53,7 +56,7 @@ void backupMenu()
switch (subMenu()) switch (subMenu())
{ {
case BACKUP_MENU_RESTORE: case BACKUP_MENU_RESTORE:
restore(m); install(m->items[m->cursor].value, false);
break; break;
case BACKUP_MENU_DELETE: case BACKUP_MENU_DELETE:
@ -62,11 +65,11 @@ void backupMenu()
{ {
resetMenu(m); resetMenu(m);
generateList(m); generateList(m);
} }
} }
break; break;
} }
printMenu(m); printMenu(m);
} }
} }
@ -119,7 +122,7 @@ static void generateList(Menu* m)
m->page += sign(m->changePage); m->page += sign(m->changePage);
m->changePage = 0; m->changePage = 0;
bool done = false; bool done = false;
struct dirent* ent; struct dirent* ent;
DIR* dir = opendir(BACKUP_PATH); DIR* dir = opendir(BACKUP_PATH);
@ -128,17 +131,16 @@ static void generateList(Menu* m)
{ {
int count = 0; int count = 0;
while ( (ent = readdir(dir)) && done == false) while ( (ent = readdir(dir)) && !done)
{ {
if (strcmp(".", ent->d_name) == 0 || strcmp("..", ent->d_name) == 0) if (ent->d_name[0] == '.')
continue; continue;
if (ent->d_type == DT_DIR) if (ent->d_type == DT_DIR)
{ {
//current item is not on page
if (count < m->page * ITEMS_PER_PAGE) if (count < m->page * ITEMS_PER_PAGE)
count += 1; count += 1;
else else
{ {
if (m->itemCount >= ITEMS_PER_PAGE) if (m->itemCount >= ITEMS_PER_PAGE)
@ -146,13 +148,40 @@ static void generateList(Menu* m)
else else
{ {
char* path = (char*)malloc(strlen(BACKUP_PATH) + strlen(ent->d_name) + 8); char* fpath = (char*)malloc(strlen(BACKUP_PATH) + strlen(ent->d_name) + 8);
sprintf(path, "%s/%s", BACKUP_PATH, ent->d_name); sprintf(fpath, "%s/%s", BACKUP_PATH, ent->d_name);
addMenuItem(m, ent->d_name, path, 0); addMenuItem(m, ent->d_name, fpath, 1);
}
}
}
else
{
if (strcasecmp(strrchr(ent->d_name, '.'), ".nds") == 0 ||
strcasecmp(strrchr(ent->d_name, '.'), ".app") == 0 ||
strcasecmp(strrchr(ent->d_name, '.'), ".dsi") == 0 ||
strcasecmp(strrchr(ent->d_name, '.'), ".ids") == 0 ||
strcasecmp(strrchr(ent->d_name, '.'), ".srl") == 0 ||
strcasecmp(strrchr(ent->d_name, '.'), ".cia") == 0)
{
if (count < m->page * ITEMS_PER_PAGE)
count += 1;
else
{
if (m->itemCount >= ITEMS_PER_PAGE)
done = true;
else
{
char* fpath = (char*)malloc(strlen(BACKUP_PATH) + strlen(ent->d_name) + 8);
sprintf(fpath, "%s/%s", BACKUP_PATH, ent->d_name);
free(path); addMenuItem(m, ent->d_name, fpath, 0);
}
free(fpath);
}
}
} }
} }
} }
@ -167,64 +196,34 @@ static void generateList(Menu* m)
if (m->cursor >= m->itemCount) if (m->cursor >= m->itemCount)
m->cursor = m->itemCount - 1; m->cursor = m->itemCount - 1;
printItem(m);
printMenu(m); printMenu(m);
} }
static void restore(Menu* m) static void printItem(Menu* m)
{ {
char* fpath = m->items[m->cursor].value; if (!m) return;
if (m->itemCount <= 0) return;
bool choice = NO; if (m->items[m->cursor].directory)
{ clearScreen(&topScreen);
char str[] = "Are you sure you want to restore\n"; else
char* msg = (char*)malloc(strlen(str) + strlen(fpath) + 1); printRomInfo(m->items[m->cursor].value);
sprintf(msg, "%s%s", str, fpath);
choice = choiceBox(msg);
free(msg);
}
if (choice == YES)
{
if (!fpath)
{
messageBox("\x1B[31mFailed to restore backup.\n\x1B[47m");
}
else
{
if (!sdnandMode && !nandio_unlock_writing())
return;
clearScreen(&bottomScreen);
if (!copyDir(fpath, sdnandMode ? "sd:/title" : "nand:/title"))
{
messagePrint("\x1B[31m\nFailed to restore backup.\n\x1B[47m");
}
else
{
messagePrint("\x1B[42m\nBackup restored.\n\x1B[47m");
}
if (!sdnandMode)
nandio_lock_writing();
}
}
} }
static bool delete(Menu* m) static bool delete(Menu* m)
{ {
if (!m) return false; if (!m) return false;
char* label = m->items[m->cursor].label;
char* fpath = m->items[m->cursor].value; char* fpath = m->items[m->cursor].value;
bool result = false; bool result = false;
bool choice = NO; bool choice = NO;
{ {
char str[] = "Are you sure you want to delete\n"; const char str[] = "Are you sure you want to delete\n";
char* msg = (char*)malloc(strlen(str) + strlen(fpath) + 4); char* msg = (char*)malloc(strlen(str) + strlen(label) + 2);
sprintf(msg, "%s\n%s", str, fpath); sprintf(msg, "%s%s?", str, label);
choice = choiceBox(msg); choice = choiceBox(msg);
@ -239,7 +238,7 @@ static bool delete(Menu* m)
} }
else else
{ {
if (!dirExists(fpath)) if (access(fpath, F_OK) != 0)
{ {
messageBox("\x1B[31mFailed to delete backup.\n\x1B[47m"); messageBox("\x1B[31mFailed to delete backup.\n\x1B[47m");
} }
@ -247,15 +246,27 @@ static bool delete(Menu* m)
{ {
clearScreen(&bottomScreen); clearScreen(&bottomScreen);
if (deleteDir(fpath)) //app
{ remove(fpath);
result = true;
messagePrint("\x1B[42m\nBackup deleted.\n\x1B[47m"); //tmd
} strcpy(strrchr(fpath, '.'), ".tmd");
else remove(fpath);
{
messagePrint("\n\x1B[31mError deleting backup.\n\x1B[47m"); //public save
} strcpy(strrchr(fpath, '.'), ".pub");
remove(fpath);
//private save
strcpy(strrchr(fpath, '.'), ".prv");
remove(fpath);
//banner save
strcpy(strrchr(fpath, '.'), ".bnr");
remove(fpath);
result = true;
messagePrint("\x1B[42m\nBackup deleted.\n\x1B[47m");
} }
} }
} }

View File

@ -160,7 +160,6 @@ static void generateList(Menu* m)
{ {
int count = 0; int count = 0;
//scan /dsi/
while ( (ent = readdir(dir)) && !done) while ( (ent = readdir(dir)) && !done)
{ {
if (ent->d_name[0] == '.') if (ent->d_name[0] == '.')
@ -187,14 +186,12 @@ static void generateList(Menu* m)
} }
else else
{ {
if (strstr(ent->d_name, ".nds") != NULL || if (strcasecmp(strrchr(ent->d_name, '.'), ".nds") == 0 ||
strstr(ent->d_name, ".app") != NULL || strcasecmp(strrchr(ent->d_name, '.'), ".app") == 0 ||
strstr(ent->d_name, ".dsi") != NULL || strcasecmp(strrchr(ent->d_name, '.'), ".dsi") == 0 ||
strstr(ent->d_name, ".cia") != NULL || strcasecmp(strrchr(ent->d_name, '.'), ".ids") == 0 ||
strstr(ent->d_name, ".NDS") != NULL || strcasecmp(strrchr(ent->d_name, '.'), ".srl") == 0 ||
strstr(ent->d_name, ".APP") != NULL || strcasecmp(strrchr(ent->d_name, '.'), ".cia") == 0)
strstr(ent->d_name, ".DSI") != NULL ||
strstr(ent->d_name, ".CIA") != NULL)
{ {
if (count < m->page * ITEMS_PER_PAGE) if (count < m->page * ITEMS_PER_PAGE)
count += 1; count += 1;

View File

@ -137,19 +137,6 @@ bool getRomCode(tDSiHeader* h, char* out)
return true; return true;
} }
bool getTitleId(tDSiHeader* h, u32* low, u32* high)
{
if (!h) return false;
if (low != NULL)
*low = h->tid_low;
if (high != NULL)
*high = h->tid_high;
return true;
}
void printRomInfo(char const* fpath) void printRomInfo(char const* fpath)
{ {
clearScreen(&topScreen); clearScreen(&topScreen);

View File

@ -12,7 +12,6 @@ bool getGameTitlePath(char const* fpath, char* out, bool full);
bool getRomLabel(tDSiHeader* h, char* out); bool getRomLabel(tDSiHeader* h, char* out);
bool getRomCode(tDSiHeader* h, char* out); bool getRomCode(tDSiHeader* h, char* out);
bool getTitleId(tDSiHeader* h, u32* low, u32* high);
void printRomInfo(char const* fpath); void printRomInfo(char const* fpath);

View File

@ -4,7 +4,7 @@
#include <nds/ndstypes.h> #include <nds/ndstypes.h>
#include <stdio.h> #include <stdio.h>
#define BACKUP_PATH "sd:/titlebackup" #define BACKUP_PATH "sd:/_nds/ntm/backup"
#define BYTES_PER_BLOCK (1024*128) #define BYTES_PER_BLOCK (1024*128)
//printing //printing

View File

@ -228,13 +228,13 @@ static int subMenu()
static void backup(Menu* m) static void backup(Menu* m)
{ {
char* fpath = m->items[m->cursor].value; char* fpath = m->items[m->cursor].value;
char* backname = NULL; char *backname = NULL;
tDSiHeader* h = getRomHeader(fpath); tDSiHeader* h = getRomHeader(fpath);
{ {
//make backup folder name //make backup folder name
char label[16]; char label[13];
getRomLabel(h, label); getRomLabel(h, label);
char gamecode[5]; char gamecode[5];
@ -245,14 +245,14 @@ static void backup(Menu* m)
//make sure dir is unused //make sure dir is unused
char* dstpath = (char*)malloc(strlen(BACKUP_PATH) + strlen(backname) + 32); char* dstpath = (char*)malloc(strlen(BACKUP_PATH) + strlen(backname) + 32);
sprintf(dstpath, "%s/%s", BACKUP_PATH, backname); sprintf(dstpath, "%s/%s.nds", BACKUP_PATH, backname);
int try = 1; int try = 1;
while (dirExists(dstpath)) while (access(dstpath, F_OK) == 0)
{ {
try += 1; try += 1;
sprintf(backname, "%s-%s(%d)", label, gamecode, try); sprintf(backname, "%s-%s(%d)", label, gamecode, try);
sprintf(dstpath, "%s/%s", BACKUP_PATH, backname); sprintf(dstpath, "%s/%s.nds", BACKUP_PATH, backname);
} }
free(dstpath); free(dstpath);
@ -260,10 +260,10 @@ static void backup(Menu* m)
bool choice = NO; bool choice = NO;
{ {
char str[] = "Are you sure you want to backup\n"; const char str[] = "Are you sure you want to backup\n";
char* msg = (char*)malloc(strlen(str) + strlen(backname) + 1); char* msg = (char*)malloc(strlen(str) + strlen(backname) + 2);
sprintf(msg, "%s%s", str, backname); sprintf(msg, "%s%s?", str, backname);
choice = choiceBox(msg); choice = choiceBox(msg);
free(msg); free(msg);
@ -271,12 +271,8 @@ static void backup(Menu* m)
if (choice == YES) if (choice == YES)
{ {
u32 tid_low = 1; char srcpath[30];
u32 tid_high = 1; sprintf(srcpath, "%s:/title/%08lx/%08lx", sdnandMode ? "sd" : "nand", h->tid_high, h->tid_low);
getTitleId(h, &tid_low, &tid_high);
char* srcpath = (char*)malloc(strlen("nand:/title/") + 32);
sprintf(srcpath, "%s:/title/%08x/%08x", sdnandMode ? "sd" : "nand", (unsigned int)tid_high, (unsigned int)tid_low);
if (getSDCardFree() < getDirSize(srcpath, 0)) if (getSDCardFree() < getDirSize(srcpath, 0))
{ {
@ -284,42 +280,86 @@ static void backup(Menu* m)
} }
else else
{ {
char* dstpath = (char*)malloc(strlen(BACKUP_PATH) + strlen(backname) + 8);
sprintf(dstpath, "%s/%s", BACKUP_PATH, backname);
//create dirs //create dirs
mkdir(BACKUP_PATH, 0777); // sd:/titlebackup {
mkdir(dstpath, 0777); // sd:/titlebackup/App Name - XXXX //create subdirectories
free(dstpath); char backupPath[sizeof(BACKUP_PATH)];
strcpy(backupPath, BACKUP_PATH);
dstpath = (char*)malloc(strlen(BACKUP_PATH) + strlen(backname) + 16); for (char *slash = strchr(backupPath, '/'); *slash; slash = strchr(slash + 1, '/'))
sprintf(dstpath, "%s/%s/%08x", BACKUP_PATH, backname, (unsigned int)tid_high); {
char temp = *slash;
mkdir(dstpath, 0777); // sd:/titlebackup/App Name - XXXX/tid_high *slash = '\0';
free(dstpath); mkdir(backupPath, 0777);
*slash = temp;
dstpath = (char*)malloc(strlen(BACKUP_PATH) + strlen(backname) + 32); }
sprintf(dstpath, "%s/%s/%08x/%08x", BACKUP_PATH, backname, (unsigned int)tid_high, (unsigned int)tid_low); mkdir(backupPath, 0777); // sd:/_nds/ntm/backup
}
mkdir(dstpath, 0777); // sd:/titlebackup/App Name - XXXX/tid_high/tid_low
// iprintf("dst %s\nsrc %s", dstpath, srcpath);
// keyWait(KEY_A);
clearScreen(&bottomScreen); clearScreen(&bottomScreen);
if (!copyDir(srcpath, dstpath)) char path[256], dstpath[256];
messagePrint("\x1B[31m\nBackup error.\x1B[47m");
else
messagePrint("\x1B[42m\nBackup finished.\x1B[47m");
free(dstpath); //tmd
sprintf(path, "%s/content/title.tmd", srcpath);
sprintf(dstpath, "%s/%s.tmd", BACKUP_PATH, backname);
nocashMessage(path);
nocashMessage(dstpath);
if (access(path, F_OK) == 0)
{
//get app version
FILE *tmd = fopen(path, "rb");
if (tmd)
{
u8 appVersion;
fseek(tmd, 0x1E7, SEEK_SET);
fread(&appVersion, sizeof(appVersion), 1, tmd);
fclose(tmd);
iprintf("%s -> \n%s...\n", path, dstpath);
copyFile(path, dstpath);
//app
sprintf(path, "%s/content/000000%02x.app", srcpath, appVersion);
sprintf(dstpath, "%s/%s.nds", BACKUP_PATH, backname);
if (access(path, F_OK) == 0)
{
iprintf("%s -> \n%s...\n", path, dstpath);
copyFile(path, dstpath);
}
}
}
//public save
sprintf(path, "%s/data/public.sav", srcpath);
sprintf(dstpath, "%s/%s.pub", BACKUP_PATH, backname);
if (access(path, F_OK) == 0)
{
iprintf("%s -> \n%s...\n", path, dstpath);
copyFile(path, dstpath);
}
//private save
sprintf(path, "%s/data/private.sav", srcpath);
sprintf(dstpath, "%s/%s.prv", BACKUP_PATH, backname);
if (access(path, F_OK) == 0)
{
iprintf("%s -> \n%s...\n", path, dstpath);
copyFile(path, dstpath);
}
//banner save
sprintf(path, "%s/data/banner.sav", srcpath);
sprintf(dstpath, "%s/%s.bnr", BACKUP_PATH, backname);
if (access(path, F_OK) == 0)
{
iprintf("%s -> \n%s...\n", path, dstpath);
copyFile(path, dstpath);
}
messagePrint("\x1B[42m\nBackup finished.\x1B[47m");
} }
free(srcpath);
} }
free(backname);
free(h); free(h);
} }