rt-thread-official/components/dfs/filesystems/uffs/uffs_ext.c

321 lines
5.9 KiB
C

/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
uffs filesystem examples.
*/
#include <rtthread.h>
//#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "uffs/uffs_config.h"
#include "uffs/uffs_public.h"
#include "uffs/uffs_fs.h"
#include "uffs/uffs_utils.h"
#include "uffs/uffs_core.h"
#include "uffs/uffs_mtb.h"
#include "uffs/uffs_find.h"
#include "uffs/uffs_fd.h"
#include "emu/cmdline.h"
#include "uffs_ext.h"
#include <dfs_posix.h>
#include <rtgui/filerw.h>
#ifdef RT_USING_FINSH
#include <finsh.h>
#endif
#define PFX "exp: "
#define MAX_PATH_LENGTH 128
#if (0)
//uffs拷贝函数,参数之间加空格
//需要从elm拷贝到uffs时(跨文件系统),参数名称前加::
//例如uffs_copy("::/01.hdc /dir1/01.hdc")
//上例从SD卡拷贝一个文件01.hdc到flash中,
//也可用dfs的函数,那样就不用考虑是否跨文件系统了.
int uffs_copy(const char *tail)
{
const char *src;
const char *des;
char buf[100];
int fd1=-1, fd2=-1;
int len;
int src_local = FALSE, des_local = FALSE;
int fd3=-1, fd4=-1;
if(!tail)
return FALSE;
src = cli_getparam(tail, &des);
if(!des)
return FALSE;
if(memcmp(src, "::", 2) == 0)
{
src += 2;
src_local = TRUE;
}
if(memcmp(des, "::", 2) == 0)
{
des += 2;
des_local = TRUE;
}
if(src_local)
{
//if((fp1 = fopen(src, "rb")) == NULL)
if((fd3 = open(src,O_RDONLY,0)) < 0)
{
uffs_Perror(UFFS_ERR_NORMAL, "Can't open %s for copy.", src);
goto fail_ext;
}
}
else
{
if((fd1 = uffs_open(src, UO_RDONLY)) < 0)
{
uffs_Perror(UFFS_ERR_NORMAL, "Can't open %s for copy.", src);
goto fail_ext;
}
}
if(des_local)
{
if((fd4 = open(des,O_WRONLY | O_CREAT,0)) < 0)
{
uffs_Perror(UFFS_ERR_NORMAL, "Can't open %s for copy.", des);
goto fail_ext;
}
}
else
{
if((fd2 = uffs_open(des, UO_RDWR|UO_CREATE|UO_TRUNC)) < 0)
{
uffs_Perror(UFFS_ERR_NORMAL, "Can't open %s for copy.", des);
goto fail_ext;
}
}
uffs_Perror(UFFS_ERR_NORMAL, "copy %s to %s... ",src,des);
while((src_local ? (1) : (uffs_eof(fd1) == 0)))
{
if(src_local)
{
len = read(fd3, buf, sizeof(buf));
}
else
{
len = uffs_read(fd1, buf, sizeof(buf));
}
if(len == 0)
break;
if(len < 0)
{
uffs_Perror(UFFS_ERR_NORMAL, "read file %s fail!", src);
break;
}
if(des_local)
{
if(write(fd4, buf, len) != len)
{
uffs_Perror(UFFS_ERR_NORMAL, "write file %s fail!", des);
break;
}
}
else
{
if(uffs_write(fd2, buf, len) != len)
{
uffs_Perror(UFFS_ERR_NORMAL, "write file %s fail ?", des);
break;
}
}
}
uffs_Perror(UFFS_ERR_NORMAL, "succ.");
fail_ext:
if(fd1 > 0)
uffs_close(fd1);
if(fd2 > 0)
uffs_close(fd2);
if(fd3 > 0)
close(fd3);
if(fd4 > 0)
close(fd4);
return TRUE;
}
FINSH_FUNCTION_EXPORT(uffs_copy, copy files. local file start with ::)
#endif
//计算路径下的文件(夹)个数
int CountFileUnder(const char *dir)
{
int count = 0;
uffs_DIR *dirp;
dirp = uffs_opendir(dir);
if(dirp)
{
while(uffs_readdir(dirp) != NULL)
count++;
if(dirp != NULL)
uffs_closedir(dirp);
}
return count;
}
/*
* 函数功能: 列出文件清单
* 输入参数: name:分区名称
* 返回参数: 成功:TRUE,失败:rt_false
*/
int uffs_ls(const char *name)
{
uffs_DIR *dirp;
struct uffs_dirent *ent;
struct uffs_stat stat_buf;
int count = 0;
char buf[MAX_FILENAME_LENGTH+2];
char *sub;
if(name == NULL)
{
return FALSE;
}
dirp = uffs_opendir(name); //会获得一个uffs_DIR实例
if(dirp == NULL)
{
rt_kprintf("Can't open '%s' for list\n", name);
}
else
{
rt_kprintf("%-16s%-8s%-8s%-8s\n","name","type","size","serial");
rt_kprintf("-----------------------------------------\n");
ent = uffs_readdir(dirp);
while(ent)
{
rt_kprintf("%-16s", ent->d_name);
strcpy(buf, name);
sub = buf;
if(name[strlen(name)-1] != '/')
sub = strcat(buf, "/");
sub = strcat(sub, ent->d_name);
if(ent->d_type & FILE_ATTR_DIR)
{
sub = strcat(sub, "/");
rt_kprintf("%-8s", "<DIR>");
rt_kprintf("%-8d", CountFileUnder(sub));
}
else
{
uffs_stat(sub, &stat_buf);
rt_kprintf("%-8s", "");
rt_kprintf("%-8d", stat_buf.st_size);
}
rt_kprintf("%-8d\n", ent->d_ino);
count++;
ent = uffs_readdir(dirp);
}
if(dirp != NULL)
uffs_closedir(dirp);
rt_kprintf("Total: %d objects.\n", count);
}
return TRUE;
}
/*
* 函数功能: 格式化分区
* 输入参数: 分区名称
* 返回参数:
*/
int uffs_format(const char *name)
{
int ret;
const char *mount = "/";
uffs_Device *dev;
if(name)
{
mount = name;
}
dev = uffs_GetDeviceFromMountPoint(mount);
if(dev == NULL)
{
uffs_Perror(UFFS_ERR_NORMAL, "Can't get device from mount point.");
}
else
{
if(dev->ref_count == 1)
{
ret = uffs_FormatDevice(dev);
uffs_Perror(UFFS_ERR_NORMAL, "Format %s.",ret==RT_EOK?"succ":"fail");
}
else
{
uffs_Perror(UFFS_ERR_NORMAL, "dev->ref_count: %d, can't format this device.", dev->ref_count);
}
uffs_PutDevice(dev);
}
return TRUE;
}
/*
* 函数功能: 创建一个文件
* 输入参数: 文件名称
* 返回参数:
*/
int uffs_mkfile(const char *name)
{
uffs_Object *fp;
int ret = 0;
int err = 0;
fp = uffs_GetObject();
if(fp != NULL)
{
if(uffs_CreateObject(fp, name, UO_CREATE) != U_SUCC)
{
err = fp->err;
ret = -1;
uffs_Perror(UFFS_ERR_NORMAL, "Create %s fail, err: %d", name, uffs_get_error());
}
else
{
uffs_Perror(UFFS_ERR_NORMAL, "Create %s succ.", name);
uffs_CloseObject(fp);
ret = 0;
}
uffs_PutObject(fp);
}
else
{
err = UEMFILE;
ret = -1;
}
uffs_set_error(-err);
return ret;
}
#if (0)
#ifdef RT_USING_FINSH
FINSH_FUNCTION_EXPORT(uffs_ls, list uffs system files.)
FINSH_FUNCTION_EXPORT(uffs_mkfile, make uffs system file.)
FINSH_FUNCTION_EXPORT(uffs_mkdir, make uffs system dir.)
FINSH_FUNCTION_EXPORT(uffs_rmdir, remove uffs system dir.)
FINSH_FUNCTION_EXPORT(uffs_format, format uffs partition.)
#endif
#endif