| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 | 
							- /*
 
-  * Copyright (c) 2006-2018, RT-Thread Development Team
 
-  *
 
-  * SPDX-License-Identifier: Apache-2.0
 
-  *
 
-  * Change Logs:
 
-  * Date           Author       Notes
 
-  */
 
- #include <rtthread.h>
 
- #include <dfs.h>
 
- #include <dfs_fs.h>
 
- #include <dfs_file.h>
 
- #include "dfs_romfs.h"
 
- int dfs_romfs_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data)
 
- {
 
-     struct romfs_dirent *root_dirent;
 
-     if (data == NULL)
 
-         return -EIO;
 
-     root_dirent = (struct romfs_dirent *)data;
 
-     fs->data = root_dirent;
 
-     return RT_EOK;
 
- }
 
- int dfs_romfs_unmount(struct dfs_filesystem *fs)
 
- {
 
-     return RT_EOK;
 
- }
 
- int dfs_romfs_ioctl(struct dfs_fd *file, int cmd, void *args)
 
- {
 
-     return -EIO;
 
- }
 
- rt_inline int check_dirent(struct romfs_dirent *dirent)
 
- {
 
-     if ((dirent->type != ROMFS_DIRENT_FILE && dirent->type != ROMFS_DIRENT_DIR)
 
-         || dirent->size == ~0)
 
-         return -1;
 
-     return 0;
 
- }
 
- struct romfs_dirent *dfs_romfs_lookup(struct romfs_dirent *root_dirent, const char *path, rt_size_t *size)
 
- {
 
-     rt_size_t index, found;
 
-     const char *subpath, *subpath_end;
 
-     struct romfs_dirent *dirent;
 
-     rt_size_t dirent_size;
 
-     /* Check the root_dirent. */
 
-     if (check_dirent(root_dirent) != 0)
 
-         return NULL;
 
-     if (path[0] == '/' && path[1] == '\0')
 
-     {
 
-         *size = root_dirent->size;
 
-         return root_dirent;
 
-     }
 
-     /* goto root directy entries */
 
-     dirent = (struct romfs_dirent *)root_dirent->data;
 
-     dirent_size = root_dirent->size;
 
-     /* get the end position of this subpath */
 
-     subpath_end = path;
 
-     /* skip /// */
 
-     while (*subpath_end && *subpath_end == '/')
 
-         subpath_end ++;
 
-     subpath = subpath_end;
 
-     while ((*subpath_end != '/') && *subpath_end)
 
-         subpath_end ++;
 
-     while (dirent != NULL)
 
-     {
 
-         found = 0;
 
-         /* search in folder */
 
-         for (index = 0; index < dirent_size; index ++)
 
-         {
 
-             if (check_dirent(&dirent[index]) != 0)
 
-                 return NULL;
 
-             if (rt_strlen(dirent[index].name) == (subpath_end - subpath) &&
 
-                     rt_strncmp(dirent[index].name, subpath, (subpath_end - subpath)) == 0)
 
-             {
 
-                 dirent_size = dirent[index].size;
 
-                 /* skip /// */
 
-                 while (*subpath_end && *subpath_end == '/')
 
-                     subpath_end ++;
 
-                 subpath = subpath_end;
 
-                 while ((*subpath_end != '/') && *subpath_end)
 
-                     subpath_end ++;
 
-                 if (!(*subpath))
 
-                 {
 
-                     *size = dirent_size;
 
-                     return &dirent[index];
 
-                 }
 
-                 if (dirent[index].type == ROMFS_DIRENT_DIR)
 
-                 {
 
-                     /* enter directory */
 
-                     dirent = (struct romfs_dirent *)dirent[index].data;
 
-                     found = 1;
 
-                     break;
 
-                 }
 
-                 else
 
-                 {
 
-                     /* return file dirent */
 
-                     if (subpath != NULL)
 
-                         break; /* not the end of path */
 
-                     return &dirent[index];
 
-                 }
 
-             }
 
-         }
 
-         if (!found)
 
-             break; /* not found */
 
-     }
 
-     /* not found */
 
-     return NULL;
 
- }
 
- int dfs_romfs_read(struct dfs_fd *file, void *buf, size_t count)
 
- {
 
-     rt_size_t length;
 
-     struct romfs_dirent *dirent;
 
-     dirent = (struct romfs_dirent *)file->data;
 
-     RT_ASSERT(dirent != NULL);
 
-     if (check_dirent(dirent) != 0)
 
-     {
 
-         return -EIO;
 
-     }
 
-     if (count < file->size - file->pos)
 
-         length = count;
 
-     else
 
-         length = file->size - file->pos;
 
-     if (length > 0)
 
-         memcpy(buf, &(dirent->data[file->pos]), length);
 
-     /* update file current position */
 
-     file->pos += length;
 
-     return length;
 
- }
 
- int dfs_romfs_lseek(struct dfs_fd *file, off_t offset)
 
