luat_lib_ftp.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. /*
  2. @module ftp
  3. @summary ftp 客户端
  4. @version 1.0
  5. @date 2022.09.05
  6. @demo ftp
  7. @tag LUAT_USE_FTP
  8. */
  9. #include "luat_base.h"
  10. #include "luat_network_adapter.h"
  11. #include "luat_msgbus.h"
  12. #include "luat_mem.h"
  13. #include "luat_ftp.h"
  14. #define LUAT_LOG_TAG "ftp"
  15. #include "luat_log.h"
  16. static uint64_t ftp_idp = 0;
  17. static int32_t l_ftp_callback(lua_State *L, void* ptr){
  18. rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
  19. luat_ftp_ctrl_t *luat_ftp_ctrl = (luat_ftp_ctrl_t *)msg->ptr;
  20. // LLOGD("l_ftp_callback arg1:%d arg2:%d idp:%lld",msg->arg1,msg->arg2,ftp_idp);
  21. if (ftp_idp){
  22. if (msg->arg1 == FTP_ERROR){
  23. lua_pushboolean(L, 0);
  24. }else if (msg->arg1 == FTP_SUCCESS_DATE){
  25. lua_pushlstring(L,(const char *)(luat_ftp_ctrl->result_buffer.Data),luat_ftp_ctrl->result_buffer.Pos);
  26. }else{
  27. lua_pushboolean(L, 1);
  28. }
  29. luat_cbcwait(L, ftp_idp, 1);
  30. ftp_idp = 0;
  31. }
  32. OS_DeInitBuffer(&luat_ftp_ctrl->result_buffer);
  33. return 0;
  34. }
  35. static void luat_ftp_cb(luat_ftp_ctrl_t *luat_ftp_ctrl, FTP_SUCCESS_STATE_e event){
  36. rtos_msg_t msg = {0};
  37. msg.handler = l_ftp_callback;
  38. msg.ptr = luat_ftp_ctrl;
  39. msg.arg1 = event;
  40. luat_msgbus_put(&msg, 0);
  41. }
  42. /*
  43. FTP客户端
  44. @api ftp.login(adapter,ip_addr,port,username,password)
  45. @int 适配器序号, 如果不填,会选择平台自带的方式,然后是最后一个注册的适配器,可选值请查阅socket库的常量表
  46. @string ip_addr 地址
  47. @string port 端口,默认21
  48. @string username 用户名
  49. @string password 密码
  50. @bool/table 是否为ssl加密连接,默认不加密,true为无证书最简单的加密,table为有证书的加密 <br>server_cert 服务器ca证书数据 <br>client_cert 客户端证书数据 <br>client_key 客户端私钥加密数据 <br>client_password 客户端私钥口令数据
  51. @return bool/string 成功返回true 失败返回string
  52. @usage
  53. ftp_login = ftp.login(nil,"xxx")
  54. */
  55. static int l_ftp_login(lua_State *L) {
  56. int result = 0;
  57. size_t len = 0;
  58. luat_ftp_tls_t* luat_ftp_tls = NULL;
  59. uint8_t adapter = luaL_optinteger(L, 1, network_register_get_default());
  60. const char *ip_addr = luaL_checklstring(L, 2, &len);
  61. uint16_t port = luaL_optinteger(L, 3, 21);
  62. const char *username = luaL_optlstring(L, 4, "",&len);
  63. const char *password = luaL_optlstring(L, 5, "",&len);
  64. // 加密相关
  65. if (lua_isboolean(L, 6)){
  66. if (lua_toboolean(L, 6)){
  67. luat_ftp_tls = (luat_ftp_tls_t *)luat_heap_malloc(sizeof(luat_ftp_tls_t));
  68. memset(luat_ftp_tls, 0, sizeof(luat_ftp_tls_t));
  69. }
  70. }else if (lua_istable(L, 6)){
  71. luat_ftp_tls = (luat_ftp_tls_t *)luat_heap_malloc(sizeof(luat_ftp_tls_t));
  72. memset(luat_ftp_tls, 0, sizeof(luat_ftp_tls_t));
  73. lua_pushstring(L, "server_cert");
  74. if (LUA_TSTRING == lua_gettable(L, 6)) {
  75. luat_ftp_tls->server_cert = luaL_checklstring(L, -1, &len);
  76. }
  77. lua_pop(L, 1);
  78. lua_pushstring(L, "client_cert");
  79. if (LUA_TSTRING == lua_gettable(L, 6)) {
  80. luat_ftp_tls->client_cert = luaL_checklstring(L, -1, &len);
  81. }
  82. lua_pop(L, 1);
  83. lua_pushstring(L, "client_key");
  84. if (LUA_TSTRING == lua_gettable(L, 6)) {
  85. luat_ftp_tls->client_key = luaL_checklstring(L, -1, &len);
  86. }
  87. lua_pop(L, 1);
  88. lua_pushstring(L, "client_password");
  89. if (LUA_TSTRING == lua_gettable(L, 6)) {
  90. luat_ftp_tls->client_password = luaL_checklstring(L, -1, &len);
  91. }
  92. lua_pop(L, 1);
  93. }
  94. if (luat_ftp_tls!=NULL){
  95. if (lua_isstring(L, 6)){
  96. luat_ftp_tls->server_cert = luaL_checklstring(L, 6, &len);
  97. }
  98. if (lua_isstring(L, 7)){
  99. luat_ftp_tls->client_cert = luaL_checklstring(L, 7, &len);
  100. }
  101. if (lua_isstring(L, 8)){
  102. luat_ftp_tls->client_key = luaL_checklstring(L, 8, &len);
  103. }
  104. if (lua_isstring(L, 9)){
  105. luat_ftp_tls->client_password = luaL_checklstring(L, 9, &len);
  106. }
  107. }
  108. if (0!=(result = luat_ftp_login(adapter,ip_addr,port,username,password,luat_ftp_tls,luat_ftp_cb))){
  109. LLOGE("ftp login fail");
  110. luat_ftp_release();
  111. lua_pushinteger(L,result);
  112. luat_pushcwait_error(L,1);
  113. }else{
  114. ftp_idp = luat_pushcwait(L);
  115. }
  116. if (luat_ftp_tls){
  117. luat_heap_free(luat_ftp_tls);
  118. }
  119. return 1;
  120. }
  121. /*
  122. FTP命令
  123. @api ftp.command(cmd)
  124. @string cmd 命令 目前支持:NOOP SYST TYPE PWD MKD CWD CDUP RMD DELE LIST
  125. @return string 成功返回true 失败返回string
  126. @usage
  127. // 空操作,防止连接断掉
  128. print(ftp.command("NOOP").wait())
  129. // 报告远程系统的操作系统类型
  130. print(ftp.command("SYST").wait())
  131. // 指定文件类型
  132. print(ftp.command("TYPE I").wait())
  133. // 显示当前工作目录名
  134. print(ftp.command("PWD").wait())
  135. // 创建目录
  136. print(ftp.command("MKD QWER").wait())
  137. // 改变当前工作目录
  138. print(ftp.command("CWD /QWER").wait())
  139. // 返回上一层目录
  140. print(ftp.command("CDUP").wait())
  141. // 删除目录
  142. print(ftp.command("RMD QWER").wait())
  143. // 获取当前工作目录下的文件名列表
  144. print(ftp.command("LIST").wait())
  145. // 删除文件
  146. print(ftp.command("DELE /1/12222.txt").wait())
  147. */
  148. static int l_ftp_command(lua_State *L) {
  149. size_t len;
  150. const char * command = luaL_optlstring(L, 1, "",&len);
  151. if (luat_ftp_command(command)){
  152. LLOGE("ftp command fail");
  153. lua_pushinteger(L,FTP_ERROR_FILE);
  154. luat_pushcwait_error(L,1);
  155. }else{
  156. ftp_idp = luat_pushcwait(L);
  157. }
  158. return 1;
  159. }
  160. /*
  161. FTP文件下载
  162. @api ftp.pull(local_name,remote_name)
  163. @string local_name 本地文件
  164. @string remote_name 服务器文件
  165. @return bool/string 成功返回true 失败返回string
  166. @usage
  167. ftp.pull("/1222.txt","/1222.txt").wait()
  168. */
  169. static int l_ftp_pull(lua_State *L) {
  170. size_t len;
  171. const char * local_name = luaL_optlstring(L, 1, "",&len);
  172. const char * remote_name = luaL_optlstring(L, 2, "",&len);
  173. if (luat_ftp_pull(local_name,remote_name)){
  174. LLOGE("ftp pull fail");
  175. lua_pushinteger(L,FTP_ERROR_FILE);
  176. luat_pushcwait_error(L,1);
  177. }else{
  178. ftp_idp = luat_pushcwait(L);
  179. }
  180. return 1;
  181. }
  182. /*
  183. FTP文件上传
  184. @api ftp.push(local_name,remote_name)
  185. @string local_name 本地文件
  186. @string remote_name 服务器文件
  187. @return bool/string 成功返回true 失败返回string
  188. @usage
  189. ftp.push("/1222.txt","/1222.txt").wait()
  190. */
  191. static int l_ftp_push(lua_State *L) {
  192. size_t len;
  193. const char * local_name = luaL_optlstring(L, 1, "",&len);
  194. const char * remote_name = luaL_optlstring(L, 2, "",&len);
  195. if (luat_ftp_push(local_name,remote_name)){
  196. LLOGE("ftp push fail");
  197. lua_pushinteger(L,FTP_ERROR_CONNECT);
  198. luat_pushcwait_error(L,1);
  199. }else{
  200. ftp_idp = luat_pushcwait(L);
  201. }
  202. return 1;
  203. }
  204. /*
  205. FTP客户端关闭
  206. @api ftp.close()
  207. @return bool/string 成功返回true 失败返回string
  208. @usage
  209. ftp.close().wait()
  210. */
  211. static int l_ftp_close(lua_State *L) {
  212. if (luat_ftp_close()){
  213. lua_pushinteger(L,FTP_ERROR_CONNECT);
  214. luat_pushcwait_error(L,1);
  215. }else{
  216. ftp_idp = luat_pushcwait(L);
  217. }
  218. return 1;
  219. }
  220. /*
  221. 配置是否打开debug信息
  222. @api ftp.debug(onoff)
  223. @boolean 是否打开debug开关
  224. @return nil 无返回值
  225. @usage ftp.debug(true)
  226. */
  227. static int l_ftp_set_debug(lua_State *L){
  228. if (lua_isboolean(L, 1)){
  229. luat_ftp_debug(lua_toboolean(L, 1));
  230. }
  231. return 0;
  232. }
  233. #include "rotable2.h"
  234. #ifdef LUAT_USE_NETWORK
  235. static const rotable_Reg_t reg_ftp[] =
  236. {
  237. {"login", ROREG_FUNC(l_ftp_login)},
  238. {"command", ROREG_FUNC(l_ftp_command)},
  239. {"pull", ROREG_FUNC(l_ftp_pull)},
  240. {"push", ROREG_FUNC(l_ftp_push)},
  241. {"close", ROREG_FUNC(l_ftp_close)},
  242. {"debug", ROREG_FUNC(l_ftp_set_debug)},
  243. { NULL, ROREG_INT(0)}
  244. };
  245. #else
  246. static const rotable_Reg_t reg_ftp_emtry[] =
  247. {
  248. { NULL, ROREG_INT(0)}
  249. };
  250. #endif
  251. LUAMOD_API int luaopen_ftp( lua_State *L ) {
  252. #ifdef LUAT_USE_NETWORK
  253. luat_newlib2(L, reg_ftp);
  254. #else
  255. luat_newlib2(L, reg_ftp_emtry);
  256. LLOGE("ftp require network enable!!");
  257. #endif
  258. return 1;
  259. }