uboot/fs/fat/file.c
<<
>>
Prefs
   1/*
   2 * file.c
   3 *
   4 * Mini "VFS" by Marcus Sundberg
   5 *
   6 * 2002-07-28 - rjones@nexus-tech.net - ported to ppcboot v1.1.6
   7 * 2003-03-10 - kharris@nexus-tech.net - ported to uboot
   8 *
   9 * SPDX-License-Identifier:     GPL-2.0+
  10 */
  11
  12#include <common.h>
  13#include <config.h>
  14#include <malloc.h>
  15#include <fat.h>
  16#include <linux/stat.h>
  17#include <linux/time.h>
  18
  19/* Supported filesystems */
  20static const struct filesystem filesystems[] = {
  21        { file_fat_detectfs,  file_fat_ls,  file_fat_read,  "FAT" },
  22};
  23#define NUM_FILESYS     (sizeof(filesystems)/sizeof(struct filesystem))
  24
  25/* The filesystem which was last detected */
  26static int current_filesystem = FSTYPE_NONE;
  27
  28/* The current working directory */
  29#define CWD_LEN         511
  30char file_cwd[CWD_LEN+1] = "/";
  31
  32const char *
  33file_getfsname(int idx)
  34{
  35        if (idx < 0 || idx >= NUM_FILESYS)
  36                return NULL;
  37
  38        return filesystems[idx].name;
  39}
  40
  41static void
  42pathcpy(char *dest, const char *src)
  43{
  44        char *origdest = dest;
  45
  46        do {
  47                if (dest-file_cwd >= CWD_LEN) {
  48                        *dest = '\0';
  49                        return;
  50                }
  51                *(dest) = *(src);
  52                if (*src == '\0') {
  53                        if (dest-- != origdest && ISDIRDELIM(*dest)) {
  54                                *dest = '\0';
  55                        }
  56                        return;
  57                }
  58                ++dest;
  59
  60                if (ISDIRDELIM(*src))
  61                        while (ISDIRDELIM(*src)) src++;
  62                else
  63                        src++;
  64        } while (1);
  65}
  66
  67int
  68file_cd(const char *path)
  69{
  70        if (ISDIRDELIM(*path)) {
  71                while (ISDIRDELIM(*path)) path++;
  72                strncpy(file_cwd+1, path, CWD_LEN-1);
  73        } else {
  74                const char *origpath = path;
  75                char *tmpstr = file_cwd;
  76                int back = 0;
  77
  78                while (*tmpstr != '\0') tmpstr++;
  79                do {
  80                        tmpstr--;
  81                } while (ISDIRDELIM(*tmpstr));
  82
  83                while (*path == '.') {
  84                        path++;
  85                        while (*path == '.') {
  86                                path++;
  87                                back++;
  88                        }
  89                        if (*path != '\0' && !ISDIRDELIM(*path)) {
  90                                path = origpath;
  91                                back = 0;
  92                                break;
  93                        }
  94                        while (ISDIRDELIM(*path)) path++;
  95                        origpath = path;
  96                }
  97
  98                while (back--) {
  99                        /* Strip off path component */
 100                        while (!ISDIRDELIM(*tmpstr)) {
 101                                tmpstr--;
 102                        }
 103                        if (tmpstr == file_cwd) {
 104                                /* Incremented again right after the loop. */
 105                                tmpstr--;
 106                                break;
 107                        }
 108                        /* Skip delimiters */
 109                        while (ISDIRDELIM(*tmpstr)) tmpstr--;
 110                }
 111                tmpstr++;
 112                if (*path == '\0') {
 113                        if (tmpstr == file_cwd) {
 114                                *tmpstr = '/';
 115                                tmpstr++;
 116                        }
 117                        *tmpstr = '\0';
 118                        return 0;
 119                }
 120                *tmpstr = '/';
 121                pathcpy(tmpstr+1, path);
 122        }
 123
 124        return 0;
 125}
 126
 127int
 128file_detectfs(void)
 129{
 130        int i;
 131
 132        current_filesystem = FSTYPE_NONE;
 133
 134        for (i = 0; i < NUM_FILESYS; i++) {
 135                if (filesystems[i].detect() == 0) {
 136                        strcpy(file_cwd, "/");
 137                        current_filesystem = i;
 138                        break;
 139                }
 140        }
 141
 142        return current_filesystem;
 143}
 144
 145int
 146file_ls(const char *dir)
 147{
 148        char fullpath[1024];
 149        const char *arg;
 150
 151        if (current_filesystem == FSTYPE_NONE) {
 152                printf("Can't list files without a filesystem!\n");
 153                return -1;
 154        }
 155
 156        if (ISDIRDELIM(*dir)) {
 157                arg = dir;
 158        } else {
 159                sprintf(fullpath, "%s/%s", file_cwd, dir);
 160                arg = fullpath;
 161        }
 162        return filesystems[current_filesystem].ls(arg);
 163}
 164
 165int file_read(const char *filename, void *buffer, int maxsize)
 166{
 167        char fullpath[1024];
 168        const char *arg;
 169
 170        if (current_filesystem == FSTYPE_NONE) {
 171                printf("Can't load file without a filesystem!\n");
 172                return -1;
 173        }
 174
 175        if (ISDIRDELIM(*filename)) {
 176                arg = filename;
 177        } else {
 178                sprintf(fullpath, "%s/%s", file_cwd, filename);
 179                arg = fullpath;
 180        }
 181
 182        return filesystems[current_filesystem].read(arg, buffer, maxsize);
 183}
 184