diff options
| author | bernard.xiong <[email protected]> | 2010-04-18 15:01:28 +0000 |
|---|---|---|
| committer | bernard.xiong <[email protected]> | 2010-04-18 15:01:28 +0000 |
| commit | 075498e7963fb23699e645c50ca0214d19a0041a (patch) | |
| tree | 3dfe75ed9aac5d654137d5844ccd8d9222381e9f /components/dfs/src | |
| parent | 04fa66ca3d781e516a6ac38c3b18c673ee16df04 (diff) | |
move to components directory
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@634 bbd45198-f89e-11dd-88c7-29a3b14d5316
Diffstat (limited to 'components/dfs/src')
| -rw-r--r-- | components/dfs/src/dfs_fs.c | 386 | ||||
| -rw-r--r-- | components/dfs/src/dfs_init.c | 84 | ||||
| -rw-r--r-- | components/dfs/src/dfs_posix.c | 622 | ||||
| -rw-r--r-- | components/dfs/src/dfs_raw.c | 684 | ||||
| -rw-r--r-- | components/dfs/src/dfs_util.c | 295 |
5 files changed, 2071 insertions, 0 deletions
diff --git a/components/dfs/src/dfs_fs.c b/components/dfs/src/dfs_fs.c new file mode 100644 index 0000000000..a20b9b26c0 --- /dev/null +++ b/components/dfs/src/dfs_fs.c @@ -0,0 +1,386 @@ +/*
++------------------------------------------------------------------------------
+| Project : Device Filesystem
++------------------------------------------------------------------------------
+| Copyright 2004, 2005 www.fayfayspace.org.
+| All rights reserved.
+|------------------------------------------------------------------------------
+| File : dfs_fs.c, the filesystem related implementations of Device FileSystem
+|------------------------------------------------------------------------------
+| Chang Logs:
+| Date Author Notes
+| 2005-02-22 ffxz The first version.
++------------------------------------------------------------------------------
+*/
+#include <dfs_fs.h>
+#include <dfs_raw.h>
+#include <dfs_util.h>
+
+#include <string.h>
+
+/*
++------------------------------------------------------------------------------
+| Function : dfs_register
++------------------------------------------------------------------------------
+| Description : registers a filesystem
+|
+| Parameters : ops, the implementation of filesystem
+| Returns : the status of register
+| 0 , successful
+| -1, failed
++------------------------------------------------------------------------------
+*/
+int dfs_register(struct dfs_filesystem_operation* ops)
+{
+ int index, result;
+
+ result = 0;
+
+ /* lock filesystem */
+ dfs_lock();
+
+ /* check if this filesystem was already registered */
+ for (index = 0; index < DFS_FILESYSTEM_TYPES_MAX; index++)
+ {
+ if (filesystem_operation_table[index] != RT_NULL &&
+ strcmp(filesystem_operation_table[index]->name, ops->name) == 0)
+ {
+ result = -1;
+ goto err;
+ }
+ }
+
+ /* find out an empty filesystem type entry */
+ for (index = 0; index < DFS_FILESYSTEM_TYPES_MAX && filesystem_operation_table[index] != RT_NULL;
+ index++) ;
+
+ /* filesystem type table full */
+ if (index == DFS_FILESYSTEM_TYPES_MAX)
+ {
+ result = -1;
+ goto err;
+ }
+
+ /* save the filesystem's operations */
+ filesystem_operation_table[index] = ops;
+
+err:
+ dfs_unlock();
+ return result;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : dfs_filesystem_lookup
++------------------------------------------------------------------------------
+| Description : lookup the mounted filesystem on the specified path
+|
+| Parameters : path, the specified path string
+| Returns : the found filesystem
++------------------------------------------------------------------------------
+*/
+struct dfs_filesystem* dfs_filesystem_lookup(const char *path)
+{
+ struct dfs_filesystem* fs;
+ rt_uint32_t index, fspath, prefixlen;
+
+ fs = RT_NULL;
+ prefixlen = 0;
+
+ /* lock filesystem */
+ dfs_lock();
+
+ /* lookup it in the filesystem table */
+ for (index = 0; index < DFS_FILESYSTEMS_MAX + 1; index++)
+ {
+ fspath = strlen(filesystem_table[index].path);
+ if (fspath < prefixlen) continue;
+
+ if ((filesystem_table[index].ops != RT_NULL) &&
+ str_is_prefix(filesystem_table[index].path, path) == 0)
+ {
+ fs = &filesystem_table[index];
+ prefixlen = fspath;
+ }
+ }
+
+ dfs_unlock();
+
+ return fs;
+}
+
+rt_err_t dfs_filesystem_get_partition(struct dfs_partition* part, rt_uint8_t* buf, rt_uint32_t pindex)
+{
+#define DPT_ADDRESS 0x1be /* device partition offset in Boot Sector */
+#define DPT_ITEM_SIZE 16 /* partition item size */
+
+ rt_uint8_t* dpt;
+ rt_uint8_t type;
+ rt_err_t result;
+
+ RT_ASSERT(part != RT_NULL);
+ RT_ASSERT(buf != RT_NULL);
+
+ result = RT_EOK;
+
+ dpt = buf + DPT_ADDRESS + pindex * DPT_ITEM_SIZE;
+
+ if ((*dpt != 0x80) && (*dpt != 0x00))
+ {
+ /* which is not a partition table */
+ result = -RT_ERROR;
+ return result;
+ }
+
+ /* get partition type */
+ type = *(dpt+4);
+
+ if (type != 0)
+ {
+ /* set partition type */
+ part->type = type;
+
+ /* get partition offset and size */
+ part->offset = *(dpt+ 8) | *(dpt+ 9) << 8 |
+ *(dpt+10) << 16 | *(dpt+11) << 24;
+ part->size = *(dpt+12) | *(dpt+13) << 8 |
+ *(dpt+14) << 16 | *(dpt+15) << 24;
+
+#ifdef RT_USING_FINSH
+ rt_kprintf("part[%d], begin: %d, size: ",
+ pindex, part->offset * 512);
+ if ( (part->size>>11) > 0 ) /* MB */
+ {
+ unsigned int part_size;
+ part_size = part->size>>11;/* MB */
+ if ( (part_size>>10) > 0) /* GB */
+ {
+ rt_kprintf("%d.%d%s",part_size>>10,part_size&0x3FF,"GB\r\n");/* GB */
+ }
+ else
+ {
+ rt_kprintf("%d.%d%s",part_size,(part->size>>1)&0x3FF,"MB\r\n");/* MB */
+ }
+ }
+ else
+ {
+ rt_kprintf("%d%s",part->size>>1,"KB\r\n");/* KB */
+ }
+#endif
+ }
+ else
+ {
+ result = -RT_ERROR;
+ }
+
+ return result;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : dfs_mount
++------------------------------------------------------------------------------
+| Description : mount a filesystem to specified path
+|
+| Parameters : device_name, the implementation of filesystem
+| path,
+| filesystemtype,
+| rwflag,
+| data,
+| Returns : the status of register
+| 0 , successful
+| -1, failed
++------------------------------------------------------------------------------
+*/
+int dfs_mount(const char* device_name, const char* path,
+ const char* filesystemtype, unsigned long rwflag, const
+ void* data)
+{
+ struct dfs_filesystem_operation* ops;
+ struct dfs_filesystem* fs;
+ char *fullpath=RT_NULL;
+#ifdef DFS_USING_WORKDIR
+ char full_path[DFS_PATH_MAX + 1];
+#endif
+ rt_device_t dev_id;
+ int index;
+
+ /* open specific device */
+ dev_id = rt_device_find(device_name);
+ if (dev_id == RT_NULL)
+ {
+ /* no this device */
+ rt_set_errno(-DFS_STATUS_ENODEV);
+ return -1;
+ }
+
+ /* find out specific filesystem */
+ dfs_lock();
+ for ( index = 0; index < DFS_FILESYSTEM_TYPES_MAX; index++ )
+ {
+ if (strcmp(filesystem_operation_table[index]->name, filesystemtype) == 0)break;
+ }
+
+ /* can't find filesystem */
+ if ( index == DFS_FILESYSTEM_TYPES_MAX )
+ {
+ rt_set_errno(-DFS_STATUS_ENODEV);
+ dfs_unlock();
+ return -1;
+ }
+ ops = filesystem_operation_table[index];
+ dfs_unlock();
+
+ /* make full path for special file */
+ fullpath = (char*)path;
+ if ( fullpath[0] != '/') /* not an abstract path */
+ {
+#ifdef DFS_USING_WORKDIR
+ /* build full path */
+ fullpath = full_path;
+ dfs_lock();
+ build_fullpath(working_directory, path, fullpath);
+ dfs_unlock();
+#else
+ rt_set_errno(-DFS_STATUS_ENOTDIR);
+ return -1;
+#endif
+ }
+
+ /* Check if the path exists or not, raw APIs call, fixme */
+ if ( (strcmp(fullpath, "/") != 0) && (strcmp(fullpath, "/dev") != 0) )
+ {
+ struct dfs_fd fd;
+
+ if ( dfile_raw_open(&fd, fullpath, DFS_O_RDONLY | DFS_O_DIRECTORY) < 0 )
+ {
+ rt_set_errno(-DFS_STATUS_ENOTDIR);
+ return -1;
+ }
+ dfile_raw_close(&fd);
+ }
+
+ /* check whether the file system mounted or not */
+ dfs_lock();
+ for (index =0; index < DFS_FILESYSTEMS_MAX; index++)
+ {
+ if ( filesystem_table[index].ops != RT_NULL &&
+ strcmp(filesystem_table[index].path, path) == 0 )
+ {
+ rt_set_errno(-DFS_STATUS_EINVAL);
+ goto err1;
+ }
+ }
+
+ /* find out en empty filesystem table entry */
+ for (index = 0; index < DFS_FILESYSTEMS_MAX && filesystem_table[index].ops != RT_NULL;
+ index++) ;
+ if ( index == DFS_FILESYSTEMS_MAX ) /* can't find en empty filesystem table entry */
+ {
+ rt_set_errno(-DFS_STATUS_EMMOUNT);
+ goto err1;
+ }
+
+ /* register file system */
+ fs = &(filesystem_table[index]);
+ strncpy(fs->path, fullpath, strlen(fullpath));
+ fs->ops = ops;
+ fs->dev_id = dev_id;
+ /* release filesystem_table lock */
+ dfs_unlock();
+
+ /* open device, but do not check the status of device */
+ rt_device_open(fs->dev_id, RT_DEVICE_OFLAG_RDWR);
+
+ if ( ops->mount == RT_NULL ) /* there is no mount implementation */
+ {
+ dfs_lock();
+ /* clear filesystem table entry */
+ rt_memset(fs, 0, sizeof(struct dfs_filesystem));
+ dfs_unlock();
+
+ rt_set_errno(-DFS_STATUS_ENOSYS);
+ return -1;
+ }
+ /* call mount of this filesystem */
+ else if ( ops->mount(fs) < 0 )
+ {
+ /* mount failed */
+ dfs_lock();
+
+ /* close device */
+ rt_device_close(fs->dev_id);
+
+ /* clear filesystem table entry */
+ rt_memset(fs, 0, sizeof(struct dfs_filesystem));
+
+ dfs_unlock();
+ return -1;
+ }
+
+ return 0;
+
+err1:
+ dfs_unlock();
+ return -1;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : dfs_unmount
++------------------------------------------------------------------------------
+| Description : unmount a filesystem
+|
+| Parameters :
+| Returns : the status of register
+| 0 , successful
+| -1, failed
++------------------------------------------------------------------------------
+*/
+int dfs_unmount(const char *specialfile)
+{
+ char *fullpath;
+#ifdef DFS_USING_WORKDIR
+ char full_path[DFS_PATH_MAX + 1];
+#endif
+ struct dfs_filesystem* fs = RT_NULL;
+
+ fullpath = (char*)specialfile;
+ if ( fullpath[0] != '/')
+ {
+#ifdef DFS_USING_WORKDIR
+ /* build full path */
+ fullpath = full_path;
+ dfs_lock();
+ build_fullpath(working_directory, specialfile, fullpath);
+ dfs_unlock();
+#else
+ rt_set_errno(-DFS_STATUS_ENOTDIR);
+ return -1;
+#endif
+ }
+
+ /* lock filesystem */
+ dfs_lock();
+
+ fs = dfs_filesystem_lookup(fullpath);
+ if (fs != RT_NULL && fs->ops->unmount != RT_NULL && fs->ops->unmount(fs) < 0)
+ {
+ goto err1;
+ }
+
+ /* close device, but do not check the status of device */
+ rt_device_close(fs->dev_id);
+
+ /* clear this filesystem table entry */
+ rt_memset(fs, 0, sizeof(struct dfs_filesystem));
+
+ dfs_unlock();
+
+ return 0;
+
+err1:
+ dfs_unlock();
+
+ return -1;
+}
diff --git a/components/dfs/src/dfs_init.c b/components/dfs/src/dfs_init.c new file mode 100644 index 0000000000..2667c7dd88 --- /dev/null +++ b/components/dfs/src/dfs_init.c @@ -0,0 +1,84 @@ +/* ++------------------------------------------------------------------------------ +| Project : Device Filesystem ++------------------------------------------------------------------------------ +| Copyright 2004, 2005 www.fayfayspace.org. +| All rights reserved. +|------------------------------------------------------------------------------ +| File : dfs.c, the implementation of Device FileSystem +|------------------------------------------------------------------------------ +| Chang Logs: +| Date Author Notes +| 2002-12-31 ffxz The first version. +| 2005-01-22 ffxz Clean up the code. ++------------------------------------------------------------------------------ +*/ +#include <dfs_def.h> +#include <dfs_config.h> + +#include <dfs_fs.h> +#include <dfs_raw.h> + +#include <string.h> + +/* Global variables */ +struct dfs_filesystem_operation* filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX + 1]; +struct dfs_filesystem filesystem_table[DFS_FILESYSTEMS_MAX + 1]; + +/* device filesystem lock */ +struct rt_mutex dlock; + +#ifdef DFS_USING_WORKDIR +char working_directory[DFS_PATH_MAX + 1]; +#endif + +#ifdef DFS_USING_STDIO +struct dfs_fd fd_table[3 + DFS_FD_MAX]; +#else +struct dfs_fd fd_table[DFS_FD_MAX]; +#endif + +/* ++------------------------------------------------------------------------------ +| Function : dfs_init ++------------------------------------------------------------------------------ +| Description : Inits the Device Filesystem +| Parameters : null +| Returns : null ++------------------------------------------------------------------------------ +*/ +void dfs_init() +{ + int index; + + /* clear filesystem operations table */ + for (index = 0; index < DFS_FILESYSTEM_TYPES_MAX + 1; index++) + filesystem_operation_table[index] = RT_NULL; + + /* create device filesystem lock */ + rt_mutex_init(&dlock, "dlock", RT_IPC_FLAG_FIFO); + + /* clear filesystem table */ + rt_memset(filesystem_table, 0, sizeof(filesystem_table)); + +#ifdef DFS_USING_WORKDIR + /* set current working directory */ + strcpy(working_directory, "/"); +#endif + + /* clean fd table */ + rt_memset(fd_table, 0, sizeof(fd_table)); +} + +void dfs_lock() +{ + rt_err_t result; + + result = rt_mutex_take(&dlock, RT_WAITING_FOREVER); + RT_ASSERT(result == RT_EOK); +} + +void dfs_unlock() +{ + rt_mutex_release(&dlock); +} diff --git a/components/dfs/src/dfs_posix.c b/components/dfs/src/dfs_posix.c new file mode 100644 index 0000000000..4780cdec2a --- /dev/null +++ b/components/dfs/src/dfs_posix.c @@ -0,0 +1,622 @@ +/*
++------------------------------------------------------------------------------
+| Project : Device Filesystem
++------------------------------------------------------------------------------
+| Copyright 2004, 2005 www.fayfayspace.org.
+| All rights reserved.
+|------------------------------------------------------------------------------
+| File : dfs_posix.c, the interface related implementations of Device FileSystem
+|------------------------------------------------------------------------------
+| Chang Logs:
+| Date Author Notes
+| 2009-05-27 Yi.qiu The first version.
++------------------------------------------------------------------------------
+*/
+#include <string.h>
+#include <dfs_util.h>
+#include <dfs_posix.h>
+
+/*
++------------------------------------------------------------------------------
+| Function : open
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+int open(const char *file, int flags, int mode)
+{
+ int fd, result;
+ struct dfs_fd* d;
+
+ /* allocate a fd */
+ fd = fd_new();
+ if (fd < 0) return -1;
+ d = fd_get(fd);
+
+ result = dfile_raw_open(d, file, flags);
+ if (result < 0)
+ {
+ rt_set_errno(result);
+ fd_put(d);
+ fd_put(d);
+
+ return -1;
+ }
+
+ /* release the ref-count of fd */
+ fd_put(d);
+ return fd;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : close
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+int close(int fd)
+{
+ int result;
+ struct dfs_fd* d;
+
+ d = fd_get(fd);
+ if (d == RT_NULL)
+ {
+ rt_set_errno(-RT_ERROR);
+ return -1;
+ }
+
+ result = dfile_raw_close(d);
+ fd_put(d);
+ fd_put(d);
+
+ if (result < 0)
+ {
+ rt_set_errno(result);
+ return -1;
+ }
+ return 0;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : read
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+int read(int fd, char *buf, int len)
+{
+ int result;
+ struct dfs_fd* d;
+
+ /* get the fd */
+ d = fd_get(fd);
+ if (d == RT_NULL)
+ {
+ rt_set_errno(-RT_ERROR);
+ return -1;
+ }
+
+ result = dfile_raw_read(d, buf, len);
+ if (result < 0)
+ {
+ rt_set_errno(result);
+ fd_put(d);
+
+ return -1;
+ }
+
+ /* release the ref-count of fd */
+ fd_put(d);
+ return result;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : write
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+int write(int fd, char *buf, int len)
+{
+ int result;
+ struct dfs_fd* d;
+
+ /* get the fd */
+ d = fd_get(fd);
+ if (d == RT_NULL)
+ {
+ rt_set_errno(-RT_ERROR);
+ return -1;
+ }
+
+ result = dfile_raw_write(d, buf, len);
+ if (result < 0)
+ {
+ rt_set_errno(result);
+ fd_put(d);
+
+ return -1;
+ }
+
+ /* release the ref-count of fd */
+ fd_put(d);
+ return result;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : lseek
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+int lseek(int fd, int offset, int dir)
+{
+ int result;
+ struct dfs_fd* d;
+
+ d = fd_get(fd);
+ if (d == RT_NULL)
+ {
+ rt_set_errno(-RT_ERROR);
+ return -1;
+ }
+
+ switch (dir)
+ {
+ case DFS_SEEK_SET:
+ break;
+
+ case DFS_SEEK_CUR:
+ offset += d->pos;
+ break;
+
+ case DFS_SEEK_END:
+ offset += d->size;
+ break;
+ }
+
+ result = dfile_raw_lseek(d, offset);
+ if (result < 0)
+ {
+ rt_set_errno(result);
+ fd_put(d);
+ return -1;
+ }
+
+ /* release the ref-count of fd */
+ fd_put(d);
+ return offset;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : rename
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+int rename(const char* old, const char* new )
+{
+ int result;
+
+ result = dfile_raw_rename(old, new);
+ if (result < 0)
+ {
+ rt_set_errno(result);
+ return -1;
+ }
+ return 0;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : unlink
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+int unlink(const char *pathname)
+{
+ int result;
+
+ result = dfile_raw_unlink(pathname);
+ if (result < 0)
+ {
+ rt_set_errno(result);
+ return -1;
+ }
+ return 0;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : stat
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+int stat(const char *file, struct dfs_stat *buf)
+{
+ int result;
+
+ result = dfile_raw_stat(file, (struct dfs_stat *)buf);
+ if (result < 0)
+ {
+ rt_set_errno(result);
+ return -1;
+ }
+ return result;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : mkdir
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+int mkdir (const char *path, rt_uint16_t mode)
+{
+ int fd;
+ struct dfs_fd* d;
+ int result;
+
+ fd = fd_new();
+ d = fd_get(fd);
+
+ result = dfile_raw_open(d, path, DFS_O_DIRECTORY | DFS_O_CREAT);
+ fd_put(d);
+ fd_put(d);
+
+ if (result < 0)
+ {
+ rt_set_errno(result);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : rmdir
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+int rmdir(const char *pathname)
+{
+ int result;
+
+ result = dfile_raw_unlink(pathname);
+ if (result < 0)
+ {
+ rt_set_errno(result);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : opendir
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+DIR* opendir(const char* name)
+{
+ struct dfs_fd* d;
+ int fd, result;
+ DIR* t;
+
+ t = RT_NULL;
+
+ /* allocate a fd */
+ fd = fd_new();
+ if (fd == -1) { rt_kprintf("no fd\n"); return RT_NULL; }
+ d = fd_get(fd);
+
+ result = dfile_raw_open(d, name, DFS_O_RDONLY | DFS_O_DIRECTORY);
+ if (result >= 0)
+ {
+ /* open successfully */
+ t = (DIR *) rt_malloc (sizeof(DIR));
+ if (t == RT_NULL)
+ {
+ dfile_raw_close(d);
+ fd_put(d);
+ }
+ else
+ {
+ rt_memset(t, 0, sizeof(DIR));
+ t->fd = fd;
+ }
+ fd_put(d);
+ return t;
+ }
+
+ /* open failed */
+ fd_put(d);
+ fd_put(d);
+ rt_set_errno(result);
+
+ return RT_NULL;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : readdir
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+struct dfs_dirent* readdir(DIR *d)
+{
+ int result;
+ struct dfs_fd* fd;
+
+ fd = fd_get(d->fd);
+ if (fd == RT_NULL)
+ {
+ rt_set_errno(-RT_ERROR);
+ return RT_NULL;
+ }
+
+ if (!d->num || (d->cur += ((struct dfs_dirent*)(d->buf + d->cur))->d_reclen) >= d->num)
+ {
+ result = dfile_raw_getdents(fd, (struct dfs_dirent*)d->buf, sizeof(d->buf) - 1);
+ if (result <= 0)
+ {
+ rt_set_errno(result);
+ fd_put(fd);
+
+ return RT_NULL;
+ }
+
+ d->num = result;
+ d->cur = 0;
+ }
+
+ fd_put(fd);
+ return (struct dfs_dirent*)(d->buf+d->cur);
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : telldir
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+rt_off_t telldir(DIR *d)
+{
+ struct dfs_fd* fd;
+ rt_off_t result;
+
+ fd = fd_get(d->fd);
+ if (fd == RT_NULL)
+ {
+ rt_set_errno(-RT_ERROR);
+ return 0;
+ }
+
+ result = fd->pos - d->num + d->cur;
+ fd_put(fd);
+
+ return result;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : seekdir
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+void seekdir(DIR *d, rt_off_t offset)
+{
+ struct dfs_fd* fd;
+
+ fd = fd_get(d->fd);
+ if (fd == RT_NULL)
+ {
+ rt_set_errno(-RT_ERROR);
+ return ;
+ }
+
+ if (dfile_raw_lseek(fd, offset) >= 0) d->num = d->cur = 0;
+ fd_put(fd);
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : rewinddir
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+void rewinddir(DIR *d)
+{
+ struct dfs_fd* fd;
+
+ fd = fd_get(d->fd);
+ if (fd == RT_NULL)
+ {
+ rt_set_errno(-RT_ERROR);
+ return ;
+ }
+
+ if (dfile_raw_lseek(fd, 0) >= 0) d->num = d->cur = 0;
+ fd_put(fd);
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : closedir
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+int closedir(DIR* d)
+{
+ int result;
+ struct dfs_fd* fd;
+
+ fd = fd_get(d->fd);
+ if (fd == RT_NULL)
+ {
+ rt_set_errno(-RT_ERROR);
+ return -1;
+ }
+
+ result = dfile_raw_close(fd);
+ fd_put(fd);
+
+ fd_put(fd);
+ rt_free(d);
+
+ if (result < 0)
+ {
+ rt_set_errno(result);
+ return -1;
+ }
+ else return 0;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : chdir
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+int chdir(const char *path)
+{
+ char* fullpath, full_path[DFS_PATH_MAX + 1];
+
+ if(path == RT_NULL || rt_strlen(path) > DFS_PATH_MAX)
+ return -1;
+
+ fullpath = (char*)path;
+ if ( fullpath[0] != '/' )
+ {
+ /* build full path */
+ fullpath = full_path;
+#ifdef DFS_USING_WORKDIR
+ dfs_lock();
+ build_fullpath(working_directory, path, fullpath);
+ strcpy(working_directory, fullpath);
+ dfs_unlock();
+#endif
+ }
+ else
+ {
+#ifdef DFS_USING_WORKDIR
+ dfs_lock();
+ rt_strncpy(working_directory, path, strlen(path) + 1);
+ working_directory[strlen(path)] = '\0';
+ dfs_unlock();
+#endif
+ }
+
+ return 0;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : chdir
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+char* getcwd(char *buf, rt_size_t size)
+{
+#ifdef DFS_USING_WORKDIR
+ dfs_lock();
+ rt_strncpy(buf, working_directory, size);
+ dfs_unlock();
+#else
+ rt_kprintf("WARNING: not support working directory\n");
+#endif
+ return buf;
+}
+
diff --git a/components/dfs/src/dfs_raw.c b/components/dfs/src/dfs_raw.c new file mode 100644 index 0000000000..c96b4089bd --- /dev/null +++ b/components/dfs/src/dfs_raw.c @@ -0,0 +1,684 @@ +/*
++------------------------------------------------------------------------------
+| Project : Device Filesystem
++------------------------------------------------------------------------------
+| Copyright 2004, 2005 www.fayfayspace.org.
+| All rights reserved.
+|------------------------------------------------------------------------------
+| File : dfs_raw.c, the raw APIs of Device FileSystem
+|------------------------------------------------------------------------------
+| Chang Logs:
+| Date Author Notes
+| 2005-02-22 ffxz The first version.
++------------------------------------------------------------------------------
+*/
+#include <dfs_raw.h>
+#include <dfs_util.h>
+#include <string.h>
+
+extern struct dfs_fd fd_table[];
+
+#define NO_WORKING_DIR "system does not support working dir\n"
+
+/*
++------------------------------------------------------------------------------
+| Function : fd_new
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+int fd_new(void)
+{
+ struct dfs_fd* d;
+ int idx;
+
+ /* lock filesystem */
+ dfs_lock();
+
+ /* find an empty fd entry */
+#ifdef DFS_USING_STDIO
+ for (idx = 3; idx < DFS_FD_MAX + 3 && fd_table[idx].ref_count > 0; idx++);
+#else
+ for (idx = 0; idx < DFS_FD_MAX && fd_table[idx].ref_count > 0; idx++);
+#endif
+
+ /* can't find an empty fd entry */
+#ifdef DFS_USING_STDIO
+ if (idx == DFS_FD_MAX + 3)
+#else
+ if (idx == DFS_FD_MAX)
+#endif
+ {
+ idx = -1;
+ goto __result;
+ }
+
+ d = &(fd_table[idx]);
+ d->ref_count = 1;
+
+__result:
+ dfs_unlock();
+ return idx;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : fd_get
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+struct dfs_fd* fd_get(int fd)
+{
+ struct dfs_fd* d;
+
+#ifdef DFS_USING_STDIO
+ if ( fd < 3 || fd > DFS_FD_MAX + 3) return RT_NULL;
+#else
+ if ( fd < 0 || fd > DFS_FD_MAX ) return RT_NULL;
+#endif
+
+ d = &fd_table[fd];
+
+ dfs_lock();
+ d->ref_count ++;
+ dfs_unlock();
+
+ return d;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : fd_put
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+void fd_put(struct dfs_fd* fd)
+{
+ dfs_lock();
+ fd->ref_count --;
+ /* clear this fd entry */
+ if ( fd->ref_count == 0 )
+ {
+ rt_memset(fd, 0, sizeof(struct dfs_fd));
+ }
+ dfs_unlock();
+};
+
+/*
++------------------------------------------------------------------------------
+| Function : dfile_raw_open
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+int dfile_raw_open(struct dfs_fd* fd, const char *path, int flags)
+{
+ struct dfs_filesystem* fs;
+ char *fullpath;
+#ifdef DFS_USING_WORKDIR
+ char full_path[DFS_PATH_MAX + 1];
+#endif
+ int fspathlen, result;
+
+ /* parameter check */
+ if ( fd == RT_NULL ) return -DFS_STATUS_EINVAL;
+
+ /* make sure we have an absolute path */
+ fullpath = (char*)path;
+ if ( fullpath[0] != '/')
+ {
+#ifdef DFS_USING_WORKDIR
+ /* build full path */
+ fullpath = &full_path[0];
+ dfs_lock();
+ build_fullpath(working_directory, path, fullpath);
+ dfs_unlock();
+#else
+ rt_kprintf(NO_WORKING_DIR);
+ return -1;
+#endif
+ }
+
+ dfs_log(DFS_DEBUG_INFO, ("open file:%s", fullpath));
+
+ /* find filesystem */
+ fs = dfs_filesystem_lookup(fullpath);
+ if ( fs == RT_NULL ) return -DFS_STATUS_ENOENT;
+
+ dfs_log(DFS_DEBUG_INFO, ("open in filesystem:%s", fs->ops->name));
+ fd->fs = fs;
+
+ /* initilize the fd item */
+ fd->type = FT_REGULAR;
+ //fd->ref_count = 1;
+ fd->flags = flags;
+ fd->size = 0;
+ fd->pos = 0;
+
+ fspathlen = strlen(fs->path);
+ rt_memset(fd->path, 0, DFS_PATH_MAX + 1);
+ if (*(fullpath + fspathlen) != '/') strcpy(fd->path, "/");
+ strcat(fd->path, fullpath + fspathlen);
+
+ /* specific file system open routine */
+ if (fs->ops->open == RT_NULL)
+ {
+ /* clear fd */
+ rt_memset(fd->path, 0, DFS_PATH_MAX + 1);
+
+ fd->type = FT_REGULAR;
+ fd->ref_count = 0;
+ fd->fs = RT_NULL;
+ fd->flags = 0;
+ fd->size = 0;
+ fd->pos = 0;
+ fd->data = RT_NULL;
+
+ return -DFS_STATUS_ENOSYS;
+ }
+
+ if ((result = fs->ops->open(fd)) < 0)
+ {
+ /* clear fd */
+ fd->fs = RT_NULL;
+ fd->flags = 0;
+ fd->data = RT_NULL;
+
+ dfs_log(DFS_DEBUG_INFO, ("open failed"));
+
+ return result;
+ }
+
+ fd->flags |= DFS_F_OPEN;
+ if ( flags & DFS_O_DIRECTORY )
+ {
+ fd->type = FT_DIRECTORY;
+ fd->flags |= DFS_F_DIRECTORY;
+ }
+
+ dfs_log(DFS_DEBUG_INFO, ("open successful"));
+ return 0;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : dfile_raw_close
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+int dfile_raw_close(struct dfs_fd* fd)
+{
+ int result = 0;
+
+ if (fd != RT_NULL && fd->fs->ops->close != RT_NULL) result = fd->fs->ops->close(fd);
+
+ /* close fd error, return */
+ if ( result < 0 ) return result;
+
+ fd->flags &= ~DFS_F_OPEN;
+
+ return result;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : dfile_raw_ioctl
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+int dfile_raw_ioctl(struct dfs_fd* fd, int cmd, void *args)
+{
+ struct dfs_filesystem* fs;
+
+ if (fd == RT_NULL || fd->type != FT_REGULAR) return -DFS_STATUS_EINVAL;
+
+ fs = fd->fs;
+#if 0 /* not support right now */
+ if (cmd == FILEGETSIZE)
+ {
+ if (args == RT_NULL) return -DFS_STATUS_EINVAL;
+
+ *((rt_uint32_t *) args) = fd->size;
+
+ return 0;
+ }
+ else if (cmd == FILEGETPOS)
+ {
+ if (args == RT_NULL) return -DFS_STATUS_EINVAL;
+
+ *((rt_uint32_t *) args) = fd->pos;
+
+ return 0;
+ }
+#endif
+
+ if (fs->ops->ioctl != RT_NULL) return fs->ops->ioctl(fd, cmd, args);
+
+ return -DFS_STATUS_ENOSYS;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : dfile_raw_read
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+int dfile_raw_read(struct dfs_fd* fd, void *buf, rt_size_t len)
+{
+ struct dfs_filesystem* fs;
+ int result = 0;
+
+ if (fd == RT_NULL) return -DFS_STATUS_EINVAL;
+
+ fs = (struct dfs_filesystem*) fd->fs;
+ if (fs->ops->read == RT_NULL) return -DFS_STATUS_ENOSYS;
+
+ if ( (result = fs->ops->read(fd, buf, len)) < 0 ) fd->flags |= DFS_F_EOF;
+
+ return result;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : dfile_raw_getdents
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+int dfile_raw_getdents(struct dfs_fd* fd, struct dfs_dirent* dirp, rt_size_t nbytes)
+{
+ struct dfs_filesystem* fs;
+
+ /* parameter check */
+ if (fd == RT_NULL || fd->type != FT_DIRECTORY) return -DFS_STATUS_EINVAL;
+
+ fs = (struct dfs_filesystem*) fd->fs;
+ if (fs->ops->getdents != RT_NULL) return fs->ops->getdents(fd, dirp, nbytes);
+
+ return -DFS_STATUS_ENOSYS;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : dfile_raw_unlink
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+int dfile_raw_unlink(const char *path)
+{
+ struct dfs_filesystem* fs;
+ char *fullpath, *real_path, search_path[DFS_PATH_MAX + 1];
+#ifdef DFS_USING_WORKDIR
+ char full_path[DFS_PATH_MAX+1];
+#endif
+ struct dfs_fd* fd;
+ int index, fspathlen;
+
+ /* Make sure we have an absolute path */
+ fullpath = (char*)path;
+ if ( fullpath[0] != '/')
+ {
+#ifdef DFS_USING_WORKDIR
+ /* build full path */
+ fullpath = full_path;
+ dfs_lock();
+ build_fullpath(working_directory, path, fullpath);
+ dfs_unlock();
+#else
+ rt_kprintf(NO_WORKING_DIR);
+ return -1;
+#endif
+ }
+
+ if ( (fs = dfs_filesystem_lookup(fullpath)) == RT_NULL) return -DFS_STATUS_ENOENT;
+
+ /* Check whether file is already open */
+ dfs_lock();
+ for (index = 0; index < DFS_FD_MAX; index++)
+ {
+ fd = &(fd_table[index]);
+ if (fd->fs == RT_NULL) continue;
+
+ build_fullpath(fd->fs->path, fd->path, search_path);
+ if (strcmp(fullpath, search_path) == 0)
+ {
+ dfs_unlock();
+ return -DFS_STATUS_EEXIST;
+ }
+ }
+ dfs_unlock();
+
+ fspathlen = strlen(fs->path);
+ real_path = search_path;
+ rt_memset( real_path, 0, sizeof( real_path ) );
+ if (*(fullpath + fspathlen) != '/') strcpy(real_path, "/");
+ strcat(real_path, fullpath + fspathlen);
+
+ if (fs->ops->unlink != RT_NULL) return fs->ops->unlink(fs, real_path);
+
+ return -DFS_STATUS_ENOSYS;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : dfile_raw_write
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+int dfile_raw_write(struct dfs_fd* fd, const void *buf, rt_size_t len)
+{
+ struct dfs_filesystem* fs = fd->fs;
+
+ if (fd == RT_NULL) return -DFS_STATUS_EINVAL;
+ if (fs->ops->write == RT_NULL) return -DFS_STATUS_ENOSYS;
+
+ return fs->ops->write(fd, buf, len);
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : dfile_raw_lseek
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+int dfile_raw_lseek(struct dfs_fd* fd, rt_off_t offset)
+{
+ struct dfs_filesystem* fs = fd->fs;
+
+ if (fd == RT_NULL) return -DFS_STATUS_EINVAL;
+ if (fs->ops->lseek == RT_NULL) return -DFS_STATUS_ENOSYS;
+
+ return fs->ops->lseek(fd, offset);
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : dfile_raw_stat
++------------------------------------------------------------------------------
+| Description : get the file or directory stat description
+|
+| Parameters : path, the file or directory path
+| buf, the stat description will be saved in it
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+int dfile_raw_stat(const char *path, struct dfs_stat *buf)
+{
+ struct dfs_filesystem* fs;
+ char* fullpath, real_path[DFS_PATH_MAX + 1];
+#ifdef DFS_USING_WORKDIR
+ char full_path[DFS_PATH_MAX + 1];
+#endif
+ int fspathlen;
+
+ fullpath = (char*)path;
+ if ( fullpath[0] != '/' )
+ {
+#ifdef DFS_USING_WORKDIR
+ /* build full path */
+ fullpath = full_path;
+ dfs_lock();
+ build_fullpath(working_directory, path, fullpath);
+ dfs_unlock();
+#else
+ rt_kprintf(NO_WORKING_DIR);
+ return -1;
+#endif
+ }
+
+ if ( (fs = dfs_filesystem_lookup(fullpath)) == RT_NULL )
+ {
+ dfs_log(DFS_DEBUG_ERROR, ("can't find mounted filesystem on this path:%s", fullpath));
+ return -DFS_STATUS_ENOENT;
+ }
+
+ fspathlen = strlen(fs->path);
+ rt_memset(real_path, 0, sizeof(real_path));
+ if (*(fullpath + fspathlen) != '/') real_path[0] = '/';
+ strcat(real_path, fullpath + fspathlen);
+
+ if (real_path[0] == '/' && real_path[1] == '\0')
+ {
+ /* it's the root directory */
+ buf->st_dev = 0;
+
+ buf->st_mode = DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
+ DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
+ buf->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
+
+ buf->st_size = 0;
+ buf->st_mtime = 0;
+ buf->st_blksize = 512;
+ return DFS_STATUS_OK;
+ }
+
+ if (fs->ops->stat == RT_NULL)
+ {
+ dfs_log(DFS_DEBUG_ERROR, ("the filesystem didn't implement this function"));
+ return -DFS_STATUS_ENOSYS;
+ }
+
+ return fs->ops->stat(fs, real_path, buf);
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : dfile_raw_rename
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters :
+| Returns :
+|
++------------------------------------------------------------------------------
+*/
+int dfile_raw_rename(const char* oldpath, const char* newpath)
+{
+ struct dfs_filesystem *oldfs, *newfs;
+ char *oldfullpath, *newfullpath;
+#ifdef DFS_USING_WORKDIR
+ /* Change DFS_PATH_MAX to DFS_PATH_MAX + 1, [email protected]*/
+ char old_realpath[DFS_PATH_MAX + 1], new_realpath[DFS_PATH_MAX + 1];
+#endif
+
+ oldfullpath = (char*)oldpath;
+ newfullpath = (char*)newpath;
+
+ if ( oldfullpath[0] != '/' )
+ {
+#ifdef DFS_USING_WORKDIR
+ /* build full path */
+ oldfullpath = old_realpath;
+ dfs_lock();
+ build_fullpath(working_directory, oldpath, oldfullpath);
+ dfs_unlock();
+#else
+ rt_kprintf(NO_WORKING_DIR);
+ return -1;
+#endif
+ }
+
+ if ( newfullpath[0] != '/' )
+ {
+#ifdef DFS_USING_WORKDIR
+ /* build full path */
+ newfullpath = new_realpath;
+ dfs_lock();
+ build_fullpath(working_directory, newpath, newfullpath);
+ dfs_unlock();
+#else
+ rt_kprintf(NO_WORKING_DIR);
+ return -1;
+#endif
+ }
+
+ if ( (oldfs = dfs_filesystem_lookup(oldfullpath)) == RT_NULL )
+ {
+ return -DFS_STATUS_ENOENT;
+ }
+
+ if ( (newfs = dfs_filesystem_lookup(newfullpath)) == RT_NULL )
+ {
+ return -DFS_STATUS_ENOENT;
+ }
+
+ if ( oldfs == newfs )
+ {
+ if ( oldfs->ops->rename == RT_NULL ) return -DFS_STATUS_ENOSYS;
+
+ return oldfs->ops->rename(oldfs, oldfullpath, newfullpath);
+ }
+
+ /* not at same file system, return EXDEV */
+ return -DFS_STATUS_EXDEV;
+}
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+
+static char fullpath[256 + 1];
+static struct dfs_fd fd;
+static struct dfs_dirent dirent;
+void ls(const char* pathname)
+{
+ struct dfs_stat stat;
+ int length;
+
+ /* list directory */
+ if ( dfile_raw_open(&fd, pathname, DFS_O_DIRECTORY) == 0 )
+ {
+ rt_kprintf("Directory %s:\n", pathname);
+ do
+ {
+ rt_memset(&dirent, 0, sizeof(struct dfs_dirent));
+ length = dfile_raw_getdents(&fd, &dirent, sizeof(struct dfs_dirent));
+ if ( length > 0 )
+ {
+ rt_memset(&stat, 0, sizeof(struct dfs_stat));
+
+ /* build full path for each file */
+ if (pathname[strlen(pathname) - 1] != '/')
+ rt_snprintf(fullpath, sizeof(fullpath), "%s%c%s", pathname, '/', dirent.d_name);
+ else
+ rt_snprintf(fullpath, sizeof(fullpath), "%s%s", pathname, dirent.d_name);
+
+ dfile_raw_stat(fullpath, &stat);
+ if ( stat.st_mode & DFS_S_IFDIR )
+ {
+ rt_kprintf("%s\t\t<DIR>\n", dirent.d_name);
+ }
+ else
+ {
+ rt_kprintf("%s\t\t%lu\n", dirent.d_name, stat.st_size);
+ }
+ }
+ }while(length > 0);
+
+ dfile_raw_close(&fd);
+ }
+ else
+ {
+ rt_kprintf("No such directory\n");
+ }
+}
+FINSH_FUNCTION_EXPORT(ls, list directory contents)
+
+static void mkdir(const char* pathname)
+{
+ /* make a new directory */
+ if (dfile_raw_open(&fd, pathname, DFS_O_DIRECTORY | DFS_O_CREAT) == 0)
+ {
+ dfile_raw_close(&fd);
+ }
+ else rt_kprintf("Can't mkdir %s\n", pathname);
+}
+FINSH_FUNCTION_EXPORT(mkdir, make a directory)
+
+void rm(const char* filename)
+{
+ if (dfile_raw_unlink(filename) < 0)
+ {
+ rt_kprintf("Delete %s failed\n", filename);
+ }
+}
+FINSH_FUNCTION_EXPORT(rm, remove files or directories)
+
+void cat(const char* filename)
+{
+ rt_uint32_t length;
+ char buffer[81];
+
+ if (dfile_raw_open(&fd, filename, DFS_O_RDONLY) < 0)
+ {
+ rt_kprintf("Open %s failed\n", filename);
+ return;
+ }
+
+ do
+ {
+ rt_memset(buffer, 0, sizeof(buffer));
+ length = dfile_raw_read(&fd, buffer, 81);
+ if (length > 0)
+ {
+ rt_kprintf("%s", buffer);
+ }
+ }while (length > 0);
+
+ dfile_raw_close(&fd);
+}
+FINSH_FUNCTION_EXPORT(cat, print file)
+
+#endif
diff --git a/components/dfs/src/dfs_util.c b/components/dfs/src/dfs_util.c new file mode 100644 index 0000000000..af7bab3bf6 --- /dev/null +++ b/components/dfs/src/dfs_util.c @@ -0,0 +1,295 @@ +/*
++------------------------------------------------------------------------------
+| Project : Device Filesystem
++------------------------------------------------------------------------------
+| Copyright 2004, 2005 www.fayfayspace.org.
+| All rights reserved.
+|------------------------------------------------------------------------------
+| File : dfs_utl.c, some misc functions of Device FileSystem
+|------------------------------------------------------------------------------
+| Chang Logs:
+| Date Author Notes
+| 2005-01-26 ffxz The first version
++------------------------------------------------------------------------------
+*/
+
+#include <string.h>
+
+#include <dfs_fs.h>
+#include <dfs_util.h>
+
+/*
++------------------------------------------------------------------------------
+| Function : dir_name
++------------------------------------------------------------------------------
+| Description : Gets the directory name in specified path string
+|
+| Parameters : path, the specified path string
+| path_name, return the path name in this parameter
+| len, the length of path name
+| Returns : the status of path_name:
+| 0 , successful
+| -1, failed
+| For Example :
+| path, dir_name
+| /, /
+| /usr, /
+| /usr/lib, /usr
+| /usr/lib/, /usr
++------------------------------------------------------------------------------
+*/
+int dir_name(const char* path, char* dirname, int len)
+{
+ int pos;
+
+ if ( path[0] == '/' && path[1] == '\0' )
+ {
+ *dirname++ = '/';
+ *dirname = '\0';
+ return 0;
+ }
+
+ pos = strlen(path);
+ while ( *(path + pos - 1) =='/' ) pos --;
+ while ( pos > 0 && *(path + pos - 1) != '/' ) pos --;
+ while ( pos > 0 && *(path + pos - 1) == '/' ) pos --;
+
+ if ( pos > len ) return -1;
+
+ if ( pos != 0)
+ {
+ memcpy(dirname, path, pos);
+ *(dirname+pos) = '\0';
+ }
+ else
+ {
+ *dirname++ = '/';
+ *dirname = '\0';
+ }
+
+ return 0;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : file_name
++------------------------------------------------------------------------------
+| Description : Gets the file name in specified path string
+|
+| Parameters : path, the specified path string
+| filename, return the path name in this parameter
+| len, the length of file name
+| Returns : the status of file_name:
+| 0 , successful
+| -1, failed
+| For Example :
+| path, filename
+| /, RT_NULL
+| /usr, usr
+| /usr/lib, lib
+| /usr/lib/, lib
++------------------------------------------------------------------------------
+*/
+int file_name(const char* path, char* filename, int len)
+{
+ int pos, size;
+
+ if ( path[0] == '/' && path[1] == '\0' )
+ {
+ *filename = '\0';
+ return 0;
+ }
+
+ pos = strlen(path);
+ while ( *(path + pos -1)=='/' ) pos --;
+ size = pos;
+
+ while ( *(path + pos -1) != '/' && pos > 0 ) pos --;
+
+ if ( size - pos > len ) return -1;
+ else size = size - pos ;
+
+ memcpy(filename, path + pos, size);
+ *(filename+size) = '\0';
+
+ return 0;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : next_path_name
++------------------------------------------------------------------------------
+| Description : Gets the next directory name from specified path string
+|
+| Parameters : path, the specified path string
+| pos, the specified position of path string
+| next, return the next path in this parameter
+| Returns : the position of next directory item,
+| -1, if pos reach in the end of the specified path string
+| For Example :
++------------------------------------------------------------------------------
+*/
+int next_dir_name(const char* path, int pos, char* next)
+{
+ const char* q;
+
+ if ( pos > strlen(path) || pos < 0|| path == RT_NULL ) return -1;
+
+ q = path + pos;
+
+ /* check for firt '/' */
+ while ( *q == '/' ) q++;
+ if ( *q == '\0' )
+ {
+ *next = '\0';
+ return -1;
+ }
+
+ while ( *q != '/' && *q != '\0' )
+ {
+ *next++ = *q++;
+ }
+ *next = '\0';
+
+ return q - path + 1;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function : build_fullpath
++------------------------------------------------------------------------------
+| Description : make up the full path from directory and filename
+|
+| Parameters : path, the specified path string
+| filename, return the path name in this parameter
+| fullpath, the returned full path name
+| Returns : null
++------------------------------------------------------------------------------
+*/
+void build_fullpath(const char *directory, const char *filename, char *fullpath)
+{
+ char elem[DFS_PATH_MAX + 1];
+ int pos, start, len;
+
+ len = 0;
+ /* check parameters */
+ RT_ASSERT(directory != RT_NULL);
+ RT_ASSERT(filename != RT_NULL);
+ RT_ASSERT(fullpath != RT_NULL);
+
+ /* copy full of directory */
+ strncpy(fullpath, directory, DFS_PATH_MAX + 1);
+
+ for (pos = 0; filename[pos] != '\0'; )
+ {
+ /* strip '//' */
+ while (filename[pos] == '/') pos++;
+
+ /* get the filename element, save to elem array */
+ for (start = pos; filename[pos] != '/' && filename[pos] != '\0'; pos++)
+ len = pos - start + 1;
+
+ strncpy(elem, filename + start, DFS_PATH_MAX + 1);
+ /* clear the end of elem */
+ elem[(len < DFS_PATH_MAX + 1? len : DFS_PATH_MAX + 1)] = '\0';
+
+ /* strip '..' */
+ if (elem[0] == '.' && elem[1] == '.')
+ {
+ if (strlen(fullpath) == 0) strcpy(fullpath, ""); /* empty filename */
+ else if (fullpath[0] == '/' && fullpath[1] !='\0')
+ {
+ int i = strlen(fullpath);
+
+ while (fullpath[i - 1] == '/') i--;
+ while (i > 0 && fullpath[i - 1] != '/') i--;
+
+ fullpath[i] = '\0';
+ }
+ }
+ /* not '.', copy as normally */
+ else if (elem[0] != '.')
+ {
+ len = strlen(fullpath);
+
+ if (len == 0) strncpy(fullpath, elem, DFS_PATH_MAX + 1);
+ else if (fullpath[len - 1] == '/')
+ {
+ if (elem[0] == '/') strncat(fullpath, elem + 1, DFS_PATH_MAX + 1);
+ else strncat(fullpath, elem, DFS_PATH_MAX + 1);
+ }
+ else
+ {
+ if (elem[0] == '/') strcat(fullpath, elem);
+ else
+ {
+ strncat(fullpath, "/", DFS_PATH_MAX + 1);
+ strncat(fullpath + 1, elem, DFS_PATH_MAX + 1);
+ }
+ }
+ }
+ }
+
+ if ( fullpath[0] != '/' && fullpath[(len = strlen(fullpath)) - 1] == '/')
+ {
+ fullpath[len - 1] = '\0';
+ }
+}
+
+int str_is_prefix(const char* prefix, const char* str)
+{
+ while ((*prefix) && (*str) && (*prefix == *str))
+ {
+ prefix ++;
+ str ++;
+ }
+
+ if (*prefix == 0) return 0;
+
+ return -1;
+}
+
+#if !defined(RT_USING_MINILIBC) && !defined(RT_USING_NEWLIB)
+#if !defined(__ICCARM__)
+char *strrchr(const char *t, int c)
+{
+ register char ch;
+ register const char *l=0;
+
+ ch = c;
+ for (;;)
+ {
+ if ((*t == ch)) l=t;
+ if ((!*t)) return (char*)l; ++t;
+ }
+}
+#endif
+
+#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION / 10000 < 35)
+int strncasecmp ( const char* s1, const char* s2, size_t len )
+{
+ register unsigned int x2;
+ register unsigned int x1;
+ register const char* end = s1 + len;
+
+ while (1)
+ {
+ if ((s1 >= end) )
+ return 0;
+
+ x2 = *s2 - 'A'; if ((x2 < 26u)) x2 += 32;
+ x1 = *s1 - 'A'; if ((x1 < 26u)) x1 += 32;
+ s1++; s2++;
+
+ if ((x2 != x1))
+ break;
+
+ if ((x1 == (unsigned int)-'A'))
+ break;
+ }
+
+ return x1 - x2;
+}
+#endif /* end of __ARMCC_VERSION */
+
+#endif
|
