Add C based module + lua based API code (WIP)
This commit is contained in:
866
modules/ulib.c
Normal file
866
modules/ulib.c
Normal file
@@ -0,0 +1,866 @@
|
||||
#ifdef LINUX
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <pwd.h>
|
||||
#include <shadow.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/sendfile.h>
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <ctype.h>
|
||||
#include "lua/lualib.h"
|
||||
// zip library
|
||||
#include "3rd/zip/zip.h"
|
||||
|
||||
|
||||
#define MAX_PATH_LEN 1024
|
||||
|
||||
/**
|
||||
* Trim a string by a character on both ends
|
||||
* @param str The target string
|
||||
* @param delim the delim
|
||||
*/
|
||||
static void trim(char* str, const char delim)
|
||||
{
|
||||
if(!str || strlen(str) == 0) return;
|
||||
char * p = str;
|
||||
int l = strlen(p);
|
||||
while(l > 0 && p[l - 1] == delim)
|
||||
p[--l] = 0;
|
||||
while(* p && (* p) == delim ) ++p, --l;
|
||||
memmove(str, p, l + 1);
|
||||
}
|
||||
|
||||
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);
|
||||
lua_pushstring(L, strerror(errno));
|
||||
return 2;
|
||||
}
|
||||
spwd = getspnam(username);
|
||||
/*if (spwd == NULL)
|
||||
{
|
||||
lua_pushboolean(L,0);
|
||||
printf("no permission to read shadow password file\n");
|
||||
return 1;
|
||||
}*/
|
||||
|
||||
if (spwd != NULL) /* If there is a shadow password record */
|
||||
{
|
||||
pwd->pw_passwd = spwd->sp_pwdp; /* Use the shadow password */
|
||||
}
|
||||
/*else
|
||||
{
|
||||
lua_pushboolean(L,0);
|
||||
printf("shadow record is null \n" );
|
||||
return 1;
|
||||
}*/
|
||||
/* Encrypt password and erase cleartext version immediately */
|
||||
encrypted = crypt(password, pwd->pw_passwd);
|
||||
if (encrypted == NULL)
|
||||
{
|
||||
lua_pushboolean(L,0);
|
||||
lua_pushstring(L, strerror(errno));
|
||||
return 2;
|
||||
}
|
||||
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
|
||||
lua_pushboolean(L,0);
|
||||
lua_pushstring(L, "Login by shadow passwd is not supported on this system");
|
||||
return 2;
|
||||
#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;
|
||||
}
|
||||
|
||||
static int l_waitpid(lua_State* L)
|
||||
{
|
||||
int pid = luaL_checknumber(L,1);
|
||||
int nohang = luaL_checknumber(L,2);
|
||||
pid_t st;
|
||||
int status;
|
||||
if(nohang)
|
||||
{
|
||||
st = waitpid(pid, &status, WNOHANG);
|
||||
}
|
||||
else
|
||||
{
|
||||
st = waitpid(pid, &status, 0);
|
||||
}
|
||||
lua_pushnumber(L, st);
|
||||
return 1;
|
||||
}
|
||||
static int l_kill(lua_State* L)
|
||||
{
|
||||
int pid = luaL_checknumber(L,1);
|
||||
if(pid == -1) pid = getpid();
|
||||
int status = kill(pid, SIGHUP);
|
||||
lua_pushnumber(L, status);
|
||||
return 1;
|
||||
}
|
||||
static int l_setuid(lua_State* L)
|
||||
{
|
||||
uid_t uid = (uid_t) luaL_checknumber(L,1);
|
||||
if((int)uid != -1)
|
||||
{
|
||||
if(setuid(uid) < 0)
|
||||
{
|
||||
lua_pushboolean(L,0);
|
||||
lua_pushstring(L, strerror(errno));
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("UID set\n");
|
||||
lua_pushboolean(L,1);
|
||||
return 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)
|
||||
{
|
||||
if(setgid(gid) < 0)
|
||||
{
|
||||
lua_pushboolean(L,0);
|
||||
lua_pushstring(L, strerror(errno));
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("GID set\n");
|
||||
lua_pushboolean(L,1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
lua_pushboolean(L,0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
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) {
|
||||
return 1;
|
||||
}
|
||||
if (getgrouplist(name, gid, groups, &ngroups) == -1) {
|
||||
free(groups);
|
||||
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 void timestr(time_t time, char* buf,int len,char* format, int gmt)
|
||||
{
|
||||
struct tm t;
|
||||
if(gmt)
|
||||
{
|
||||
gmtime_r(&time, &t);
|
||||
}
|
||||
else
|
||||
{
|
||||
localtime_r(&time, &t);
|
||||
}
|
||||
strftime(buf, len, format, &t);
|
||||
}
|
||||
|
||||
|
||||
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");
|
||||
timestr(st.st_ctime,date,sizeof(date),"%a, %d %b %Y %H:%M:%S GMT",1);
|
||||
lua_pushstring(L,date);
|
||||
lua_settable(L,-3);
|
||||
//mtime
|
||||
|
||||
lua_pushstring(L,"mtime");
|
||||
timestr(st.st_mtime,date,sizeof(date),"%a, %d %b %Y %H:%M:%S GMT",1);
|
||||
lua_pushstring(L,date);
|
||||
lua_settable(L,-3);
|
||||
|
||||
//size
|
||||
lua_pushstring(L,"size");
|
||||
lua_pushnumber(L,st.st_size);
|
||||
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;
|
||||
}
|
||||
|
||||
static int l_send_file(lua_State* L)
|
||||
{
|
||||
int fromfd, tofd, ret;
|
||||
size_t sz = 0;
|
||||
char* old = NULL;
|
||||
char* new = NULL;
|
||||
if(lua_isnumber(L,1))
|
||||
{
|
||||
fromfd = (int)luaL_checknumber(L,1);
|
||||
}
|
||||
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;
|
||||
}
|
||||
if(lua_isnumber(L,2))
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
off_t off = 0;
|
||||
int read = 0;
|
||||
while (
|
||||
sz > 0 &&
|
||||
read != sz &&
|
||||
(
|
||||
((ret = sendfile(tofd, fromfd, &off, sz - read)) >= 0) ||
|
||||
(errno == EAGAIN)
|
||||
)
|
||||
)
|
||||
{
|
||||
if(ret < 0) ret = 0;
|
||||
read += ret;
|
||||
}
|
||||
if(read != sz)
|
||||
{
|
||||
lua_pushboolean(L,0);
|
||||
goto end_send_file;
|
||||
}
|
||||
lua_pushboolean(L,1);
|
||||
end_send_file:
|
||||
if(fromfd >= 0 && old)
|
||||
{
|
||||
(void) close(fromfd);
|
||||
}
|
||||
if(tofd >= 0 && new)
|
||||
{
|
||||
(void) close(tofd);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
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 is_dir(const char* f)
|
||||
{
|
||||
struct stat st;
|
||||
if(stat(f, &st) == -1)
|
||||
return -1; // unknow
|
||||
else if(st.st_mode & S_IFDIR)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_is_dir(lua_State *L)
|
||||
{
|
||||
const char *file = (char *)luaL_checkstring(L, 1);
|
||||
lua_pushboolean(L, is_dir(file) == 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;
|
||||
char p1[MAX_PATH_LEN];
|
||||
char p2[MAX_PATH_LEN];
|
||||
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
|
||||
snprintf(p1,MAX_PATH_LEN,"%s/%s", path, dir->d_name);
|
||||
snprintf(p2,MAX_PATH_LEN,"%s/%s",root,dir->d_name);
|
||||
if(_add_to_zip(zip,p1,p2) == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
static int l_trim(lua_State *L)
|
||||
{
|
||||
char *str = strdup((char *)luaL_checkstring(L, 1));
|
||||
const char *tok = luaL_checkstring(L, 2);
|
||||
|
||||
trim(str, tok[0]);
|
||||
lua_pushstring(L, (const char *)str);
|
||||
free(str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
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},
|
||||
{"kill", l_kill},
|
||||
{"waitpid", l_waitpid},
|
||||
{"trim", l_trim},
|
||||
{"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},
|
||||
{"getenv",l_getenv},
|
||||
{"setenv",l_setenv},
|
||||
{"unsetenv",l_unsetenv},
|
||||
{"home_dir",l_gethomedir},
|
||||
{"send_file", l_send_file},
|
||||
{"is_dir", l_is_dir},
|
||||
{NULL,NULL}
|
||||
};
|
||||
|
||||
int luaopen_ulib(lua_State *L)
|
||||
{
|
||||
luaL_newlib(L, _lib);
|
||||
return 1;
|
||||
}
|
||||
Reference in New Issue
Block a user