Merge pull request #237 from prife/dfs

dfs: support copy directory
This commit is contained in:
Bernard Xiong 2014-02-12 09:51:42 +08:00
commit 6c31900236
1 changed files with 166 additions and 2 deletions

View File

@ -593,7 +593,7 @@ void cat(const char* filename)
FINSH_FUNCTION_EXPORT(cat, print file)
#define BUF_SZ 4096
void copy(const char *src, const char *dst)
static void copyfile(const char *src, const char *dst)
{
struct dfs_fd src_fd;
rt_uint8_t *block_ptr;
@ -637,7 +637,171 @@ void copy(const char *src, const char *dst)
dfs_file_close(&fd);
rt_free(block_ptr);
}
FINSH_FUNCTION_EXPORT(copy, copy source file to destination file)
extern int mkdir(const char *path, mode_t mode);
static void copydir(const char * src, const char * dst)
{
struct dfs_fd fd;
struct dirent dirent;
struct stat stat;
int length;
if (dfs_file_open(&fd, src, DFS_O_DIRECTORY) < 0)
{
rt_kprintf("open %s failed\n", src);
return ;
}
do
{
rt_memset(&dirent, 0, sizeof(struct dirent));
length = dfs_file_getdents(&fd, &dirent, sizeof(struct dirent));
if (length > 0)
{
char * src_entry_full = RT_NULL;
char * dst_entry_full = RT_NULL;
if (strcmp(dirent.d_name, "..") == 0 || strcmp(dirent.d_name, ".") == 0)
continue;
/* build full path for each file */
if ((src_entry_full = dfs_normalize_path(src, dirent.d_name)) == RT_NULL)
{
rt_kprintf("out of memory!\n");
break;
}
if ((dst_entry_full = dfs_normalize_path(dst, dirent.d_name)) == RT_NULL)
{
rt_kprintf("out of memory!\n");
rt_free(src_entry_full);
break;
}
rt_memset(&stat, 0, sizeof(struct stat));
if (dfs_file_stat(src_entry_full, &stat) != 0)
{
rt_kprintf("open file: %s failed\n", dirent.d_name);
continue;
}
if (DFS_S_ISDIR(stat.st_mode))
{
mkdir(dst_entry_full, 0);
copydir(src_entry_full, dst_entry_full);
}
else
{
copyfile(src_entry_full, dst_entry_full);
}
rt_free(src_entry_full);
rt_free(dst_entry_full);
}
}while(length > 0);
dfs_file_close(&fd);
}
static const char *_get_path_lastname(const char *path)
{
char * ptr;
if ((ptr = strrchr(path, '/')) == RT_NULL)
return path;
/* skip the '/' then return */
return ++ptr;
}
void copy(const char *src, const char *dst)
{
#define FLAG_SRC_TYPE 0x03
#define FLAG_SRC_IS_DIR 0x01
#define FLAG_SRC_IS_FILE 0x02
#define FLAG_SRC_NON_EXSIT 0x00
#define FLAG_DST_TYPE 0x0C
#define FLAG_DST_IS_DIR 0x04
#define FLAG_DST_IS_FILE 0x08
#define FLAG_DST_NON_EXSIT 0x00
struct stat stat;
rt_uint32_t flag = 0;
/* check the staus of src and dst */
if (dfs_file_stat(src, &stat) < 0)
{
rt_kprintf("copy failed, bad %s\n", src);
return;
}
if (DFS_S_ISDIR(stat.st_mode))
flag |= FLAG_SRC_IS_DIR;
else
flag |= FLAG_SRC_IS_FILE;
if (dfs_file_stat(dst, &stat) < 0)
{
flag |= FLAG_DST_NON_EXSIT;
}
else
{
if (DFS_S_ISDIR(stat.st_mode))
flag |= FLAG_DST_IS_DIR;
else
flag |= FLAG_DST_IS_FILE;
}
//2. check status
if ((flag & FLAG_SRC_IS_DIR) && (flag & FLAG_DST_IS_FILE))
{
rt_kprintf("cp faild, cp dir to file is not permitted!\n");
return ;
}
//3. do copy
if (flag & FLAG_SRC_IS_FILE)
{
if (flag & FLAG_DST_IS_DIR)
{
char * fdst;
fdst = dfs_normalize_path(dst, _get_path_lastname(src));
if (fdst == NULL)
{
rt_kprintf("out of memory\n");
return;
}
copyfile(src, fdst);
rt_free(fdst);
}
else
{
copyfile(src, dst);
}
}
else //flag & FLAG_SRC_IS_DIR
{
if (flag & FLAG_DST_IS_DIR)
{
char * fdst;
fdst = dfs_normalize_path(dst, _get_path_lastname(src));
if (fdst == NULL)
{
rt_kprintf("out of memory\n");
return;
}
mkdir(fdst, 0);
copydir(src, fdst);
rt_free(fdst);
}
else if ((flag & FLAG_DST_TYPE) == FLAG_DST_NON_EXSIT)
{
mkdir(dst, 0);
copydir(src, dst);
}
else
{
copydir(src, dst);
}
}
}
FINSH_FUNCTION_EXPORT(copy, copy file or dir)
#endif
/* @} */