2018-09-19 15:08:49 +02:00
|
|
|
#ifdef LINUX
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <limits.h>
|
|
|
|
#include <pwd.h>
|
|
|
|
#include <shadow.h>
|
2022-08-22 22:58:42 +02:00
|
|
|
#include <fcntl.h>
|
|
|
|
#include <sys/sendfile.h>
|
2018-09-19 15:08:49 +02:00
|
|
|
#endif
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <time.h>
|
2020-08-25 17:09:04 +02:00
|
|
|
#include <dirent.h>
|
2018-09-19 15:08:49 +02:00
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/types.h>
|
2018-10-09 10:36:38 +02:00
|
|
|
#include <sys/wait.h>
|
2018-10-07 16:13:55 +02:00
|
|
|
#include <signal.h>
|
2018-09-19 15:08:49 +02:00
|
|
|
#include <errno.h>
|
|
|
|
#include <pwd.h>
|
|
|
|
#include <grp.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#include "../lualib.h"
|
2019-11-14 18:46:49 +01:00
|
|
|
#include <antd/utils.h>
|
2018-09-19 15:08:49 +02:00
|
|
|
// zip library
|
|
|
|
#include "3rd/zip/zip.h"
|
|
|
|
|
|
|
|
static int l_check_login (lua_State *L) {
|
|
|
|
#ifdef LINUX
|
|
|
|
const char* username = luaL_checkstring(L,1);
|
|
|
|
const char* password = luaL_checkstring(L,2);
|
|
|
|
|
|
|
|
char *encrypted;
|
|
|
|
struct passwd *pwd;
|
|
|
|
struct spwd *spwd;
|
|
|
|
/* Look up password and shadow password records for username */
|
|
|
|
pwd = getpwnam(username);
|
|
|
|
if (pwd == NULL)
|
|
|
|
{
|
|
|
|
lua_pushboolean(L,0);
|
2022-08-30 16:31:45 +02:00
|
|
|
ERROR("Cannot find pwd record of %s", username );
|
2018-09-19 15:08:49 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
spwd = getspnam(username);
|
2018-10-27 11:23:47 +02:00
|
|
|
/*if (spwd == NULL)
|
2018-09-19 15:08:49 +02:00
|
|
|
{
|
|
|
|
lua_pushboolean(L,0);
|
|
|
|
printf("no permission to read shadow password file\n");
|
|
|
|
return 1;
|
2018-10-27 11:23:47 +02:00
|
|
|
}*/
|
2018-09-19 15:08:49 +02:00
|
|
|
|
|
|
|
if (spwd != NULL) /* If there is a shadow password record */
|
|
|
|
{
|
|
|
|
pwd->pw_passwd = spwd->sp_pwdp; /* Use the shadow password */
|
|
|
|
}
|
2018-10-27 11:23:47 +02:00
|
|
|
/*else
|
2018-09-19 15:08:49 +02:00
|
|
|
{
|
|
|
|
lua_pushboolean(L,0);
|
|
|
|
printf("shadow record is null \n" );
|
|
|
|
return 1;
|
2018-10-27 11:23:47 +02:00
|
|
|
}*/
|
2018-09-19 15:08:49 +02:00
|
|
|
/* Encrypt password and erase cleartext version immediately */
|
|
|
|
encrypted = crypt(password, pwd->pw_passwd);
|
|
|
|
if (encrypted == NULL)
|
|
|
|
{
|
|
|
|
lua_pushboolean(L,0);
|
2022-08-30 16:31:45 +02:00
|
|
|
ERROR("Cant crypt %s", strerror(errno) );
|
2018-09-19 15:08:49 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if(strcmp(encrypted, pwd->pw_passwd) == 0)
|
|
|
|
{
|
|
|
|
lua_pushboolean(L,1);
|
|
|
|
return 1;
|
|
|
|
} else
|
|
|
|
{
|
|
|
|
lua_pushboolean(L,0);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
// macos
|
|
|
|
// just pass the check, for test only
|
2022-08-30 16:31:45 +02:00
|
|
|
lua_pushboolean(L,0);
|
|
|
|
ERROR("Login by shadow passd is not supported on this system");
|
2018-09-19 15:08:49 +02:00
|
|
|
return 1;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
static void get_userId(const char* name, uid_t* uid,gid_t* gid )
|
|
|
|
{
|
|
|
|
struct passwd *pwd;
|
|
|
|
uid_t u;
|
|
|
|
char *endptr;
|
|
|
|
if (name == NULL || *name == '\0')
|
|
|
|
{
|
|
|
|
*uid = -1; *gid=-1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
u = strtol(name, &endptr, 10);
|
|
|
|
if (*endptr == '\0')
|
|
|
|
{
|
|
|
|
*uid = u;
|
|
|
|
*gid = -1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
pwd = getpwnam(name);
|
|
|
|
if (pwd == NULL)
|
|
|
|
{
|
|
|
|
*uid = -1; *gid=-1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
*uid = pwd->pw_uid;
|
|
|
|
*gid = pwd->pw_gid;
|
|
|
|
}
|
|
|
|
static int l_fork(lua_State* L)
|
|
|
|
{
|
|
|
|
int pid = fork();
|
|
|
|
lua_pushnumber(L, pid);
|
|
|
|
return 1;
|
|
|
|
}
|
2022-08-30 16:31:45 +02:00
|
|
|
|
2018-09-19 15:08:49 +02:00
|
|
|
static int l_waitpid(lua_State* L)
|
|
|
|
{
|
|
|
|
int pid = luaL_checknumber(L,1);
|
2019-05-07 14:33:35 +02:00
|
|
|
int nohang = luaL_checknumber(L,2);
|
|
|
|
pid_t st;
|
2018-09-19 15:08:49 +02:00
|
|
|
int status;
|
2019-05-07 14:33:35 +02:00
|
|
|
if(nohang)
|
|
|
|
{
|
|
|
|
st = waitpid(pid, &status, WNOHANG);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
st = waitpid(pid, &status, 0);
|
|
|
|
}
|
|
|
|
lua_pushnumber(L, st);
|
2018-10-07 16:13:55 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
static int l_kill(lua_State* L)
|
|
|
|
{
|
|
|
|
int pid = luaL_checknumber(L,1);
|
|
|
|
if(pid == -1) pid = getpid();
|
2022-08-30 16:31:45 +02:00
|
|
|
int status = kill(pid, SIGHUP);
|
2018-10-07 16:13:55 +02:00
|
|
|
lua_pushnumber(L, status);
|
|
|
|
return 1;
|
2018-09-19 15:08:49 +02:00
|
|
|
}
|
|
|
|
static int l_setuid(lua_State* L)
|
|
|
|
{
|
|
|
|
uid_t uid = (uid_t) luaL_checknumber(L,1);
|
|
|
|
if((int)uid != -1)
|
|
|
|
{
|
2020-12-26 14:56:38 +01:00
|
|
|
if(setuid(uid) < 0)
|
2018-09-19 15:08:49 +02:00
|
|
|
{
|
2022-08-30 16:31:45 +02:00
|
|
|
ERROR("UID set problem: %s", strerror(errno));
|
2018-09-19 15:08:49 +02:00
|
|
|
lua_pushboolean(L,0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//printf("UID set\n");
|
|
|
|
lua_pushboolean(L,1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
lua_pushboolean(L,0);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
static int l_setgid(lua_State* L)
|
|
|
|
{
|
|
|
|
uid_t gid = (uid_t) luaL_checknumber(L,1);
|
|
|
|
if((int)gid != -1)
|
|
|
|
{
|
2020-12-26 14:56:38 +01:00
|
|
|
if(setgid(gid) < 0)
|
2018-09-19 15:08:49 +02:00
|
|
|
{
|
2022-08-30 16:31:45 +02:00
|
|
|
ERROR("GID set problem: %s", strerror(errno));
|
2018-09-19 15:08:49 +02:00
|
|
|
lua_pushboolean(L,0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//printf("GID set\n");
|
|
|
|
lua_pushboolean(L,1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
lua_pushboolean(L,0);
|
|
|
|
return 1;
|
|
|
|
}
|
2022-08-23 01:18:05 +02:00
|
|
|
static int l_syslog(lua_State* L)
|
|
|
|
{
|
|
|
|
const int prio = luaL_checknumber(L,1);
|
|
|
|
const char* msg = luaL_checkstring(L,2);
|
|
|
|
syslog(prio, "%s", msg);
|
|
|
|
return 1;
|
|
|
|
}
|
2018-09-19 15:08:49 +02:00
|
|
|
static int l_getuid(lua_State* L)
|
|
|
|
{
|
|
|
|
const char* name = luaL_checkstring(L,1);
|
|
|
|
uid_t uid = -1;
|
|
|
|
uid_t gid = -1;
|
|
|
|
get_userId(name,&uid,&gid);
|
|
|
|
lua_newtable(L);
|
|
|
|
|
|
|
|
lua_pushstring(L,"id");
|
|
|
|
lua_pushnumber(L,uid);
|
|
|
|
lua_settable(L,-3);
|
|
|
|
|
|
|
|
lua_pushstring(L,"gid");
|
|
|
|
lua_pushnumber(L,gid);
|
|
|
|
lua_settable(L,-3);
|
|
|
|
|
|
|
|
int j, ngroups = 30; //only first 10 group
|
|
|
|
gid_t *groups;
|
|
|
|
struct group *gr;
|
|
|
|
// find all the groups
|
|
|
|
if((int)uid != -1 && (int)gid != -1)
|
|
|
|
{
|
|
|
|
/* Retrieve group list */
|
|
|
|
groups = malloc(ngroups * sizeof (gid_t));
|
|
|
|
if (groups == NULL) {
|
2022-08-30 16:31:45 +02:00
|
|
|
LOG("malloc eror");
|
2018-09-19 15:08:49 +02:00
|
|
|
return 1;
|
|
|
|
}
|
2018-10-09 10:36:38 +02:00
|
|
|
if (getgrouplist(name, gid, groups, &ngroups) == -1) {
|
2018-09-19 15:08:49 +02:00
|
|
|
free(groups);
|
2022-08-30 16:31:45 +02:00
|
|
|
LOG("getgrouplist() returned -1; ngroups = %d", ngroups);
|
2018-09-19 15:08:49 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
/* retrieved groups, along with group names */
|
|
|
|
lua_pushstring(L,"groups");
|
|
|
|
lua_newtable(L);
|
|
|
|
|
|
|
|
for (j = 0; j < ngroups; j++) {
|
|
|
|
gr = getgrgid(groups[j]);
|
|
|
|
if (gr != NULL)
|
|
|
|
{
|
|
|
|
//printf("%d: (%s)\n", groups[j],gr->gr_name);
|
|
|
|
lua_pushnumber(L, groups[j]);
|
|
|
|
lua_pushstring(L, gr->gr_name);
|
|
|
|
lua_settable(L,-3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
lua_settable(L, -3);
|
|
|
|
free(groups);
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int l_file_stat(lua_State* L, const char* path)
|
|
|
|
{
|
|
|
|
//const char* path = luaL_checkstring(L,-1);
|
|
|
|
//printf("PATH %s\n", path);
|
|
|
|
//lua_pop(L,1);
|
|
|
|
char date[64];
|
|
|
|
struct stat st;
|
|
|
|
if( stat(path, &st) == 0 )
|
|
|
|
{
|
|
|
|
// recore for file
|
|
|
|
lua_newtable(L);
|
|
|
|
|
|
|
|
//type
|
|
|
|
lua_pushstring(L,"type");
|
|
|
|
if(S_ISDIR(st.st_mode))
|
|
|
|
lua_pushstring(L,"dir");
|
|
|
|
else
|
|
|
|
lua_pushstring(L,"file");
|
|
|
|
lua_settable(L,-3);
|
|
|
|
|
|
|
|
//ctime
|
|
|
|
lua_pushstring(L,"ctime");
|
2020-01-10 18:29:29 +01:00
|
|
|
timestr(st.st_ctime,date,sizeof(date),"%a, %d %b %Y %H:%M:%S GMT",1);
|
2018-09-19 15:08:49 +02:00
|
|
|
lua_pushstring(L,date);
|
|
|
|
lua_settable(L,-3);
|
|
|
|
//mtime
|
|
|
|
|
|
|
|
lua_pushstring(L,"mtime");
|
2020-01-10 18:29:29 +01:00
|
|
|
timestr(st.st_mtime,date,sizeof(date),"%a, %d %b %Y %H:%M:%S GMT",1);
|
2018-09-19 15:08:49 +02:00
|
|
|
lua_pushstring(L,date);
|
|
|
|
lua_settable(L,-3);
|
|
|
|
|
|
|
|
//size
|
|
|
|
lua_pushstring(L,"size");
|
|
|
|
lua_pushnumber(L,st.st_size);
|
|
|
|
lua_settable(L,-3);
|
|
|
|
//mime
|
|
|
|
if(S_ISDIR(st.st_mode))
|
|
|
|
{
|
|
|
|
lua_pushstring(L,"mime");
|
|
|
|
lua_pushstring(L, "dir");
|
|
|
|
lua_settable(L,-3);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lua_pushstring(L,"mime");
|
|
|
|
lua_pushstring(L, mime(path));
|
|
|
|
lua_settable(L,-3);
|
|
|
|
}
|
|
|
|
|
|
|
|
// uid
|
|
|
|
lua_pushstring(L,"uid");
|
|
|
|
lua_pushnumber(L,st.st_uid);
|
|
|
|
lua_settable(L,-3);
|
|
|
|
// gid
|
|
|
|
lua_pushstring(L,"gid");
|
|
|
|
lua_pushnumber(L,st.st_gid);
|
|
|
|
lua_settable(L,-3);
|
|
|
|
|
|
|
|
lua_pushstring(L,"permissions");
|
|
|
|
sprintf(date," (%3o)", st.st_mode&0777);
|
|
|
|
lua_pushstring(L,date);
|
|
|
|
lua_settable(L,-3);
|
|
|
|
|
|
|
|
// permission
|
|
|
|
lua_pushstring(L,"perm");
|
|
|
|
lua_newtable(L);
|
|
|
|
|
|
|
|
lua_pushstring(L,"owner");
|
|
|
|
lua_newtable(L);
|
|
|
|
lua_pushstring(L,"read");
|
|
|
|
lua_pushboolean(L, (st.st_mode & S_IRUSR)==0?0:1);
|
|
|
|
lua_settable(L,-3);
|
|
|
|
lua_pushstring(L,"write");
|
|
|
|
lua_pushboolean(L, (st.st_mode & S_IWUSR)==0?0:1);
|
|
|
|
lua_settable(L,-3);
|
|
|
|
lua_pushstring(L,"exec");
|
|
|
|
lua_pushboolean(L, (st.st_mode & S_IXUSR)==0?0:1);
|
|
|
|
lua_settable(L,-3);
|
|
|
|
//end owner
|
|
|
|
lua_settable(L,-3);
|
|
|
|
|
|
|
|
lua_pushstring(L,"group");
|
|
|
|
lua_newtable(L);
|
|
|
|
lua_pushstring(L,"read");
|
|
|
|
lua_pushboolean(L, (st.st_mode & S_IRGRP)==0?0:1);
|
|
|
|
lua_settable(L,-3);
|
|
|
|
lua_pushstring(L,"write");
|
|
|
|
lua_pushboolean(L, (st.st_mode & S_IWGRP)==0?0:1);
|
|
|
|
lua_settable(L,-3);
|
|
|
|
lua_pushstring(L,"exec");
|
|
|
|
lua_pushboolean(L, (st.st_mode & S_IXGRP)==0?0:1);
|
|
|
|
lua_settable(L,-3);
|
|
|
|
//end owner
|
|
|
|
lua_settable(L,-3);
|
|
|
|
|
|
|
|
lua_pushstring(L,"other");
|
|
|
|
lua_newtable(L);
|
|
|
|
lua_pushstring(L,"read");
|
|
|
|
lua_pushboolean(L, (st.st_mode & S_IROTH)==0?0:1);
|
|
|
|
lua_settable(L,-3);
|
|
|
|
lua_pushstring(L,"write");
|
|
|
|
lua_pushboolean(L, (st.st_mode & S_IWOTH)==0?0:1);
|
|
|
|
lua_settable(L,-3);
|
|
|
|
lua_pushstring(L,"exec");
|
|
|
|
lua_pushboolean(L, (st.st_mode & S_IXOTH)==0?0:1);
|
|
|
|
lua_settable(L,-3);
|
|
|
|
//end owner
|
|
|
|
lua_settable(L,-3);
|
|
|
|
|
|
|
|
// end permission
|
|
|
|
lua_settable(L,-3);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lua_newtable(L);
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int l_file_info(lua_State* L)
|
|
|
|
{
|
|
|
|
const char* path = luaL_checkstring(L,1);
|
|
|
|
l_file_stat(L,path);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int l_file_move(lua_State* L)
|
|
|
|
{
|
|
|
|
const char* old = luaL_checkstring(L,1);
|
|
|
|
const char* new = luaL_checkstring(L,2);
|
|
|
|
//printf("MOVE %s to %s\n",old,new);
|
|
|
|
lua_pushboolean(L, rename(old,new)==0);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2022-08-22 22:58:42 +02:00
|
|
|
static int l_send_file(lua_State* L)
|
|
|
|
{
|
|
|
|
int fromfd, tofd, ret;
|
2022-08-27 16:38:20 +02:00
|
|
|
size_t sz = 0;
|
|
|
|
char* old = NULL;
|
|
|
|
char* new = NULL;
|
|
|
|
if(lua_isnumber(L,1))
|
|
|
|
{
|
|
|
|
fromfd = (int)luaL_checknumber(L,1);
|
2022-08-22 22:58:42 +02:00
|
|
|
}
|
2022-08-27 16:38:20 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
old = (char*)luaL_checkstring(L,1);
|
|
|
|
if((fromfd = open(old, O_RDONLY)) < 0)
|
|
|
|
{
|
|
|
|
lua_pushboolean(L,0);
|
|
|
|
goto end_send_file;
|
|
|
|
}
|
|
|
|
struct stat st;
|
|
|
|
if(stat(old, &st)!=0)
|
|
|
|
{
|
|
|
|
lua_pushboolean(L,0);
|
|
|
|
goto end_send_file;
|
|
|
|
}
|
|
|
|
sz = st.st_size;
|
2022-08-22 22:58:42 +02:00
|
|
|
}
|
2022-08-27 16:38:20 +02:00
|
|
|
if(lua_isnumber(L,2))
|
2022-08-22 22:58:42 +02:00
|
|
|
{
|
2022-08-27 16:38:20 +02:00
|
|
|
tofd = (int) luaL_checknumber(L,2);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
new = (char*)luaL_checkstring(L,2);
|
|
|
|
if (unlink(new) < 0 && errno != ENOENT) {
|
|
|
|
lua_pushboolean(L,0);
|
|
|
|
goto end_send_file;
|
|
|
|
}
|
|
|
|
if((tofd = open(new, O_WRONLY | O_CREAT, 0600)) < 0)
|
|
|
|
{
|
|
|
|
lua_pushboolean(L,0);
|
|
|
|
goto end_send_file;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(lua_isnumber(L,3))
|
|
|
|
{
|
|
|
|
sz = (size_t) luaL_checknumber(L,3);
|
2022-08-22 22:58:42 +02:00
|
|
|
}
|
2022-08-27 16:38:20 +02:00
|
|
|
|
|
|
|
off_t off = 0;
|
2022-08-22 22:58:42 +02:00
|
|
|
int read = 0;
|
2022-08-27 16:38:20 +02:00
|
|
|
while (
|
|
|
|
sz > 0 &&
|
|
|
|
read != sz &&
|
|
|
|
(
|
|
|
|
((ret = sendfile(tofd, fromfd, &off, sz - read)) >= 0) ||
|
|
|
|
(errno == EAGAIN)
|
|
|
|
)
|
|
|
|
)
|
2022-08-22 22:58:42 +02:00
|
|
|
{
|
2022-08-27 16:38:20 +02:00
|
|
|
if(ret < 0) ret = 0;
|
2022-08-22 22:58:42 +02:00
|
|
|
read += ret;
|
|
|
|
}
|
2022-08-27 16:38:20 +02:00
|
|
|
if(read != sz)
|
2022-08-22 22:58:42 +02:00
|
|
|
{
|
|
|
|
lua_pushboolean(L,0);
|
|
|
|
goto end_send_file;
|
|
|
|
}
|
|
|
|
lua_pushboolean(L,1);
|
|
|
|
end_send_file:
|
2022-08-27 16:38:20 +02:00
|
|
|
if(fromfd >= 0 && old)
|
2022-08-22 22:58:42 +02:00
|
|
|
{
|
|
|
|
(void) close(fromfd);
|
|
|
|
}
|
2022-08-27 16:38:20 +02:00
|
|
|
if(tofd >= 0 && new)
|
2022-08-22 22:58:42 +02:00
|
|
|
{
|
|
|
|
(void) close(tofd);
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2018-09-19 15:08:49 +02:00
|
|
|
static int l_read_dir(lua_State* L)
|
|
|
|
{
|
|
|
|
const char* path = luaL_checkstring(L,1);
|
|
|
|
const char* prefix = luaL_checkstring(L,2);
|
|
|
|
DIR *d;
|
|
|
|
struct dirent *dir;
|
|
|
|
d = opendir(path);
|
|
|
|
char buff[1024];
|
|
|
|
lua_newtable(L);
|
|
|
|
if (d)
|
|
|
|
{
|
|
|
|
int id=0;
|
|
|
|
while ((dir = readdir(d)) != NULL)
|
|
|
|
{
|
|
|
|
//ignore curent directory, parent directory
|
|
|
|
if(strcmp(dir->d_name,".") == 0 ||
|
|
|
|
strcmp(dir->d_name,"..")==0/*|| *(dir->d_name)=='.'*/) continue;
|
|
|
|
sprintf(buff,"%s/%s",path,dir->d_name);
|
|
|
|
lua_pushnumber(L,id);
|
|
|
|
//lua_pushstring(L,buff);
|
|
|
|
l_file_stat(L,buff);
|
|
|
|
|
|
|
|
lua_pushstring(L,"filename");
|
|
|
|
lua_pushstring(L,dir->d_name);
|
|
|
|
lua_settable(L,-3);
|
|
|
|
|
|
|
|
sprintf(buff,"%s/%s",prefix,dir->d_name);
|
|
|
|
//printf("FILE %s\n",buff );
|
|
|
|
lua_pushstring(L,"path");
|
|
|
|
lua_pushstring(L,buff);
|
|
|
|
lua_settable(L,-3);
|
|
|
|
|
|
|
|
lua_settable(L,-3);
|
|
|
|
|
|
|
|
id++;
|
|
|
|
}
|
|
|
|
closedir(d);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lua_pushstring(L,"error");
|
|
|
|
lua_pushstring(L,"Resource not found");
|
|
|
|
lua_settable(L,-3);
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int l_chown(lua_State* L)
|
|
|
|
{
|
|
|
|
const char* path = luaL_checkstring(L,1);
|
|
|
|
int id = luaL_checknumber(L,2);
|
|
|
|
int gid = luaL_checknumber(L,3);
|
|
|
|
lua_pushboolean(L, chown(path,id,gid) == 0);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int l_mkdir(lua_State* L)
|
|
|
|
{
|
|
|
|
const char* path = luaL_checkstring(L,1);
|
|
|
|
lua_pushboolean(L, mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
static int l_exist(lua_State* L)
|
|
|
|
{
|
|
|
|
const char* path = luaL_checkstring(L,1);
|
|
|
|
lua_pushboolean(L,access( path, F_OK ) != -1 );
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
static int _recursive_delete(const char* path)
|
|
|
|
{
|
|
|
|
if(is_dir(path) == 1)
|
|
|
|
{
|
|
|
|
DIR *d;
|
|
|
|
struct dirent *dir;
|
|
|
|
d = opendir(path);
|
|
|
|
char buff[1024];
|
|
|
|
if (d)
|
|
|
|
{
|
|
|
|
while ((dir = readdir(d)) != NULL)
|
|
|
|
{
|
|
|
|
//ignore current & parent dir
|
|
|
|
if(strcmp(dir->d_name,".") == 0 || strcmp(dir->d_name,"..")==0) continue;
|
|
|
|
// get the file
|
|
|
|
sprintf(buff,"%s/%s",path,dir->d_name);
|
|
|
|
if(_recursive_delete(buff) == -1) return -1;
|
|
|
|
}
|
|
|
|
closedir(d);
|
|
|
|
// remove dir
|
|
|
|
if(rmdir(path) != 0) return -1;
|
|
|
|
} else return -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// file remove
|
|
|
|
if(remove(path) != 0) return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
static int l_delete(lua_State* L)
|
|
|
|
{
|
|
|
|
const char* f = luaL_checkstring(L,1);
|
|
|
|
lua_pushboolean(L,_recursive_delete(f) == 0);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* Only use this for simple command
|
|
|
|
* Be careful to expose this function
|
|
|
|
* to user. This can cause a serious
|
|
|
|
* security problem
|
|
|
|
*/
|
|
|
|
static int l_cmd_open(lua_State* L)
|
|
|
|
{
|
|
|
|
FILE *fp;
|
|
|
|
const char* cmd = luaL_checkstring(L,1);
|
|
|
|
|
|
|
|
/* Open the command for reading. */
|
|
|
|
fp = popen(cmd, "r");
|
|
|
|
if (fp == NULL) {
|
|
|
|
lua_pushnil(L);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
/*return the fd to lua
|
|
|
|
* user can use this to
|
|
|
|
read the output data*/
|
|
|
|
intptr_t pt = (intptr_t)fp;
|
|
|
|
lua_pushnumber(L, pt);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
static int l_cmd_read(lua_State* L)
|
|
|
|
{
|
|
|
|
/* Read the output a line at a time - output it.
|
|
|
|
read user defined data of std
|
|
|
|
*/
|
|
|
|
FILE * fd;
|
|
|
|
intptr_t pt = (intptr_t)luaL_checknumber(L, 1);
|
|
|
|
fd = (FILE*)pt;
|
|
|
|
if(fd == NULL)
|
|
|
|
{
|
|
|
|
lua_pushnil(L);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
char buff[1024];
|
|
|
|
if(fgets(buff, sizeof(buff)-1, fd) != NULL) {
|
|
|
|
lua_pushstring(L,buff);
|
|
|
|
} else
|
|
|
|
{
|
|
|
|
lua_pushnil(L);
|
|
|
|
}
|
|
|
|
/* close */
|
|
|
|
//pclose(fp);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
static int l_cmd_close(lua_State* L)
|
|
|
|
{
|
|
|
|
/* Read the output a line at a time - output it.
|
|
|
|
read user defined data of std
|
|
|
|
*/
|
|
|
|
FILE * fd;
|
|
|
|
intptr_t pt = (intptr_t)luaL_checknumber(L, 1);
|
|
|
|
fd = (FILE*)pt;
|
|
|
|
if(fd == NULL)
|
|
|
|
{
|
|
|
|
pclose(fd);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*zip file handler
|
|
|
|
* using miniz to compress and uncompress zip file
|
|
|
|
*/
|
|
|
|
|
|
|
|
static int l_unzip(lua_State* L)
|
|
|
|
{
|
|
|
|
const char* src = luaL_checkstring(L,1);
|
|
|
|
const char* dest = luaL_checkstring(L,2);
|
|
|
|
|
|
|
|
if(zip_extract(src, dest, NULL, NULL) == -1)
|
|
|
|
{
|
|
|
|
lua_pushboolean(L,0);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
lua_pushboolean(L,1);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int _add_to_zip(struct zip_t * zip, const char* path, const char* root)
|
|
|
|
{
|
|
|
|
int st = is_dir(path);
|
|
|
|
if(st == -1) return -1;
|
|
|
|
if(st)
|
|
|
|
{
|
|
|
|
// read directory
|
|
|
|
DIR *d;
|
|
|
|
struct dirent *dir;
|
|
|
|
//struct stat st;
|
|
|
|
d = opendir(path);
|
|
|
|
if (d)
|
|
|
|
{
|
|
|
|
while ((dir = readdir(d)) != NULL)
|
|
|
|
{
|
|
|
|
//ignore curent directory, parent directory
|
|
|
|
if(strcmp(dir->d_name,".") == 0 || strcmp(dir->d_name,"..")==0) continue;
|
|
|
|
// add file to zip
|
|
|
|
char* p1 = __s("%s/%s", path, dir->d_name);
|
|
|
|
char* p2 = __s("%s/%s",root,dir->d_name);
|
|
|
|
if(_add_to_zip(zip,p1,p2) == -1)
|
|
|
|
{
|
|
|
|
free(p1);
|
|
|
|
free(p2);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
free(p1);
|
|
|
|
free(p2);
|
|
|
|
}
|
|
|
|
closedir(d);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// if it is a file
|
|
|
|
// add it to zip
|
|
|
|
if(zip_entry_open(zip, root) == -1) return -1;
|
|
|
|
if(zip_entry_fwrite(zip, path) == -1) return -1;
|
|
|
|
zip_entry_close(zip);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int l_zip(lua_State* L)
|
|
|
|
{
|
|
|
|
const char* src = luaL_checkstring(L,1);
|
|
|
|
const char* dest = luaL_checkstring(L,2);
|
|
|
|
|
|
|
|
// create a zip handler
|
|
|
|
struct zip_t *zip = zip_open(dest, ZIP_DEFAULT_COMPRESSION_LEVEL, 0);
|
|
|
|
|
|
|
|
if(zip == NULL) goto pfalse;
|
|
|
|
|
|
|
|
if(_add_to_zip(zip,src,"") == -1) goto pfalse;
|
|
|
|
|
|
|
|
zip_close(zip);
|
|
|
|
|
|
|
|
lua_pushboolean(L,1);
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
// return false
|
|
|
|
pfalse:
|
|
|
|
// TODO remove if filed is created
|
|
|
|
if(zip) zip_close(zip);
|
|
|
|
lua_pushboolean(L,0);
|
|
|
|
return 1;
|
|
|
|
}
|
2022-08-22 20:37:10 +02:00
|
|
|
static int l_getenv(lua_State* L)
|
|
|
|
{
|
|
|
|
const char* name = luaL_checkstring(L,1);
|
|
|
|
if(!name)
|
|
|
|
{
|
|
|
|
lua_pushnil(L);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
char * value = getenv(name);
|
|
|
|
lua_pushstring(L, value);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int l_setenv(lua_State* L)
|
|
|
|
{
|
|
|
|
const char* name = luaL_checkstring(L,1);
|
|
|
|
const char* value = luaL_checkstring(L,2);
|
|
|
|
const int force = luaL_checknumber(L,3);
|
|
|
|
if(!name)
|
|
|
|
{
|
|
|
|
lua_pushboolean(L, 0);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if(!value)
|
|
|
|
{
|
|
|
|
lua_pushboolean(L, 0);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
int ret = setenv(name, value, force);
|
|
|
|
if(ret != 0)
|
|
|
|
{
|
|
|
|
lua_pushboolean(L, 0);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
lua_pushboolean(L,1);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int l_unsetenv(lua_State* L)
|
|
|
|
{
|
|
|
|
const char* name = luaL_checkstring(L,1);
|
|
|
|
if(!name)
|
|
|
|
{
|
|
|
|
lua_pushboolean(L, 0);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
int ret = unsetenv(name);
|
|
|
|
if(ret != 0)
|
|
|
|
{
|
|
|
|
lua_pushboolean(L, 0);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
lua_pushboolean(L,1);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int l_gethomedir(lua_State* L)
|
|
|
|
{
|
|
|
|
uid_t uid = (uid_t) luaL_checknumber(L,1);
|
|
|
|
if(uid < 0)
|
|
|
|
{
|
|
|
|
lua_pushnil(L);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
struct passwd *pw = getpwuid(uid);
|
|
|
|
|
|
|
|
if (pw == NULL) {
|
|
|
|
lua_pushnil(L);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
lua_pushstring(L, pw->pw_dir);
|
|
|
|
return 1;
|
|
|
|
}
|
2018-09-19 15:08:49 +02:00
|
|
|
|
|
|
|
static const struct luaL_Reg _lib [] = {
|
|
|
|
{"auth", l_check_login},
|
|
|
|
{"read_dir",l_read_dir},
|
|
|
|
{"file_stat",l_file_info},
|
|
|
|
{"uid",l_getuid},
|
|
|
|
{"setuid", l_setuid},
|
|
|
|
{"setgid", l_setgid},
|
|
|
|
{"fork", l_fork},
|
2018-10-07 16:13:55 +02:00
|
|
|
{"kill", l_kill},
|
2018-09-19 15:08:49 +02:00
|
|
|
{"waitpid", l_waitpid},
|
|
|
|
{"chown",l_chown},
|
|
|
|
{"delete", l_delete},
|
|
|
|
{"exists",l_exist},
|
|
|
|
{"mkdir",l_mkdir},
|
|
|
|
{"cmdopen",l_cmd_open},
|
|
|
|
{"cmdread",l_cmd_read},
|
|
|
|
{"cmdclose",l_cmd_close},
|
|
|
|
{"move",l_file_move},
|
|
|
|
{"unzip",l_unzip},
|
|
|
|
{"zip",l_zip},
|
2022-08-22 20:37:10 +02:00
|
|
|
{"getenv",l_getenv},
|
|
|
|
{"setenv",l_setenv},
|
|
|
|
{"unsetenv",l_unsetenv},
|
|
|
|
{"home_dir",l_gethomedir},
|
2022-08-22 22:58:42 +02:00
|
|
|
{"send_file", l_send_file},
|
2022-08-23 01:18:05 +02:00
|
|
|
{"syslog", l_syslog},
|
2018-09-19 15:08:49 +02:00
|
|
|
{NULL,NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
int luaopen_ulib(lua_State *L)
|
|
|
|
{
|
|
|
|
luaL_newlib(L, _lib);
|
|
|
|
return 1;
|
|
|
|
}
|