wiiload_plugin/src/fs/FSUtils.cpp

142 lines
3.0 KiB
C++
Raw Normal View History

2022-02-04 15:47:35 +01:00
#include <fcntl.h>
#include <fs/CFile.hpp>
#include <fs/FSUtils.h>
2019-11-24 14:35:38 +01:00
#include <malloc.h>
#include <stdio.h>
2022-02-04 15:47:35 +01:00
#include <string.h>
2019-11-24 14:35:38 +01:00
#include <unistd.h>
#include <utils/logger.h>
int32_t FSUtils::LoadFileToMem(const char *filepath, uint8_t **inbuffer, uint32_t *size) {
//! always initialze input
2021-09-24 21:04:06 +02:00
*inbuffer = nullptr;
2020-06-03 19:45:51 +02:00
if (size)
2019-11-24 14:35:38 +01:00
*size = 0;
int32_t iFd = open(filepath, O_RDONLY);
if (iFd < 0)
return -1;
uint32_t filesize = lseek(iFd, 0, SEEK_END);
lseek(iFd, 0, SEEK_SET);
2021-09-24 21:04:06 +02:00
auto *buffer = (uint8_t *) malloc(filesize);
if (buffer == nullptr) {
2019-11-24 14:35:38 +01:00
close(iFd);
return -2;
}
uint32_t blocksize = 0x4000;
2022-02-04 15:47:35 +01:00
uint32_t done = 0;
int32_t readBytes = 0;
2019-11-24 14:35:38 +01:00
2020-06-03 19:45:51 +02:00
while (done < filesize) {
if (done + blocksize > filesize) {
2019-11-24 14:35:38 +01:00
blocksize = filesize - done;
}
readBytes = read(iFd, buffer + done, blocksize);
2020-06-03 19:45:51 +02:00
if (readBytes <= 0)
2019-11-24 14:35:38 +01:00
break;
done += readBytes;
}
close(iFd);
if (done != filesize) {
free(buffer);
2021-09-24 21:04:06 +02:00
buffer = nullptr;
2019-11-24 14:35:38 +01:00
return -3;
}
*inbuffer = buffer;
//! sign is optional input
2020-06-03 19:45:51 +02:00
if (size) {
2019-11-24 14:35:38 +01:00
*size = filesize;
}
return filesize;
}
2020-06-03 19:45:51 +02:00
int32_t FSUtils::CheckFile(const char *filepath) {
if (!filepath)
2019-11-24 14:35:38 +01:00
return 0;
2022-02-04 15:47:35 +01:00
struct stat filestat {};
2019-11-24 14:35:38 +01:00
2020-06-03 19:45:51 +02:00
char dirnoslash[strlen(filepath) + 2];
2019-11-24 14:35:38 +01:00
snprintf(dirnoslash, sizeof(dirnoslash), "%s", filepath);
2020-06-03 19:45:51 +02:00
while (dirnoslash[strlen(dirnoslash) - 1] == '/')
dirnoslash[strlen(dirnoslash) - 1] = '\0';
2019-11-24 14:35:38 +01:00
2020-06-03 19:45:51 +02:00
char *notRoot = strrchr(dirnoslash, '/');
if (!notRoot) {
2019-11-24 14:35:38 +01:00
strcat(dirnoslash, "/");
}
if (stat(dirnoslash, &filestat) == 0)
return 1;
return 0;
}
2020-06-03 19:45:51 +02:00
int32_t FSUtils::CreateSubfolder(const char *fullpath) {
if (!fullpath)
2019-11-24 14:35:38 +01:00
return 0;
int32_t result = 0;
2020-06-03 19:45:51 +02:00
char dirnoslash[strlen(fullpath) + 1];
2019-11-24 14:35:38 +01:00
strcpy(dirnoslash, fullpath);
2020-06-03 19:45:51 +02:00
int32_t pos = strlen(dirnoslash) - 1;
while (dirnoslash[pos] == '/') {
2019-11-24 14:35:38 +01:00
dirnoslash[pos] = '\0';
pos--;
}
2020-06-03 19:45:51 +02:00
if (CheckFile(dirnoslash)) {
2019-11-24 14:35:38 +01:00
return 1;
} else {
2020-06-03 19:45:51 +02:00
char parentpath[strlen(dirnoslash) + 2];
2019-11-24 14:35:38 +01:00
strcpy(parentpath, dirnoslash);
2020-06-03 19:45:51 +02:00
char *ptr = strrchr(parentpath, '/');
2019-11-24 14:35:38 +01:00
2020-06-03 19:45:51 +02:00
if (!ptr) {
2019-11-24 14:35:38 +01:00
//!Device root directory (must be with '/')
strcat(parentpath, "/");
2022-02-04 15:47:35 +01:00
struct stat filestat {};
2019-11-24 14:35:38 +01:00
if (stat(parentpath, &filestat) == 0)
return 1;
return 0;
}
ptr++;
ptr[0] = '\0';
result = CreateSubfolder(parentpath);
}
2020-06-03 19:45:51 +02:00
if (!result)
2019-11-24 14:35:38 +01:00
return 0;
if (mkdir(dirnoslash, 0777) == -1) {
return 0;
}
return 1;
}
2020-06-03 19:45:51 +02:00
BOOL FSUtils::saveBufferToFile(const char *path, void *buffer, uint32_t size) {
2019-11-24 14:35:38 +01:00
CFile file(path, CFile::WriteOnly);
if (!file.isOpen()) {
2020-06-03 19:45:51 +02:00
DEBUG_FUNCTION_LINE("Failed to open %s\n", path);
2019-11-24 14:35:38 +01:00
return false;
}
2020-06-03 19:45:51 +02:00
file.write((const uint8_t *) buffer, size);
2019-11-24 14:35:38 +01:00
file.close();
return true;
}