mirror of
				https://github.com/lxsang/antd-lua-plugin
				synced 2025-10-30 18:05:34 +01:00 
			
		
		
		
	improvement and add more lua C wrappers
This commit is contained in:
		
							
								
								
									
										153
									
								
								lib/asl/antd.c
									
									
									
									
									
								
							
							
						
						
									
										153
									
								
								lib/asl/antd.c
									
									
									
									
									
								
							| @@ -1,5 +1,15 @@ | |||||||
| #include <antd/ws.h> | #include <antd/ws.h> | ||||||
| #include <antd/base64.h> | #include <antd/base64.h> | ||||||
|  | #include <poll.h> | ||||||
|  | #include <errno.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <sys/socket.h> | ||||||
|  | #include <netinet/in.h> | ||||||
|  | #include <sys/wait.h> | ||||||
|  | #include <sys/un.h> | ||||||
|  | #include <sys/ioctl.h> | ||||||
|  | #include <time.h> | ||||||
|  | #include <fcntl.h> | ||||||
| #include "../lualib.h" | #include "../lualib.h" | ||||||
| // add a length field, and | // add a length field, and | ||||||
| void lua_new_byte_array(lua_State *L, int n) | void lua_new_byte_array(lua_State *L, int n) | ||||||
| @@ -724,6 +734,148 @@ static int l_is_dir(lua_State *L) | |||||||
|     return 1; |     return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int l_pfork(lua_State* L) | ||||||
|  | { | ||||||
|  |     antd_client_t* client = (antd_client_t*)lua_touserdata(L,1); | ||||||
|  |     int sock = client->sock; | ||||||
|  |     // create domain socket | ||||||
|  |     struct sockaddr_un address; | ||||||
|  |     address.sun_family = AF_UNIX; | ||||||
|  |     (void)snprintf(address.sun_path, sizeof(address.sun_path), "/tmp/antd_pfork_%d.sock",sock); | ||||||
|  |     unlink(address.sun_path); | ||||||
|  |     int pfd = socket(AF_UNIX, SOCK_STREAM, 0); | ||||||
|  |     if(pfd == -1) | ||||||
|  |     { | ||||||
|  |         ERROR( "Unable to create Unix domain socket: %s", strerror(errno)); | ||||||
|  |         lua_pushnumber(L, -1); | ||||||
|  |         return 1; | ||||||
|  |     } | ||||||
|  |     if (bind(pfd, (struct sockaddr *)(&address), sizeof(address)) == -1) | ||||||
|  |     { | ||||||
|  |         ERROR("Unable to bind name: %s to a socket: %s", address.sun_path, strerror(errno)); | ||||||
|  |         lua_pushnumber(L, -1); | ||||||
|  |         return 1; | ||||||
|  |     } | ||||||
|  |     // mark the socket as passive mode | ||||||
|  |     if (listen(pfd, 10) == -1) | ||||||
|  |     { | ||||||
|  |         ERROR("Unable to listen to socket: %d (%s): %s", pfd, address.sun_path, strerror(errno)); | ||||||
|  |         lua_pushnumber(L, -1); | ||||||
|  |         close(pfd); | ||||||
|  |         return 1; | ||||||
|  |     } | ||||||
|  |     LOG( "Socket %s is created successfully", address.sun_path); | ||||||
|  |     set_nonblock(pfd); | ||||||
|  |  | ||||||
|  |     int pid = fork(); | ||||||
|  |     if(pid == 0) | ||||||
|  |     { | ||||||
|  |         int child = socket(AF_UNIX, SOCK_STREAM, 0); | ||||||
|  |         if(child == -1) | ||||||
|  |         { | ||||||
|  |             ERROR( "Unable to create Unix domain socket: %s", strerror(errno)); | ||||||
|  |             lua_pushnumber(L, -1); | ||||||
|  |             return -1; | ||||||
|  |         } | ||||||
|  |         if(connect(child, (struct sockaddr*)(&address), sizeof(address)) == -1) | ||||||
|  |         { | ||||||
|  |             ERROR( "Unable to connect to socket '%s': %s", address.sun_path, strerror(errno)); | ||||||
|  |             lua_pushnumber(L, -1); | ||||||
|  |             close(child); | ||||||
|  |             return -1; | ||||||
|  |         } | ||||||
|  |         client->sock = child; | ||||||
|  |         client->z_level = ANTD_CNONE; | ||||||
|  |         lua_pushnumber(L, 0); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         int ret, status; | ||||||
|  |         struct pollfd pfds[2]; | ||||||
|  |         pfds[0].fd = pfd; | ||||||
|  |         pfds[0].events = POLLIN; | ||||||
|  |         ret = poll(pfds, 1, -1); | ||||||
|  |         if(ret < 0 || (pfds[0].revents & (POLLERR | POLLHUP))) | ||||||
|  |         { | ||||||
|  |             ERROR("Unable to wait for child process"); | ||||||
|  |             lua_pushnumber(L, -1); | ||||||
|  |             close(pfd); | ||||||
|  |             return 1; | ||||||
|  |         } | ||||||
|  |         // now wait for child process | ||||||
|  |         int cfd = accept(pfd, NULL, NULL); | ||||||
|  |         if(cfd == -1) | ||||||
|  |         { | ||||||
|  |             ERROR("Unable to connect to child process"); | ||||||
|  |             lua_pushnumber(L, -1); | ||||||
|  |             close(pfd); | ||||||
|  |             return 1; | ||||||
|  |         } | ||||||
|  |         LOG("Child process %d is accessible from %d", pid, cfd); | ||||||
|  |         set_nonblock(cfd); | ||||||
|  |         uint8_t buff[BUFFLEN]; | ||||||
|  |         pfds[0].fd = sock; | ||||||
|  |         pfds[0].events = POLLIN; | ||||||
|  |         pfds[1].fd = cfd; | ||||||
|  |         pfds[1].events = POLLIN; | ||||||
|  |         memset(buff, 0, sizeof(buff)); | ||||||
|  |         while((ret = poll(pfds, 2, 200)) !=  -1) | ||||||
|  |         { | ||||||
|  |             if(waitpid(pid, &status, WNOHANG) != 0) | ||||||
|  |             { | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |             if(ret == 0) | ||||||
|  |             { | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |             if(pfds[0].revents & POLLIN) | ||||||
|  |             { | ||||||
|  |                 ret = read(client->sock,buff, BUFFLEN); | ||||||
|  |                 if(ret <= 0) | ||||||
|  |                 { | ||||||
|  |                     LOG("antd_recv_upto() on %d: %s",sock,  strerror(errno)); | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |                 // write data to the other side | ||||||
|  |                 if(write(cfd,buff, ret) != ret) | ||||||
|  |                 { | ||||||
|  |                     ERROR("Error on send(): %s", strerror(errno)); | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             else if (pfds[0].revents &(POLLERR | POLLHUP)) | ||||||
|  |             { | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if(pfds[1].revents & POLLIN) | ||||||
|  |             { | ||||||
|  |                 ret = read(cfd, buff, sizeof(buff)); | ||||||
|  |                 if(ret <= 0) | ||||||
|  |                 { | ||||||
|  |                     ERROR("error read() on %d: %s",cfd,  strerror(errno)); | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |                 if(antd_send(client,buff, ret) != ret) | ||||||
|  |                 { | ||||||
|  |                     ERROR("Error atnd_send(): %s", strerror(errno)); | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             else if (pfds[1].revents &(POLLERR | POLLHUP)) | ||||||
|  |             { | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         close(cfd); | ||||||
|  |     } | ||||||
|  |     close(pfd); | ||||||
|  |     unlink(address.sun_path); | ||||||
|  |     lua_pushnumber(L, pid); | ||||||
|  |     return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
| static int l_std_error(lua_State *L) | static int l_std_error(lua_State *L) | ||||||
| { | { | ||||||
|     void *client = lua_touserdata(L, 1); |     void *client = lua_touserdata(L, 1); | ||||||
| @@ -804,6 +956,7 @@ static const struct luaL_Reg standard[] = { | |||||||
|     {"ws_b", l_ws_bin}, |     {"ws_b", l_ws_bin}, | ||||||
|     {"ws_close", l_ws_close}, |     {"ws_close", l_ws_close}, | ||||||
|     {"is_dir", l_is_dir}, |     {"is_dir", l_is_dir}, | ||||||
|  |     {"pfork", l_pfork}, | ||||||
|     {NULL, NULL}}; |     {NULL, NULL}}; | ||||||
|  |  | ||||||
| int luaopen_std(lua_State *L) | int luaopen_std(lua_State *L) | ||||||
|   | |||||||
| @@ -37,7 +37,7 @@ static int l_check_login (lua_State *L) { | |||||||
|     if (pwd == NULL) |     if (pwd == NULL) | ||||||
|     { |     { | ||||||
|     	lua_pushboolean(L,0); |     	lua_pushboolean(L,0); | ||||||
| 		printf("Cannot find pwd record of %s\n", username ); | 		ERROR("Cannot find pwd record of %s", username ); | ||||||
| 		return 1; | 		return 1; | ||||||
|     } |     } | ||||||
|     spwd = getspnam(username); |     spwd = getspnam(username); | ||||||
| @@ -63,25 +63,23 @@ static int l_check_login (lua_State *L) { | |||||||
|     if (encrypted == NULL) |     if (encrypted == NULL) | ||||||
| 	{ | 	{ | ||||||
|     	lua_pushboolean(L,0); |     	lua_pushboolean(L,0); | ||||||
| 		printf("Cant crypt \n" ); | 		ERROR("Cant crypt %s", strerror(errno) ); | ||||||
| 		return 1; | 		return 1; | ||||||
| 	} | 	} | ||||||
|     if(strcmp(encrypted, pwd->pw_passwd) == 0) |     if(strcmp(encrypted, pwd->pw_passwd) == 0) | ||||||
| 	{ | 	{ | ||||||
|     	lua_pushboolean(L,1); |     	lua_pushboolean(L,1); | ||||||
| 		printf("%s\n","Successful login" ); |  | ||||||
| 		return 1; | 		return 1; | ||||||
| 	} else | 	} else | ||||||
| 	{ | 	{ | ||||||
|     	lua_pushboolean(L,0); |     	lua_pushboolean(L,0); | ||||||
| 		printf("Password incorrect \n" ); |  | ||||||
| 		return 1; | 		return 1; | ||||||
|     } |     } | ||||||
| #else | #else | ||||||
| 	// macos | 	// macos | ||||||
| 	// just pass the check, for test only | 	// just pass the check, for test only | ||||||
| 	lua_pushboolean(L,1); | 	lua_pushboolean(L,0); | ||||||
| 	printf("%s\n","Successful login" ); | 	ERROR("Login by shadow passd is not supported on this system"); | ||||||
| 	return 1; | 	return 1; | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| @@ -117,6 +115,7 @@ static int l_fork(lua_State* L) | |||||||
| 	lua_pushnumber(L, pid); | 	lua_pushnumber(L, pid); | ||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int l_waitpid(lua_State* L) | static int l_waitpid(lua_State* L) | ||||||
| { | { | ||||||
| 	int pid = luaL_checknumber(L,1); | 	int pid = luaL_checknumber(L,1); | ||||||
| @@ -138,7 +137,7 @@ static int l_kill(lua_State* L) | |||||||
| { | { | ||||||
| 	int pid = luaL_checknumber(L,1); | 	int pid = luaL_checknumber(L,1); | ||||||
| 	if(pid == -1) pid = getpid(); | 	if(pid == -1) pid = getpid(); | ||||||
| 	int status = kill(pid, SIGKILL); | 	int status = kill(pid, SIGHUP); | ||||||
| 	lua_pushnumber(L, status); | 	lua_pushnumber(L, status); | ||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
| @@ -149,7 +148,7 @@ static int l_setuid(lua_State* L) | |||||||
| 	{ | 	{ | ||||||
| 		if(setuid(uid) < 0) | 		if(setuid(uid) < 0) | ||||||
| 		{ | 		{ | ||||||
| 			printf("UID set problem: %s\n", strerror(errno)); | 			ERROR("UID set problem: %s", strerror(errno)); | ||||||
| 			lua_pushboolean(L,0); | 			lua_pushboolean(L,0); | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| @@ -169,7 +168,7 @@ static int l_setgid(lua_State* L) | |||||||
| 	{ | 	{ | ||||||
| 		if(setgid(gid) < 0) | 		if(setgid(gid) < 0) | ||||||
| 		{ | 		{ | ||||||
| 			printf("GID set problem: %s\n", strerror(errno)); | 			ERROR("GID set problem: %s", strerror(errno)); | ||||||
| 			lua_pushboolean(L,0); | 			lua_pushboolean(L,0); | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| @@ -214,12 +213,12 @@ static int l_getuid(lua_State* L) | |||||||
| 		 /* Retrieve group list */ | 		 /* Retrieve group list */ | ||||||
| 		groups = malloc(ngroups * sizeof (gid_t)); | 		groups = malloc(ngroups * sizeof (gid_t)); | ||||||
|            if (groups == NULL) { |            if (groups == NULL) { | ||||||
|                LOG("malloc eror \n"); |                LOG("malloc eror"); | ||||||
|                return 1; |                return 1; | ||||||
|            } |            } | ||||||
| 		if (getgrouplist(name, gid, groups, &ngroups) == -1) { | 		if (getgrouplist(name, gid, groups, &ngroups) == -1) { | ||||||
| 			free(groups); | 			free(groups); | ||||||
| 			LOG("getgrouplist() returned -1; ngroups = %d\n", ngroups); | 			LOG("getgrouplist() returned -1; ngroups = %d", ngroups); | ||||||
| 			return 1; | 			return 1; | ||||||
| 		} | 		} | ||||||
| 		/* retrieved groups, along with group names */ | 		/* retrieved groups, along with group names */ | ||||||
|   | |||||||
							
								
								
									
										43
									
								
								lua-api.c
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								lua-api.c
									
									
									
									
									
								
							| @@ -12,8 +12,8 @@ | |||||||
| #include <sys/socket.h> | #include <sys/socket.h> | ||||||
| #include <sys/un.h> | #include <sys/un.h> | ||||||
| #include <sys/ioctl.h> | #include <sys/ioctl.h> | ||||||
| #include <sys/select.h> |  | ||||||
| #include <time.h> | #include <time.h> | ||||||
|  | #include <poll.h> | ||||||
| #include <fcntl.h> | #include <fcntl.h> | ||||||
| #include <signal.h> | #include <signal.h> | ||||||
| #include <sys/time.h> | #include <sys/time.h> | ||||||
| @@ -25,7 +25,6 @@ | |||||||
| #define MAX_SOCK_NAME 64 | #define MAX_SOCK_NAME 64 | ||||||
| #define SOCKET_NAME "lua.sock" | #define SOCKET_NAME "lua.sock" | ||||||
|  |  | ||||||
| #define MAX_SESSION_TIMEOUT (15u * 60u) //15 min |  | ||||||
| #define PING_INTERVAL 10u               // 10s | #define PING_INTERVAL 10u               // 10s | ||||||
| #define PROCESS_TIMEOUT 200u          //100ms | #define PROCESS_TIMEOUT 200u          //100ms | ||||||
|  |  | ||||||
| @@ -72,12 +71,14 @@ static int mk_socket() | |||||||
|     if (bind(fd, (struct sockaddr *)(&address), sizeof(address)) == -1) |     if (bind(fd, (struct sockaddr *)(&address), sizeof(address)) == -1) | ||||||
|     { |     { | ||||||
|         ERROR("Unable to bind name: %s to a socket: %s", address.sun_path, strerror(errno)); |         ERROR("Unable to bind name: %s to a socket: %s", address.sun_path, strerror(errno)); | ||||||
|  |         close(fd); | ||||||
|         return -1; |         return -1; | ||||||
|     } |     } | ||||||
|     // mark the socket as passive mode |     // mark the socket as passive mode | ||||||
|     if (listen(fd, 500) == -1) |     if (listen(fd, 500) == -1) | ||||||
|     { |     { | ||||||
|         ERROR("Unable to listen to socket: %d (%s): %s", fd, sock_path, strerror(errno)); |         ERROR("Unable to listen to socket: %d (%s): %s", fd, sock_path, strerror(errno)); | ||||||
|  |         close(fd); | ||||||
|         return -1; |         return -1; | ||||||
|     } |     } | ||||||
|     LOG("Socket %s is created successfully: %d", sock_path, fd); |     LOG("Socket %s is created successfully: %d", sock_path, fd); | ||||||
| @@ -141,7 +142,7 @@ static void lua_serve() | |||||||
|             lua_thread_data_t* data = (lua_thread_data_t*)malloc(sizeof(lua_thread_data_t)); |             lua_thread_data_t* data = (lua_thread_data_t*)malloc(sizeof(lua_thread_data_t)); | ||||||
|             data->__plugin__ = &__plugin__; |             data->__plugin__ = &__plugin__; | ||||||
|             data->fd = fd; |             data->fd = fd; | ||||||
|             set_nonblock(fd); |             //set_nonblock(fd); | ||||||
|             if (pthread_create(&thread, NULL, (void *(*)(void*))handle_fn, (void *)data) != 0) |             if (pthread_create(&thread, NULL, (void *(*)(void*))handle_fn, (void *)data) != 0) | ||||||
|             { |             { | ||||||
|                 ERROR("pthread_create: cannot create lua thread: %s", strerror(errno)); |                 ERROR("pthread_create: cannot create lua thread: %s", strerror(errno)); | ||||||
| @@ -203,24 +204,22 @@ static void push_dict_to_socket(antd_client_t* cl, char* name, char* parent_name | |||||||
|  |  | ||||||
| static void *process(void *data) | static void *process(void *data) | ||||||
| { | { | ||||||
|     fd_set fd_in; |  | ||||||
|     antd_request_t *rq = (antd_request_t *)data; |     antd_request_t *rq = (antd_request_t *)data; | ||||||
|     antd_client_t* cl = (antd_client_t* ) dvalue(rq->request, "LUA_CL_DATA"); |     antd_client_t* cl = (antd_client_t* ) dvalue(rq->request, "LUA_CL_DATA"); | ||||||
|     struct timeval timeout; |     struct pollfd pfds[2]; | ||||||
|     timeout.tv_sec = 0; |     pfds[0].fd = rq->client->sock; | ||||||
|     timeout.tv_usec = PROCESS_TIMEOUT; |     pfds[0].events = POLLIN; | ||||||
|     FD_ZERO(&fd_in); |     pfds[1].fd = cl->sock; | ||||||
|     FD_SET(rq->client->sock, &fd_in); |     pfds[1].events = POLLIN; | ||||||
|     FD_SET(cl->sock, &fd_in); |  | ||||||
|     int max_fdm = rq->client->sock > cl->sock ? rq->client->sock : cl->sock; |     int rc = poll(pfds, 2, PROCESS_TIMEOUT); | ||||||
|     int rc = select(max_fdm + 1, &fd_in, NULL, NULL, &timeout); |  | ||||||
|     antd_task_t* task; |     antd_task_t* task; | ||||||
|     uint8_t buff[BUFFLEN]; |     uint8_t buff[BUFFLEN]; | ||||||
|     int ret; |     int ret; | ||||||
|     switch (rc) |     switch (rc) | ||||||
|     { |     { | ||||||
|         case -1: |         case -1: | ||||||
|             ERROR("Error on select(): %s", strerror(errno)); |             ERROR("Error on poll(): %s", strerror(errno)); | ||||||
|             antd_close(cl); |             antd_close(cl); | ||||||
|             dput(rq->request, "LUA_CL_DATA", NULL); |             dput(rq->request, "LUA_CL_DATA", NULL); | ||||||
|             return antd_create_task(NULL, data, NULL, rq->client->last_io); |             return antd_create_task(NULL, data, NULL, rq->client->last_io); | ||||||
| @@ -233,7 +232,7 @@ static void *process(void *data) | |||||||
|         // we have data |         // we have data | ||||||
|         default: |         default: | ||||||
|             // If data is on webserver |             // If data is on webserver | ||||||
|             if (FD_ISSET(rq->client->sock, &fd_in)) |             if (pfds[0].revents & POLLIN) | ||||||
|             { |             { | ||||||
|                 while((ret = antd_recv_upto(rq->client,buff, BUFFLEN)) > 0) |                 while((ret = antd_recv_upto(rq->client,buff, BUFFLEN)) > 0) | ||||||
|                 { |                 { | ||||||
| @@ -254,7 +253,14 @@ static void *process(void *data) | |||||||
|                     return antd_create_task(NULL, data, NULL, rq->client->last_io); |                     return antd_create_task(NULL, data, NULL, rq->client->last_io); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             else if(FD_ISSET(cl->sock, &fd_in)) |             else if(pfds[0].revents &(POLLERR | POLLHUP)) | ||||||
|  |             { | ||||||
|  |                 ERROR("POLLERR or POLLHUP received on %d", rq->client->sock); | ||||||
|  |                 antd_close(cl); | ||||||
|  |                 dput(rq->request, "LUA_CL_DATA", NULL); | ||||||
|  |                 return antd_create_task(NULL, data, NULL, rq->client->last_io); | ||||||
|  |             } | ||||||
|  |             if(pfds[1].revents & POLLIN) | ||||||
|             { |             { | ||||||
|                 while((ret = antd_recv_upto(cl,buff, BUFFLEN)) > 0) |                 while((ret = antd_recv_upto(cl,buff, BUFFLEN)) > 0) | ||||||
|                 { |                 { | ||||||
| @@ -275,6 +281,13 @@ static void *process(void *data) | |||||||
|                     return antd_create_task(NULL, data, NULL, rq->client->last_io); |                     return antd_create_task(NULL, data, NULL, rq->client->last_io); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |             else if(pfds[1].revents &(POLLERR | POLLHUP)) | ||||||
|  |             { | ||||||
|  |                 ERROR("POLLERR or POLLHUP received on %d", cl->sock); | ||||||
|  |                 antd_close(cl); | ||||||
|  |                 dput(rq->request, "LUA_CL_DATA", NULL); | ||||||
|  |                 return antd_create_task(NULL, data, NULL, rq->client->last_io); | ||||||
|  |             } | ||||||
|             task = antd_create_task(process, (void *)rq, NULL, time(NULL)); |             task = antd_create_task(process, (void *)rq, NULL, time(NULL)); | ||||||
|             antd_task_bind_event(task, rq->client->sock, 0, TASK_EVT_ON_WRITABLE | TASK_EVT_ON_READABLE); |             antd_task_bind_event(task, rq->client->sock, 0, TASK_EVT_ON_WRITABLE | TASK_EVT_ON_READABLE); | ||||||
|             antd_task_bind_event(task, cl->sock, 0, TASK_EVT_ON_READABLE); |             antd_task_bind_event(task, cl->sock, 0, TASK_EVT_ON_READABLE); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user