Login
1 branch 0 tags
Ben (T14/NixOS) Only animate the long names of selected files e68dfa0 1 month ago 55 Commits
moon / sdl_src / storage_sdl.c
#include "storage.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <dirent.h>
#include <errno.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);
}