mirror of
https://github.com/devkitPro/wut.git
synced 2026-03-22 01:44:41 -05:00
133 lines
3.9 KiB
C++
133 lines
3.9 KiB
C++
#include "devoptab_fsa.h"
|
|
#include "../wutnewlib/wut_clock.h"
|
|
|
|
char *
|
|
__wut_fs_fixpath(struct _reent *r,
|
|
const char *path) {
|
|
char *p;
|
|
char *fixedPath;
|
|
|
|
if (!path) {
|
|
r->_errno = EINVAL;
|
|
return NULL;
|
|
}
|
|
|
|
p = strchr(path, ':') + 1;
|
|
if (!strchr(path, ':')) {
|
|
p = (char *) path;
|
|
}
|
|
|
|
size_t pathLength = strlen(p);
|
|
if (pathLength > FS_MAX_PATH) {
|
|
r->_errno = ENAMETOOLONG;
|
|
return NULL;
|
|
}
|
|
|
|
// wii u softlocks on empty strings so give expected error back
|
|
if (pathLength == 0) {
|
|
r->_errno = ENOENT;
|
|
return NULL;
|
|
}
|
|
|
|
fixedPath = memalign(0x40, FS_MAX_PATH + 1);
|
|
if (!fixedPath) {
|
|
r->_errno = ENOMEM;
|
|
return NULL;
|
|
}
|
|
|
|
// cwd is handled by coreinit, so just strip the 'device:' if it exists
|
|
strcpy(fixedPath, p);
|
|
return fixedPath;
|
|
}
|
|
|
|
mode_t __wut_fs_translate_stat_mode(FSStat* fsStat) {
|
|
mode_t retMode = 0;
|
|
|
|
if ((fsStat->flags & FS_STAT_LINK) == FS_STAT_LINK) {
|
|
retMode |= S_IFLNK;
|
|
} else if ((fsStat->flags & FS_STAT_DIRECTORY) == FS_STAT_DIRECTORY) {
|
|
retMode |= S_IFDIR;
|
|
} else if ((fsStat->flags & FS_STAT_FILE) == FS_STAT_FILE) {
|
|
retMode |= S_IFREG;
|
|
} else if (fsStat->size == 0) {
|
|
// Mounted paths like /vol/external01 have no flags set.
|
|
// If no flag is set and the size is 0, it's a (root) dir
|
|
retMode |= S_IFDIR;
|
|
} else if (fsStat->size > 0) {
|
|
// Some regular Wii U files have no type info but will have a size
|
|
retMode |= S_IFREG;
|
|
}
|
|
|
|
// Convert normal CafeOS hexadecimal permission bits into Unix octal permission bits
|
|
mode_t permissionMode = (((fsStat->mode >> 2) & S_IRWXU) | ((fsStat->mode >> 1) & S_IRWXG) | (fsStat->mode & S_IRWXO));
|
|
|
|
return retMode | permissionMode;
|
|
}
|
|
|
|
FSMode __wut_fs_translate_permission_mode(mode_t mode) {
|
|
// Convert normal Unix octal permission bits into CafeOS hexadecimal permission bits
|
|
return (FSMode) (((mode & S_IRWXU) << 2) | ((mode & S_IRWXG) << 1) | (mode & S_IRWXO));
|
|
}
|
|
|
|
time_t __wut_fs_translate_time(FSTime timeValue) {
|
|
return (timeValue /1000000) + EPOCH_DIFF_SECS(WIIU_FSTIME_EPOCH_YEAR);
|
|
}
|
|
|
|
void __wut_fs_translate_stat(FSStat* fsStat, struct stat* posStat) {
|
|
memset(posStat, 0, sizeof(struct stat));
|
|
posStat->st_dev = (dev_t)__wut_devoptab_fs_client;
|
|
posStat->st_ino = fsStat->entryId;
|
|
posStat->st_mode = __wut_fs_translate_stat_mode(fsStat);
|
|
posStat->st_nlink = 1;
|
|
posStat->st_uid = fsStat->owner;
|
|
posStat->st_gid = fsStat->group;
|
|
posStat->st_rdev = posStat->st_dev;
|
|
posStat->st_size = fsStat->size;
|
|
posStat->st_atime = __wut_fs_translate_time(fsStat->modified);
|
|
posStat->st_ctime = __wut_fs_translate_time(fsStat->created);
|
|
posStat->st_mtime = __wut_fs_translate_time(fsStat->modified);
|
|
posStat->st_blksize = 512;
|
|
posStat->st_blocks = (posStat->st_size + posStat->st_blksize - 1) / posStat->st_size;
|
|
}
|
|
|
|
int
|
|
__wut_fs_translate_error(FSStatus error) {
|
|
switch ((int) error) {
|
|
case FS_STATUS_END:
|
|
return ENOENT;
|
|
case FS_STATUS_CANCELLED:
|
|
return ECANCELED;
|
|
case FS_STATUS_EXISTS:
|
|
return EEXIST;
|
|
case FS_STATUS_MEDIA_ERROR:
|
|
return EIO;
|
|
case FS_STATUS_NOT_FOUND:
|
|
return ENOENT;
|
|
case FS_STATUS_PERMISSION_ERROR:
|
|
return EPERM;
|
|
case FS_STATUS_STORAGE_FULL:
|
|
return ENOSPC;
|
|
case FS_STATUS_FILE_TOO_BIG:
|
|
return EFBIG;
|
|
case FS_STATUS_NOT_DIR:
|
|
return ENOTDIR;
|
|
case FS_STATUS_NOT_FILE:
|
|
return EISDIR;
|
|
case FS_STATUS_MAX:
|
|
return ENFILE;
|
|
case FS_STATUS_ACCESS_ERROR:
|
|
return EACCES;
|
|
case FS_STATUS_JOURNAL_FULL:
|
|
return ENOSPC;
|
|
case FS_STATUS_UNSUPPORTED_CMD:
|
|
return ENOTSUP;
|
|
case FS_STATUS_MEDIA_NOT_READY:
|
|
return EOWNERDEAD;
|
|
case FS_STATUS_ALREADY_OPEN:
|
|
case FS_STATUS_CORRUPTED:
|
|
case FS_STATUS_FATAL_ERROR:
|
|
return EIO;
|
|
}
|
|
return (int) error;
|
|
}
|