1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-09 22:21:29 +00:00
Files
nmap/nse_fs.cc
david 20cf487b33 Replace the mix of spaces and tabs in the main NSE files with uniform two-space
indents, which seems to be the dominant style.
2008-11-18 21:11:27 +00:00

186 lines
5.1 KiB
C++

#ifndef WIN32
#include "dirent.h"
#endif
#include "errno.h"
#include "nse_macros.h"
#include "nse_fs.h"
#include "nmap.h"
#include "nmap_error.h"
#include "NmapOps.h"
extern NmapOps o;
static bool filename_is_absolute(const char *file) {
if (file[0] == '/')
return true;
#ifdef WIN32
if ((file[0] != '\0' && file[1] == ':') || file[0] == '\\')
return true;
#endif
return false;
}
/* This is simply the most portable way to check
* if a file has a given extension.
* The portability comes at the price of reduced
* flexibility.
*/
int nse_check_extension (const char* ext, const char* path)
{
int pathlen = strlen(path);
int extlen = strlen(ext);
if (extlen > pathlen || pathlen > MAX_FILENAME_LEN)
return 0;
else
return strcmp(path + pathlen - extlen, ext) == 0;
}
int nse_fetchfile(char *path, size_t path_len, const char *file) {
int type = nmap_fetchfile(path, path_len, file);
// lets look in <nmap>/scripts too
if(type == 0) {
std::string alt_path = std::string(SCRIPT_ENGINE_LUA_DIR) + std::string(file);
type = nmap_fetchfile(path, path_len, alt_path.c_str());
}
return type;
}
/* This is a modification of nse_fetchfile that first looks for an
* absolute file name.
*/
int nse_fetchfile_absolute(char *path, size_t path_len, const char *file) {
if (filename_is_absolute(file)) {
if (o.debugging > 1)
log_write(LOG_STDOUT, "%s: Trying absolute path %s\n", SCRIPT_ENGINE, file);
Strncpy(path, file, path_len);
return nmap_fileexistsandisreadable(file);
}
return nse_fetchfile(path, path_len, file);
}
#ifdef WIN32
int nse_scandir (lua_State *L) {
HANDLE dir;
WIN32_FIND_DATA entry;
std::string path;
BOOL morefiles = FALSE;
const char *dirname = luaL_checkstring(L, 1);
int files_or_dirs = luaL_checkint(L, 2);
lua_createtable(L, 100, 0); // 100 files average
dir = FindFirstFile((std::string(dirname) + "\\*").c_str(), &entry);
if (dir == INVALID_HANDLE_VALUE)
{
error("%s: No files in '%s\\*'", SCRIPT_ENGINE, dirname);
return SCRIPT_ENGINE_ERROR;
}
while(!(morefiles == FALSE && GetLastError() == ERROR_NO_MORE_FILES)) {
// if we are looking for files and this file doesn't end with .nse or
// is a directory, then we don't look further at it
if(files_or_dirs == FILES) {
if(!((nse_check_extension(SCRIPT_ENGINE_EXTENSION, entry.cFileName))
&& !(entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
)) {
morefiles = FindNextFile(dir, &entry);
continue;
}
// if we are looking for dirs and this dir
// isn't a directory, then we don't look further at it
} else if(files_or_dirs == DIRS) {
if(!(entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
morefiles = FindNextFile(dir, &entry);
continue;
}
// they have passed an invalid value for files_or_dirs
} else {
fatal("%s: In: %s:%i This should never happen.",
SCRIPT_ENGINE, __FILE__, __LINE__);
}
// otherwise we add it to the results
// we assume that dirname ends with a directory separator of some kind
path = std::string(dirname) + "\\" + std::string(entry.cFileName);
lua_pushstring(L, path.c_str());
lua_rawseti(L, -2, lua_objlen(L, -2) + 1);
morefiles = FindNextFile(dir, &entry);
}
return 1;
}
#else
int nse_scandir (lua_State *L) {
DIR* dir;
struct dirent* entry;
struct stat stat_entry;
const char *dirname = luaL_checkstring(L, 1);
int files_or_dirs = luaL_checkint(L, 2);
lua_createtable(L, 100, 0); // 100 files average
dir = opendir(dirname);
if(dir == NULL) {
error("%s: Could not open directory '%s'.", SCRIPT_ENGINE, dirname);
return SCRIPT_ENGINE_ERROR;
}
// note that if there is a symlink in the dir, we have to rely on
// the .nse extension
// if they provide a symlink to a dir which ends with .nse, things
// break :/
while((entry = readdir(dir)) != NULL) {
std::string path = std::string(dirname) + "/" + std::string(entry->d_name);
if(stat(path.c_str(), &stat_entry) != 0)
fatal("%s: In: %s:%i This should never happen.",
SCRIPT_ENGINE, __FILE__, __LINE__);
// if we are looking for files and this file doesn't end with .nse and
// isn't a file or a link, then we don't look further at it
if(files_or_dirs == FILES) {
if(!(nse_check_extension(SCRIPT_ENGINE_EXTENSION, entry->d_name)
&& (S_ISREG(stat_entry.st_mode)
|| S_ISLNK(stat_entry.st_mode))
)) {
continue;
}
// if we are looking for dirs and this dir
// isn't a dir or a link, then we don't look further at it
} else if(files_or_dirs == DIRS) {
if(!(S_ISDIR(stat_entry.st_mode)
|| S_ISLNK(stat_entry.st_mode)
)) {
continue;
}
// they have passed an invalid value for files_or_dirs
} else {
fatal("%s: In: %s:%i This should never happen.",
SCRIPT_ENGINE, __FILE__, __LINE__);
}
// otherwise we add it to the results
lua_pushstring(L, path.c_str());
lua_rawseti(L, -2, lua_objlen(L, -2) + 1);
}
closedir(dir);
return 1;
}
#endif