mirror of https://github.com/mgba-emu/mgba.git
Updater: Fix overwriting directories with files
This commit is contained in:
parent
1ec45502fb
commit
1d37620c8c
|
@ -31,6 +31,39 @@
|
|||
|
||||
FILE* logfile;
|
||||
|
||||
bool rmdirRecursive(struct VDir* dir) {
|
||||
if (!dir) {
|
||||
return false;
|
||||
}
|
||||
bool ok = true;
|
||||
struct VDirEntry* vde;
|
||||
while ((vde = dir->listNext(dir))) {
|
||||
const char* name = vde->name(vde);
|
||||
if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
|
||||
continue;
|
||||
}
|
||||
switch (vde->type(vde)) {
|
||||
case VFS_DIRECTORY:
|
||||
fprintf(logfile, "cd %s\n", name);
|
||||
if (!rmdirRecursive(dir->openDir(dir, name))) {
|
||||
ok = false;
|
||||
}
|
||||
fprintf(logfile, "cd ..\n");
|
||||
// Fall through
|
||||
case VFS_FILE:
|
||||
case VFS_UNKNOWN:
|
||||
fprintf(logfile, "rm %s\n", name);
|
||||
if (!dir->deleteFile(dir, name)) {
|
||||
fprintf(logfile, "error\n");
|
||||
ok = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
dir->close(dir);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool extractArchive(struct VDir* archive, const char* root, bool prefix) {
|
||||
char path[PATH_MAX] = {0};
|
||||
struct VDirEntry* vde;
|
||||
|
@ -57,11 +90,13 @@ bool extractArchive(struct VDir* archive, const char* root, bool prefix) {
|
|||
case VFS_DIRECTORY:
|
||||
fprintf(logfile, "mkdir %s\n", fname);
|
||||
if (mkdir(path, 0755) < 0 && errno != EEXIST) {
|
||||
fprintf(logfile, "error %i\n", errno);
|
||||
return false;
|
||||
}
|
||||
if (!prefix) {
|
||||
struct VDir* subdir = archive->openDir(archive, fname);
|
||||
if (!subdir) {
|
||||
fprintf(logfile, "error\n");
|
||||
return false;
|
||||
}
|
||||
if (!extractArchive(subdir, path, false)) {
|
||||
|
@ -76,13 +111,28 @@ bool extractArchive(struct VDir* archive, const char* root, bool prefix) {
|
|||
vfIn = archive->openFile(archive, vde->name(vde), O_RDONLY);
|
||||
errno = 0;
|
||||
vfOut = VFileOpen(path, O_WRONLY | O_CREAT | O_TRUNC);
|
||||
if (!vfOut && errno == EACCES) {
|
||||
if (!vfOut) {
|
||||
if (errno == EACCES) {
|
||||
#ifdef _WIN32
|
||||
Sleep(1000);
|
||||
Sleep(1000);
|
||||
#else
|
||||
sleep(1);
|
||||
sleep(1);
|
||||
#endif
|
||||
vfOut = VFileOpen(path, O_WRONLY | O_CREAT | O_TRUNC);
|
||||
vfOut = VFileOpen(path, O_WRONLY | O_CREAT | O_TRUNC);
|
||||
} else if (errno == EISDIR) {
|
||||
fprintf(logfile, "rm -r %s\n", path);
|
||||
if (!rmdirRecursive(VDirOpen(path))) {
|
||||
return false;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
wchar_t wpath[MAX_PATH + 1];
|
||||
MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, MAX_PATH);
|
||||
RemoveDirectoryW(wpath);
|
||||
#else
|
||||
rmdir(path);
|
||||
#endif
|
||||
vfOut = VFileOpen(path, O_WRONLY | O_CREAT | O_TRUNC);
|
||||
}
|
||||
}
|
||||
if (!vfOut) {
|
||||
vfIn->close(vfIn);
|
||||
|
|
|
@ -151,7 +151,12 @@ bool _vdwDeleteFile(struct VDir* vd, const char* path) {
|
|||
MultiByteToWideChar(CP_UTF8, 0, path, -1, pathw, MAX_PATH);
|
||||
StringCchPrintfW(combined, MAX_PATH, L"%ws\\%ws", dir, pathw);
|
||||
|
||||
return DeleteFileW(combined);
|
||||
DWORD attrs = GetFileAttributesW(combined);
|
||||
if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
return RemoveDirectoryW(combined);
|
||||
} else {
|
||||
return DeleteFileW(combined);
|
||||
}
|
||||
}
|
||||
|
||||
const char* _vdweName(struct VDirEntry* vde) {
|
||||
|
@ -183,4 +188,4 @@ bool VDirCreate(const char* path) {
|
|||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ bool _vdDeleteFile(struct VDir* vd, const char* path) {
|
|||
char* combined = malloc(sizeof(char) * (strlen(path) + strlen(dir) + 2));
|
||||
sprintf(combined, "%s%s%s", dir, PATH_SEP, path);
|
||||
|
||||
bool ret = !unlink(combined);
|
||||
bool ret = !remove(combined);
|
||||
free(combined);
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue