text/plain
•
3.81 KB
•
164 lines
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include "storage.h"
#define SDCARD_PATH "./sdcard"
static bool mounted = false;
bool storage_init(void) {
struct stat st;
// Check if sdcard directory exists
if (stat(SDCARD_PATH, &st) == -1) {
// Try to create it
if (mkdir(SDCARD_PATH, 0755) == -1) {
fprintf(stderr, "storage: failed to create %s: %s\n", SDCARD_PATH,
strerror(errno));
return false;
}
printf("storage: created %s directory\n", SDCARD_PATH);
} else if (!S_ISDIR(st.st_mode)) {
fprintf(stderr, "storage: %s exists but is not a directory\n",
SDCARD_PATH);
return false;
}
mounted = true;
printf("storage: mounted %s\n", SDCARD_PATH);
return true;
}
bool storage_mkdir(const char* path) {
if (!mounted || !path) {
return false;
}
const char* rel = (path[0] == '/') ? path + 1 : path;
char full_path[STORAGE_MAX_PATH];
snprintf(full_path, sizeof(full_path), "%s/%s", SDCARD_PATH, rel);
struct stat st;
if (stat(full_path, &st) == 0) {
return S_ISDIR(st.st_mode);
}
return mkdir(full_path, 0755) == 0;
}
bool storage_remove(const char* path) {
if (!mounted || !path) {
return false;
}
const char* rel = (path[0] == '/') ? path + 1 : path;
char full_path[STORAGE_MAX_PATH];
snprintf(full_path, sizeof(full_path), "%s/%s", SDCARD_PATH, rel);
if (remove(full_path) != 0 && errno != ENOENT) {
fprintf(stderr, "storage: failed to remove %s: %s\n", full_path,
strerror(errno));
return false;
}
return true;
}
bool storage_is_mounted(void) {
return mounted;
}
void storage_unmount(void) {}
bool storage_remount(void) {
return true;
}
int storage_list_dir(const char* path, storage_entry_t* entries, int max) {
if (!mounted || !entries || max <= 0) {
return -1;
}
char full_path[STORAGE_MAX_PATH];
if (path == NULL || path[0] == '\0' || strcmp(path, "/") == 0) {
snprintf(full_path, sizeof(full_path), "%s", SDCARD_PATH);
} else {
// Strip leading slash to avoid double-slash in path
const char* rel = (path[0] == '/') ? path + 1 : path;
snprintf(full_path, sizeof(full_path), "%s/%s", SDCARD_PATH, rel);
}
DIR* dir = opendir(full_path);
if (!dir) {
fprintf(stderr, "storage: failed to open directory %s: %s\n", full_path,
strerror(errno));
return -1;
}
int count = 0;
struct dirent* ent;
while ((ent = readdir(dir)) != NULL && count < max) {
// Skip . and ..
if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) {
continue;
}
strncpy(entries[count].name, ent->d_name, STORAGE_MAX_NAME - 1);
entries[count].name[STORAGE_MAX_NAME - 1] = '\0';
// Get file info
char file_path[STORAGE_MAX_PATH * 2];
snprintf(file_path, sizeof(file_path), "%s/%s", full_path, ent->d_name);
struct stat st;
if (stat(file_path, &st) == 0) {
entries[count].type =
S_ISDIR(st.st_mode) ? STORAGE_TYPE_DIR : STORAGE_TYPE_FILE;
entries[count].size = (size_t)st.st_size;
} else {
entries[count].type = STORAGE_TYPE_FILE;
entries[count].size = 0;
}
count++;
}
closedir(dir);
return count;
}
storage_file_t storage_open(const char* path, const char* mode) {
if (!mounted || !path || !mode) {
return NULL;
}
const char* rel = (path[0] == '/') ? path + 1 : path;
char full_path[STORAGE_MAX_PATH];
snprintf(full_path, sizeof(full_path), "%s/%s", SDCARD_PATH, rel);
FILE* f = fopen(full_path, mode);
return (storage_file_t)f;
}
size_t storage_read(storage_file_t file, void* buf, size_t size) {
if (!file || !buf) {
return 0;
}
return fread(buf, 1, size, (FILE*)file);
}
size_t storage_write(storage_file_t file, const void* buf, size_t size) {
if (!file || !buf) {
return 0;
}
return fwrite(buf, 1, size, (FILE*)file);
}
int storage_close(storage_file_t file) {
if (!file) {
return -1;
}
return fclose((FILE*)file);
}