321 lines
5.9 KiB
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 <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
|