uffs_ext.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. /*
  2. This file is part of UFFS, the Ultra-low-cost Flash File System.
  3. uffs filesystem examples.
  4. */
  5. #include <rtthread.h>
  6. //#include <stdio.h>
  7. #include <string.h>
  8. #include <stdlib.h>
  9. #include "uffs/uffs_config.h"
  10. #include "uffs/uffs_public.h"
  11. #include "uffs/uffs_fs.h"
  12. #include "uffs/uffs_utils.h"
  13. #include "uffs/uffs_core.h"
  14. #include "uffs/uffs_mtb.h"
  15. #include "uffs/uffs_find.h"
  16. #include "uffs/uffs_fd.h"
  17. #include "emu/cmdline.h"
  18. #include "uffs_ext.h"
  19. #include <dfs_posix.h>
  20. #include <rtgui/filerw.h>
  21. #ifdef RT_USING_FINSH
  22. #include <finsh.h>
  23. #endif
  24. #define PFX "exp: "
  25. #define MAX_PATH_LENGTH 128
  26. #if (0)
  27. //uffs拷贝函数,参数之间加空格
  28. //需要从elm拷贝到uffs时(跨文件系统),参数名称前加::
  29. //例如uffs_copy("::/01.hdc /dir1/01.hdc")
  30. //上例从SD卡拷贝一个文件01.hdc到flash中,
  31. //也可用dfs的函数,那样就不用考虑是否跨文件系统了.
  32. int uffs_copy(const char *tail)
  33. {
  34. const char *src;
  35. const char *des;
  36. char buf[100];
  37. int fd1=-1, fd2=-1;
  38. int len;
  39. int src_local = FALSE, des_local = FALSE;
  40. int fd3=-1, fd4=-1;
  41. if(!tail)
  42. return FALSE;
  43. src = cli_getparam(tail, &des);
  44. if(!des)
  45. return FALSE;
  46. if(memcmp(src, "::", 2) == 0)
  47. {
  48. src += 2;
  49. src_local = TRUE;
  50. }
  51. if(memcmp(des, "::", 2) == 0)
  52. {
  53. des += 2;
  54. des_local = TRUE;
  55. }
  56. if(src_local)
  57. {
  58. //if((fp1 = fopen(src, "rb")) == NULL)
  59. if((fd3 = open(src,O_RDONLY,0)) < 0)
  60. {
  61. uffs_Perror(UFFS_ERR_NORMAL, "Can't open %s for copy.", src);
  62. goto fail_ext;
  63. }
  64. }
  65. else
  66. {
  67. if((fd1 = uffs_open(src, UO_RDONLY)) < 0)
  68. {
  69. uffs_Perror(UFFS_ERR_NORMAL, "Can't open %s for copy.", src);
  70. goto fail_ext;
  71. }
  72. }
  73. if(des_local)
  74. {
  75. if((fd4 = open(des,O_WRONLY | O_CREAT,0)) < 0)
  76. {
  77. uffs_Perror(UFFS_ERR_NORMAL, "Can't open %s for copy.", des);
  78. goto fail_ext;
  79. }
  80. }
  81. else
  82. {
  83. if((fd2 = uffs_open(des, UO_RDWR|UO_CREATE|UO_TRUNC)) < 0)
  84. {
  85. uffs_Perror(UFFS_ERR_NORMAL, "Can't open %s for copy.", des);
  86. goto fail_ext;
  87. }
  88. }
  89. uffs_Perror(UFFS_ERR_NORMAL, "copy %s to %s... ",src,des);
  90. while((src_local ? (1) : (uffs_eof(fd1) == 0)))
  91. {
  92. if(src_local)
  93. {
  94. len = read(fd3, buf, sizeof(buf));
  95. }
  96. else
  97. {
  98. len = uffs_read(fd1, buf, sizeof(buf));
  99. }
  100. if(len == 0)
  101. break;
  102. if(len < 0)
  103. {
  104. uffs_Perror(UFFS_ERR_NORMAL, "read file %s fail!", src);
  105. break;
  106. }
  107. if(des_local)
  108. {
  109. if(write(fd4, buf, len) != len)
  110. {
  111. uffs_Perror(UFFS_ERR_NORMAL, "write file %s fail!", des);
  112. break;
  113. }
  114. }
  115. else
  116. {
  117. if(uffs_write(fd2, buf, len) != len)
  118. {
  119. uffs_Perror(UFFS_ERR_NORMAL, "write file %s fail ?", des);
  120. break;
  121. }
  122. }
  123. }
  124. uffs_Perror(UFFS_ERR_NORMAL, "succ.");
  125. fail_ext:
  126. if(fd1 > 0)
  127. uffs_close(fd1);
  128. if(fd2 > 0)
  129. uffs_close(fd2);
  130. if(fd3 > 0)
  131. close(fd3);
  132. if(fd4 > 0)
  133. close(fd4);
  134. return TRUE;
  135. }
  136. FINSH_FUNCTION_EXPORT(uffs_copy, copy files. local file start with ::)
  137. #endif
  138. //计算路径下的文件(夹)个数
  139. int CountFileUnder(const char *dir)
  140. {
  141. int count = 0;
  142. uffs_DIR *dirp;
  143. dirp = uffs_opendir(dir);
  144. if(dirp)
  145. {
  146. while(uffs_readdir(dirp) != NULL)
  147. count++;
  148. if(dirp != NULL)
  149. uffs_closedir(dirp);
  150. }
  151. return count;
  152. }
  153. /*
  154. * 函数功能: 列出文件清单
  155. * 输入参数: name:分区名称
  156. * 返回参数: 成功:TRUE,失败:rt_false
  157. */
  158. int uffs_ls(const char *name)
  159. {
  160. uffs_DIR *dirp;
  161. struct uffs_dirent *ent;
  162. struct uffs_stat stat_buf;
  163. int count = 0;
  164. char buf[MAX_FILENAME_LENGTH+2];
  165. char *sub;
  166. if(name == NULL)
  167. {
  168. return FALSE;
  169. }
  170. dirp = uffs_opendir(name); //会获得一个uffs_DIR实例
  171. if(dirp == NULL)
  172. {
  173. rt_kprintf("Can't open '%s' for list\n", name);
  174. }
  175. else
  176. {
  177. rt_kprintf("%-16s%-8s%-8s%-8s\n","name","type","size","serial");
  178. rt_kprintf("-----------------------------------------\n");
  179. ent = uffs_readdir(dirp);
  180. while(ent)
  181. {
  182. rt_kprintf("%-16s", ent->d_name);
  183. strcpy(buf, name);
  184. sub = buf;
  185. if(name[strlen(name)-1] != '/')
  186. sub = strcat(buf, "/");
  187. sub = strcat(sub, ent->d_name);
  188. if(ent->d_type & FILE_ATTR_DIR)
  189. {
  190. sub = strcat(sub, "/");
  191. rt_kprintf("%-8s", "<DIR>");
  192. rt_kprintf("%-8d", CountFileUnder(sub));
  193. }
  194. else
  195. {
  196. uffs_stat(sub, &stat_buf);
  197. rt_kprintf("%-8s", "");
  198. rt_kprintf("%-8d", stat_buf.st_size);
  199. }
  200. rt_kprintf("%-8d\n", ent->d_ino);
  201. count++;
  202. ent = uffs_readdir(dirp);
  203. }
  204. if(dirp != NULL)
  205. uffs_closedir(dirp);
  206. rt_kprintf("Total: %d objects.\n", count);
  207. }
  208. return TRUE;
  209. }
  210. /*
  211. * 函数功能: 格式化分区
  212. * 输入参数: 分区名称
  213. * 返回参数:
  214. */
  215. int uffs_format(const char *name)
  216. {
  217. int ret;
  218. const char *mount = "/";
  219. uffs_Device *dev;
  220. if(name)
  221. {
  222. mount = name;
  223. }
  224. dev = uffs_GetDeviceFromMountPoint(mount);
  225. if(dev == NULL)
  226. {
  227. uffs_Perror(UFFS_ERR_NORMAL, "Can't get device from mount point.");
  228. }
  229. else
  230. {
  231. if(dev->ref_count == 1)
  232. {
  233. ret = uffs_FormatDevice(dev);
  234. uffs_Perror(UFFS_ERR_NORMAL, "Format %s.",ret==RT_EOK?"succ":"fail");
  235. }
  236. else
  237. {
  238. uffs_Perror(UFFS_ERR_NORMAL, "dev->ref_count: %d, can't format this device.", dev->ref_count);
  239. }
  240. uffs_PutDevice(dev);
  241. }
  242. return TRUE;
  243. }
  244. /*
  245. * 函数功能: 创建一个文件
  246. * 输入参数: 文件名称
  247. * 返回参数:
  248. */
  249. int uffs_mkfile(const char *name)
  250. {
  251. uffs_Object *fp;
  252. int ret = 0;
  253. int err = 0;
  254. fp = uffs_GetObject();
  255. if(fp != NULL)
  256. {
  257. if(uffs_CreateObject(fp, name, UO_CREATE) != U_SUCC)
  258. {
  259. err = fp->err;
  260. ret = -1;
  261. uffs_Perror(UFFS_ERR_NORMAL, "Create %s fail, err: %d", name, uffs_get_error());
  262. }
  263. else
  264. {
  265. uffs_Perror(UFFS_ERR_NORMAL, "Create %s succ.", name);
  266. uffs_CloseObject(fp);
  267. ret = 0;
  268. }
  269. uffs_PutObject(fp);
  270. }
  271. else
  272. {
  273. err = UEMFILE;
  274. ret = -1;
  275. }
  276. uffs_set_error(-err);
  277. return ret;
  278. }
  279. #if (0)
  280. #ifdef RT_USING_FINSH
  281. FINSH_FUNCTION_EXPORT(uffs_ls, list uffs system files.)
  282. FINSH_FUNCTION_EXPORT(uffs_mkfile, make uffs system file.)
  283. FINSH_FUNCTION_EXPORT(uffs_mkdir, make uffs system dir.)
  284. FINSH_FUNCTION_EXPORT(uffs_rmdir, remove uffs system dir.)
  285. FINSH_FUNCTION_EXPORT(uffs_format, format uffs partition.)
  286. #endif
  287. #endif