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 * See file CREDITS for list of people who contributed to this
  10 * project.
  11 *
  12 * This program is free software; you can redistribute it and/or
  13 * modify it under the terms of the GNU General Public License as
  14 * published by the Free Software Foundation; either version 2 of
  15 * the License, or (at your option) any later version.
  16 *
  17 * This program is distributed in the hope that it will be useful,
  18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20 * GNU General Public License for more details.
  21 *
  22 * You should have received a copy of the GNU General Public License
  23 * along with this program; if not, write to the Free Software
  24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  25 * MA 02111-1307 USA
  26 */
  27
  28#include <common.h>
  29#include <config.h>
  30#include <malloc.h>
  31#include <fat.h>
  32#include <linux/stat.h>
  33#include <linux/time.h>
  34
  35/* Supported filesystems */
  36static const struct filesystem filesystems[] = {
  37        { file_fat_detectfs,  file_fat_ls,  file_fat_read,  "FAT" },
  38};
  39#define NUM_FILESYS     (sizeof(filesystems)/sizeof(struct filesystem))
  40
  41/* The filesystem which was last detected */
  42static int current_filesystem = FSTYPE_NONE;
  43
  44/* The current working directory */
  45#define CWD_LEN         511
  46char file_cwd[CWD_LEN+1] = "/";
  47
  48const char *
  49file_getfsname(int idx)
  50{
  51        if (idx < 0 || idx >= NUM_FILESYS)
  52                return NULL;
  53
  54        return filesystems[idx].name;
  55}
  56
  57static void
  58pathcpy(char *dest, const char *src)
  59{
  60        char *origdest = dest;
  61
  62        do {
  63                if (dest-file_cwd >= CWD_LEN) {
  64                        *dest = '\0';
  65                        return;
  66                }
  67                *(dest) = *(src);
  68                if (*src == '\0') {
  69                        if (dest-- != origdest && ISDIRDELIM(*dest)) {
  70                                *dest = '\0';
  71                        }
  72                        return;
  73                }
  74                ++dest;
  75
  76                if (ISDIRDELIM(*src))
  77                        while (ISDIRDELIM(*src)) src++;
  78                else
  79                        src++;
  80        } while (1);
  81}
  82
  83int
  84file_cd(const char *path)
  85{
  86        if (ISDIRDELIM(*path)) {
  87                while (ISDIRDELIM(*path)) path++;
  88                strncpy(file_cwd+1, path, CWD_LEN-1);
  89        } else {
  90                const char *origpath = path;
  91                char *tmpstr = file_cwd;
  92                int back = 0;
  93
  94                while (*tmpstr != '\0') tmpstr++;
  95                do {
  96                        tmpstr--;
  97                } while (ISDIRDELIM(*tmpstr));
  98
  99                while (*path == '.') {
 100                        path++;
 101                        while (*path == '.') {
 102                                path++;
 103                                back++;
 104                        }
 105                        if (*path != '\0' && !ISDIRDELIM(*path)) {
 106                                path = origpath;
 107                                back = 0;
 108                                break;
 109                        }
 110                        while (ISDIRDELIM(*path)) path++;
 111                        origpath = path;
 112                }
 113
 114                while (back--) {
 115                        /* Strip off path component */
 116                        while (!ISDIRDELIM(*tmpstr)) {
 117                                tmpstr--;
 118                        }
 119                        if (tmpstr == file_cwd) {
 120                                /* Incremented again right after the loop. */
 121                                tmpstr--;
 122                                break;
 123                        }
 124                        /* Skip delimiters */
 125                        while (ISDIRDELIM(*tmpstr)) tmpstr--;
 126                }
 127                tmpstr++;
 128                if (*path == '\0') {
 129                        if (tmpstr == file_cwd) {
 130                                *tmpstr = '/';
 131                                tmpstr++;
 132                        }
 133                        *tmpstr = '\0';
 134                        return 0;
 135                }
 136                *tmpstr = '/';
 137                pathcpy(tmpstr+1, path);
 138        }
 139
 140        return 0;
 141}
 142
 143int
 144file_detectfs(void)
 145{
 146        int i;
 147
 148        current_filesystem = FSTYPE_NONE;
 149
 150        for (i = 0; i < NUM_FILESYS; i++) {
 151                if (filesystems[i].detect() == 0) {
 152                        strcpy(file_cwd, "/");
 153                        current_filesystem = i;
 154                        break;
 155                }
 156        }
 157
 158        return current_filesystem;
 159}
 160
 161int
 162file_ls(const char *dir)
 163{
 164        char fullpath[1024];
 165        const char *arg;
 166
 167        if (current_filesystem == FSTYPE_NONE) {
 168                printf("Can't list files without a filesystem!\n");
 169                return -1;
 170        }
 171
 172        if (ISDIRDELIM(*dir)) {
 173                arg = dir;
 174        } else {
 175                sprintf(fullpath, "%s/%s", file_cwd, dir);
 176                arg = fullpath;
 177        }
 178        return filesystems[current_filesystem].ls(arg);
 179}
 180
 181long
 182file_read(const char *filename, void *buffer, unsigned long maxsize)
 183{
 184        char fullpath[1024];
 185        const char *arg;
 186
 187        if (current_filesystem == FSTYPE_NONE) {
 188                printf("Can't load file without a filesystem!\n");
 189                return -1;
 190        }
 191
 192        if (ISDIRDELIM(*filename)) {
 193                arg = filename;
 194        } else {
 195                sprintf(fullpath, "%s/%s", file_cwd, filename);
 196                arg = fullpath;
 197        }
 198
 199        return filesystems[current_filesystem].read(arg, buffer, maxsize);
 200}
 201