diff options
Diffstat (limited to '')
-rw-r--r-- | nse_fs.cc | 300 |
1 files changed, 300 insertions, 0 deletions
diff --git a/nse_fs.cc b/nse_fs.cc new file mode 100644 index 0000000..b1548af --- /dev/null +++ b/nse_fs.cc @@ -0,0 +1,300 @@ +/* +** Note: this is a port of LuaFileSystem for the +** Nmap project (https://nmap.org). +** Many functions have been removed, because we only really +** need: dir, mkdir, rmdir and possibly link. + */ + +/* + * LuaFileSystem library: + * by Roberto Ierusalimschy, Andre Carregal and Tomas Guisasola + * as part of the Kepler Project. + * LuaFileSystem is currently maintained by Fabio Mascarenhas. + * + * Copyright Kepler Project 2003 (http://www.keplerproject.org/luafilesystem) + * + * LuaFileSystem is a Lua library developed to complement the set + * of functions related to file systems offered by the standard + * Lua distribution. + * LuaFileSystem offers a portable way to access the underlying + * directory structure and file attributes. + * + * LuaFileSystem is free software and uses the same license as Lua 5.1. + * + * the most recent copy can be found at + * http://www.keplerproject.org/luafilesystem/ + * + **/ + +#include "nse_lua.h" + +#include "nmap.h" +#include "nse_fs.h" +#include "nse_utility.h" +#include "nmap_error.h" +#include "NmapOps.h" + +#ifdef _WIN32 +#include <direct.h> +#include <sys/utime.h> +#else +#include <dirent.h> +#include <utime.h> +#endif + +#include <errno.h> +#include <string.h> + +#include <string> + +#define DIR_METATABLE "directory metatable" + +#ifndef MAX_PATH +#define MAX_PATH 2048 +#endif + +/* Define 'strerror' for systems that do not implement it */ +#ifdef NO_STRERROR +#define strerror(_) "System unable to describe the error" +#endif + +typedef struct dir_data { + int closed; +#ifdef _WIN32 + long hFile; + char pattern[MAX_PATH+1]; +#else + DIR *dir; +#endif +} dir_data; + +/* +** Utility functions +*/ +static int pusherror(lua_State *L, const char *info) +{ + lua_pushnil(L); + if (info==NULL) + lua_pushstring(L, strerror(errno)); + else + lua_pushfstring(L, "%s: %s", info, strerror(errno)); + lua_pushinteger(L, errno); + return 3; +} + +static int pushresult(lua_State *L, int i, const char *info) +{ + if (i==-1) + return pusherror(L, info); + lua_pushboolean(L, true); + return 1; +} + +/* +** Creates a link. +** @param #1 Object to link to. +** @param #2 Name of link. +** @param #3 True if link is symbolic (optional). +*/ +static int make_link(lua_State *L) +{ +#ifndef _WIN32 + const char *oldpath = luaL_checkstring(L, 1); + const char *newpath = luaL_checkstring(L, 2); + return pushresult(L, + (lua_toboolean(L,3) ? symlink : link)(oldpath, newpath), NULL); +#else + return pusherror(L, "make_link is not supported on Windows"); +#endif +} + +/* +** Creates a directory. +** @param #1 Directory path. +*/ +static int make_dir (lua_State *L) { + const char *path = luaL_checkstring (L, 1); + int fail; +#ifdef _WIN32 + fail = _mkdir (path); +#else + fail = mkdir (path, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | + S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH ); +#endif + if (fail) { + lua_pushnil (L); + lua_pushfstring (L, "%s", strerror(errno)); + return 2; + } + lua_pushboolean (L, 1); + return 1; +} + +/* +** Removes a directory. +** @param #1 Directory path. +*/ +static int remove_dir (lua_State *L) { + const char *path = luaL_checkstring (L, 1); + int fail; + + fail = rmdir (path); + + if (fail) { + lua_pushnil (L); + lua_pushfstring (L, "%s", strerror(errno)); + return 2; + } + lua_pushboolean (L, 1); + return 1; +} + +/* +** Directory iterator +*/ +static int dir_iter (lua_State *L) { +#ifdef _WIN32 + struct _finddata_t c_file; +#else + struct dirent *entry; +#endif + dir_data *d = (dir_data *)luaL_checkudata (L, 1, DIR_METATABLE); + luaL_argcheck (L, d->closed == 0, 1, "closed directory"); +#ifdef _WIN32 + if (d->hFile == 0L) { /* first entry */ + if ((d->hFile = _findfirst (d->pattern, &c_file)) == -1L) { + lua_pushnil (L); + lua_pushstring (L, strerror (errno)); + d->closed = 1; + return 2; + } else { + lua_pushstring (L, c_file.name); + return 1; + } + } else { /* next entry */ + if (_findnext (d->hFile, &c_file) == -1L) { + /* no more entries => close directory */ + _findclose (d->hFile); + d->closed = 1; + return 0; + } else { + lua_pushstring (L, c_file.name); + return 1; + } + } +#else + if ((entry = readdir (d->dir)) != NULL) { + lua_pushstring (L, entry->d_name); + return 1; + } else { + /* no more entries => close directory */ + closedir (d->dir); + d->closed = 1; + return 0; + } +#endif +} + +/* +** Closes directory iterators +*/ +static int dir_close (lua_State *L) { + dir_data *d = (dir_data *)lua_touserdata (L, 1); +#ifdef _WIN32 + if (!d->closed && d->hFile) { + _findclose(d->hFile); + } +#else + if (!d->closed && d->dir) { + closedir(d->dir); + } +#endif + d->closed = 1; + return 0; +} + +/* +** Factory of directory iterators +*/ +static int dir_iter_factory (lua_State *L) { + const char *path = luaL_checkstring (L, 1); + dir_data *d; + lua_pushcfunction (L, dir_iter); + d = (dir_data *) lua_newuserdata (L, sizeof(dir_data)); + luaL_getmetatable (L, DIR_METATABLE); + lua_setmetatable (L, -2); + d->closed = 0; +#ifdef _WIN32 + d->hFile = 0L; + if (strlen(path) > MAX_PATH-2) + luaL_error (L, "path too long: %s", path); + else + sprintf (d->pattern, "%s/*", path); +#else + d->dir = opendir (path); + if (d->dir == NULL) + luaL_error (L, "cannot open %s: %s", path, strerror (errno)); +#endif + return 2; +} + + +/* +** Creates directory metatable. +*/ +static int dir_create_meta (lua_State *L) { + luaL_newmetatable (L, DIR_METATABLE); + + /* Method table */ + lua_newtable(L); + lua_pushcfunction (L, dir_iter); + lua_setfield(L, -2, "next"); + lua_pushcfunction (L, dir_close); + lua_setfield(L, -2, "close"); + + /* Metamethods */ + lua_setfield(L, -2, "__index"); + lua_pushcfunction (L, dir_close); + lua_setfield (L, -2, "__gc"); + return 1; +} + +/* +** Assumes the table is on top of the stack. +*/ +static void set_info (lua_State *L) { + lua_pushliteral (L, "_COPYRIGHT"); + lua_pushliteral (L, "Copyright (C) 2003-2009 Kepler Project"); + lua_settable (L, -3); + lua_pushliteral (L, "_DESCRIPTION"); + lua_pushliteral (L, "LuaFileSystem is a Lua library developed to complement the set of functions related to file systems offered by the standard Lua distribution"); + lua_settable (L, -3); + lua_pushliteral (L, "_VERSION"); + lua_pushliteral (L, "LuaFileSystem 1.5.0"); + lua_settable (L, -3); +} + +static int get_path_separator(lua_State *L){ +#ifdef WIN32 + lua_pushstring(L, "\\"); +#else + lua_pushstring(L, "/"); +#endif + return 1; +} + +static const struct luaL_Reg fslib[] = { + {"dir", dir_iter_factory}, + {"link", make_link}, + {"mkdir", make_dir}, + {"rmdir", remove_dir}, + {"get_path_separator", get_path_separator}, + {NULL, NULL}, +}; + +LUALIB_API int luaopen_lfs(lua_State *L) { + dir_create_meta (L); + luaL_newlib(L, fslib); + set_info (L); + return 1; +} |