tftp_port.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2019-02-26 tyx first implementation
  9. */
  10. #include <rtthread.h>
  11. #if RT_VER_NUM >= 0x40100
  12. #include <unistd.h>
  13. #include <fcntl.h>
  14. #else
  15. #include <dfs_posix.h>
  16. #endif /* RT_VER_NUM >= 0x40100 */
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include "tftp.h"
  21. RT_WEAK void *tftp_file_open(const char *fname, const char *mode, int is_write)
  22. {
  23. int fd = 0;
  24. if (!rt_strcmp(mode, "octet"))
  25. {
  26. if (is_write)
  27. {
  28. fd = open(fname, O_WRONLY | O_CREAT, 0);
  29. }
  30. else
  31. {
  32. fd = open(fname, O_RDONLY, 0);
  33. }
  34. }
  35. else
  36. {
  37. rt_kprintf("tftp: No support this mode(%s).", mode);
  38. }
  39. return (void *)fd;
  40. }
  41. RT_WEAK int tftp_file_write(void *handle, int pos, void *buff, int len)
  42. {
  43. int fd = (int)handle;
  44. return write(fd, buff, len);
  45. }
  46. RT_WEAK int tftp_file_read(void *handle, int pos, void *buff, int len)
  47. {
  48. int fd = (int)handle;
  49. return read(fd, buff, len);
  50. }
  51. RT_WEAK void tftp_file_close(void *handle)
  52. {
  53. close((int)handle);
  54. }
  55. static struct tftp_server *server;
  56. static void tftp_server_thread(void *param)
  57. {
  58. tftp_server_run((struct tftp_server *)param);
  59. server = RT_NULL;
  60. }
  61. #define _S_MODE_CMD (100)
  62. #define _CW_MODE_CMD (101)
  63. #define _CR_MODE_CMD (102)
  64. #define _IP_MODE_CMD (103)
  65. #define _P_MODE_CMD (104)
  66. #define _STOP_MODE_CMD (107)
  67. #define _UNKNOWN_MODE_CMD (0)
  68. struct _tftp_cmd
  69. {
  70. const char *cmd_str;
  71. const char *help_info;
  72. int cmd;
  73. };
  74. static const struct _tftp_cmd _cmd_tab[] =
  75. {
  76. {"-s", "begin tftp server", _S_MODE_CMD},
  77. {"-w", "client write file to server", _CW_MODE_CMD},
  78. {"-r", "client read file from server", _CR_MODE_CMD},
  79. {"-p", "server port to listen on/connect to", _P_MODE_CMD},
  80. {"--stop", "stop tftp server", _STOP_MODE_CMD},
  81. };
  82. static void _tftp_help(void)
  83. {
  84. int i;
  85. printf("Usage: tftp [-s|-w|-r host] [path]\n");
  86. printf(" tftp [-h|--stop]\n\n");
  87. for (i = 0; i < sizeof(_cmd_tab) / sizeof(_cmd_tab[0]); i++)
  88. {
  89. printf(" %-6.6s: %s\n", _cmd_tab[i].cmd_str, _cmd_tab[i].help_info);
  90. }
  91. printf("\neg: \n");
  92. printf(" open server: tftp -s /\n");
  93. printf(" read file : tftp -r 192.168.1.1 test.data\n");
  94. printf(" wriet file : tftp -w 192.168.1.1 test.data\n");
  95. }
  96. static int _tftp_msh(int argc, char *argv[])
  97. {
  98. int i, j, cmd;
  99. int tftp_mode = 0;
  100. char *ip = RT_NULL;
  101. char *path[2] = {0};
  102. int port = 0, stop = 0;
  103. if (argc == 1)
  104. {
  105. goto _help;
  106. }
  107. for (i = 1; i < argc; i++)
  108. {
  109. cmd = _UNKNOWN_MODE_CMD;
  110. for (j = 0; j < sizeof(_cmd_tab) / sizeof(_cmd_tab[0]); j++)
  111. {
  112. if (strcmp(_cmd_tab[j].cmd_str, argv[i]) == 0)
  113. {
  114. cmd = _cmd_tab[j].cmd;
  115. break;
  116. }
  117. }
  118. switch (cmd)
  119. {
  120. case _S_MODE_CMD:
  121. if (tftp_mode != 0)
  122. {
  123. goto _help;
  124. }
  125. tftp_mode = _S_MODE_CMD;
  126. break;
  127. case _CW_MODE_CMD:
  128. case _CR_MODE_CMD:
  129. if (tftp_mode != 0)
  130. {
  131. goto _help;
  132. }
  133. tftp_mode = cmd;
  134. if ((i + 1) < argc)
  135. {
  136. ip = argv[i + 1];
  137. i ++;
  138. }
  139. break;
  140. case _P_MODE_CMD:
  141. if (port != 0)
  142. {
  143. goto _help;
  144. }
  145. if ((i + 1) < argc)
  146. {
  147. port = atoi(argv[i + 1]);
  148. i ++;
  149. }
  150. break;
  151. case _STOP_MODE_CMD:
  152. if (argc != 2)
  153. {
  154. goto _help;
  155. }
  156. stop = 1;
  157. break;
  158. default:
  159. {
  160. if (path[0] == RT_NULL)
  161. {
  162. path[0] = argv[i];
  163. }
  164. else if (path[1] == RT_NULL)
  165. {
  166. path[1] = argv[i];
  167. }
  168. else
  169. {
  170. goto _help;
  171. }
  172. }
  173. }
  174. }
  175. if (stop && server)
  176. {
  177. tftp_server_destroy(server);
  178. return 0;
  179. }
  180. if (port == 0)
  181. {
  182. port = 69;
  183. }
  184. if (tftp_mode == _S_MODE_CMD)
  185. {
  186. rt_thread_t tid;
  187. if (server != RT_NULL)
  188. {
  189. printf("tftp server is run");
  190. return 0;
  191. }
  192. if (path[0] == RT_NULL)
  193. {
  194. path[0] = "/";
  195. }
  196. server = tftp_server_create(path[0], port);
  197. tftp_server_write_set(server, 1);
  198. tid = rt_thread_create("tftps", tftp_server_thread, server, 2048, 18, 20);
  199. if (tid == NULL)
  200. {
  201. return -1;
  202. }
  203. rt_thread_startup(tid);
  204. return 0;
  205. }
  206. else if ((tftp_mode == _CW_MODE_CMD) || (tftp_mode == _CR_MODE_CMD))
  207. {
  208. struct tftp_client *client;
  209. if (ip == RT_NULL || path[0] == RT_NULL)
  210. {
  211. goto _help;
  212. }
  213. if (path[1] == RT_NULL)
  214. {
  215. path[1] = path[0];
  216. }
  217. client = tftp_client_create(ip, port);
  218. if (tftp_mode == _CR_MODE_CMD)
  219. {
  220. printf("file size:%d\n", tftp_client_pull(client, path[0], path[1]));
  221. }
  222. else
  223. {
  224. printf("file size:%d\n", tftp_client_push(client, path[0], path[1]));
  225. }
  226. tftp_client_destroy(client);
  227. return 0;
  228. }
  229. else
  230. {
  231. goto _help;
  232. }
  233. _help:
  234. _tftp_help();
  235. return -1;
  236. }
  237. MSH_CMD_EXPORT_ALIAS(_tftp_msh, tftp, tftp);