msh_file.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2015-09-25 Bernard the first verion for FinSH
  9. */
  10. #include <rtthread.h>
  11. #if defined(FINSH_USING_MSH) && defined(RT_USING_DFS)
  12. #include <finsh.h>
  13. #include "msh.h"
  14. #include <dfs_posix.h>
  15. static int msh_readline(int fd, char *line_buf, int size)
  16. {
  17. char ch;
  18. int index = 0;
  19. do
  20. {
  21. if (read(fd, &ch, 1) != 1)
  22. {
  23. /* nothing in this file */
  24. return 0;
  25. }
  26. }
  27. while (ch == '\n' || ch == '\r');
  28. /* set the first character */
  29. line_buf[index ++] = ch;
  30. while (index < size)
  31. {
  32. if (read(fd, &ch, 1) == 1)
  33. {
  34. if (ch == '\n' || ch == '\r')
  35. {
  36. line_buf[index] = '\0';
  37. break;
  38. }
  39. line_buf[index++] = ch;
  40. }
  41. else
  42. {
  43. line_buf[index] = '\0';
  44. break;
  45. }
  46. }
  47. return index;
  48. }
  49. int msh_exec_script(const char *cmd_line, int size)
  50. {
  51. int ret;
  52. int fd = -1;
  53. char *pg_name;
  54. int length, cmd_length = 0;
  55. if (size == 0) return -RT_ERROR;
  56. /* get the length of command0 */
  57. while ((cmd_line[cmd_length] != ' ' && cmd_line[cmd_length] != '\t') && cmd_length < size)
  58. cmd_length ++;
  59. /* get name length */
  60. length = cmd_length + 32;
  61. /* allocate program name memory */
  62. pg_name = (char *) rt_malloc(length);
  63. if (pg_name == RT_NULL) return -RT_ENOMEM;
  64. /* copy command0 */
  65. memcpy(pg_name, cmd_line, cmd_length);
  66. pg_name[cmd_length] = '\0';
  67. if (strstr(pg_name, ".sh") != RT_NULL || strstr(pg_name, ".SH") != RT_NULL)
  68. {
  69. /* try to open program */
  70. fd = open(pg_name, O_RDONLY, 0);
  71. /* search in /bin path */
  72. if (fd < 0)
  73. {
  74. rt_snprintf(pg_name, length - 1, "/bin/%.*s", cmd_length, cmd_line);
  75. fd = open(pg_name, O_RDONLY, 0);
  76. }
  77. }
  78. rt_free(pg_name);
  79. if (fd >= 0)
  80. {
  81. /* found script */
  82. char *line_buf;
  83. int length;
  84. line_buf = (char *) rt_malloc(RT_CONSOLEBUF_SIZE);
  85. /* read line by line and then exec it */
  86. do
  87. {
  88. length = msh_readline(fd, line_buf, RT_CONSOLEBUF_SIZE);
  89. if (length > 0)
  90. {
  91. char ch = '\0';
  92. int index;
  93. for (index = 0; index < length; index ++)
  94. {
  95. ch = line_buf[index];
  96. if (ch == ' ' || ch == '\t') continue;
  97. else break;
  98. }
  99. if (ch != '#') /* not a comment */
  100. msh_exec(line_buf, length);
  101. }
  102. }
  103. while (length > 0);
  104. close(fd);
  105. rt_free(line_buf);
  106. ret = 0;
  107. }
  108. else
  109. {
  110. ret = -1;
  111. }
  112. return ret;
  113. }
  114. #ifdef DFS_USING_WORKDIR
  115. extern char working_directory[];
  116. #endif
  117. int cmd_ls(int argc, char **argv)
  118. {
  119. extern void ls(const char *pathname);
  120. if (argc == 1)
  121. {
  122. #ifdef DFS_USING_WORKDIR
  123. ls(working_directory);
  124. #else
  125. ls("/");
  126. #endif
  127. }
  128. else
  129. {
  130. ls(argv[1]);
  131. }
  132. return 0;
  133. }
  134. FINSH_FUNCTION_EXPORT_ALIAS(cmd_ls, __cmd_ls, List information about the FILEs.);
  135. int cmd_cp(int argc, char **argv)
  136. {
  137. void copy(const char *src, const char *dst);
  138. if (argc != 3)
  139. {
  140. rt_kprintf("Usage: cp SOURCE DEST\n");
  141. rt_kprintf("Copy SOURCE to DEST.\n");
  142. }
  143. else
  144. {
  145. copy(argv[1], argv[2]);
  146. }
  147. return 0;
  148. }
  149. FINSH_FUNCTION_EXPORT_ALIAS(cmd_cp, __cmd_cp, Copy SOURCE to DEST.);
  150. int cmd_mv(int argc, char **argv)
  151. {
  152. if (argc != 3)
  153. {
  154. rt_kprintf("Usage: mv SOURCE DEST\n");
  155. rt_kprintf("Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n");
  156. }
  157. else
  158. {
  159. int fd;
  160. char *dest = RT_NULL;
  161. rt_kprintf("%s => %s\n", argv[1], argv[2]);
  162. fd = open(argv[2], O_DIRECTORY, 0);
  163. if (fd >= 0)
  164. {
  165. char *src;
  166. close(fd);
  167. /* it's a directory */
  168. dest = (char *)rt_malloc(DFS_PATH_MAX);
  169. if (dest == RT_NULL)
  170. {
  171. rt_kprintf("out of memory\n");
  172. return -RT_ENOMEM;
  173. }
  174. src = argv[1] + rt_strlen(argv[1]);
  175. while (src != argv[1])
  176. {
  177. if (*src == '/') break;
  178. src --;
  179. }
  180. rt_snprintf(dest, DFS_PATH_MAX - 1, "%s/%s", argv[2], src);
  181. }
  182. else
  183. {
  184. fd = open(argv[2], O_RDONLY, 0);
  185. if (fd >= 0)
  186. {
  187. close(fd);
  188. unlink(argv[2]);
  189. }
  190. dest = argv[2];
  191. }
  192. rename(argv[1], dest);
  193. if (dest != RT_NULL && dest != argv[2]) rt_free(dest);
  194. }
  195. return 0;
  196. }
  197. FINSH_FUNCTION_EXPORT_ALIAS(cmd_mv, __cmd_mv, Rename SOURCE to DEST.);
  198. int cmd_cat(int argc, char **argv)
  199. {
  200. int index;
  201. extern void cat(const char *filename);
  202. if (argc == 1)
  203. {
  204. rt_kprintf("Usage: cat [FILE]...\n");
  205. rt_kprintf("Concatenate FILE(s)\n");
  206. return 0;
  207. }
  208. for (index = 1; index < argc; index ++)
  209. {
  210. cat(argv[index]);
  211. }
  212. return 0;
  213. }
  214. FINSH_FUNCTION_EXPORT_ALIAS(cmd_cat, __cmd_cat, Concatenate FILE(s));
  215. int cmd_rm(int argc, char **argv)
  216. {
  217. int index;
  218. if (argc == 1)
  219. {
  220. rt_kprintf("Usage: rm FILE...\n");
  221. rt_kprintf("Remove (unlink) the FILE(s).\n");
  222. return 0;
  223. }
  224. for (index = 1; index < argc; index ++)
  225. {
  226. unlink(argv[index]);
  227. }
  228. return 0;
  229. }
  230. FINSH_FUNCTION_EXPORT_ALIAS(cmd_rm, __cmd_rm, Remove(unlink) the FILE(s).);
  231. #ifdef DFS_USING_WORKDIR
  232. int cmd_cd(int argc, char **argv)
  233. {
  234. if (argc == 1)
  235. {
  236. rt_kprintf("%s\n", working_directory);
  237. }
  238. else if (argc == 2)
  239. {
  240. if (chdir(argv[1]) != 0)
  241. {
  242. rt_kprintf("No such directory: %s\n", argv[1]);
  243. }
  244. }
  245. return 0;
  246. }
  247. FINSH_FUNCTION_EXPORT_ALIAS(cmd_cd, __cmd_cd, Change the shell working directory.);
  248. int cmd_pwd(int argc, char **argv)
  249. {
  250. rt_kprintf("%s\n", working_directory);
  251. return 0;
  252. }
  253. FINSH_FUNCTION_EXPORT_ALIAS(cmd_pwd, __cmd_pwd, Print the name of the current working directory.);
  254. #endif
  255. int cmd_mkdir(int argc, char **argv)
  256. {
  257. if (argc == 1)
  258. {
  259. rt_kprintf("Usage: mkdir [OPTION] DIRECTORY\n");
  260. rt_kprintf("Create the DIRECTORY, if they do not already exist.\n");
  261. }
  262. else
  263. {
  264. mkdir(argv[1], 0);
  265. }
  266. return 0;
  267. }
  268. FINSH_FUNCTION_EXPORT_ALIAS(cmd_mkdir, __cmd_mkdir, Create the DIRECTORY.);
  269. int cmd_mkfs(int argc, char **argv)
  270. {
  271. int result = 0;
  272. char *type = "elm"; /* use the default file system type as 'fatfs' */
  273. if (argc == 2)
  274. {
  275. result = dfs_mkfs(type, argv[1]);
  276. }
  277. else if (argc == 4)
  278. {
  279. if (strcmp(argv[1], "-t") == 0)
  280. {
  281. type = argv[2];
  282. result = dfs_mkfs(type, argv[3]);
  283. }
  284. }
  285. else
  286. {
  287. rt_kprintf("Usage: mkfs [-t type] device\n");
  288. return 0;
  289. }
  290. if (result != RT_EOK)
  291. {
  292. rt_kprintf("mkfs failed, result=%d\n", result);
  293. }
  294. return 0;
  295. }
  296. FINSH_FUNCTION_EXPORT_ALIAS(cmd_mkfs, __cmd_mkfs, format disk with file system);
  297. extern int df(const char *path);
  298. int cmd_df(int argc, char** argv)
  299. {
  300. if (argc != 2)
  301. {
  302. df("/");
  303. }
  304. else
  305. {
  306. if ((strcmp(argv[1], "--help") == 0) || (strcmp(argv[1], "-h") == 0))
  307. {
  308. rt_kprintf("df [path]\n");
  309. }
  310. else
  311. {
  312. df(argv[1]);
  313. }
  314. }
  315. return 0;
  316. }
  317. FINSH_FUNCTION_EXPORT_ALIAS(cmd_df, __cmd_df, disk free);
  318. int cmd_echo(int argc, char** argv)
  319. {
  320. if (argc == 2)
  321. {
  322. rt_kprintf("%s\n", argv[1]);
  323. }
  324. else if (argc == 3)
  325. {
  326. int fd;
  327. fd = open(argv[2], O_RDWR | O_APPEND | O_CREAT, 0);
  328. if (fd >= 0)
  329. {
  330. write (fd, argv[1], strlen(argv[1]));
  331. close(fd);
  332. }
  333. else
  334. {
  335. rt_kprintf("open file:%s failed!\n", argv[2]);
  336. }
  337. }
  338. else
  339. {
  340. rt_kprintf("Usage: echo \"string\" [filename]\n");
  341. }
  342. return 0;
  343. }
  344. FINSH_FUNCTION_EXPORT_ALIAS(cmd_echo, __cmd_echo, echo string to file);
  345. #endif /* defined(FINSH_USING_MSH) && defined(RT_USING_DFS) */