- {
 
-     if (offset <= file->size)
 
-     {
 
-         file->pos = offset;
 
-         return file->pos;
 
-     }
 
-     return -EIO;
 
- }
 
- int dfs_romfs_close(struct dfs_fd *file)
 
- {
 
-     file->data = NULL;
 
-     return RT_EOK;
 
- }
 
- int dfs_romfs_open(struct dfs_fd *file)
 
- {
 
-     rt_size_t size;
 
-     struct romfs_dirent *dirent;
 
-     struct romfs_dirent *root_dirent;
 
-     struct dfs_filesystem *fs;
 
-     fs = (struct dfs_filesystem *)file->data;
 
-     root_dirent = (struct romfs_dirent *)fs->data;
 
-     if (check_dirent(root_dirent) != 0)
 
-         return -EIO;
 
-     if (file->flags & (O_CREAT | O_WRONLY | O_APPEND | O_TRUNC | O_RDWR))
 
-         return -EINVAL;
 
-     dirent = dfs_romfs_lookup(root_dirent, file->path, &size);
 
-     if (dirent == NULL)
 
-         return -ENOENT;
 
-     /* entry is a directory file type */
 
-     if (dirent->type == ROMFS_DIRENT_DIR)
 
-     {
 
-         if (!(file->flags & O_DIRECTORY))
 
-             return -ENOENT;
 
-     }
 
-     else
 
-     {
 
-         /* entry is a file, but open it as a directory */
 
-         if (file->flags & O_DIRECTORY)
 
-             return -ENOENT;
 
-     }
 
-     file->data = dirent;
 
-     file->size = size;
 
-     file->pos = 0;
 
-     return RT_EOK;
 
- }
 
- int dfs_romfs_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
 
- {
 
-     rt_size_t size;
 
-     struct romfs_dirent *dirent;
 
-     struct romfs_dirent *root_dirent;
 
-     root_dirent = (struct romfs_dirent *)fs->data;
 
-     dirent = dfs_romfs_lookup(root_dirent, path, &size);
 
-     if (dirent == NULL)
 
-         return -ENOENT;
 
-     st->st_dev = 0;
 
-     st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
 
-                   S_IWUSR | S_IWGRP | S_IWOTH;
 
-     if (dirent->type == ROMFS_DIRENT_DIR)
 
-     {
 
-         st->st_mode &= ~S_IFREG;
 
-         st->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
 
-     }
 
-     st->st_size = dirent->size;
 
-     st->st_mtime = 0;
 
-     return RT_EOK;
 
- }
 
- int dfs_romfs_getdents(struct dfs_fd *file, struct dirent *dirp, uint32_t count)
 
- {
 
-     rt_size_t index;
 
-     const char *name;
 
-     struct dirent *d;
 
-     struct romfs_dirent *dirent, *sub_dirent;
 
-     dirent = (struct romfs_dirent *)file->data;
 
-     if (check_dirent(dirent) != 0)
 
-         return -EIO;
 
-     RT_ASSERT(dirent->type == ROMFS_DIRENT_DIR);
 
-     /* enter directory */
 
-     dirent = (struct romfs_dirent *)dirent->data;
 
-     /* make integer count */
 
-     count = (count / sizeof(struct dirent));
 
-     if (count == 0)
 
-         return -EINVAL;
 
-     index = 0;
 
-     for (index = 0; index < count && file->pos < file->size; index ++)
 
-     {
 
-         d = dirp + index;
 
-         sub_dirent = &dirent[file->pos];
 
-         name = sub_dirent->name;
 
-         /* fill dirent */
 
-         if (sub_dirent->type == ROMFS_DIRENT_DIR)
 
-             d->d_type = DT_DIR;
 
-         else
 
-             d->d_type = DT_REG;
 
-         d->d_namlen = rt_strlen(name);
 
-         d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
 
-         rt_strncpy(d->d_name, name, rt_strlen(name) + 1);
 
-         /* move to next position */
 
-         ++ file->pos;
 
-     }
 
-     return index * sizeof(struct dirent);
 
- }
 
- static const struct dfs_file_ops _rom_fops =
 
- {
 
-     dfs_romfs_open,
 
-     dfs_romfs_close,
 
-     dfs_romfs_ioctl,
 
-     dfs_romfs_read,
 
-     NULL,
 
-     NULL,
 
-     dfs_romfs_lseek,
 
-     dfs_romfs_getdents,
 
- };
 
- static const struct dfs_filesystem_ops _romfs =
 
- {
 
-     "rom",
 
-     DFS_FS_FLAG_DEFAULT,
 
-     &_rom_fops,
 
-     dfs_romfs_mount,
 
-     dfs_romfs_unmount,
 
-     NULL,
 
-     NULL,
 
-     NULL,
 
-     dfs_romfs_stat,
 
-     NULL,
 
- };
 
- int dfs_romfs_init(void)
 
- {
 
-     /* register rom file system */
 
-     dfs_register(&_romfs);
 
-     return 0;
 
- }
 
- INIT_COMPONENT_EXPORT(dfs_romfs_init);
 
 
  |