diff options
| author | [email protected] <[email protected]> | 2011-10-08 14:50:08 +0000 |
|---|---|---|
| committer | [email protected] <[email protected]> | 2011-10-08 14:50:08 +0000 |
| commit | b2f92176865f623129e61a411568ef3b5e361836 (patch) | |
| tree | 9bed58e4aa1457224d300313614fc58202cc7f19 | |
| parent | 9278fe2a8c33acf45e85700a9bba982685a58e97 (diff) | |
change to UNIX end of line.
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1746 bbd45198-f89e-11dd-88c7-29a3b14d5316
| -rw-r--r-- | components/dfs/filesystems/devfs/console.c | 170 | ||||
| -rw-r--r-- | components/dfs/filesystems/devfs/devfs.c | 546 | ||||
| -rw-r--r-- | components/dfs/filesystems/devfs/devfs.h | 16 | ||||
| -rw-r--r-- | components/dfs/filesystems/nfs/rpc/auth.h | 208 | ||||
| -rw-r--r-- | components/dfs/filesystems/nfs/rpc/pmap.c | 120 | ||||
| -rw-r--r-- | components/dfs/filesystems/nfs/rpc/pmap.h | 116 | ||||
| -rw-r--r-- | components/dfs/include/dfs.h | 74 | ||||
| -rw-r--r-- | components/dfs/include/dfs_elm.h | 58 | ||||
| -rw-r--r-- | components/dfs/include/dfs_file.h | 70 | ||||
| -rw-r--r-- | components/dfs/include/dfs_fs.h | 178 | ||||
| -rw-r--r-- | components/dfs/include/dfs_init.h | 84 | ||||
| -rw-r--r-- | components/dfs/include/dfs_posix.h | 232 | ||||
| -rw-r--r-- | components/dfs/src/dfs.c | 730 | ||||
| -rw-r--r-- | components/dfs/src/dfs_file.c | 1178 | ||||
| -rw-r--r-- | components/dfs/src/dfs_fs.c | 920 | ||||
| -rw-r--r-- | components/dfs/src/dfs_posix.c | 1336 |
16 files changed, 3018 insertions, 3018 deletions
diff --git a/components/dfs/filesystems/devfs/console.c b/components/dfs/filesystems/devfs/console.c index 46fc380460..cce707a817 100644 --- a/components/dfs/filesystems/devfs/console.c +++ b/components/dfs/filesystems/devfs/console.c @@ -1,85 +1,85 @@ -/*
- * RT-Thread Console Device File
- *
- */
-#include <rtthread.h>
-
-struct console_device
-{
- struct rt_device parent;
-
- rt_device_t device; /* the actual device */
-};
-struct console_device _console;
-
-/* common device interface */
-static rt_err_t console_init(rt_device_t dev)
-{
- return RT_EOK;
-}
-
-static rt_err_t console_open(rt_device_t dev, rt_uint16_t oflag)
-{
- return RT_EOK;
-}
-
-static rt_err_t console_close(rt_device_t dev)
-{
- return RT_EOK;
-}
-
-static rt_size_t console_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
-{
- struct console_device* device;
-
- device = (struct console_device*)dev;
- RT_ASSERT(device != RT_NULL);
-
- return rt_device_read(device->device, pos, buffer, size);
-}
-
-static rt_size_t console_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
-{
- struct console_device* device;
-
- device = (struct console_device*)dev;
- RT_ASSERT(device != RT_NULL);
-
- return rt_device_write(device->device, pos, buffer, size);
-}
-
-static rt_err_t console_control(rt_device_t dev, rt_uint8_t cmd, void *args)
-{
- return rt_device_control(_console.device, cmd, args);
-}
-
-void rt_console_init(const char* device_name)
-{
- rt_device_t device;
- /* register to device framework */
-
- device = rt_device_find(device_name);
- if (device != RT_NULL)
- {
- struct console_device* console;
- /* get console device */
- console = &_console;
- rt_memset(console, 0, sizeof(_console));
-
- /* device initialization */
- console->parent.type = RT_Device_Class_Char;
- /* set device interface */
- console->parent.init = console_init;
- console->parent.open = console_open;
- console->parent.close = console_close;
- console->parent.read = console_read;
- console->parent.write = console_write;
- console->parent.control = RT_NULL;
- console->parent.user_data = RT_NULL;
-
- console->device = device;
-
- rt_device_register(&console->parent, "console", RT_DEVICE_FLAG_RDWR);
- }
-}
-
+/* + * RT-Thread Console Device File + * + */ +#include <rtthread.h> + +struct console_device +{ + struct rt_device parent; + + rt_device_t device; /* the actual device */ +}; +struct console_device _console; + +/* common device interface */ +static rt_err_t console_init(rt_device_t dev) +{ + return RT_EOK; +} + +static rt_err_t console_open(rt_device_t dev, rt_uint16_t oflag) +{ + return RT_EOK; +} + +static rt_err_t console_close(rt_device_t dev) +{ + return RT_EOK; +} + +static rt_size_t console_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) +{ + struct console_device* device; + + device = (struct console_device*)dev; + RT_ASSERT(device != RT_NULL); + + return rt_device_read(device->device, pos, buffer, size); +} + +static rt_size_t console_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) +{ + struct console_device* device; + + device = (struct console_device*)dev; + RT_ASSERT(device != RT_NULL); + + return rt_device_write(device->device, pos, buffer, size); +} + +static rt_err_t console_control(rt_device_t dev, rt_uint8_t cmd, void *args) +{ + return rt_device_control(_console.device, cmd, args); +} + +void rt_console_init(const char* device_name) +{ + rt_device_t device; + /* register to device framework */ + + device = rt_device_find(device_name); + if (device != RT_NULL) + { + struct console_device* console; + /* get console device */ + console = &_console; + rt_memset(console, 0, sizeof(_console)); + + /* device initialization */ + console->parent.type = RT_Device_Class_Char; + /* set device interface */ + console->parent.init = console_init; + console->parent.open = console_open; + console->parent.close = console_close; + console->parent.read = console_read; + console->parent.write = console_write; + console->parent.control = RT_NULL; + console->parent.user_data = RT_NULL; + + console->device = device; + + rt_device_register(&console->parent, "console", RT_DEVICE_FLAG_RDWR); + } +} + diff --git a/components/dfs/filesystems/devfs/devfs.c b/components/dfs/filesystems/devfs/devfs.c index 98f2146f6d..2a8e78df5e 100644 --- a/components/dfs/filesystems/devfs/devfs.c +++ b/components/dfs/filesystems/devfs/devfs.c @@ -1,276 +1,276 @@ -#include <rtthread.h>
-#include <dfs.h>
-#include <dfs_fs.h>
-
-#include "devfs.h"
-
-/* introduce from kservice.c */
+#include <rtthread.h> +#include <dfs.h> +#include <dfs_fs.h> + +#include "devfs.h" + +/* introduce from kservice.c */ #define rt_list_entry(node, type, member) \ ((type *)((char *)(node) - (unsigned long)(&((type *)0)->member))) -
-struct device_dirent
-{
- rt_device_t *devices;
- rt_uint16_t read_index;
- rt_uint16_t device_count;
-};
-
-int dfs_device_fs_mount(struct dfs_filesystem* fs, unsigned long rwflag, const void* data)
-{
- return DFS_STATUS_OK;
-}
-
-int dfs_device_fs_ioctl(struct dfs_fd* file, int cmd, void* args)
-{
- rt_err_t result;
- rt_device_t dev_id;
-
- RT_ASSERT(file != RT_NULL);
-
- /* get device handler */
- dev_id = (rt_device_t)file->data;
- RT_ASSERT(dev_id != RT_NULL);
-
- /* close device handler */
- result = rt_device_control(dev_id, cmd, args);
- if (result == RT_EOK)
- return DFS_STATUS_OK;
-
- return -DFS_STATUS_EIO;
-}
-
-int dfs_device_fs_read(struct dfs_fd* file, void *buf, rt_size_t count)
-{
- int result;
- rt_device_t dev_id;
-
- RT_ASSERT(file != RT_NULL);
-
- /* get device handler */
- dev_id = (rt_device_t)file->data;
- RT_ASSERT(dev_id != RT_NULL);
-
- /* read device data */
- result = rt_device_read(dev_id, file->pos, buf, count);
- file->pos += result;
-
- return result;
-}
-
-int dfs_device_fs_write(struct dfs_fd* file, const void *buf, rt_size_t count)
-{
- int result;
- rt_device_t dev_id;
-
- RT_ASSERT(file != RT_NULL);
-
- /* get device handler */
- dev_id = (rt_device_t)file->data;
- RT_ASSERT(dev_id != RT_NULL);
-
- /* read device data */
- result = rt_device_write(dev_id, file->pos, buf, count);
- file->pos += result;
-
- return result;
-}
-
-int dfs_device_fs_close(struct dfs_fd* file)
-{
- rt_err_t result;
- rt_device_t dev_id;
-
- RT_ASSERT(file != RT_NULL);
-
- if (file->type == FT_DIRECTORY)
- {
- struct device_dirent *root_dirent;
-
- root_dirent = (struct device_dirent*)file->data;
- RT_ASSERT(root_dirent != RT_NULL);
-
- /* release dirent */
- rt_free(root_dirent);
- return DFS_STATUS_OK;
- }
-
- /* get device handler */
- dev_id = (rt_device_t)file->data;
- RT_ASSERT(dev_id != RT_NULL);
-
- /* close device handler */
- result = rt_device_close(dev_id);
- if (result == RT_EOK)
- {
- file->data = RT_NULL;
- return DFS_STATUS_OK;
- }
-
- return -DFS_STATUS_EIO;
-}
-
-int dfs_device_fs_open(struct dfs_fd* file)
-{
- rt_device_t device;
-
- if (file->flags & DFS_O_CREAT) return -DFS_STATUS_EINVAL;
-
- /* open root directory */
- if ((file->path[0] == '/') && (file->path[1] == '\0') &&
- (file->flags & DFS_O_DIRECTORY))
- {
- struct rt_object* object;
- struct rt_list_node* node;
- struct rt_object_information *information;
- struct device_dirent* root_dirent;
- rt_uint32_t count = 0;
-
- extern struct rt_object_information rt_object_container[];
-
- /* lock scheduler */
- rt_enter_critical();
- /* traverse device object */
- information = &rt_object_container[RT_Object_Class_Device];
- for (node = information->object_list.next; node != &(information->object_list); node = node->next)
- {
- count ++;
- }
-
- root_dirent = (struct device_dirent*) rt_malloc (sizeof(struct device_dirent) +
- count * sizeof(rt_device_t));
- if (root_dirent != RT_NULL)
- {
- root_dirent->devices = (rt_device_t *)(root_dirent + 1);
- root_dirent->read_index = 0;
- root_dirent->device_count = count;
- count = 0;
- /* get all device node */
- for (node = information->object_list.next; node != &(information->object_list); node = node->next)
- {
- object = rt_list_entry(node, struct rt_object, list);
- root_dirent->devices[count] = (rt_device_t)object;
- count ++;
- }
- }
- rt_exit_critical();
-
- /* set data */
- file->data = root_dirent;
- return DFS_STATUS_OK;
- }
-
- device = rt_device_find(&file->path[1]);
- if (device == RT_NULL)
- return -DFS_STATUS_ENODEV;
-
- file->data = device;
- return DFS_STATUS_OK;
-}
-
-int dfs_device_fs_stat(struct dfs_filesystem* fs, const char *path, struct stat *st)
-{
- /* stat root directory */
- if ((path[0] == '/') && (path[1] == '\0'))
- {
- st->st_dev = 0;
-
- st->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
- DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
- st->st_mode &= ~DFS_S_IFREG;
- st->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
-
- st->st_size = 0;
- st->st_mtime = 0;
- st->st_blksize = 512;
- return DFS_STATUS_OK;
- }
- else
- {
- rt_device_t dev_id;
-
- dev_id = rt_device_find(&path[1]);
- if (dev_id != RT_NULL)
- {
- st->st_dev = 0;
-
- st->st_mode = DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
- DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
-
- if (dev_id->type == RT_Device_Class_Char)
- st->st_mode |= DFS_S_IFCHR;
- else if (dev_id->type == RT_Device_Class_Block)
- st->st_mode |= DFS_S_IFBLK;
- else
- st->st_mode |= DFS_S_IFREG;
-
- st->st_size = 0;
- st->st_mtime = 0;
- st->st_blksize = 512;
- return DFS_STATUS_OK;
- }
- }
-
- return -DFS_STATUS_ENOENT;
-}
-
-int dfs_device_fs_getdents(struct dfs_fd* file, struct dirent* dirp, rt_uint32_t count)
-{
- rt_uint32_t index;
- rt_object_t object;
- struct dirent* d;
- struct device_dirent *root_dirent;
-
- root_dirent = (struct device_dirent*)file->data;
- RT_ASSERT(root_dirent != RT_NULL);
-
- /* make integer count */
- count = (count / sizeof(struct dirent));
- if ( count == 0 ) return -DFS_STATUS_EINVAL;
-
- for (index = 0; index < count && index + root_dirent->read_index < root_dirent->device_count;
- index ++)
- {
- object = (rt_object_t)root_dirent->devices[root_dirent->read_index + index];
-
- d = dirp + index;
- d->d_type = DFS_DT_REG;
- d->d_namlen = RT_NAME_MAX;
- d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
- rt_strncpy(d->d_name, object->name, RT_NAME_MAX);
- }
-
- root_dirent->read_index += index;
-
- return index * sizeof(struct dirent);
-}
-
-static const struct dfs_filesystem_operation _device_fs =
-{
- "devfs",
- dfs_device_fs_mount,
- RT_NULL,
- RT_NULL,
- RT_NULL,
-
- dfs_device_fs_open,
- dfs_device_fs_close,
- dfs_device_fs_ioctl,
- dfs_device_fs_read,
- dfs_device_fs_write,
- RT_NULL,
- RT_NULL,
- dfs_device_fs_getdents,
- RT_NULL,
- dfs_device_fs_stat,
- RT_NULL,
-};
-
-int devfs_init(void)
-{
- /* register rom file system */
- dfs_register(&_device_fs);
-
- return 0;
-}
-
+struct device_dirent +{ + rt_device_t *devices; + rt_uint16_t read_index; + rt_uint16_t device_count; +}; + +int dfs_device_fs_mount(struct dfs_filesystem* fs, unsigned long rwflag, const void* data) +{ + return DFS_STATUS_OK; +} + +int dfs_device_fs_ioctl(struct dfs_fd* file, int cmd, void* args) +{ + rt_err_t result; + rt_device_t dev_id; + + RT_ASSERT(file != RT_NULL); + + /* get device handler */ + dev_id = (rt_device_t)file->data; + RT_ASSERT(dev_id != RT_NULL); + + /* close device handler */ + result = rt_device_control(dev_id, cmd, args); + if (result == RT_EOK) + return DFS_STATUS_OK; + + return -DFS_STATUS_EIO; +} + +int dfs_device_fs_read(struct dfs_fd* file, void *buf, rt_size_t count) +{ + int result; + rt_device_t dev_id; + + RT_ASSERT(file != RT_NULL); + + /* get device handler */ + dev_id = (rt_device_t)file->data; + RT_ASSERT(dev_id != RT_NULL); + + /* read device data */ + result = rt_device_read(dev_id, file->pos, buf, count); + file->pos += result; + + return result; +} + +int dfs_device_fs_write(struct dfs_fd* file, const void *buf, rt_size_t count) +{ + int result; + rt_device_t dev_id; + + RT_ASSERT(file != RT_NULL); + + /* get device handler */ + dev_id = (rt_device_t)file->data; + RT_ASSERT(dev_id != RT_NULL); + + /* read device data */ + result = rt_device_write(dev_id, file->pos, buf, count); + file->pos += result; + + return result; +} + +int dfs_device_fs_close(struct dfs_fd* file) +{ + rt_err_t result; + rt_device_t dev_id; + + RT_ASSERT(file != RT_NULL); + + if (file->type == FT_DIRECTORY) + { + struct device_dirent *root_dirent; + + root_dirent = (struct device_dirent*)file->data; + RT_ASSERT(root_dirent != RT_NULL); + + /* release dirent */ + rt_free(root_dirent); + return DFS_STATUS_OK; + } + + /* get device handler */ + dev_id = (rt_device_t)file->data; + RT_ASSERT(dev_id != RT_NULL); + + /* close device handler */ + result = rt_device_close(dev_id); + if (result == RT_EOK) + { + file->data = RT_NULL; + return DFS_STATUS_OK; + } + + return -DFS_STATUS_EIO; +} + +int dfs_device_fs_open(struct dfs_fd* file) +{ + rt_device_t device; + + if (file->flags & DFS_O_CREAT) return -DFS_STATUS_EINVAL; + + /* open root directory */ + if ((file->path[0] == '/') && (file->path[1] == '\0') && + (file->flags & DFS_O_DIRECTORY)) + { + struct rt_object* object; + struct rt_list_node* node; + struct rt_object_information *information; + struct device_dirent* root_dirent; + rt_uint32_t count = 0; + + extern struct rt_object_information rt_object_container[]; + + /* lock scheduler */ + rt_enter_critical(); + + /* traverse device object */ + information = &rt_object_container[RT_Object_Class_Device]; + for (node = information->object_list.next; node != &(information->object_list); node = node->next) + { + count ++; + } + + root_dirent = (struct device_dirent*) rt_malloc (sizeof(struct device_dirent) + + count * sizeof(rt_device_t)); + if (root_dirent != RT_NULL) + { + root_dirent->devices = (rt_device_t *)(root_dirent + 1); + root_dirent->read_index = 0; + root_dirent->device_count = count; + count = 0; + /* get all device node */ + for (node = information->object_list.next; node != &(information->object_list); node = node->next) + { + object = rt_list_entry(node, struct rt_object, list); + root_dirent->devices[count] = (rt_device_t)object; + count ++; + } + } + rt_exit_critical(); + + /* set data */ + file->data = root_dirent; + return DFS_STATUS_OK; + } + + device = rt_device_find(&file->path[1]); + if (device == RT_NULL) + return -DFS_STATUS_ENODEV; + + file->data = device; + return DFS_STATUS_OK; +} + +int dfs_device_fs_stat(struct dfs_filesystem* fs, const char *path, struct stat *st) +{ + /* stat root directory */ + if ((path[0] == '/') && (path[1] == '\0')) + { + st->st_dev = 0; + + st->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH | + DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH; + st->st_mode &= ~DFS_S_IFREG; + st->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH; + + st->st_size = 0; + st->st_mtime = 0; + st->st_blksize = 512; + return DFS_STATUS_OK; + } + else + { + rt_device_t dev_id; + + dev_id = rt_device_find(&path[1]); + if (dev_id != RT_NULL) + { + st->st_dev = 0; + + st->st_mode = DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH | + DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH; + + if (dev_id->type == RT_Device_Class_Char) + st->st_mode |= DFS_S_IFCHR; + else if (dev_id->type == RT_Device_Class_Block) + st->st_mode |= DFS_S_IFBLK; + else + st->st_mode |= DFS_S_IFREG; + + st->st_size = 0; + st->st_mtime = 0; + st->st_blksize = 512; + return DFS_STATUS_OK; + } + } + + return -DFS_STATUS_ENOENT; +} + +int dfs_device_fs_getdents(struct dfs_fd* file, struct dirent* dirp, rt_uint32_t count) +{ + rt_uint32_t index; + rt_object_t object; + struct dirent* d; + struct device_dirent *root_dirent; + + root_dirent = (struct device_dirent*)file->data; + RT_ASSERT(root_dirent != RT_NULL); + + /* make integer count */ + count = (count / sizeof(struct dirent)); + if ( count == 0 ) return -DFS_STATUS_EINVAL; + + for (index = 0; index < count && index + root_dirent->read_index < root_dirent->device_count; + index ++) + { + object = (rt_object_t)root_dirent->devices[root_dirent->read_index + index]; + + d = dirp + index; + d->d_type = DFS_DT_REG; + d->d_namlen = RT_NAME_MAX; + d->d_reclen = (rt_uint16_t)sizeof(struct dirent); + rt_strncpy(d->d_name, object->name, RT_NAME_MAX); + } + + root_dirent->read_index += index; + + return index * sizeof(struct dirent); +} + +static const struct dfs_filesystem_operation _device_fs = +{ + "devfs", + dfs_device_fs_mount, + RT_NULL, + RT_NULL, + RT_NULL, + + dfs_device_fs_open, + dfs_device_fs_close, + dfs_device_fs_ioctl, + dfs_device_fs_read, + dfs_device_fs_write, + RT_NULL, + RT_NULL, + dfs_device_fs_getdents, + RT_NULL, + dfs_device_fs_stat, + RT_NULL, +}; + +int devfs_init(void) +{ + /* register rom file system */ + dfs_register(&_device_fs); + + return 0; +} + diff --git a/components/dfs/filesystems/devfs/devfs.h b/components/dfs/filesystems/devfs/devfs.h index 90583e979f..248aab91d7 100644 --- a/components/dfs/filesystems/devfs/devfs.h +++ b/components/dfs/filesystems/devfs/devfs.h @@ -1,8 +1,8 @@ -#ifndef __DEVICE_FS_H__
-#define __DEVICE_FS_H__
-
-#include <rtthread.h>
-
-int devfs_init(void);
-
-#endif
+#ifndef __DEVICE_FS_H__ +#define __DEVICE_FS_H__ + +#include <rtthread.h> + +int devfs_init(void); + +#endif diff --git a/components/dfs/filesystems/nfs/rpc/auth.h b/components/dfs/filesystems/nfs/rpc/auth.h index e117e7e411..3351fbbf95 100644 --- a/components/dfs/filesystems/nfs/rpc/auth.h +++ b/components/dfs/filesystems/nfs/rpc/auth.h @@ -1,104 +1,104 @@ -#ifndef __AUTH_H__
-#define __AUTH_H__
-
-#include <rpc/xdr.h>
-
-/*
- * Status returned from authentication check
- */
-enum auth_stat {
- AUTH_OK=0,
- /*
- * failed at remote end
- */
- AUTH_BADCRED=1, /* bogus credentials (seal broken) */
- AUTH_REJECTEDCRED=2, /* client should begin new session */
- AUTH_BADVERF=3, /* bogus verifier (seal broken) */
- AUTH_REJECTEDVERF=4, /* verifier expired or was replayed */
- AUTH_TOOWEAK=5, /* rejected due to security reasons */
- /*
- * failed locally
- */
- AUTH_INVALIDRESP=6, /* bogus response verifier */
- AUTH_FAILED=7 /* some unknown reason */
-};
-
-union des_block {
- struct {
- uint32_t high;
- uint32_t low;
- } key;
- char c[8];
-};
-typedef union des_block des_block;
-
-/*
- * Authentication info. Opaque to client.
- */
-struct opaque_auth {
- enum_t oa_flavor; /* flavor of auth */
- char* oa_base; /* address of more auth stuff */
- unsigned int oa_length; /* not to exceed MAX_AUTH_BYTES */
-};
-
-/*
- * Auth handle, interface to client side authenticators.
- */
-typedef struct AUTH AUTH;
-struct AUTH {
- struct opaque_auth ah_cred;
- struct opaque_auth ah_verf;
- union des_block ah_key;
- struct auth_ops {
- void (*ah_nextverf) (AUTH *);
- int (*ah_marshal) (AUTH *, XDR *); /* nextverf & serialize */
- int (*ah_validate) (AUTH *, struct opaque_auth *);
- /* validate verifier */
- int (*ah_refresh) (AUTH *); /* refresh credentials */
- void (*ah_destroy) (AUTH *); /* destroy this structure */
- } *ah_ops;
- char* ah_private;
-};
-
-extern struct opaque_auth _null_auth;
-
-
-/*
- * Authentication ops.
- * The ops and the auth handle provide the interface to the authenticators.
- *
- * AUTH *auth;
- * XDR *xdrs;
- * struct opaque_auth verf;
- */
-#define AUTH_NEXTVERF(auth) \
- ((*((auth)->ah_ops->ah_nextverf))(auth))
-#define auth_nextverf(auth) \
- ((*((auth)->ah_ops->ah_nextverf))(auth))
-
-#define AUTH_MARSHALL(auth, xdrs) \
- ((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
-#define auth_marshall(auth, xdrs) \
- ((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
-
-#define AUTH_VALIDATE(auth, verfp) \
- ((*((auth)->ah_ops->ah_validate))((auth), verfp))
-#define auth_validate(auth, verfp) \
- ((*((auth)->ah_ops->ah_validate))((auth), verfp))
-
-#define AUTH_REFRESH(auth) \
- ((*((auth)->ah_ops->ah_refresh))(auth))
-#define auth_refresh(auth) \
- ((*((auth)->ah_ops->ah_refresh))(auth))
-
-#define AUTH_DESTROY(auth) \
- ((*((auth)->ah_ops->ah_destroy))(auth))
-#define auth_destroy(auth) \
- ((*((auth)->ah_ops->ah_destroy))(auth))
-
-#define MAX_AUTH_BYTES 400
-#define MAXNETNAMELEN 255 /* maximum length of network user's name */
-
-AUTH *authnone_create(void);
-
-#endif
+#ifndef __AUTH_H__ +#define __AUTH_H__ + +#include <rpc/xdr.h> + +/* + * Status returned from authentication check + */ +enum auth_stat { + AUTH_OK=0, + /* + * failed at remote end + */ + AUTH_BADCRED=1, /* bogus credentials (seal broken) */ + AUTH_REJECTEDCRED=2, /* client should begin new session */ + AUTH_BADVERF=3, /* bogus verifier (seal broken) */ + AUTH_REJECTEDVERF=4, /* verifier expired or was replayed */ + AUTH_TOOWEAK=5, /* rejected due to security reasons */ + /* + * failed locally + */ + AUTH_INVALIDRESP=6, /* bogus response verifier */ + AUTH_FAILED=7 /* some unknown reason */ +}; + +union des_block { + struct { + uint32_t high; + uint32_t low; + } key; + char c[8]; +}; +typedef union des_block des_block; + +/* + * Authentication info. Opaque to client. + */ +struct opaque_auth { + enum_t oa_flavor; /* flavor of auth */ + char* oa_base; /* address of more auth stuff */ + unsigned int oa_length; /* not to exceed MAX_AUTH_BYTES */ +}; + +/* + * Auth handle, interface to client side authenticators. + */ +typedef struct AUTH AUTH; +struct AUTH { + struct opaque_auth ah_cred; + struct opaque_auth ah_verf; + union des_block ah_key; + struct auth_ops { + void (*ah_nextverf) (AUTH *); + int (*ah_marshal) (AUTH *, XDR *); /* nextverf & serialize */ + int (*ah_validate) (AUTH *, struct opaque_auth *); + /* validate verifier */ + int (*ah_refresh) (AUTH *); /* refresh credentials */ + void (*ah_destroy) (AUTH *); /* destroy this structure */ + } *ah_ops; + char* ah_private; +}; + +extern struct opaque_auth _null_auth; + + +/* + * Authentication ops. + * The ops and the auth handle provide the interface to the authenticators. + * + * AUTH *auth; + * XDR *xdrs; + * struct opaque_auth verf; + */ +#define AUTH_NEXTVERF(auth) \ + ((*((auth)->ah_ops->ah_nextverf))(auth)) +#define auth_nextverf(auth) \ + ((*((auth)->ah_ops->ah_nextverf))(auth)) + +#define AUTH_MARSHALL(auth, xdrs) \ + ((*((auth)->ah_ops->ah_marshal))(auth, xdrs)) +#define auth_marshall(auth, xdrs) \ + ((*((auth)->ah_ops->ah_marshal))(auth, xdrs)) + +#define AUTH_VALIDATE(auth, verfp) \ + ((*((auth)->ah_ops->ah_validate))((auth), verfp)) +#define auth_validate(auth, verfp) \ + ((*((auth)->ah_ops->ah_validate))((auth), verfp)) + +#define AUTH_REFRESH(auth) \ + ((*((auth)->ah_ops->ah_refresh))(auth)) +#define auth_refresh(auth) \ + ((*((auth)->ah_ops->ah_refresh))(auth)) + +#define AUTH_DESTROY(auth) \ + ((*((auth)->ah_ops->ah_destroy))(auth)) +#define auth_destroy(auth) \ + ((*((auth)->ah_ops->ah_destroy))(auth)) + +#define MAX_AUTH_BYTES 400 +#define MAXNETNAMELEN 255 /* maximum length of network user's name */ + +AUTH *authnone_create(void); + +#endif diff --git a/components/dfs/filesystems/nfs/rpc/pmap.c b/components/dfs/filesystems/nfs/rpc/pmap.c index 0a1fb9af89..cbf5add2ab 100644 --- a/components/dfs/filesystems/nfs/rpc/pmap.c +++ b/components/dfs/filesystems/nfs/rpc/pmap.c @@ -1,60 +1,60 @@ -#include "pmap.h"
-#include "clnt.h"
-#include <rpc/rpc.h>
-
-static struct timeval timeout = { 5, 0 };
-static struct timeval tottimeout = { 60, 0 };
-
-
-bool_t xdr_pmap(xdrs, regs)
-XDR *xdrs;
-struct pmap *regs;
-{
- if (xdr_u_long(xdrs, ®s->pm_prog) &&
- xdr_u_long(xdrs, ®s->pm_vers) &&
- xdr_u_long(xdrs, ®s->pm_prot))
- return (xdr_u_long(xdrs, ®s->pm_port));
- return (FALSE);
-}
-
-/*
- * Find the mapped port for program,version.
- * Calls the pmap service remotely to do the lookup.
- * Returns 0 if no map exists.
- */
-unsigned short pmap_getport(address, program, version, protocol)
-struct sockaddr_in *address;
-unsigned long program;
-unsigned long version;
-unsigned int protocol;
-{
- unsigned short port = 0;
- int socket = -1;
- register CLIENT *client;
- struct pmap parms;
-
- address->sin_port = htons((unsigned short)PMAPPORT);
- if (protocol == IPPROTO_UDP)
- client = clntudp_bufcreate(address, PMAPPROG, PMAPVERS, timeout,
- &socket, RPCSMALLMSGSIZE,
- RPCSMALLMSGSIZE);
-
- if (client != (CLIENT *) NULL)
- {
- parms.pm_prog = program;
- parms.pm_vers = version;
- parms.pm_prot = protocol;
- parms.pm_port = 0; /* not needed or used */
- if (CLNT_CALL(client, PMAPPROC_GETPORT, (xdrproc_t)xdr_pmap, (char*)&parms,
- (xdrproc_t)xdr_u_short, (char*)&port, tottimeout) != RPC_SUCCESS)
- {
- rt_kprintf("pmap failure\n");
- }
- CLNT_DESTROY(client);
- }
-
- (void) lwip_close(socket);
- address->sin_port = 0;
-
- return (port);
-}
+#include "pmap.h" +#include "clnt.h" +#include <rpc/rpc.h> + +static struct timeval timeout = { 5, 0 }; +static struct timeval tottimeout = { 60, 0 }; + + +bool_t xdr_pmap(xdrs, regs) +XDR *xdrs; +struct pmap *regs; +{ + if (xdr_u_long(xdrs, ®s->pm_prog) && + xdr_u_long(xdrs, ®s->pm_vers) && + xdr_u_long(xdrs, ®s->pm_prot)) + return (xdr_u_long(xdrs, ®s->pm_port)); + return (FALSE); +} + +/* + * Find the mapped port for program,version. + * Calls the pmap service remotely to do the lookup. + * Returns 0 if no map exists. + */ +unsigned short pmap_getport(address, program, version, protocol) +struct sockaddr_in *address; +unsigned long program; +unsigned long version; +unsigned int protocol; +{ + unsigned short port = 0; + int socket = -1; + register CLIENT *client; + struct pmap parms; + + address->sin_port = htons((unsigned short)PMAPPORT); + if (protocol == IPPROTO_UDP) + client = clntudp_bufcreate(address, PMAPPROG, PMAPVERS, timeout, + &socket, RPCSMALLMSGSIZE, + RPCSMALLMSGSIZE); + + if (client != (CLIENT *) NULL) + { + parms.pm_prog = program; + parms.pm_vers = version; + parms.pm_prot = protocol; + parms.pm_port = 0; /* not needed or used */ + if (CLNT_CALL(client, PMAPPROC_GETPORT, (xdrproc_t)xdr_pmap, (char*)&parms, + (xdrproc_t)xdr_u_short, (char*)&port, tottimeout) != RPC_SUCCESS) + { + rt_kprintf("pmap failure\n"); + } + CLNT_DESTROY(client); + } + + (void) lwip_close(socket); + address->sin_port = 0; + + return (port); +} diff --git a/components/dfs/filesystems/nfs/rpc/pmap.h b/components/dfs/filesystems/nfs/rpc/pmap.h index 96a67375bb..aaf28a331a 100644 --- a/components/dfs/filesystems/nfs/rpc/pmap.h +++ b/components/dfs/filesystems/nfs/rpc/pmap.h @@ -1,58 +1,58 @@ -#ifndef __RPC_PMAP_PROT_H__
-#define __RPC_PMAP_PROT_H__
-
-#include <rpc/xdr.h>
-
-/* The following procedures are supported by the protocol:
- *
- * PMAPPROC_NULL() returns ()
- * takes nothing, returns nothing
- *
- * PMAPPROC_SET(struct pmap) returns (bool_t)
- * TRUE is success, FALSE is failure. Registers the tuple
- * [prog, vers, prot, port].
- *
- * PMAPPROC_UNSET(struct pmap) returns (bool_t)
- * TRUE is success, FALSE is failure. Un-registers pair
- * [prog, vers]. prot and port are ignored.
- *
- * PMAPPROC_GETPORT(struct pmap) returns (long unsigned).
- * 0 is failure. Otherwise returns the port number where the pair
- * [prog, vers] is registered. It may lie!
- *
- * PMAPPROC_DUMP() RETURNS (struct pmaplist *)
- *
- * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>)
- * RETURNS (port, string<>);
- * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs);
- * Calls the procedure on the local machine. If it is not registered,
- * this procedure is quite; ie it does not return error information!!!
- * This procedure only is supported on rpc/udp and calls via
- * rpc/udp. This routine only passes null authentication parameters.
- * This file has no interface to xdr routines for PMAPPROC_CALLIT.
- *
- * The service supports remote procedure calls on udp/ip or tcp/ip socket 111.
- */
-
-#define PMAPPORT ((unsigned short)111)
-#define PMAPPROG ((unsigned long)100000)
-#define PMAPVERS ((unsigned long)2)
-#define PMAPVERS_PROTO ((unsigned long)2)
-#define PMAPVERS_ORIG ((unsigned long)1)
-#define PMAPPROC_NULL ((unsigned long)0)
-#define PMAPPROC_SET ((unsigned long)1)
-#define PMAPPROC_UNSET ((unsigned long)2)
-#define PMAPPROC_GETPORT ((unsigned long)3)
-#define PMAPPROC_DUMP ((unsigned long)4)
-#define PMAPPROC_CALLIT ((unsigned long)5)
-
-struct pmap {
- long unsigned pm_prog;
- long unsigned pm_vers;
- long unsigned pm_prot;
- long unsigned pm_port;
-};
-
-extern bool_t xdr_pmap (XDR *__xdrs, struct pmap *__regs);
-
-#endif
+#ifndef __RPC_PMAP_PROT_H__ +#define __RPC_PMAP_PROT_H__ + +#include <rpc/xdr.h> + +/* The following procedures are supported by the protocol: + * + * PMAPPROC_NULL() returns () + * takes nothing, returns nothing + * + * PMAPPROC_SET(struct pmap) returns (bool_t) + * TRUE is success, FALSE is failure. Registers the tuple + * [prog, vers, prot, port]. + * + * PMAPPROC_UNSET(struct pmap) returns (bool_t) + * TRUE is success, FALSE is failure. Un-registers pair + * [prog, vers]. prot and port are ignored. + * + * PMAPPROC_GETPORT(struct pmap) returns (long unsigned). + * 0 is failure. Otherwise returns the port number where the pair + * [prog, vers] is registered. It may lie! + * + * PMAPPROC_DUMP() RETURNS (struct pmaplist *) + * + * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>) + * RETURNS (port, string<>); + * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs); + * Calls the procedure on the local machine. If it is not registered, + * this procedure is quite; ie it does not return error information!!! + * This procedure only is supported on rpc/udp and calls via + * rpc/udp. This routine only passes null authentication parameters. + * This file has no interface to xdr routines for PMAPPROC_CALLIT. + * + * The service supports remote procedure calls on udp/ip or tcp/ip socket 111. + */ + +#define PMAPPORT ((unsigned short)111) +#define PMAPPROG ((unsigned long)100000) +#define PMAPVERS ((unsigned long)2) +#define PMAPVERS_PROTO ((unsigned long)2) +#define PMAPVERS_ORIG ((unsigned long)1) +#define PMAPPROC_NULL ((unsigned long)0) +#define PMAPPROC_SET ((unsigned long)1) +#define PMAPPROC_UNSET ((unsigned long)2) +#define PMAPPROC_GETPORT ((unsigned long)3) +#define PMAPPROC_DUMP ((unsigned long)4) +#define PMAPPROC_CALLIT ((unsigned long)5) + +struct pmap { + long unsigned pm_prog; + long unsigned pm_vers; + long unsigned pm_prot; + long unsigned pm_port; +}; + +extern bool_t xdr_pmap (XDR *__xdrs, struct pmap *__regs); + +#endif diff --git a/components/dfs/include/dfs.h b/components/dfs/include/dfs.h index dc5d311bc6..04fe678387 100644 --- a/components/dfs/include/dfs.h +++ b/components/dfs/include/dfs.h @@ -1,37 +1,37 @@ -/*
- * File : dfs.h
- * This file is part of Device File System in RT-Thread RTOS
- * COPYRIGHT (C) 2004-2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE.
- *
- * Change Logs:
- * Date Author Notes
- * 2005-02-22 Bernard The first version.
- */
-
-#ifndef __DFS_H__
-#define __DFS_H__
-
-#include <string.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-char* dfs_normalize_path(const char* directory, const char* filename);
-const char* dfs_subdir(const char* directory, const char* filename);
-
-/* FD APIs */
-int fd_new(void);
-struct dfs_fd* fd_get(int fd);
-void fd_put(struct dfs_fd* fd);
-int fd_is_open(const char* pathname);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+/* + * File : dfs.h + * This file is part of Device File System in RT-Thread RTOS + * COPYRIGHT (C) 2004-2010, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE. + * + * Change Logs: + * Date Author Notes + * 2005-02-22 Bernard The first version. + */ + +#ifndef __DFS_H__ +#define __DFS_H__ + +#include <string.h> + +#ifdef __cplusplus +extern "C" { +#endif + +char* dfs_normalize_path(const char* directory, const char* filename); +const char* dfs_subdir(const char* directory, const char* filename); + +/* FD APIs */ +int fd_new(void); +struct dfs_fd* fd_get(int fd); +void fd_put(struct dfs_fd* fd); +int fd_is_open(const char* pathname); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/dfs/include/dfs_elm.h b/components/dfs/include/dfs_elm.h index dea7162080..c54ee83c1d 100644 --- a/components/dfs/include/dfs_elm.h +++ b/components/dfs/include/dfs_elm.h @@ -1,29 +1,29 @@ -/*
-+------------------------------------------------------------------------------
-| Project : Device Filesystem
-+------------------------------------------------------------------------------
-| Copyright 2004, 2005 www.fayfayspace.org.
-| All rights reserved.
-|------------------------------------------------------------------------------
-| File : dfs_efs.h
-|------------------------------------------------------------------------------
-| Chang Logs:
-| Date Author Notes
-| 2010-02-06 Bernard Add elm_init function declaration
-+------------------------------------------------------------------------------
-*/
-
-#ifndef __DFS_ELM_H__
-#define __DFS_ELM_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int elm_init(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+/* ++------------------------------------------------------------------------------ +| Project : Device Filesystem ++------------------------------------------------------------------------------ +| Copyright 2004, 2005 www.fayfayspace.org. +| All rights reserved. +|------------------------------------------------------------------------------ +| File : dfs_efs.h +|------------------------------------------------------------------------------ +| Chang Logs: +| Date Author Notes +| 2010-02-06 Bernard Add elm_init function declaration ++------------------------------------------------------------------------------ +*/ + +#ifndef __DFS_ELM_H__ +#define __DFS_ELM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +int elm_init(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/dfs/include/dfs_file.h b/components/dfs/include/dfs_file.h index ab75916977..3cf6681924 100644 --- a/components/dfs/include/dfs_file.h +++ b/components/dfs/include/dfs_file.h @@ -1,35 +1,35 @@ -/*
-+------------------------------------------------------------------------------
-| Project : Device Filesystem
-+------------------------------------------------------------------------------
-| Copyright 2004, 2005 www.fayfayspace.org.
-| All rights reserved.
-|------------------------------------------------------------------------------
-| File : dfs_raw.h, the raw APIs of Device FileSystem
-|------------------------------------------------------------------------------
-| Chang Logs:
-| Date Author Notes
-| 2005-01-26 ffxz The first version
-+------------------------------------------------------------------------------
-*/
-
-#ifndef __DFS_RAW_H__
-#define __DFS_RAW_H__
-
-#include <dfs_def.h>
-#include <dfs.h>
-#include <dfs_fs.h>
-
-int dfs_file_open(struct dfs_fd* fd, const char *path, int flags);
-int dfs_file_close(struct dfs_fd* fd);
-int dfs_file_ioctl(struct dfs_fd* fd, int cmd, void *args);
-int dfs_file_read(struct dfs_fd* fd, void *buf, rt_size_t len);
-int dfs_file_getdents(struct dfs_fd* fd, struct dirent* dirp, rt_size_t nbytes);
-int dfs_file_unlink(const char *path);
-int dfs_file_write(struct dfs_fd* fd, const void *buf, rt_size_t len);
-int dfs_file_lseek(struct dfs_fd* fd, rt_off_t offset);
-int dfs_file_stat(const char *path, struct stat *buf);
-int dfs_file_rename(const char* oldpath, const char* newpath);
-
-#endif
-
+/* ++------------------------------------------------------------------------------ +| Project : Device Filesystem ++------------------------------------------------------------------------------ +| Copyright 2004, 2005 www.fayfayspace.org. +| All rights reserved. +|------------------------------------------------------------------------------ +| File : dfs_raw.h, the raw APIs of Device FileSystem +|------------------------------------------------------------------------------ +| Chang Logs: +| Date Author Notes +| 2005-01-26 ffxz The first version ++------------------------------------------------------------------------------ +*/ + +#ifndef __DFS_RAW_H__ +#define __DFS_RAW_H__ + +#include <dfs_def.h> +#include <dfs.h> +#include <dfs_fs.h> + +int dfs_file_open(struct dfs_fd* fd, const char *path, int flags); +int dfs_file_close(struct dfs_fd* fd); +int dfs_file_ioctl(struct dfs_fd* fd, int cmd, void *args); +int dfs_file_read(struct dfs_fd* fd, void *buf, rt_size_t len); +int dfs_file_getdents(struct dfs_fd* fd, struct dirent* dirp, rt_size_t nbytes); +int dfs_file_unlink(const char *path); +int dfs_file_write(struct dfs_fd* fd, const void *buf, rt_size_t len); +int dfs_file_lseek(struct dfs_fd* fd, rt_off_t offset); +int dfs_file_stat(const char *path, struct stat *buf); +int dfs_file_rename(const char* oldpath, const char* newpath); + +#endif + diff --git a/components/dfs/include/dfs_fs.h b/components/dfs/include/dfs_fs.h index b04de24f0b..fafac355c1 100644 --- a/components/dfs/include/dfs_fs.h +++ b/components/dfs/include/dfs_fs.h @@ -1,89 +1,89 @@ -/*
- * File : dfs_fs.h
- * This file is part of Device File System in RT-Thread RTOS
- * COPYRIGHT (C) 2004-2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE.
- *
- * Change Logs:
- * Date Author Notes
- * 2005-02-22 Bernard The first version.
- */
-#ifndef __DFS_FS_H__
-#define __DFS_FS_H__
-
-#include <dfs_def.h>
-
-/* Pre-declaration */
-struct dfs_filesystem;
-struct dfs_fd;
-
-/* File system operations struct */
-struct dfs_filesystem_operation
-{
- char *name;
-
- /* mount and unmount file system */
- int (*mount) (struct dfs_filesystem* fs, unsigned long rwflag, const void* data);
- int (*unmount) (struct dfs_filesystem* fs);
-
- /* make a file system */
- int (*mkfs) (const char* device_name);
- int (*statfs) (struct dfs_filesystem* fs, struct statfs *buf);
-
- int (*open) (struct dfs_fd* fd);
- int (*close) (struct dfs_fd* fd);
- int (*ioctl) (struct dfs_fd* fd, int cmd, void *args);
- int (*read) (struct dfs_fd* fd, void* buf, rt_size_t count);
- int (*write) (struct dfs_fd* fd, const void* buf, rt_size_t count);
- int (*flush) (struct dfs_fd* fd);
- int (*lseek) (struct dfs_fd* fd, rt_off_t offset);
- int (*getdents) (struct dfs_fd* fd, struct dirent* dirp, rt_uint32_t count);
-
- int (*unlink) (struct dfs_filesystem* fs, const char* pathname);
- int (*stat) (struct dfs_filesystem* fs, const char* filename, struct stat* buf);
- int (*rename) (struct dfs_filesystem* fs, const char* oldpath, const char* newpath);
-};
-
-/* Mounted file system */
-struct dfs_filesystem
-{
- rt_device_t dev_id; /* Attached device */
-
- char* path; /* File system mount point */
- const struct dfs_filesystem_operation* ops; /* Operations for file system type */
-
- void *data; /* Specific file system data */
-};
-
-/* file system partition table */
-struct dfs_partition
-{
- rt_uint8_t type; /* file system type */
- rt_off_t offset; /* partition start offset */
- rt_size_t size; /* partition size */
- rt_sem_t lock;
-};
-
-int dfs_register(const struct dfs_filesystem_operation* ops);
-struct dfs_filesystem* dfs_filesystem_lookup(const char *path);
-rt_err_t dfs_filesystem_get_partition(struct dfs_partition* part, rt_uint8_t* buf, rt_uint32_t pindex);
-
-int dfs_mount(const char* device_name, const char* path,
- const char* filesystemtype, rt_uint32_t rwflag, const
- void* data);
-int dfs_unmount(const char *specialfile);
-
-/* extern variable */
-extern const struct dfs_filesystem_operation* filesystem_operation_table[];
-extern struct dfs_filesystem filesystem_table[];
-
-extern char working_directory[];
-
-void dfs_lock(void);
-void dfs_unlock(void);
-int dfs_statfs(const char* path, struct statfs* buffer);
-
-#endif
+/* + * File : dfs_fs.h + * This file is part of Device File System in RT-Thread RTOS + * COPYRIGHT (C) 2004-2010, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE. + * + * Change Logs: + * Date Author Notes + * 2005-02-22 Bernard The first version. + */ +#ifndef __DFS_FS_H__ +#define __DFS_FS_H__ + +#include <dfs_def.h> + +/* Pre-declaration */ +struct dfs_filesystem; +struct dfs_fd; + +/* File system operations struct */ +struct dfs_filesystem_operation +{ + char *name; + + /* mount and unmount file system */ + int (*mount) (struct dfs_filesystem* fs, unsigned long rwflag, const void* data); + int (*unmount) (struct dfs_filesystem* fs); + + /* make a file system */ + int (*mkfs) (const char* device_name); + int (*statfs) (struct dfs_filesystem* fs, struct statfs *buf); + + int (*open) (struct dfs_fd* fd); + int (*close) (struct dfs_fd* fd); + int (*ioctl) (struct dfs_fd* fd, int cmd, void *args); + int (*read) (struct dfs_fd* fd, void* buf, rt_size_t count); + int (*write) (struct dfs_fd* fd, const void* buf, rt_size_t count); + int (*flush) (struct dfs_fd* fd); + int (*lseek) (struct dfs_fd* fd, rt_off_t offset); + int (*getdents) (struct dfs_fd* fd, struct dirent* dirp, rt_uint32_t count); + + int (*unlink) (struct dfs_filesystem* fs, const char* pathname); + int (*stat) (struct dfs_filesystem* fs, const char* filename, struct stat* buf); + int (*rename) (struct dfs_filesystem* fs, const char* oldpath, const char* newpath); +}; + +/* Mounted file system */ +struct dfs_filesystem +{ + rt_device_t dev_id; /* Attached device */ + + char* path; /* File system mount point */ + const struct dfs_filesystem_operation* ops; /* Operations for file system type */ + + void *data; /* Specific file system data */ +}; + +/* file system partition table */ +struct dfs_partition +{ + rt_uint8_t type; /* file system type */ + rt_off_t offset; /* partition start offset */ + rt_size_t size; /* partition size */ + rt_sem_t lock; +}; + +int dfs_register(const struct dfs_filesystem_operation* ops); +struct dfs_filesystem* dfs_filesystem_lookup(const char *path); +rt_err_t dfs_filesystem_get_partition(struct dfs_partition* part, rt_uint8_t* buf, rt_uint32_t pindex); + +int dfs_mount(const char* device_name, const char* path, + const char* filesystemtype, rt_uint32_t rwflag, const + void* data); +int dfs_unmount(const char *specialfile); + +/* extern variable */ +extern const struct dfs_filesystem_operation* filesystem_operation_table[]; +extern struct dfs_filesystem filesystem_table[]; + +extern char working_directory[]; + +void dfs_lock(void); +void dfs_unlock(void); +int dfs_statfs(const char* path, struct statfs* buffer); + +#endif diff --git a/components/dfs/include/dfs_init.h b/components/dfs/include/dfs_init.h index 712ce61156..bc4e6faab5 100644 --- a/components/dfs/include/dfs_init.h +++ b/components/dfs/include/dfs_init.h @@ -1,42 +1,42 @@ -/*
-
-+------------------------------------------------------------------------------
-
-| Project : Device Filesystem
-
-+------------------------------------------------------------------------------
-
-| Copyright 2004, 2005 www.fayfayspace.org.
-
-| All rights reserved.
-
-|------------------------------------------------------------------------------
-
-| File : dfs_init.h, the initilization definitions of Device FileSystem
-|------------------------------------------------------------------------------
-| Chang Logs:
-
-| Date Author Notes
-
-| 2005-02-21 ffxz The first version.
-+------------------------------------------------------------------------------
-*/
-
-#ifndef __DFS_INIT_H__
-#define __DFS_INIT_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* initilization of dfs */
-void dfs_init(void);
-
-/* initilization of dfs with filesystem server */
-void dfs_server_init(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+/* + ++------------------------------------------------------------------------------ + +| Project : Device Filesystem + ++------------------------------------------------------------------------------ + +| Copyright 2004, 2005 www.fayfayspace.org. + +| All rights reserved. + +|------------------------------------------------------------------------------ + +| File : dfs_init.h, the initilization definitions of Device FileSystem +|------------------------------------------------------------------------------ +| Chang Logs: + +| Date Author Notes + +| 2005-02-21 ffxz The first version. ++------------------------------------------------------------------------------ +*/ + +#ifndef __DFS_INIT_H__ +#define __DFS_INIT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* initilization of dfs */ +void dfs_init(void); + +/* initilization of dfs with filesystem server */ +void dfs_server_init(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/dfs/include/dfs_posix.h b/components/dfs/include/dfs_posix.h index ad4d3fc167..2eee57a1a8 100644 --- a/components/dfs/include/dfs_posix.h +++ b/components/dfs/include/dfs_posix.h @@ -1,116 +1,116 @@ -/*
- * File : dfs_def.h
- * This file is part of Device File System in RT-Thread RTOS
- * COPYRIGHT (C) 2004-2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE.
- *
- * Change Logs:
- * Date Author Notes
- * 2009-05-27 Yi.qiu The first version.
- * 2010-07-18 Bernard add stat and statfs structure definitions.
- * 2011-05-16 Yi.qiu Change parameter name of rename, "new" is C++ key word.
- */
-#ifndef __DFS_POSIX_H__
-#define __DFS_POSIX_H__
-
-#include <dfs_file.h>
-#include <dfs_def.h>
-
-#ifndef RT_USING_NEWLIB
-#define O_RDONLY DFS_O_RDONLY
-#define O_WRONLY DFS_O_WRONLY
-#define O_RDWR DFS_O_RDWR
-#define O_ACCMODE DFS_O_ACCMODE
-#define O_CREAT DFS_O_CREAT
-#define O_EXCL DFS_O_EXCL
-#define O_TRUNC DFS_O_TRUNC
-#define O_APPEND DFS_O_APPEND
-#define O_DIRECTORY DFS_O_DIRECTORY
-
-#define S_IFMT DFS_S_IFMT
-#define S_IFSOCK DFS_S_IFSOCK
-#define S_IFLNK DFS_S_IFLNK
-#define S_IFREG DFS_S_IFREG
-#define S_IFBLK DFS_S_IFBLK
-#define S_IFDIR DFS_S_IFDIR
-#define S_IFCHR DFS_S_IFCHR
-#define S_IFIFO DFS_S_IFIFO
-#define S_ISUID DFS_S_ISUID
-#define S_ISGID DFS_S_ISGID
-#define S_ISVTX DFS_S_ISVTX
-
-#define S_ISLNK(m) (((m) & DFS_S_IFMT) == DFS_S_IFLNK)
-#define S_ISREG(m) (((m) & DFS_S_IFMT) == DFS_S_IFREG)
-#define S_ISDIR(m) (((m) & DFS_S_IFMT) == DFS_S_IFDIR)
-#define S_ISCHR(m) (((m) & DFS_S_IFMT) == DFS_S_IFCHR)
-#define S_ISBLK(m) (((m) & DFS_S_IFMT) == DFS_S_IFBLK)
-#define S_ISFIFO(m) (((m) & DFS_S_IFMT) == DFS_S_IFIFO)
-#define S_ISSOCK(m) (((m) & DFS_S_IFMT) == DFS_S_IFSOCK)
-
-#define S_IRWXU DFS_S_IRWXU
-#define S_IRUSR DFS_S_IRUSR
-#define S_IWUSR DFS_S_IWUSR
-#define S_IXUSR DFS_S_IXUSR
-
-#define S_IRWXG DFS_S_IRWXG
-#define S_IRGRP DFS_S_IRGRP
-#define S_IWGRP DFS_S_IWGRP
-#define S_IXGRP DFS_S_IXGRP
-
-#define S_IRWXO DFS_S_IRWXO
-#define S_IROTH DFS_S_IROTH
-#define S_IWOTH DFS_S_IWOTH
-#define S_IXOTH DFS_S_IXOTH
-
-#if defined(__CC_ARM)
-#include <stdio.h>
-#else
-#define SEEK_SET DFS_SEEK_SET
-#define SEEK_CUR DFS_SEEK_CUR
-#define SEEK_END DFS_SEEK_END
-#endif
-
-typedef struct
-{
- int fd; /* directory file */
- char buf[512];
- int num;
- int cur;
-} DIR;
-
-/* directory api*/
-int mkdir (const char *path, mode_t mode);
-DIR* opendir(const char* name);
-struct dirent* readdir(DIR *d);
-long telldir(DIR *d);
-void seekdir(DIR *d, off_t offset);
-void rewinddir(DIR *d);
-int closedir(DIR* d);
-
-#else
-/* use newlib header file */
-#include <sys/stat.h>
-#endif
-
-/* file api*/
-int open(const char *file, int flags, int mode);
-int close(int d);
-int read(int fd, void *buf, size_t len);
-int write(int fd, const void *buf, size_t len);
-off_t lseek(int fd, off_t offset, int whence);
-int rename(const char *from, const char *to);
-int unlink(const char *pathname);
-int stat(const char *file, struct stat *buf);
-int fstat(int fildes, struct stat *buf);
-int statfs(const char *path, struct statfs *buf);
-
-/* directory api*/
-int rmdir(const char *path);
-int chdir(const char *path);
-char *getcwd(char *buf, size_t size);
-
-#endif
-
+/* + * File : dfs_def.h + * This file is part of Device File System in RT-Thread RTOS + * COPYRIGHT (C) 2004-2010, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE. + * + * Change Logs: + * Date Author Notes + * 2009-05-27 Yi.qiu The first version. + * 2010-07-18 Bernard add stat and statfs structure definitions. + * 2011-05-16 Yi.qiu Change parameter name of rename, "new" is C++ key word. + */ +#ifndef __DFS_POSIX_H__ +#define __DFS_POSIX_H__ + +#include <dfs_file.h> +#include <dfs_def.h> + +#ifndef RT_USING_NEWLIB +#define O_RDONLY DFS_O_RDONLY +#define O_WRONLY DFS_O_WRONLY +#define O_RDWR DFS_O_RDWR +#define O_ACCMODE DFS_O_ACCMODE +#define O_CREAT DFS_O_CREAT +#define O_EXCL DFS_O_EXCL +#define O_TRUNC DFS_O_TRUNC +#define O_APPEND DFS_O_APPEND +#define O_DIRECTORY DFS_O_DIRECTORY + +#define S_IFMT DFS_S_IFMT +#define S_IFSOCK DFS_S_IFSOCK +#define S_IFLNK DFS_S_IFLNK +#define S_IFREG DFS_S_IFREG +#define S_IFBLK DFS_S_IFBLK +#define S_IFDIR DFS_S_IFDIR +#define S_IFCHR DFS_S_IFCHR +#define S_IFIFO DFS_S_IFIFO +#define S_ISUID DFS_S_ISUID +#define S_ISGID DFS_S_ISGID +#define S_ISVTX DFS_S_ISVTX + +#define S_ISLNK(m) (((m) & DFS_S_IFMT) == DFS_S_IFLNK) +#define S_ISREG(m) (((m) & DFS_S_IFMT) == DFS_S_IFREG) +#define S_ISDIR(m) (((m) & DFS_S_IFMT) == DFS_S_IFDIR) +#define S_ISCHR(m) (((m) & DFS_S_IFMT) == DFS_S_IFCHR) +#define S_ISBLK(m) (((m) & DFS_S_IFMT) == DFS_S_IFBLK) +#define S_ISFIFO(m) (((m) & DFS_S_IFMT) == DFS_S_IFIFO) +#define S_ISSOCK(m) (((m) & DFS_S_IFMT) == DFS_S_IFSOCK) + +#define S_IRWXU DFS_S_IRWXU +#define S_IRUSR DFS_S_IRUSR +#define S_IWUSR DFS_S_IWUSR +#define S_IXUSR DFS_S_IXUSR + +#define S_IRWXG DFS_S_IRWXG +#define S_IRGRP DFS_S_IRGRP +#define S_IWGRP DFS_S_IWGRP +#define S_IXGRP DFS_S_IXGRP + +#define S_IRWXO DFS_S_IRWXO +#define S_IROTH DFS_S_IROTH +#define S_IWOTH DFS_S_IWOTH +#define S_IXOTH DFS_S_IXOTH + +#if defined(__CC_ARM) +#include <stdio.h> +#else +#define SEEK_SET DFS_SEEK_SET +#define SEEK_CUR DFS_SEEK_CUR +#define SEEK_END DFS_SEEK_END +#endif + +typedef struct +{ + int fd; /* directory file */ + char buf[512]; + int num; + int cur; +} DIR; + +/* directory api*/ +int mkdir (const char *path, mode_t mode); +DIR* opendir(const char* name); +struct dirent* readdir(DIR *d); +long telldir(DIR *d); +void seekdir(DIR *d, off_t offset); +void rewinddir(DIR *d); +int closedir(DIR* d); + +#else +/* use newlib header file */ +#include <sys/stat.h> +#endif + +/* file api*/ +int open(const char *file, int flags, int mode); +int close(int d); +int read(int fd, void *buf, size_t len); +int write(int fd, const void *buf, size_t len); +off_t lseek(int fd, off_t offset, int whence); +int rename(const char *from, const char *to); +int unlink(const char *pathname); +int stat(const char *file, struct stat *buf); +int fstat(int fildes, struct stat *buf); +int statfs(const char *path, struct statfs *buf); + +/* directory api*/ +int rmdir(const char *path); +int chdir(const char *path); +char *getcwd(char *buf, size_t size); + +#endif + diff --git a/components/dfs/src/dfs.c b/components/dfs/src/dfs.c index eaf8650310..bf042a1b58 100644 --- a/components/dfs/src/dfs.c +++ b/components/dfs/src/dfs.c @@ -1,365 +1,365 @@ -/*
- * File : dfs.c
- * This file is part of Device File System in RT-Thread RTOS
- * COPYRIGHT (C) 2004-2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE.
- *
- * Change Logs:
- * Date Author Notes
- * 2005-02-22 Bernard The first version.
- * 2010-07-16
- */
-
-#include <dfs.h>
-#include <dfs_fs.h>
-#include <dfs_file.h>
-
-#define NO_WORKING_DIR "system does not support working dir\n"
-
-/* Global variables */
-const struct dfs_filesystem_operation* filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX];
-struct dfs_filesystem filesystem_table[DFS_FILESYSTEMS_MAX];
-
-/* device filesystem lock */
-static struct rt_mutex fslock;
-
-#ifdef DFS_USING_WORKDIR
-char working_directory[DFS_PATH_MAX] = {"/"};
-#endif
-
-#ifdef DFS_USING_STDIO
-struct dfs_fd fd_table[3 + DFS_FD_MAX];
-#else
-struct dfs_fd fd_table[DFS_FD_MAX];
-#endif
-
-/**
- * @addtogroup DFS
- */
-/*@{*/
-
-/**
- * this function will initialize device file system.
- */
-void dfs_init()
-{
- /* clear filesystem operations table */
- rt_memset(filesystem_operation_table, 0, sizeof(filesystem_operation_table));
- /* clear filesystem table */
- rt_memset(filesystem_table, 0, sizeof(filesystem_table));
- /* clean fd table */
- rt_memset(fd_table, 0, sizeof(fd_table));
-
- /* create device filesystem lock */
- rt_mutex_init(&fslock, "fslock", RT_IPC_FLAG_FIFO);
-
-#ifdef DFS_USING_WORKDIR
- /* set current working directory */
- rt_memset(working_directory, 0, sizeof(working_directory));
- working_directory[0] = '/';
-#endif
-}
-
-/**
- * this function will lock device file system.
- *
- * @note please don't invoke it on ISR.
- */
-void dfs_lock()
-{
- rt_err_t result;
-
- result = rt_mutex_take(&fslock, RT_WAITING_FOREVER);
- if (result != RT_EOK)
- {
- RT_ASSERT(0);
- }
-}
-
-/**
- * this function will lock device file system.
- *
- * @note please don't invoke it on ISR.
- */
-void dfs_unlock()
-{
- rt_mutex_release(&fslock);
-}
-
-/**
- * @ingroup Fd
- * This function will allocate a file descriptor.
- *
- * @return -1 on failed or the allocated file descriptor.
- */
-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;
-}
-
-/**
- * @ingroup Fd
- *
- * This function will return a file descriptor structure according to file
- * descriptor.
- *
- * @return NULL on on this file descriptor or the file descriptor structure
- * pointer.
- */
-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
-
- dfs_lock();
- d = &fd_table[fd];
-
- /* increase the reference count */
- d->ref_count ++;
- dfs_unlock();
-
- return d;
-}
-
-/**
- * @ingroup Fd
- *
- * This function will put the file descriptor.
- */
-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();
-};
-
-/**
- * @ingroup Fd
- *
- * This function will return whether this file has been opend.
- *
- * @param pathname the file path name.
- *
- * @return 0 on file has been open successfully, -1 on open failed.
- */
-int fd_is_open(const char* pathname)
-{
- char *fullpath;
- unsigned int index;
- struct dfs_filesystem* fs;
- struct dfs_fd* fd;
-
- fullpath = dfs_normalize_path(RT_NULL, pathname);
- if (fullpath != RT_NULL)
- {
- char *mountpath;
- fs = dfs_filesystem_lookup(fullpath);
- if (fs == RT_NULL)
- {
- /* can't find mounted file system */
- rt_free(fullpath);
- return -1;
- }
-
- /* get file path name under mounted file system */
- if (fs->path[0] == '/' && fs->path[1] == '\0')
- mountpath = fullpath;
- else mountpath = fullpath + strlen(fs->path);
-
- dfs_lock();
- for (index = 0; index < DFS_FD_MAX; index++)
- {
- fd = &(fd_table[index]);
- if (fd->fs == RT_NULL) continue;
-
- if (fd->fs == fs &&
- strcmp(fd->path, mountpath) == 0)
- {
- /* found file in file descriptor table */
- rt_free(fullpath);
- dfs_unlock();
- return 0;
- }
- }
- dfs_unlock();
-
- rt_free(fullpath);
- }
-
- return -1;
-}
-
-/**
- * this function will return a sub-path name under directory.
- *
- * @param directory the parent directory.
- * @param filename the filename.
- *
- * @return the subdir pointer in filename
- */
-const char* dfs_subdir(const char* directory, const char* filename)
-{
- const char* dir;
-
- if (strlen(directory) == strlen(filename)) /* it's a same path */
- return RT_NULL;
-
- dir = filename + strlen(directory);
- if ((*dir != '/') && (dir != filename))
- {
- dir --;
- }
- return dir;
-}
-
-/**
- * this function will normalize a path according to specified parent directory and file name.
- *
- * @param directory the parent path
- * @param filename the file name
- *
- * @return the built full file path (absoluted path)
- */
-char* dfs_normalize_path(const char* directory, const char* filename)
-{
- char *fullpath;
- char *dst0, *dst, *src;
-
- /* check parameters */
- RT_ASSERT(filename != RT_NULL);
-
-#ifdef DFS_USING_WORKDIR
- if (directory == NULL) /* shall use working directory */
- directory = &working_directory[0];
-#else
- if ((directory == NULL) && (filename[0] != '/'))
- {
- rt_kprintf(NO_WORKING_DIR);
- return RT_NULL;
- }
-#endif
-
- if (filename[0] != '/') /* it's a absolute path, use it directly */
- {
- fullpath = rt_malloc(strlen(directory) + strlen(filename) + 2);
-
- /* join path and file name */
- rt_snprintf(fullpath, strlen(directory) + strlen(filename) + 2,
- "%s/%s", directory, filename);
- }
- else
- {
- fullpath = rt_strdup(filename); /* copy string */
- }
-
- src = fullpath;
- dst = fullpath;
-
- dst0 = dst;
- while (1)
- {
- char c = *src;
-
- if (c == '.')
- {
- if (!src[1]) src ++; /* '.' and ends */
- else if (src[1] == '/')
- {
- /* './' case */
- src += 2;
-
- while ((*src == '/') && (*src != '\0')) src ++;
- continue;
- }
- else if (src[1] == '.')
- {
- if (!src[2])
- {
- /* '..' and ends case */
- src += 2;
- goto up_one;
- }
- else if (src[2] == '/')
- {
- /* '../' case */
- src += 3;
-
- while ((*src == '/') && (*src != '\0')) src ++;
- goto up_one;
- }
- }
- }
-
- /* copy up the next '/' and erase all '/' */
- while ((c = *src++) != '\0' && c != '/') *dst ++ = c;
-
- if (c == '/')
- {
- *dst ++ = '/';
- while (c == '/') c = *src++;
-
- src --;
- }
- else if (!c) break;
-
- continue;
-
-up_one:
- dst --;
- if (dst < dst0) { rt_free(fullpath); return NULL;}
- while (dst0 < dst && dst[-1] != '/') dst --;
- }
-
- *dst = '\0';
-
- /* remove '/' in the end of path if exist */
- dst --;
- if ((dst != fullpath) && (*dst == '/')) *dst = '\0';
-
- return fullpath;
-}
-/*@}*/
-
+/* + * File : dfs.c + * This file is part of Device File System in RT-Thread RTOS + * COPYRIGHT (C) 2004-2010, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE. + * + * Change Logs: + * Date Author Notes + * 2005-02-22 Bernard The first version. + * 2010-07-16 + */ + +#include <dfs.h> +#include <dfs_fs.h> +#include <dfs_file.h> + +#define NO_WORKING_DIR "system does not support working dir\n" + +/* Global variables */ +const struct dfs_filesystem_operation* filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX]; +struct dfs_filesystem filesystem_table[DFS_FILESYSTEMS_MAX]; + +/* device filesystem lock */ +static struct rt_mutex fslock; + +#ifdef DFS_USING_WORKDIR +char working_directory[DFS_PATH_MAX] = {"/"}; +#endif + +#ifdef DFS_USING_STDIO +struct dfs_fd fd_table[3 + DFS_FD_MAX]; +#else +struct dfs_fd fd_table[DFS_FD_MAX]; +#endif + +/** + * @addtogroup DFS + */ +/*@{*/ + +/** + * this function will initialize device file system. + */ +void dfs_init() +{ + /* clear filesystem operations table */ + rt_memset(filesystem_operation_table, 0, sizeof(filesystem_operation_table)); + /* clear filesystem table */ + rt_memset(filesystem_table, 0, sizeof(filesystem_table)); + /* clean fd table */ + rt_memset(fd_table, 0, sizeof(fd_table)); + + /* create device filesystem lock */ + rt_mutex_init(&fslock, "fslock", RT_IPC_FLAG_FIFO); + +#ifdef DFS_USING_WORKDIR + /* set current working directory */ + rt_memset(working_directory, 0, sizeof(working_directory)); + working_directory[0] = '/'; +#endif +} + +/** + * this function will lock device file system. + * + * @note please don't invoke it on ISR. + */ +void dfs_lock() +{ + rt_err_t result; + + result = rt_mutex_take(&fslock, RT_WAITING_FOREVER); + if (result != RT_EOK) + { + RT_ASSERT(0); + } +} + +/** + * this function will lock device file system. + * + * @note please don't invoke it on ISR. + */ +void dfs_unlock() +{ + rt_mutex_release(&fslock); +} + +/** + * @ingroup Fd + * This function will allocate a file descriptor. + * + * @return -1 on failed or the allocated file descriptor. + */ +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; +} + +/** + * @ingroup Fd + * + * This function will return a file descriptor structure according to file + * descriptor. + * + * @return NULL on on this file descriptor or the file descriptor structure + * pointer. + */ +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 + + dfs_lock(); + d = &fd_table[fd]; + + /* increase the reference count */ + d->ref_count ++; + dfs_unlock(); + + return d; +} + +/** + * @ingroup Fd + * + * This function will put the file descriptor. + */ +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(); +}; + +/** + * @ingroup Fd + * + * This function will return whether this file has been opend. + * + * @param pathname the file path name. + * + * @return 0 on file has been open successfully, -1 on open failed. + */ +int fd_is_open(const char* pathname) +{ + char *fullpath; + unsigned int index; + struct dfs_filesystem* fs; + struct dfs_fd* fd; + + fullpath = dfs_normalize_path(RT_NULL, pathname); + if (fullpath != RT_NULL) + { + char *mountpath; + fs = dfs_filesystem_lookup(fullpath); + if (fs == RT_NULL) + { + /* can't find mounted file system */ + rt_free(fullpath); + return -1; + } + + /* get file path name under mounted file system */ + if (fs->path[0] == '/' && fs->path[1] == '\0') + mountpath = fullpath; + else mountpath = fullpath + strlen(fs->path); + + dfs_lock(); + for (index = 0; index < DFS_FD_MAX; index++) + { + fd = &(fd_table[index]); + if (fd->fs == RT_NULL) continue; + + if (fd->fs == fs && + strcmp(fd->path, mountpath) == 0) + { + /* found file in file descriptor table */ + rt_free(fullpath); + dfs_unlock(); + return 0; + } + } + dfs_unlock(); + + rt_free(fullpath); + } + + return -1; +} + +/** + * this function will return a sub-path name under directory. + * + * @param directory the parent directory. + * @param filename the filename. + * + * @return the subdir pointer in filename + */ +const char* dfs_subdir(const char* directory, const char* filename) +{ + const char* dir; + + if (strlen(directory) == strlen(filename)) /* it's a same path */ + return RT_NULL; + + dir = filename + strlen(directory); + if ((*dir != '/') && (dir != filename)) + { + dir --; + } + return dir; +} + +/** + * this function will normalize a path according to specified parent directory and file name. + * + * @param directory the parent path + * @param filename the file name + * + * @return the built full file path (absoluted path) + */ +char* dfs_normalize_path(const char* directory, const char* filename) +{ + char *fullpath; + char *dst0, *dst, *src; + + /* check parameters */ + RT_ASSERT(filename != RT_NULL); + +#ifdef DFS_USING_WORKDIR + if (directory == NULL) /* shall use working directory */ + directory = &working_directory[0]; +#else + if ((directory == NULL) && (filename[0] != '/')) + { + rt_kprintf(NO_WORKING_DIR); + return RT_NULL; + } +#endif + + if (filename[0] != '/') /* it's a absolute path, use it directly */ + { + fullpath = rt_malloc(strlen(directory) + strlen(filename) + 2); + + /* join path and file name */ + rt_snprintf(fullpath, strlen(directory) + strlen(filename) + 2, + "%s/%s", directory, filename); + } + else + { + fullpath = rt_strdup(filename); /* copy string */ + } + + src = fullpath; + dst = fullpath; + + dst0 = dst; + while (1) + { + char c = *src; + + if (c == '.') + { + if (!src[1]) src ++; /* '.' and ends */ + else if (src[1] == '/') + { + /* './' case */ + src += 2; + + while ((*src == '/') && (*src != '\0')) src ++; + continue; + } + else if (src[1] == '.') + { + if (!src[2]) + { + /* '..' and ends case */ + src += 2; + goto up_one; + } + else if (src[2] == '/') + { + /* '../' case */ + src += 3; + + while ((*src == '/') && (*src != '\0')) src ++; + goto up_one; + } + } + } + + /* copy up the next '/' and erase all '/' */ + while ((c = *src++) != '\0' && c != '/') *dst ++ = c; + + if (c == '/') + { + *dst ++ = '/'; + while (c == '/') c = *src++; + + src --; + } + else if (!c) break; + + continue; + +up_one: + dst --; + if (dst < dst0) { rt_free(fullpath); return NULL;} + while (dst0 < dst && dst[-1] != '/') dst --; + } + + *dst = '\0'; + + /* remove '/' in the end of path if exist */ + dst --; + if ((dst != fullpath) && (*dst == '/')) *dst = '\0'; + + return fullpath; +} +/*@}*/ + diff --git a/components/dfs/src/dfs_file.c b/components/dfs/src/dfs_file.c index 58d57ea3da..f102c15d32 100644 --- a/components/dfs/src/dfs_file.c +++ b/components/dfs/src/dfs_file.c @@ -1,589 +1,589 @@ -/*
- * File : dfs_file.c
- * This file is part of Device File System in RT-Thread RTOS
- * COPYRIGHT (C) 2004-2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE.
- *
- * Change Logs:
- * Date Author Notes
- * 2005-02-22 Bernard The first version.
- */
-#include <dfs.h>
-#include <dfs_file.h>
-
-/**
- * @addtogroup FileApi
- */
-/*@{*/
-
-/**
- * this function will open a file which specified by path with specified flags.
- *
- * @param fd the file descriptor pointer to return the corresponding result.
- * @param path the spaciefied file path.
- * @param flags the flags for open operator.
- *
- * @return 0 on successful, -1 on failed.
- */
-int dfs_file_open(struct dfs_fd* fd, const char *path, int flags)
-{
- struct dfs_filesystem* fs;
- char *fullpath;
- int result;
-
- /* parameter check */
- if ( fd == RT_NULL ) return -DFS_STATUS_EINVAL;
-
- /* make sure we have an absolute path */
- fullpath = dfs_normalize_path(RT_NULL, path);
- if (fullpath == RT_NULL)
- {
- return -1;
- }
-
- dfs_log(DFS_DEBUG_INFO, ("open file:%s", fullpath));
-
- /* find filesystem */
- fs = dfs_filesystem_lookup(fullpath);
- if ( fs == RT_NULL )
- {
- rt_free(fullpath); /* release path */
- 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->flags = flags;
- fd->size = 0;
- fd->pos = 0;
-
- if (dfs_subdir(fs->path, fullpath) == RT_NULL)
- fd->path = rt_strdup("/");
- else
- fd->path = rt_strdup(dfs_subdir(fs->path, fullpath));
- rt_free(fullpath);
- dfs_log(DFS_DEBUG_INFO, ("actul file path: %s\n", fd->path));
-
- /* specific file system open routine */
- if (fs->ops->open == RT_NULL)
- {
- /* clear fd */
- rt_free(fd->path);
- rt_memset(fd, 0, sizeof(*fd));
-
- return -DFS_STATUS_ENOSYS;
- }
-
- if ((result = fs->ops->open(fd)) < 0)
- {
- /* clear fd */
- rt_free(fd->path);
- rt_memset(fd, 0, sizeof(*fd));
-
- 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;
-}
-
-/**
- * this function will close a file descriptor.
- *
- * @param fd the file descriptor to be closed.
- *
- * @return 0 on successful, -1 on failed.
- */
-int dfs_file_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;
-
- rt_free(fd->path);
- rt_memset(fd, 0, sizeof(struct dfs_fd));
-
- return result;
-}
-
-/**
- * this function will perform a io control on a file descriptor.
- *
- * @param fd the file descriptor.
- * @param cmd the command to send to file descriptor.
- * @param args the argument to send to file descriptor.
- *
- * @return 0 on successful, -1 on failed.
- */
-int dfs_file_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 (fs->ops->ioctl != RT_NULL) return fs->ops->ioctl(fd, cmd, args);
-
- return -DFS_STATUS_ENOSYS;
-}
-
-/**
- * this function will read specified length data from a file descriptor to a buffer.
- *
- * @param fd the file descriptor.
- * @param buf the buffer to save the read data.
- * @param len the length of data buffer to be read.
- *
- * @return the actual read data bytes or 0 on end of file or failed.
- */
-int dfs_file_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;
-}
-
-/**
- * this function will fetch directory entries from a directory descriptor.
- *
- * @param fd the directory decriptor.
- * @param dirp the dirent buffer to save result.
- * @param nbytes the aviable room in the buffer.
- *
- * @return the read dirent, others on failed.
- */
-int dfs_file_getdents(struct dfs_fd* fd, struct 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;
-}
-
-/**
- * this function will unlink (remove) a specified path file from file system.
- *
- * @param path the specified path file to be unlinked.
- *
- * @return 0 on successful, -1 on failed.
- */
-int dfs_file_unlink(const char *path)
-{
- int result;
- char *fullpath;
- struct dfs_filesystem* fs;
-
- result = DFS_STATUS_OK;
-
- /* Make sure we have an absolute path */
- fullpath = dfs_normalize_path(RT_NULL, path);
- if ( fullpath == RT_NULL)
- {
- return -DFS_STATUS_EINVAL;
- }
-
- /* get filesystem */
- if ( (fs = dfs_filesystem_lookup(fullpath)) == RT_NULL)
- {
- result = -DFS_STATUS_ENOENT;
- goto __exit;
- }
-
- /* Check whether file is already open */
- if (fd_is_open(fullpath) == 0)
- {
- result = -DFS_STATUS_EBUSY;
- goto __exit;
- }
-
- if (fs->ops->unlink != RT_NULL)
- {
- if (dfs_subdir(fs->path, fullpath) == RT_NULL)
- result = fs->ops->unlink(fs, "/");
- else
- result = fs->ops->unlink(fs, dfs_subdir(fs->path, fullpath));
- }
- else result = -DFS_STATUS_ENOSYS;
-
-__exit:
- rt_free(fullpath);
- return result;
-}
-
-/**
- * this function will write some specified length data to file system.
- *
- * @param fd the file descriptor.
- * @param buf the data buffer to be written.
- * @param len the data buffer length
- *
- * @return the actual written data length.
- */
-int dfs_file_write(struct dfs_fd* fd, const void *buf, rt_size_t len)
-{
- struct dfs_filesystem* fs;
-
- if (fd == RT_NULL) return -DFS_STATUS_EINVAL;
-
- fs = fd->fs;
- if (fs->ops->write == RT_NULL) return -DFS_STATUS_ENOSYS;
-
- return fs->ops->write(fd, buf, len);
-}
-
-/**
- * this function will flush buffer on a file descriptor.
- *
- * @param fd the file descriptor.
- *
- * @return 0 on successful, -1 on failed.
- */
-int dfs_file_flush(struct dfs_fd* fd)
-{
- struct dfs_filesystem* fs;
-
- if (fd == RT_NULL) return -DFS_STATUS_EINVAL;
-
- fs = fd->fs;
- if (fs->ops->flush == RT_NULL) return -DFS_STATUS_ENOSYS;
-
- return fs->ops->flush(fd);
-}
-
-/**
- * this function will seek the offset for specified file descriptor.
- *
- * @param fd the file descriptor.
- * @param offset the offset to be seeked.
- *
- * @return the current position after seek.
- */
-int dfs_file_lseek(struct dfs_fd* fd, rt_off_t offset)
-{
- int result;
- struct dfs_filesystem* fs = fd->fs;
-
- if (fd == RT_NULL) return -DFS_STATUS_EINVAL;
- if (fs->ops->lseek == RT_NULL) return -DFS_STATUS_ENOSYS;
-
- result = fs->ops->lseek(fd, offset);
-
- /* update current position */
- if (result >= 0)
- fd->pos = result;
-
- return result;
-}
-
-/**
- * this function will get file information.
- *
- * @param path the file path.
- * @param buf the data buffer to save stat description.
- *
- * @return 0 on successful, -1 on failed.
- */
-int dfs_file_stat(const char *path, struct stat *buf)
-{
- int result;
- char* fullpath;
- struct dfs_filesystem* fs;
-
- fullpath = dfs_normalize_path(RT_NULL, path);
- if ( fullpath == RT_NULL )
- {
- return -1;
- }
-
- if ((fs = dfs_filesystem_lookup(fullpath)) == RT_NULL)
- {
- dfs_log(DFS_DEBUG_ERROR, ("can't find mounted filesystem on this path:%s", fullpath));
- rt_free(fullpath);
- return -DFS_STATUS_ENOENT;
- }
-
- if ((fullpath[0] == '/' && fullpath[1] == '\0') ||
- (dfs_subdir(fs->path, fullpath) == RT_NULL))
- {
- /* 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;
-
- /* release full path */
- rt_free(fullpath);
-
- return DFS_STATUS_OK;
- }
- else
- {
- if (fs->ops->stat == RT_NULL)
- {
- rt_free(fullpath);
- dfs_log(DFS_DEBUG_ERROR, ("the filesystem didn't implement this function"));
- return -DFS_STATUS_ENOSYS;
- }
-
- /* get the real file path and get file stat */
- result = fs->ops->stat(fs, dfs_subdir(fs->path, fullpath), buf);
- }
-
- rt_free(fullpath);
-
- return result;
-}
-
-/**
- * this funciton will rename an old path name to a new path name.
- *
- * @param oldpath the old path name.
- * @param newpath the new path name.
- *
- * @return 0 on successful, -1 on failed.
- */
-int dfs_file_rename(const char* oldpath, const char* newpath)
-{
- int result;
- struct dfs_filesystem *oldfs, *newfs;
- char *oldfullpath, *newfullpath;
-
- result = DFS_STATUS_OK;
- newfullpath = RT_NULL;
-
- oldfullpath = dfs_normalize_path(RT_NULL, oldpath);
- if ( oldfullpath == RT_NULL )
- {
- result = -DFS_STATUS_ENOENT;
- goto __exit;
- }
-
- newfullpath = dfs_normalize_path(RT_NULL, newpath);
- if ( newfullpath == RT_NULL )
- {
- result = -DFS_STATUS_ENOENT;
- goto __exit;
- }
-
- if ( (oldfs = dfs_filesystem_lookup(oldfullpath)) == RT_NULL )
- {
- result = -DFS_STATUS_ENOENT;
- goto __exit;
- }
-
- if ( (newfs = dfs_filesystem_lookup(newfullpath)) == RT_NULL )
- {
- result = -DFS_STATUS_ENOENT;
- goto __exit;
- }
-
- if ( oldfs == newfs )
- {
- if ( oldfs->ops->rename == RT_NULL )
- {
- result = -DFS_STATUS_ENOSYS;
- goto __exit;
- }
-
- result = oldfs->ops->rename(oldfs, oldfullpath, newfullpath);
- goto __exit;
- }
-
- result = -DFS_STATUS_EXDEV;
-
-__exit:
- rt_free(oldfullpath);
- rt_free(newfullpath);
-
- /* not at same file system, return EXDEV */
- return result;
-}
-
-#ifdef RT_USING_FINSH
-#include <finsh.h>
-
-static struct dfs_fd fd;
-static struct dirent dirent;
-void ls(const char* pathname)
-{
- struct stat stat;
- int length;
- char *fullpath, *path;
-
- fullpath = RT_NULL;
- if (pathname == RT_NULL)
- {
-#ifdef DFS_USING_WORKDIR
- /* open current working directory */
- path = rt_strdup(working_directory);
-#else
- path = rt_strdup("/");
-#endif
- if (path == RT_NULL) return ; /* out of memory */
- }
- else
- {
- path = (char*)pathname;
- }
-
- /* list directory */
- if ( dfs_file_open(&fd, path, DFS_O_DIRECTORY) == 0 )
- {
- rt_kprintf("Directory %s:\n", path);
- do
- {
- rt_memset(&dirent, 0, sizeof(struct dirent));
- length = dfs_file_getdents(&fd, &dirent, sizeof(struct dirent));
- if ( length > 0 )
- {
- rt_memset(&stat, 0, sizeof(struct stat));
-
- /* build full path for each file */
- fullpath = dfs_normalize_path(path, dirent.d_name);
- if (fullpath == RT_NULL) break;
-
- if (dfs_file_stat(fullpath, &stat) == 0)
- {
- rt_kprintf("%-20s", dirent.d_name);
- if ( DFS_S_ISDIR(stat.st_mode))
- {
- rt_kprintf("%-25s\n", "<DIR>");
- }
- else
- {
- rt_kprintf("%-25lu\n", stat.st_size);
- }
- }
- else
- rt_kprintf("BAD file: %s\n", dirent.d_name);
- rt_free(fullpath);
- }
- }while(length > 0);
-
- dfs_file_close(&fd);
- }
- else
- {
- rt_kprintf("No such directory\n");
- }
- if (pathname == RT_NULL) rt_free(path);
-}
-FINSH_FUNCTION_EXPORT(ls, list directory contents)
-
-void rm(const char* filename)
-{
- if (dfs_file_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 (dfs_file_open(&fd, filename, DFS_O_RDONLY) < 0)
- {
- rt_kprintf("Open %s failed\n", filename);
- return;
- }
-
- do
- {
- rt_memset(buffer, 0, sizeof(buffer));
- length = dfs_file_read(&fd, buffer, sizeof(buffer)-1 );
- if (length > 0)
- {
- rt_kprintf("%s", buffer);
- }
- }while (length > 0);
-
- dfs_file_close(&fd);
-}
-FINSH_FUNCTION_EXPORT(cat, print file)
-
-#define BUF_SZ 4096
-void copy(const char* src, const char* dst)
-{
- struct dfs_fd src_fd;
- rt_uint8_t *block_ptr;
- rt_uint32_t read_bytes;
-
- block_ptr = rt_malloc(BUF_SZ);
- if (block_ptr == RT_NULL)
- {
- rt_kprintf("out of memory\n");
- return;
- }
-
- if (dfs_file_open(&src_fd, src, DFS_O_RDONLY) < 0)
- {
- rt_free(block_ptr);
- rt_kprintf("Read %s failed\n", src);
- return;
- }
- if (dfs_file_open(&fd, dst, DFS_O_WRONLY | DFS_O_CREAT) < 0)
- {
- rt_free(block_ptr);
- dfs_file_close(&src_fd);
-
- rt_kprintf("Write %s failed\n", dst);
- return;
- }
-
- do
- {
- read_bytes = dfs_file_read(&src_fd, block_ptr, BUF_SZ);
- if (read_bytes > 0)
- {
- dfs_file_write(&fd, block_ptr, read_bytes);
- }
- } while (read_bytes > 0);
-
- dfs_file_close(&src_fd);
- dfs_file_close(&fd);
- rt_free(block_ptr);
-}
-FINSH_FUNCTION_EXPORT(copy, copy source file to destination file)
-
-#endif
-/* @} */
-
+/* + * File : dfs_file.c + * This file is part of Device File System in RT-Thread RTOS + * COPYRIGHT (C) 2004-2010, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE. + * + * Change Logs: + * Date Author Notes + * 2005-02-22 Bernard The first version. + */ +#include <dfs.h> +#include <dfs_file.h> + +/** + * @addtogroup FileApi + */ +/*@{*/ + +/** + * this function will open a file which specified by path with specified flags. + * + * @param fd the file descriptor pointer to return the corresponding result. + * @param path the spaciefied file path. + * @param flags the flags for open operator. + * + * @return 0 on successful, -1 on failed. + */ +int dfs_file_open(struct dfs_fd* fd, const char *path, int flags) +{ + struct dfs_filesystem* fs; + char *fullpath; + int result; + + /* parameter check */ + if ( fd == RT_NULL ) return -DFS_STATUS_EINVAL; + + /* make sure we have an absolute path */ + fullpath = dfs_normalize_path(RT_NULL, path); + if (fullpath == RT_NULL) + { + return -1; + } + + dfs_log(DFS_DEBUG_INFO, ("open file:%s", fullpath)); + + /* find filesystem */ + fs = dfs_filesystem_lookup(fullpath); + if ( fs == RT_NULL ) + { + rt_free(fullpath); /* release path */ + 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->flags = flags; + fd->size = 0; + fd->pos = 0; + + if (dfs_subdir(fs->path, fullpath) == RT_NULL) + fd->path = rt_strdup("/"); + else + fd->path = rt_strdup(dfs_subdir(fs->path, fullpath)); + rt_free(fullpath); + dfs_log(DFS_DEBUG_INFO, ("actul file path: %s\n", fd->path)); + + /* specific file system open routine */ + if (fs->ops->open == RT_NULL) + { + /* clear fd */ + rt_free(fd->path); + rt_memset(fd, 0, sizeof(*fd)); + + return -DFS_STATUS_ENOSYS; + } + + if ((result = fs->ops->open(fd)) < 0) + { + /* clear fd */ + rt_free(fd->path); + rt_memset(fd, 0, sizeof(*fd)); + + 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; +} + +/** + * this function will close a file descriptor. + * + * @param fd the file descriptor to be closed. + * + * @return 0 on successful, -1 on failed. + */ +int dfs_file_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; + + rt_free(fd->path); + rt_memset(fd, 0, sizeof(struct dfs_fd)); + + return result; +} + +/** + * this function will perform a io control on a file descriptor. + * + * @param fd the file descriptor. + * @param cmd the command to send to file descriptor. + * @param args the argument to send to file descriptor. + * + * @return 0 on successful, -1 on failed. + */ +int dfs_file_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 (fs->ops->ioctl != RT_NULL) return fs->ops->ioctl(fd, cmd, args); + + return -DFS_STATUS_ENOSYS; +} + +/** + * this function will read specified length data from a file descriptor to a buffer. + * + * @param fd the file descriptor. + * @param buf the buffer to save the read data. + * @param len the length of data buffer to be read. + * + * @return the actual read data bytes or 0 on end of file or failed. + */ +int dfs_file_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; +} + +/** + * this function will fetch directory entries from a directory descriptor. + * + * @param fd the directory decriptor. + * @param dirp the dirent buffer to save result. + * @param nbytes the aviable room in the buffer. + * + * @return the read dirent, others on failed. + */ +int dfs_file_getdents(struct dfs_fd* fd, struct 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; +} + +/** + * this function will unlink (remove) a specified path file from file system. + * + * @param path the specified path file to be unlinked. + * + * @return 0 on successful, -1 on failed. + */ +int dfs_file_unlink(const char *path) +{ + int result; + char *fullpath; + struct dfs_filesystem* fs; + + result = DFS_STATUS_OK; + + /* Make sure we have an absolute path */ + fullpath = dfs_normalize_path(RT_NULL, path); + if ( fullpath == RT_NULL) + { + return -DFS_STATUS_EINVAL; + } + + /* get filesystem */ + if ( (fs = dfs_filesystem_lookup(fullpath)) == RT_NULL) + { + result = -DFS_STATUS_ENOENT; + goto __exit; + } + + /* Check whether file is already open */ + if (fd_is_open(fullpath) == 0) + { + result = -DFS_STATUS_EBUSY; + goto __exit; + } + + if (fs->ops->unlink != RT_NULL) + { + if (dfs_subdir(fs->path, fullpath) == RT_NULL) + result = fs->ops->unlink(fs, "/"); + else + result = fs->ops->unlink(fs, dfs_subdir(fs->path, fullpath)); + } + else result = -DFS_STATUS_ENOSYS; + +__exit: + rt_free(fullpath); + return result; +} + +/** + * this function will write some specified length data to file system. + * + * @param fd the file descriptor. + * @param buf the data buffer to be written. + * @param len the data buffer length + * + * @return the actual written data length. + */ +int dfs_file_write(struct dfs_fd* fd, const void *buf, rt_size_t len) +{ + struct dfs_filesystem* fs; + + if (fd == RT_NULL) return -DFS_STATUS_EINVAL; + + fs = fd->fs; + if (fs->ops->write == RT_NULL) return -DFS_STATUS_ENOSYS; + + return fs->ops->write(fd, buf, len); +} + +/** + * this function will flush buffer on a file descriptor. + * + * @param fd the file descriptor. + * + * @return 0 on successful, -1 on failed. + */ +int dfs_file_flush(struct dfs_fd* fd) +{ + struct dfs_filesystem* fs; + + if (fd == RT_NULL) return -DFS_STATUS_EINVAL; + + fs = fd->fs; + if (fs->ops->flush == RT_NULL) return -DFS_STATUS_ENOSYS; + + return fs->ops->flush(fd); +} + +/** + * this function will seek the offset for specified file descriptor. + * + * @param fd the file descriptor. + * @param offset the offset to be seeked. + * + * @return the current position after seek. + */ +int dfs_file_lseek(struct dfs_fd* fd, rt_off_t offset) +{ + int result; + struct dfs_filesystem* fs = fd->fs; + + if (fd == RT_NULL) return -DFS_STATUS_EINVAL; + if (fs->ops->lseek == RT_NULL) return -DFS_STATUS_ENOSYS; + + result = fs->ops->lseek(fd, offset); + + /* update current position */ + if (result >= 0) + fd->pos = result; + + return result; +} + +/** + * this function will get file information. + * + * @param path the file path. + * @param buf the data buffer to save stat description. + * + * @return 0 on successful, -1 on failed. + */ +int dfs_file_stat(const char *path, struct stat *buf) +{ + int result; + char* fullpath; + struct dfs_filesystem* fs; + + fullpath = dfs_normalize_path(RT_NULL, path); + if ( fullpath == RT_NULL ) + { + return -1; + } + + if ((fs = dfs_filesystem_lookup(fullpath)) == RT_NULL) + { + dfs_log(DFS_DEBUG_ERROR, ("can't find mounted filesystem on this path:%s", fullpath)); + rt_free(fullpath); + return -DFS_STATUS_ENOENT; + } + + if ((fullpath[0] == '/' && fullpath[1] == '\0') || + (dfs_subdir(fs->path, fullpath) == RT_NULL)) + { + /* 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; + + /* release full path */ + rt_free(fullpath); + + return DFS_STATUS_OK; + } + else + { + if (fs->ops->stat == RT_NULL) + { + rt_free(fullpath); + dfs_log(DFS_DEBUG_ERROR, ("the filesystem didn't implement this function")); + return -DFS_STATUS_ENOSYS; + } + + /* get the real file path and get file stat */ + result = fs->ops->stat(fs, dfs_subdir(fs->path, fullpath), buf); + } + + rt_free(fullpath); + + return result; +} + +/** + * this funciton will rename an old path name to a new path name. + * + * @param oldpath the old path name. + * @param newpath the new path name. + * + * @return 0 on successful, -1 on failed. + */ +int dfs_file_rename(const char* oldpath, const char* newpath) +{ + int result; + struct dfs_filesystem *oldfs, *newfs; + char *oldfullpath, *newfullpath; + + result = DFS_STATUS_OK; + newfullpath = RT_NULL; + + oldfullpath = dfs_normalize_path(RT_NULL, oldpath); + if ( oldfullpath == RT_NULL ) + { + result = -DFS_STATUS_ENOENT; + goto __exit; + } + + newfullpath = dfs_normalize_path(RT_NULL, newpath); + if ( newfullpath == RT_NULL ) + { + result = -DFS_STATUS_ENOENT; + goto __exit; + } + + if ( (oldfs = dfs_filesystem_lookup(oldfullpath)) == RT_NULL ) + { + result = -DFS_STATUS_ENOENT; + goto __exit; + } + + if ( (newfs = dfs_filesystem_lookup(newfullpath)) == RT_NULL ) + { + result = -DFS_STATUS_ENOENT; + goto __exit; + } + + if ( oldfs == newfs ) + { + if ( oldfs->ops->rename == RT_NULL ) + { + result = -DFS_STATUS_ENOSYS; + goto __exit; + } + + result = oldfs->ops->rename(oldfs, oldfullpath, newfullpath); + goto __exit; + } + + result = -DFS_STATUS_EXDEV; + +__exit: + rt_free(oldfullpath); + rt_free(newfullpath); + + /* not at same file system, return EXDEV */ + return result; +} + +#ifdef RT_USING_FINSH +#include <finsh.h> + +static struct dfs_fd fd; +static struct dirent dirent; +void ls(const char* pathname) +{ + struct stat stat; + int length; + char *fullpath, *path; + + fullpath = RT_NULL; + if (pathname == RT_NULL) + { +#ifdef DFS_USING_WORKDIR + /* open current working directory */ + path = rt_strdup(working_directory); +#else + path = rt_strdup("/"); +#endif + if (path == RT_NULL) return ; /* out of memory */ + } + else + { + path = (char*)pathname; + } + + /* list directory */ + if ( dfs_file_open(&fd, path, DFS_O_DIRECTORY) == 0 ) + { + rt_kprintf("Directory %s:\n", path); + do + { + rt_memset(&dirent, 0, sizeof(struct dirent)); + length = dfs_file_getdents(&fd, &dirent, sizeof(struct dirent)); + if ( length > 0 ) + { + rt_memset(&stat, 0, sizeof(struct stat)); + + /* build full path for each file */ + fullpath = dfs_normalize_path(path, dirent.d_name); + if (fullpath == RT_NULL) break; + + if (dfs_file_stat(fullpath, &stat) == 0) + { + rt_kprintf("%-20s", dirent.d_name); + if ( DFS_S_ISDIR(stat.st_mode)) + { + rt_kprintf("%-25s\n", "<DIR>"); + } + else + { + rt_kprintf("%-25lu\n", stat.st_size); + } + } + else + rt_kprintf("BAD file: %s\n", dirent.d_name); + rt_free(fullpath); + } + }while(length > 0); + + dfs_file_close(&fd); + } + else + { + rt_kprintf("No such directory\n"); + } + if (pathname == RT_NULL) rt_free(path); +} +FINSH_FUNCTION_EXPORT(ls, list directory contents) + +void rm(const char* filename) +{ + if (dfs_file_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 (dfs_file_open(&fd, filename, DFS_O_RDONLY) < 0) + { + rt_kprintf("Open %s failed\n", filename); + return; + } + + do + { + rt_memset(buffer, 0, sizeof(buffer)); + length = dfs_file_read(&fd, buffer, sizeof(buffer)-1 ); + if (length > 0) + { + rt_kprintf("%s", buffer); + } + }while (length > 0); + + dfs_file_close(&fd); +} +FINSH_FUNCTION_EXPORT(cat, print file) + +#define BUF_SZ 4096 +void copy(const char* src, const char* dst) +{ + struct dfs_fd src_fd; + rt_uint8_t *block_ptr; + rt_uint32_t read_bytes; + + block_ptr = rt_malloc(BUF_SZ); + if (block_ptr == RT_NULL) + { + rt_kprintf("out of memory\n"); + return; + } + + if (dfs_file_open(&src_fd, src, DFS_O_RDONLY) < 0) + { + rt_free(block_ptr); + rt_kprintf("Read %s failed\n", src); + return; + } + if (dfs_file_open(&fd, dst, DFS_O_WRONLY | DFS_O_CREAT) < 0) + { + rt_free(block_ptr); + dfs_file_close(&src_fd); + + rt_kprintf("Write %s failed\n", dst); + return; + } + + do + { + read_bytes = dfs_file_read(&src_fd, block_ptr, BUF_SZ); + if (read_bytes > 0) + { + dfs_file_write(&fd, block_ptr, read_bytes); + } + } while (read_bytes > 0); + + dfs_file_close(&src_fd); + dfs_file_close(&fd); + rt_free(block_ptr); +} +FINSH_FUNCTION_EXPORT(copy, copy source file to destination file) + +#endif +/* @} */ + diff --git a/components/dfs/src/dfs_fs.c b/components/dfs/src/dfs_fs.c index 3a04a05f28..da1e456c7b 100644 --- a/components/dfs/src/dfs_fs.c +++ b/components/dfs/src/dfs_fs.c @@ -1,460 +1,460 @@ -/*
- * File : dfs_fs.c
- * This file is part of Device File System in RT-Thread RTOS
- * COPYRIGHT (C) 2004-2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE.
- *
- * Change Logs:
- * Date Author Notes
- * 2005-02-22 Bernard The first version.
- * 2010-06-30 Bernard Optimize for RT-Thread RTOS
- * 2011-03-12 Bernard fix the filesystem lookup issue.
- */
-#include <dfs_fs.h>
-#include <dfs_file.h>
-
-/**
- * @addtogroup FsApi
- */
-/*@{*/
-
-/**
- * this function will register a file system instance to device file system.
- *
- * @param ops the file system instance to be registered.
- *
- * @return 0 on sucessful, -1 on failed.
- */
-int dfs_register(const 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;
-}
-
-/**
- * this function will return the file system mounted on specified path.
- *
- * @param path the specified path string.
- *
- * @return the found file system or NULL if no file system mounted on
- * specified path
- */
-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; index++)
- {
- if (filesystem_table[index].path == RT_NULL) continue;
- else
- {
- fspath = strlen(filesystem_table[index].path);
- if (fspath < prefixlen) continue;
- }
-
- if ((filesystem_table[index].ops != RT_NULL) &&
- (strncmp(filesystem_table[index].path, path, fspath) == 0))
- {
- /* check next path separator */
- if ( fspath > 1 && (strlen(path) > fspath) &&
- (path[fspath] != '/')) continue;
-
- fs = &filesystem_table[index];
- prefixlen = fspath;
- }
- }
-
- dfs_unlock();
-
- return fs;
-}
-
-/**
- * this function will fetch the partition table on specified buffer.
- *
- * @param part the returned partition structure.
- * @param buf the buffer contains partition table.
- * @param pindex the index of partition table to fetch.
- *
- * @return RT_EOK on successful or -RT_ERROR on failed.
- */
-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;
-
- rt_kprintf("found 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 */
- }
- }
- else
- {
- result = -RT_ERROR;
- }
-
- return result;
-}
-
-/**
- * this function will mount a file system on a specified path.
- *
- * @param device_name the name of device which includes a file system.
- * @param path the path to mount a file system
- * @param filesystemtype the file system type
- * @param rwflag the read/write etc. flag.
- * @param data the private data(parameter) for this file system.
- *
- * @return 0 on successful or -1 on failed.
- */
-int dfs_mount(const char* device_name, const char* path,
- const char* filesystemtype, unsigned long rwflag, const
- void* data)
-{
- const struct dfs_filesystem_operation* ops;
- struct dfs_filesystem* fs;
- char *fullpath=RT_NULL;
- rt_device_t dev_id;
- int index;
-
- /* open specific device */
- if (device_name != RT_NULL)
- {
- dev_id = rt_device_find(device_name);
- if (dev_id == RT_NULL)
- {
- /* no this device */
- rt_set_errno(-DFS_STATUS_ENODEV);
- return -1;
- }
- }
- else
- {
- /* which is a non-device filesystem mount */
- dev_id = RT_NULL;
- }
-
- /* 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 = dfs_normalize_path(RT_NULL, path);
- if ( fullpath == RT_NULL) /* not an abstract path */
- {
- rt_set_errno(-DFS_STATUS_ENOTDIR);
- return -1;
- }
-
- /* Check if the path exists or not, raw APIs call, fixme */
- if ( (strcmp(fullpath, "/") != 0) && (strcmp(fullpath, "/dev") != 0) )
- {
- struct dfs_fd fd;
-
- if ( dfs_file_open(&fd, fullpath, DFS_O_RDONLY | DFS_O_DIRECTORY) < 0 )
- {
- rt_free(fullpath);
- rt_set_errno(-DFS_STATUS_ENOTDIR);
- return -1;
- }
- dfs_file_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_ENOSPC);
- goto err1;
- }
-
- /* register file system */
- fs = &(filesystem_table[index]);
- fs->path = 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 */
- if (dev_id != RT_NULL) rt_device_open(fs->dev_id, RT_DEVICE_OFLAG_RDWR);
-
- if (ops->mount == RT_NULL) /* there is no mount implementation */
- {
- if (dev_id != RT_NULL) rt_device_close(dev_id);
- dfs_lock();
- /* clear filesystem table entry */
- rt_memset(fs, 0, sizeof(struct dfs_filesystem));
- dfs_unlock();
-
- rt_free(fullpath);
- rt_set_errno(-DFS_STATUS_ENOSYS);
- return -1;
- }
- /* call mount of this filesystem */
- else if (ops->mount(fs, rwflag, data) < 0)
- {
- /* close device */
- if (dev_id != RT_NULL) rt_device_close(fs->dev_id);
-
- /* mount failed */
- dfs_lock();
- /* clear filesystem table entry */
- rt_memset(fs, 0, sizeof(struct dfs_filesystem));
- dfs_unlock();
-
- rt_free(fullpath);
- return -1;
- }
-
- return 0;
-
-err1:
- dfs_unlock();
- if (fullpath != RT_NULL) rt_free(fullpath);
-
- return -1;
-}
-
-/**
- * this function will umount a file system on specified path.
- *
- * @param specialfile the specified path which mounted a file system.
- *
- * @return 0 on successful or -1 on failed.
- */
-int dfs_unmount(const char *specialfile)
-{
- char *fullpath;
- struct dfs_filesystem* fs = RT_NULL;
-
- fullpath = dfs_normalize_path(RT_NULL, specialfile);
- if (fullpath == RT_NULL)
- {
- rt_set_errno(-DFS_STATUS_ENOTDIR);
- return -1;
- }
-
- /* 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 */
- if (fs->dev_id != RT_NULL)
- rt_device_close(fs->dev_id);
-
- /* clear this filesystem table entry */
- rt_memset(fs, 0, sizeof(struct dfs_filesystem));
-
- dfs_unlock();
- rt_free(fullpath);
-
- return 0;
-
-err1:
- dfs_unlock();
- rt_free(fullpath);
-
- return -1;
-}
-
-/**
- * make a file system on the special device
- *
- * @param fs_name the file system name
- * @param device_name the special device name
- *
- * @return 0 on successful, otherwise failed.
- */
-int dfs_mkfs(const char* fs_name, const char* device_name)
-{
- int index;
-
- /* lock filesystem */
- dfs_lock();
- /* find the file system operations */
- for (index = 0; index < DFS_FILESYSTEM_TYPES_MAX; index++)
- {
- if (filesystem_operation_table[index] != RT_NULL &&
- strcmp(filesystem_operation_table[index]->name, fs_name) == 0)
- {
- /* find file system operation */
- const struct dfs_filesystem_operation* ops = filesystem_operation_table[index];
- dfs_unlock();
-
- if (ops->mkfs != RT_NULL)
- return ops->mkfs(device_name);
-
- break;
- }
- }
- dfs_unlock();
-
- return -1;
-}
-
-/**
- * this function will return the information about a mounted file system.
- *
- * @param path the path which mounted file system.
- * @param buffer the buffer to save the returned information.
- *
- * @return 0 on successful, others on failed.
- */
-int dfs_statfs(const char* path, struct statfs* buffer)
-{
- struct dfs_filesystem* fs;
-
- fs = dfs_filesystem_lookup(path);
- if (fs != NULL)
- {
- if (fs->ops->statfs!= RT_NULL)
- return fs->ops->statfs(fs, buffer);
- }
-
- return -1;
-}
-
-#ifdef RT_USING_FINSH
-#include <finsh.h>
-void mkfs(const char* fs_name, const char* device_name)
-{
- dfs_mkfs(fs_name, device_name);
-}
-FINSH_FUNCTION_EXPORT(mkfs, make a file system);
-
-void df(const char* path)
-{
- struct statfs buffer;
-
- if (dfs_statfs(path, &buffer) == 0)
- {
- rt_kprintf("disk free: %d block[%d bytes per block]\n", buffer.f_bfree, buffer.f_bsize);
- }
-}
-FINSH_FUNCTION_EXPORT(df, get disk free);
-#endif
-
-/* @} */
+/* + * File : dfs_fs.c + * This file is part of Device File System in RT-Thread RTOS + * COPYRIGHT (C) 2004-2010, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE. + * + * Change Logs: + * Date Author Notes + * 2005-02-22 Bernard The first version. + * 2010-06-30 Bernard Optimize for RT-Thread RTOS + * 2011-03-12 Bernard fix the filesystem lookup issue. + */ +#include <dfs_fs.h> +#include <dfs_file.h> + +/** + * @addtogroup FsApi + */ +/*@{*/ + +/** + * this function will register a file system instance to device file system. + * + * @param ops the file system instance to be registered. + * + * @return 0 on sucessful, -1 on failed. + */ +int dfs_register(const 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; +} + +/** + * this function will return the file system mounted on specified path. + * + * @param path the specified path string. + * + * @return the found file system or NULL if no file system mounted on + * specified path + */ +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; index++) + { + if (filesystem_table[index].path == RT_NULL) continue; + else + { + fspath = strlen(filesystem_table[index].path); + if (fspath < prefixlen) continue; + } + + if ((filesystem_table[index].ops != RT_NULL) && + (strncmp(filesystem_table[index].path, path, fspath) == 0)) + { + /* check next path separator */ + if ( fspath > 1 && (strlen(path) > fspath) && + (path[fspath] != '/')) continue; + + fs = &filesystem_table[index]; + prefixlen = fspath; + } + } + + dfs_unlock(); + + return fs; +} + +/** + * this function will fetch the partition table on specified buffer. + * + * @param part the returned partition structure. + * @param buf the buffer contains partition table. + * @param pindex the index of partition table to fetch. + * + * @return RT_EOK on successful or -RT_ERROR on failed. + */ +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; + + rt_kprintf("found 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 */ + } + } + else + { + result = -RT_ERROR; + } + + return result; +} + +/** + * this function will mount a file system on a specified path. + * + * @param device_name the name of device which includes a file system. + * @param path the path to mount a file system + * @param filesystemtype the file system type + * @param rwflag the read/write etc. flag. + * @param data the private data(parameter) for this file system. + * + * @return 0 on successful or -1 on failed. + */ +int dfs_mount(const char* device_name, const char* path, + const char* filesystemtype, unsigned long rwflag, const + void* data) +{ + const struct dfs_filesystem_operation* ops; + struct dfs_filesystem* fs; + char *fullpath=RT_NULL; + rt_device_t dev_id; + int index; + + /* open specific device */ + if (device_name != RT_NULL) + { + dev_id = rt_device_find(device_name); + if (dev_id == RT_NULL) + { + /* no this device */ + rt_set_errno(-DFS_STATUS_ENODEV); + return -1; + } + } + else + { + /* which is a non-device filesystem mount */ + dev_id = RT_NULL; + } + + /* 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 = dfs_normalize_path(RT_NULL, path); + if ( fullpath == RT_NULL) /* not an abstract path */ + { + rt_set_errno(-DFS_STATUS_ENOTDIR); + return -1; + } + + /* Check if the path exists or not, raw APIs call, fixme */ + if ( (strcmp(fullpath, "/") != 0) && (strcmp(fullpath, "/dev") != 0) ) + { + struct dfs_fd fd; + + if ( dfs_file_open(&fd, fullpath, DFS_O_RDONLY | DFS_O_DIRECTORY) < 0 ) + { + rt_free(fullpath); + rt_set_errno(-DFS_STATUS_ENOTDIR); + return -1; + } + dfs_file_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_ENOSPC); + goto err1; + } + + /* register file system */ + fs = &(filesystem_table[index]); + fs->path = 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 */ + if (dev_id != RT_NULL) rt_device_open(fs->dev_id, RT_DEVICE_OFLAG_RDWR); + + if (ops->mount == RT_NULL) /* there is no mount implementation */ + { + if (dev_id != RT_NULL) rt_device_close(dev_id); + dfs_lock(); + /* clear filesystem table entry */ + rt_memset(fs, 0, sizeof(struct dfs_filesystem)); + dfs_unlock(); + + rt_free(fullpath); + rt_set_errno(-DFS_STATUS_ENOSYS); + return -1; + } + /* call mount of this filesystem */ + else if (ops->mount(fs, rwflag, data) < 0) + { + /* close device */ + if (dev_id != RT_NULL) rt_device_close(fs->dev_id); + + /* mount failed */ + dfs_lock(); + /* clear filesystem table entry */ + rt_memset(fs, 0, sizeof(struct dfs_filesystem)); + dfs_unlock(); + + rt_free(fullpath); + return -1; + } + + return 0; + +err1: + dfs_unlock(); + if (fullpath != RT_NULL) rt_free(fullpath); + + return -1; +} + +/** + * this function will umount a file system on specified path. + * + * @param specialfile the specified path which mounted a file system. + * + * @return 0 on successful or -1 on failed. + */ +int dfs_unmount(const char *specialfile) +{ + char *fullpath; + struct dfs_filesystem* fs = RT_NULL; + + fullpath = dfs_normalize_path(RT_NULL, specialfile); + if (fullpath == RT_NULL) + { + rt_set_errno(-DFS_STATUS_ENOTDIR); + return -1; + } + + /* 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 */ + if (fs->dev_id != RT_NULL) + rt_device_close(fs->dev_id); + + /* clear this filesystem table entry */ + rt_memset(fs, 0, sizeof(struct dfs_filesystem)); + + dfs_unlock(); + rt_free(fullpath); + + return 0; + +err1: + dfs_unlock(); + rt_free(fullpath); + + return -1; +} + +/** + * make a file system on the special device + * + * @param fs_name the file system name + * @param device_name the special device name + * + * @return 0 on successful, otherwise failed. + */ +int dfs_mkfs(const char* fs_name, const char* device_name) +{ + int index; + + /* lock filesystem */ + dfs_lock(); + /* find the file system operations */ + for (index = 0; index < DFS_FILESYSTEM_TYPES_MAX; index++) + { + if (filesystem_operation_table[index] != RT_NULL && + strcmp(filesystem_operation_table[index]->name, fs_name) == 0) + { + /* find file system operation */ + const struct dfs_filesystem_operation* ops = filesystem_operation_table[index]; + dfs_unlock(); + + if (ops->mkfs != RT_NULL) + return ops->mkfs(device_name); + + break; + } + } + dfs_unlock(); + + return -1; +} + +/** + * this function will return the information about a mounted file system. + * + * @param path the path which mounted file system. + * @param buffer the buffer to save the returned information. + * + * @return 0 on successful, others on failed. + */ +int dfs_statfs(const char* path, struct statfs* buffer) +{ + struct dfs_filesystem* fs; + + fs = dfs_filesystem_lookup(path); + if (fs != NULL) + { + if (fs->ops->statfs!= RT_NULL) + return fs->ops->statfs(fs, buffer); + } + + return -1; +} + +#ifdef RT_USING_FINSH +#include <finsh.h> +void mkfs(const char* fs_name, const char* device_name) +{ + dfs_mkfs(fs_name, device_name); +} +FINSH_FUNCTION_EXPORT(mkfs, make a file system); + +void df(const char* path) +{ + struct statfs buffer; + + if (dfs_statfs(path, &buffer) == 0) + { + rt_kprintf("disk free: %d block[%d bytes per block]\n", buffer.f_bfree, buffer.f_bsize); + } +} +FINSH_FUNCTION_EXPORT(df, get disk free); +#endif + +/* @} */ diff --git a/components/dfs/src/dfs_posix.c b/components/dfs/src/dfs_posix.c index c1e80a3d9d..f3e6a3edfd 100644 --- a/components/dfs/src/dfs_posix.c +++ b/components/dfs/src/dfs_posix.c @@ -1,668 +1,668 @@ -/*
- * File : dfs_posix.c
- * This file is part of Device File System in RT-Thread RTOS
- * COPYRIGHT (C) 2004-2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE.
- *
- * Change Logs:
- * Date Author Notes
- * 2009-05-27 Yi.qiu The first version
- */
-
-#include <dfs.h>
-#include <dfs_posix.h>
-
-/**
- * @addtogroup FsPosixApi
- */
-/*@{*/
-
-/**
- * this function is a POSIX compliant version, which will open a file and return
- * a file descriptor.
- *
- * @param file the path name of file.
- * @param flags the file open flags.
- * @param mode
- *
- * @return the non-negative integer on successful open, others for failed.
- */
-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 = dfs_file_open(d, file, flags);
- if (result < 0)
- {
- rt_set_errno(result);
-
- /* release the ref-count of fd */
- fd_put(d);
- fd_put(d);
-
- return -1;
- }
-
- /* release the ref-count of fd */
- fd_put(d);
- return fd;
-}
-
-/**
- * this function is a POSIX compliant version, which will close the open
- * file descriptor.
- *
- * @param fd the file descriptor.
- *
- * @return 0 on successful, -1 on failed.
- */
-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 = dfs_file_close(d);
- fd_put(d);
-
- if (result < 0)
- {
- rt_set_errno(result);
- return -1;
- }
-
- fd_put(d);
- return 0;
-}
-
-/**
- * this function is a POSIX compliant version, which will read specified data buffer
- * length for an open file descriptor.
- *
- * @param fd the file descriptor.
- * @param buf the buffer to save the read data.
- * @param len the maximal length of data buffer
- *
- * @return the actual read data buffer length
- */
-int read(int fd, void *buf, size_t 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 = dfs_file_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;
-}
-
-/**
- * this function is a POSIX compliant version, which will write pecified data buffer
- * length for an open file descriptor.
- *
- * @param fd the file descriptor
- * @param buf the data buffer to be written.
- * @param len the data buffer length.
- *
- * @return the actual written data buffer length.
- */
-int write(int fd, const void *buf, size_t 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 = dfs_file_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;
-}
-
-/**
- * this function is a POSIX compliant version, which will seek the offset for an
- * open file descriptor.
- *
- * @param fd the file descriptor.
- * @param offset the offset to be seeked.
- * @param whence the directory of seek.
- *
- * @return the current file position, or -1 on failed.
- */
-off_t lseek(int fd, off_t offset, int whence)
-{
- int result;
- struct dfs_fd* d;
-
- d = fd_get(fd);
- if (d == RT_NULL)
- {
- rt_set_errno(-RT_ERROR);
- return -1;
- }
-
- switch (whence)
- {
- case DFS_SEEK_SET:
- break;
-
- case DFS_SEEK_CUR:
- offset += d->pos;
- break;
-
- case DFS_SEEK_END:
- offset += d->size;
- break;
- }
-
- result = dfs_file_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;
-}
-
-/**
- * this function is a POSIX compliant version, which will rename old file name to
- * new file name.
- *
- * @param old the old file name.
- * @param new the new file name.
- *
- * @return 0 on successful, -1 on failed.
- *
- * note: the old and new file name must be belong to a same file system.
- */
-int rename(const char* old, const char* new)
-{
- int result;
-
- result = dfs_file_rename(old, new);
- if (result < 0)
- {
- rt_set_errno(result);
- return -1;
- }
- return 0;
-}
-
-/**
- * this function is a POSIX compliant version, which will unlink (remove) a
- * specified path file from file system.
- *
- * @param pathname the specified path name to be unlinked.
- *
- * @return 0 on successful, -1 on failed.
- */
-int unlink(const char *pathname)
-{
- int result;
-
- result = dfs_file_unlink(pathname);
- if (result < 0)
- {
- rt_set_errno(result);
- return -1;
- }
- return 0;
-}
-
-/**
- * this function is a POSIX compliant version, which will get file information.
- *
- * @param file the file name
- * @param buf the data buffer to save stat description.
- *
- * @return 0 on successful, -1 on failed.
- */
-int stat(const char *file, struct stat *buf)
-{
- int result;
-
- result = dfs_file_stat(file, buf);
- if (result < 0)
- {
- rt_set_errno(result);
- return -1;
- }
- return result;
-}
-
-/**
- * this function is a POSIX compliant version, which will get file status.
- *
- * @param fildes the file description
- * @param buf the data buffer to save stat description.
- */
-int fstat(int fildes, struct stat *buf)
-{
- struct dfs_fd* d;
-
- /* get the fd */
- d = fd_get(fildes);
- if (d == RT_NULL)
- {
- rt_set_errno(-RT_ERROR);
- return -1;
- }
-
- /* it's the root directory */
- buf->st_dev = 0;
-
- buf->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
- DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
- if (d->type == FT_DIRECTORY)
- {
- buf->st_mode &= ~DFS_S_IFREG;
- buf->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
- }
-
- buf->st_size = d->size;
- buf->st_mtime = 0;
- buf->st_blksize = 512;
-
- fd_put(d);
-
- return DFS_STATUS_OK;
-}
-
-/**
- * this function is a POSIX compliant version, which will return the
- * information about a mounted file system.
- *
- * @param path the path which mounted file system.
- * @param buf the buffer to save the returned information.
- *
- * @return 0 on successful, others on failed.
- */
-int statfs(const char *path, struct statfs *buf)
-{
- int result;
-
- result = dfs_statfs(path, buf);
- if (result < 0)
- {
- rt_set_errno(result);
- return -1;
- }
-
- return result;
-}
-
-/**
- * this function is a POSIX compliant version, which will make a directory
- *
- * @param path the directory path to be made.
- * @param mode
- *
- * @return 0 on successful, others on failed.
- */
-int mkdir (const char *path, mode_t mode)
-{
- int fd;
- struct dfs_fd* d;
- int result;
-
- fd = fd_new();
- if (fd == -1) { rt_kprintf("no fd\n"); return -1; }
-
- d = fd_get(fd);
-
- result = dfs_file_open(d, path, DFS_O_DIRECTORY | DFS_O_CREAT);
-
- if (result < 0)
- {
- rt_set_errno(result);
- fd_put(d);
- return -1;
- }
-
- dfs_file_close(d);
- fd_put(d);
- return 0;
-}
-#ifdef RT_USING_FINSH
-#include <finsh.h>
-FINSH_FUNCTION_EXPORT(mkdir, create a directory);
-#endif
-
-/**
- * this function is a POSIX compliant version, which will remove a directory.
- *
- * @param pathname the path name to be removed.
- *
- * @return 0 on sucessfull, others on failed.
- */
-int rmdir(const char *pathname)
-{
- int result;
-
- result = dfs_file_unlink(pathname);
- if (result < 0)
- {
- rt_set_errno(result);
- return -1;
- }
-
- return 0;
-}
-
-/**
- * this function is a POSIX compliant version, which will open a directory.
- *
- * @param name the path name to be open.
- *
- * @return the DIR pointer of directory, NULL on open failed.
- */
-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 = dfs_file_open(d, name, DFS_O_RDONLY | DFS_O_DIRECTORY);
- if (result >= 0)
- {
- /* open successfully */
- t = (DIR *) rt_malloc (sizeof(DIR));
- if (t == RT_NULL)
- {
- dfs_file_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;
-}
-
-/**
- * this function is a POSIX compliant version, which will return a pointer
- * to a dirent structure representing the next directory entry in the
- * directory stream.
- *
- * @param d the directory stream pointer.
- *
- * @return the next directory entry, NULL on the end of directory or failed.
- */
-struct 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 dirent*)(d->buf + d->cur))->d_reclen) >= d->num)
- {
- /* get a new entry */
- result = dfs_file_getdents(fd, (struct 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; /* current entry index */
- }
-
- fd_put(fd);
- return (struct dirent*)(d->buf+d->cur);
-}
-
-/**
- * this function is a POSIX compliant version, which will return current
- * location in directory stream.
- *
- * @param d the directory stream pointer.
- *
- * @return the current location in directory stream.
- */
-long telldir(DIR *d)
-{
- struct dfs_fd* fd;
- long 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;
-}
-
-/**
- * this function is a POSIX compliant version, which will set position of
- * next directory structure in the directory stream.
- *
- * @param d the directory stream.
- * @param offset the offset in directory stream.
- */
-void seekdir(DIR *d, off_t offset)
-{
- struct dfs_fd* fd;
-
- fd = fd_get(d->fd);
- if (fd == RT_NULL)
- {
- rt_set_errno(-RT_ERROR);
- return ;
- }
-
- /* seek to the offset position of directory */
- if (dfs_file_lseek(fd, offset) >= 0) d->num = d->cur = 0;
- fd_put(fd);
-}
-
-/**
- * this function is a POSIX compliant version, which will reset directory stream.
- *
- * @param d the directory stream.
- */
-void rewinddir(DIR *d)
-{
- struct dfs_fd* fd;
-
- fd = fd_get(d->fd);
- if (fd == RT_NULL)
- {
- rt_set_errno(-RT_ERROR);
- return ;
- }
-
- /* seek to the beginning of directory */
- if (dfs_file_lseek(fd, 0) >= 0) d->num = d->cur = 0;
- fd_put(fd);
-}
-
-/**
- * this function is a POSIX compliant version, which will close a directory
- * stream.
- *
- * @param d the directory stream.
- *
- * @return 0 on successful, -1 on failed.
- */
-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 = dfs_file_close(fd);
- fd_put(fd);
-
- fd_put(fd);
- rt_free(d);
-
- if (result < 0)
- {
- rt_set_errno(result);
- return -1;
- }
- else return 0;
-}
-
-#ifdef DFS_USING_WORKDIR
-/**
- * this function is a POSIX compliant version, which will change working directory.
- *
- * @param path the path name to be changed to.
- *
- * @return 0 on successful, -1 on failed.
- */
-int chdir(const char *path)
-{
- char* fullpath;
- DIR* d;
-
- if(path == RT_NULL)
- {
- dfs_lock();
- rt_kprintf("%s\n", working_directory);
- dfs_unlock();
- return 0;
- }
-
- if (rt_strlen(path) > DFS_PATH_MAX)
- return -1;
-
- fullpath = dfs_normalize_path(NULL, path);
- if (fullpath == RT_NULL)
- return -1; /* build path failed */
-
- dfs_lock();
- d = opendir(fullpath);
- if (d == RT_NULL)
- {
- rt_free(fullpath);
- /* this is a not exist directory */
- dfs_unlock();
- return -1;
- }
-
- /* close directory stream */
- closedir(d);
-
- /* copy full path to working directory */
- strncpy(working_directory, fullpath, DFS_PATH_MAX);
- rt_free(fullpath); /* release normalize directory path name */
-
- dfs_unlock();
-
- return 0;
-}
-#ifdef RT_USING_FINSH
-FINSH_FUNCTION_EXPORT_ALIAS(chdir, cd, change current working directory);
-#endif
-#endif
-
-/**
- * this function is a POSIX compliant version, which will return current
- * working directory.
- *
- * @param buf the returned current directory.
- * @param size the buffer size.
- *
- * @return the returned current directory.
- */
-char *getcwd(char *buf, size_t size)
-{
-#ifdef DFS_USING_WORKDIR
- rt_enter_critical();
- rt_strncpy(buf, working_directory, size);
- rt_exit_critical();
-#else
- rt_kprintf("WARNING: not support working directory\n");
-#endif
- return buf;
-}
-
-/* @} */
+/* + * File : dfs_posix.c + * This file is part of Device File System in RT-Thread RTOS + * COPYRIGHT (C) 2004-2010, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE. + * + * Change Logs: + * Date Author Notes + * 2009-05-27 Yi.qiu The first version + */ + +#include <dfs.h> +#include <dfs_posix.h> + +/** + * @addtogroup FsPosixApi + */ +/*@{*/ + +/** + * this function is a POSIX compliant version, which will open a file and return + * a file descriptor. + * + * @param file the path name of file. + * @param flags the file open flags. + * @param mode + * + * @return the non-negative integer on successful open, others for failed. + */ +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 = dfs_file_open(d, file, flags); + if (result < 0) + { + rt_set_errno(result); + + /* release the ref-count of fd */ + fd_put(d); + fd_put(d); + + return -1; + } + + /* release the ref-count of fd */ + fd_put(d); + return fd; +} + +/** + * this function is a POSIX compliant version, which will close the open + * file descriptor. + * + * @param fd the file descriptor. + * + * @return 0 on successful, -1 on failed. + */ +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 = dfs_file_close(d); + fd_put(d); + + if (result < 0) + { + rt_set_errno(result); + return -1; + } + + fd_put(d); + return 0; +} + +/** + * this function is a POSIX compliant version, which will read specified data buffer + * length for an open file descriptor. + * + * @param fd the file descriptor. + * @param buf the buffer to save the read data. + * @param len the maximal length of data buffer + * + * @return the actual read data buffer length + */ +int read(int fd, void *buf, size_t 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 = dfs_file_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; +} + +/** + * this function is a POSIX compliant version, which will write pecified data buffer + * length for an open file descriptor. + * + * @param fd the file descriptor + * @param buf the data buffer to be written. + * @param len the data buffer length. + * + * @return the actual written data buffer length. + */ +int write(int fd, const void *buf, size_t 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 = dfs_file_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; +} + +/** + * this function is a POSIX compliant version, which will seek the offset for an + * open file descriptor. + * + * @param fd the file descriptor. + * @param offset the offset to be seeked. + * @param whence the directory of seek. + * + * @return the current file position, or -1 on failed. + */ +off_t lseek(int fd, off_t offset, int whence) +{ + int result; + struct dfs_fd* d; + + d = fd_get(fd); + if (d == RT_NULL) + { + rt_set_errno(-RT_ERROR); + return -1; + } + + switch (whence) + { + case DFS_SEEK_SET: + break; + + case DFS_SEEK_CUR: + offset += d->pos; + break; + + case DFS_SEEK_END: + offset += d->size; + break; + } + + result = dfs_file_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; +} + +/** + * this function is a POSIX compliant version, which will rename old file name to + * new file name. + * + * @param old the old file name. + * @param new the new file name. + * + * @return 0 on successful, -1 on failed. + * + * note: the old and new file name must be belong to a same file system. + */ +int rename(const char* old, const char* new) +{ + int result; + + result = dfs_file_rename(old, new); + if (result < 0) + { + rt_set_errno(result); + return -1; + } + return 0; +} + +/** + * this function is a POSIX compliant version, which will unlink (remove) a + * specified path file from file system. + * + * @param pathname the specified path name to be unlinked. + * + * @return 0 on successful, -1 on failed. + */ +int unlink(const char *pathname) +{ + int result; + + result = dfs_file_unlink(pathname); + if (result < 0) + { + rt_set_errno(result); + return -1; + } + return 0; +} + +/** + * this function is a POSIX compliant version, which will get file information. + * + * @param file the file name + * @param buf the data buffer to save stat description. + * + * @return 0 on successful, -1 on failed. + */ +int stat(const char *file, struct stat *buf) +{ + int result; + + result = dfs_file_stat(file, buf); + if (result < 0) + { + rt_set_errno(result); + return -1; + } + return result; +} + +/** + * this function is a POSIX compliant version, which will get file status. + * + * @param fildes the file description + * @param buf the data buffer to save stat description. + */ +int fstat(int fildes, struct stat *buf) +{ + struct dfs_fd* d; + + /* get the fd */ + d = fd_get(fildes); + if (d == RT_NULL) + { + rt_set_errno(-RT_ERROR); + return -1; + } + + /* it's the root directory */ + buf->st_dev = 0; + + buf->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH | + DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH; + if (d->type == FT_DIRECTORY) + { + buf->st_mode &= ~DFS_S_IFREG; + buf->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH; + } + + buf->st_size = d->size; + buf->st_mtime = 0; + buf->st_blksize = 512; + + fd_put(d); + + return DFS_STATUS_OK; +} + +/** + * this function is a POSIX compliant version, which will return the + * information about a mounted file system. + * + * @param path the path which mounted file system. + * @param buf the buffer to save the returned information. + * + * @return 0 on successful, others on failed. + */ +int statfs(const char *path, struct statfs *buf) +{ + int result; + + result = dfs_statfs(path, buf); + if (result < 0) + { + rt_set_errno(result); + return -1; + } + + return result; +} + +/** + * this function is a POSIX compliant version, which will make a directory + * + * @param path the directory path to be made. + * @param mode + * + * @return 0 on successful, others on failed. + */ +int mkdir (const char *path, mode_t mode) +{ + int fd; + struct dfs_fd* d; + int result; + + fd = fd_new(); + if (fd == -1) { rt_kprintf("no fd\n"); return -1; } + + d = fd_get(fd); + + result = dfs_file_open(d, path, DFS_O_DIRECTORY | DFS_O_CREAT); + + if (result < 0) + { + rt_set_errno(result); + fd_put(d); + return -1; + } + + dfs_file_close(d); + fd_put(d); + return 0; +} +#ifdef RT_USING_FINSH +#include <finsh.h> +FINSH_FUNCTION_EXPORT(mkdir, create a directory); +#endif + +/** + * this function is a POSIX compliant version, which will remove a directory. + * + * @param pathname the path name to be removed. + * + * @return 0 on sucessfull, others on failed. + */ +int rmdir(const char *pathname) +{ + int result; + + result = dfs_file_unlink(pathname); + if (result < 0) + { + rt_set_errno(result); + return -1; + } + + return 0; +} + +/** + * this function is a POSIX compliant version, which will open a directory. + * + * @param name the path name to be open. + * + * @return the DIR pointer of directory, NULL on open failed. + */ +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 = dfs_file_open(d, name, DFS_O_RDONLY | DFS_O_DIRECTORY); + if (result >= 0) + { + /* open successfully */ + t = (DIR *) rt_malloc (sizeof(DIR)); + if (t == RT_NULL) + { + dfs_file_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; +} + +/** + * this function is a POSIX compliant version, which will return a pointer + * to a dirent structure representing the next directory entry in the + * directory stream. + * + * @param d the directory stream pointer. + * + * @return the next directory entry, NULL on the end of directory or failed. + */ +struct 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 dirent*)(d->buf + d->cur))->d_reclen) >= d->num) + { + /* get a new entry */ + result = dfs_file_getdents(fd, (struct 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; /* current entry index */ + } + + fd_put(fd); + return (struct dirent*)(d->buf+d->cur); +} + +/** + * this function is a POSIX compliant version, which will return current + * location in directory stream. + * + * @param d the directory stream pointer. + * + * @return the current location in directory stream. + */ +long telldir(DIR *d) +{ + struct dfs_fd* fd; + long 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; +} + +/** + * this function is a POSIX compliant version, which will set position of + * next directory structure in the directory stream. + * + * @param d the directory stream. + * @param offset the offset in directory stream. + */ +void seekdir(DIR *d, off_t offset) +{ + struct dfs_fd* fd; + + fd = fd_get(d->fd); + if (fd == RT_NULL) + { + rt_set_errno(-RT_ERROR); + return ; + } + + /* seek to the offset position of directory */ + if (dfs_file_lseek(fd, offset) >= 0) d->num = d->cur = 0; + fd_put(fd); +} + +/** + * this function is a POSIX compliant version, which will reset directory stream. + * + * @param d the directory stream. + */ +void rewinddir(DIR *d) +{ + struct dfs_fd* fd; + + fd = fd_get(d->fd); + if (fd == RT_NULL) + { + rt_set_errno(-RT_ERROR); + return ; + } + + /* seek to the beginning of directory */ + if (dfs_file_lseek(fd, 0) >= 0) d->num = d->cur = 0; + fd_put(fd); +} + +/** + * this function is a POSIX compliant version, which will close a directory + * stream. + * + * @param d the directory stream. + * + * @return 0 on successful, -1 on failed. + */ +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 = dfs_file_close(fd); + fd_put(fd); + + fd_put(fd); + rt_free(d); + + if (result < 0) + { + rt_set_errno(result); + return -1; + } + else return 0; +} + +#ifdef DFS_USING_WORKDIR +/** + * this function is a POSIX compliant version, which will change working directory. + * + * @param path the path name to be changed to. + * + * @return 0 on successful, -1 on failed. + */ +int chdir(const char *path) +{ + char* fullpath; + DIR* d; + + if(path == RT_NULL) + { + dfs_lock(); + rt_kprintf("%s\n", working_directory); + dfs_unlock(); + return 0; + } + + if (rt_strlen(path) > DFS_PATH_MAX) + return -1; + + fullpath = dfs_normalize_path(NULL, path); + if (fullpath == RT_NULL) + return -1; /* build path failed */ + + dfs_lock(); + d = opendir(fullpath); + if (d == RT_NULL) + { + rt_free(fullpath); + /* this is a not exist directory */ + dfs_unlock(); + return -1; + } + + /* close directory stream */ + closedir(d); + + /* copy full path to working directory */ + strncpy(working_directory, fullpath, DFS_PATH_MAX); + rt_free(fullpath); /* release normalize directory path name */ + + dfs_unlock(); + + return 0; +} +#ifdef RT_USING_FINSH +FINSH_FUNCTION_EXPORT_ALIAS(chdir, cd, change current working directory); +#endif +#endif + +/** + * this function is a POSIX compliant version, which will return current + * working directory. + * + * @param buf the returned current directory. + * @param size the buffer size. + * + * @return the returned current directory. + */ +char *getcwd(char *buf, size_t size) +{ +#ifdef DFS_USING_WORKDIR + rt_enter_critical(); + rt_strncpy(buf, working_directory, size); + rt_exit_critical(); +#else + rt_kprintf("WARNING: not support working directory\n"); +#endif + return buf; +} + +/* @} */ |
