[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Creating a lua extension from a recursive C function
- From: Francesco Abbate <francesco.bbt@...>
- Date: Sun, 8 May 2011 01:08:13 +0200
Hi,
I did not resist to the temptation to write myself the code, this is
actually a very nice exercise for the Lua C API.
Here the code:
#include <lua.h>
#include <lauxlib.h>
#include <errno.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>
#include <stdio.h>
#define TREE_FILE_LIMIT 1024 /* Directory with more file than this get
ignored. */
static void tree(lua_State *L, const char *pathbuf) {
const char *dirbuf = lua_pushfstring (L, "%s/", pathbuf);
DIR *d = opendir(dirbuf);
if (!d)
luaL_error (L, "cannot read directory: %s", pathbuf);
lua_pop (L, 1);
lua_newtable (L);
struct dirent *entry;
int entries = 0;
while(entry = readdir(d)) { entries++; }
if (entries > TREE_FILE_LIMIT) {
closedir(d);
goto endls;
}
rewinddir(d);
int k = 1;
while ((entry = readdir(d)) != NULL) {
char *name = entry-> d_name;
char c0 = name[0], c1 = name[1];
if (!(c0 == '.' && (!c1 || (c1 == '.' && !name[2])))) { // quickly
skip . and ..
const char *filename = lua_pushfstring (L, "%s/%s", pathbuf, name);
struct stat s;
if (lstat(filename, &s) != -1) {
lua_pop (L, 1);
if (S_ISDIR(s.st_mode)) {
lua_newtable (L);
tree(L, filename);
lua_setfield (L, -2, name);
} else {
lua_pushstring (L, name);
lua_rawseti (L, -2, k);
k++;
}
}
}
}
closedir(d);
};
int get_tree(lua_State *L) {
const char *pathbuf = luaL_checkstring(L, 1);
lua_newtable (L);
tree(L, pathbuf);
lua_setfield (L, -2, pathbuf);
return 1;
}
Please note that I didn't test it and there could be some errors!!
Note also that there are no checks about the growing Lua stack, this
test should be added because the Lua C call does not check that
automatically.
I think the lua_pushfstring is very useful and it does suppress the
potential buffer overflow that you have in your application.
Best regards,
Francesco