mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2025-05-18 15:29:16 +02:00
107 lines
2.4 KiB
C
107 lines
2.4 KiB
C
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "fygue.h"
|
|
|
|
//---
|
|
// Internals
|
|
//---
|
|
|
|
/* _fygue_dir_fat_read(): read and update internal cache
|
|
*
|
|
* return
|
|
* -2 no directory found
|
|
* -1 internal error
|
|
* 0 success */
|
|
static int _fygue_dir_fat_read(
|
|
struct fygue_fsinfo *fsinfo,
|
|
struct fygue_descriptor *desc
|
|
) {
|
|
struct fygue_fat_dirent fat_dirent;
|
|
struct dirent **dirent;
|
|
void *tmp;
|
|
size_t len;
|
|
int rc;
|
|
|
|
rc = fygue_fat_dir_read(
|
|
&(fsinfo->fat),
|
|
&(desc->resolve.dir.fat),
|
|
&fat_dirent
|
|
);
|
|
if (rc <= -3)
|
|
return -2;
|
|
if (rc < 0) {
|
|
errno = EIO;
|
|
return -1;
|
|
}
|
|
tmp = reallocarray(
|
|
desc->resolve.dir.dirent,
|
|
desc->resolve.dir.count + 1,
|
|
sizeof(struct dirent *)
|
|
);
|
|
if (tmp == NULL) {
|
|
errno = ENOMEM;
|
|
return -1;
|
|
}
|
|
desc->resolve.dir.dirent = tmp;
|
|
desc->resolve.dir.count += 1;
|
|
//FIXME: ensure UTF-8/SHIFT-JS
|
|
len = strlen(fat_dirent.name);
|
|
dirent = &(desc->resolve.dir.dirent[desc->resolve.dir.pos]);
|
|
*dirent = calloc(1, sizeof(struct dirent) + len + 2);
|
|
if (*dirent == NULL) {
|
|
desc->resolve.dir.count -= 1;
|
|
errno = ENOMEM;
|
|
return -1;
|
|
}
|
|
//FIXME: ensure UTF-8/SHIFT-JS
|
|
(*dirent)->d_ino = fat_dirent.cluster_id;
|
|
(*dirent)->d_type = DT_REG;
|
|
memcpy((*dirent)->d_name, fat_dirent.name, len + 1);
|
|
return 0;
|
|
}
|
|
|
|
//---
|
|
// Public
|
|
//---
|
|
|
|
/* fygue_dir_read(): directory read implementation
|
|
*
|
|
* notes
|
|
* - assume that the directory have read permission */
|
|
int fygue_dir_read(
|
|
struct fygue_descriptor *desc,
|
|
struct dirent **dirent,
|
|
size_t size
|
|
) {
|
|
struct fygue_fsinfo *fsinfo;
|
|
int rc;
|
|
|
|
ENOTSUP_IF_NOT_FYGUE(-1);
|
|
if (desc == NULL || desc->resolve.type != FYGUE_FILE_TYPE_DIR) {
|
|
errno = EBADF;
|
|
return -1;
|
|
}
|
|
if (dirent == NULL) {
|
|
errno = EFAULT;
|
|
return -1;
|
|
}
|
|
if (size < sizeof *dirent) {
|
|
errno = EINVAL;
|
|
return -1;
|
|
}
|
|
if (fygue_descriptor_sync(&fsinfo, desc) != 0) {
|
|
errno = EIO;
|
|
return -1;
|
|
}
|
|
if (desc->resolve.dir.pos >= desc->resolve.dir.count)
|
|
{
|
|
rc = _fygue_dir_fat_read(fsinfo, desc);
|
|
if (rc == -2)
|
|
return 0;
|
|
if (rc < 0)
|
|
return rc;
|
|
}
|
|
*dirent = desc->resolve.dir.dirent[desc->resolve.dir.pos];
|
|
desc->resolve.dir.pos += 1;
|
|
return sizeof *dirent;
|
|
}
|