File FilesystemUtils.c
File List > core > FilesystemUtils.c
Go to the documentation of this file
#include "FilesystemUtils.h"
#ifdef WIN32
#include <windows.h>
#include <stdio.h>
#include <direct.h>
#else
#include <stdlib.h>
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#endif
#include <string.h>
#include "Log.h"
int FS_GetTempDir(char* outBuf, int size)
{
#ifdef WIN32
char base[MAX_PATH];
char name[MAX_PATH];
DWORD len = GetTempPathA(sizeof(base), base);
if (len == 0 || len > sizeof(base))
return -1;
UINT u = GetTempFileNameA(base, "app", 0, name);
if (u == 0)
return -1;
DeleteFileA(name);
if (_mkdir(name) != 0)
return -1;
strncpy(outBuf, name, size);
return 0;
#else
const char *tmp = getenv("TMPDIR");
if (!tmp) tmp = "/tmp";
char templ[512];
snprintf(templ, sizeof(templ), "%s/StardewEngineXXXXXX", tmp);
char *res = mkdtemp(templ);
if (!res)
return -1;
strncpy(outBuf, res, size);
return 0;
#endif
}
int FS_DeleteDirRecursive(char* path)
{
#ifdef _WIN32
char pattern[512];
snprintf(pattern, sizeof(pattern), "%s\\*", path);
WIN32_FIND_DATAA data;
HANDLE h = FindFirstFileA(pattern, &data);
if (h == INVALID_HANDLE_VALUE)
return -1;
do
{
if (!strcmp(data.cFileName, ".") || !strcmp(data.cFileName, ".."))
continue;
char buf[512];
snprintf(buf, sizeof(buf), "%s\\%s", path, data.cFileName);
if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
FS_DeleteDirRecursive(buf);
RemoveDirectoryA(buf);
}
else
{
DeleteFileA(buf);
}
} while (FindNextFileA(h, &data));
FindClose(h);
return RemoveDirectoryA(path) ? 0 : -1;
#else
DIR* dir = opendir(path);
if (!dir) return -1;
struct dirent* entry;
while ((entry = readdir(dir)))
{
if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
continue;
char buf[512];
snprintf(buf, sizeof(buf), "%s/%s", path, entry->d_name);
struct stat st;
if (stat(buf, &st) == -1)
continue;
if (S_ISDIR(st.st_mode))
{
FS_DeleteDirRecursive(buf);
rmdir(buf);
}
else
{
unlink(buf);
}
}
closedir(dir);
return rmdir(path);
#endif
}
int FS_CopyFile(char* src, char* dst)
{
FILE* psrc = fopen(src, "rb");
if (!psrc)
{
Log_Error("fopen src");
return -1;
}
// Determine file size using fseek + ftell
if (fseek(psrc, 0, SEEK_END) != 0)
{
Log_Error("fseek");
fclose(psrc);
return -1;
}
long filesize = ftell(psrc);
if (filesize < 0)
{
Log_Error("ftell");
fclose(psrc);
return -1;
}
if (fseek(psrc, 0, SEEK_SET) != 0)
{
Log_Error("fseek rewind");
fclose(psrc);
return -1;
}
// Allocate buffer
char *buffer = (char *)malloc(filesize);
if (!buffer)
{
Log_Error("malloc");
fclose(psrc);
return -1;
}
// Read file into buffer
size_t bytes_read = fread(buffer, 1, filesize, psrc);
if (bytes_read != filesize)
{
Log_Error("fread");
free(buffer);
fclose(psrc);
return -1;
}
fclose(psrc);
// Write to destination
FILE* pdst = fopen(dst, "wb");
if (!dst)
{
Log_Error("fopen dst");
free(buffer);
return -1;
}
size_t bytes_written = fwrite(buffer, 1, filesize, pdst);
if (bytes_written != filesize)
{
Log_Error("fwrite");
free(buffer);
fclose(pdst);
return -1;
}
free(buffer);
fclose(pdst);
return 0; // success
}