176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** Code implementing read only functionality copied from 376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** src/lfs.c at commit 2fd989cd6c777583be1c93616018c55b2cbb1bcf: 476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** 576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** LuaFileSystem 1.6.2 676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** Copyright 2003-2014 Kepler Project 776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** http://www.keplerproject.org/luafilesystem 876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** 976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** File system manipulation library. 1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** This library offers these functions: 1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** lfs.attributes (filepath [, attributename]) 1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** lfs.chdir (path) 1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** lfs.currentdir () 1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** lfs.dir (path) 1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** 1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** $Id: lfs.c,v 1.61 2009/07/04 02:10:16 mascarenhas Exp $ 1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman*/ 1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <dirent.h> 2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <errno.h> 2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <fcntl.h> 2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <string.h> 2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <sys/stat.h> 2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <sys/types.h> 2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <unistd.h> 2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "lua.h" 2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "lauxlib.h" 2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "lualib.h" 3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define chdir_error strerror(errno) 3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Size of path buffer string, stolen from pwd.c */ 3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifndef PATH_MAX 3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman# ifdef NAME_MAX 3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman# define PATH_MAX NAME_MAX 3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman# elif FILENAME_MAX 3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman# define PATH_MAX FILENAME_MAX 3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman# else 4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman# define PATH_MAX 256 4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman# endif /* NAME_MAX */ 4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif /* PATH_MAX */ 4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define DIR_METATABLE "directory metatable" 4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmantypedef struct dir_data { 4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int closed; 4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DIR *dir; 4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} dir_data; 5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define STAT_STRUCT struct stat 5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define STAT_FUNC stat_via_fstat 5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Emulate stat via fstat */ 5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanint stat_via_fstat (const char *path, struct stat *buf) 5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int fd = open (path, O_RDONLY); 5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (fd == -1) { 6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DIR *dir = opendir (path); 6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!dir) return -1; 6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman closedir (dir); 6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman buf->st_mode=S_IFDIR; 6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman buf->st_size=0; 6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (fstat (fd, buf) == -1) { 6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int err = errno; 6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman close (fd); 7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman errno = err; 7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return -1; 7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman close (fd); 7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** This function changes the working (current) directory 7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman*/ 8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int change_dir (lua_State *L) { 8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const char *path = luaL_checkstring(L, 1); 8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (chdir(path)) { 8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_pushnil (L); 8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_pushfstring (L,"Unable to change working directory to '%s'\n%s\n", 8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman path, chdir_error); 8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 2; 8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { 8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_pushboolean (L, 1); 8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 1; 9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** This function returns the current directory 9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** If unable to get the current directory, it returns nil 9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** and a string describing the error 9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman*/ 9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int get_dir (lua_State *L) { 10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman char *path; 10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Passing (NULL, 0) is not guaranteed to work. Use a temp buffer and size instead. */ 10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman char buf[PATH_MAX]; 10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((path = getcwd(buf, PATH_MAX)) == NULL) { 10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_pushnil(L); 10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_pushstring(L, strerror(errno)); 10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 2; 10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else { 10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_pushstring(L, path); 11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 1; 11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** Directory iterator 11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman*/ 11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int dir_iter (lua_State *L) { 11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct dirent *entry; 12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dir_data *d = (dir_data *)luaL_checkudata (L, 1, DIR_METATABLE); 12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luaL_argcheck (L, d->closed == 0, 1, "closed directory"); 12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ((entry = readdir (d->dir)) != NULL) { 12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_pushstring (L, entry->d_name); 12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 1; 12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { 12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* no more entries => close directory */ 12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman closedir (d->dir); 12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman d->closed = 1; 12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** Closes directory iterators 13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman*/ 13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int dir_close (lua_State *L) { 13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dir_data *d = (dir_data *)lua_touserdata (L, 1); 13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!d->closed && d->dir) { 14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman closedir (d->dir); 14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman d->closed = 1; 14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** Factory of directory iterators 14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman*/ 15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int dir_iter_factory (lua_State *L) { 15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const char *path = luaL_checkstring (L, 1); 15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dir_data *d; 15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_pushcfunction (L, dir_iter); 15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman d = (dir_data *) lua_newuserdata (L, sizeof(dir_data)); 15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luaL_getmetatable (L, DIR_METATABLE); 15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_setmetatable (L, -2); 15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman d->closed = 0; 15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman d->dir = opendir (path); 15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (d->dir == NULL) 16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luaL_error (L, "cannot open %s: %s", path, strerror (errno)); 16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 2; 16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** Creates directory metatable. 16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman*/ 16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int dir_create_meta (lua_State *L) { 16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luaL_newmetatable (L, DIR_METATABLE); 17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Method table */ 17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_newtable(L); 17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_pushcfunction (L, dir_iter); 17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_setfield(L, -2, "next"); 17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_pushcfunction (L, dir_close); 17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_setfield(L, -2, "close"); 17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Metamethods */ 17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_setfield(L, -2, "__index"); 18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_pushcfunction (L, dir_close); 18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_setfield (L, -2, "__gc"); 18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 1; 18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** Convert the inode protection mode to a string. 18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman*/ 18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic const char *mode2string (mode_t mode) { 19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( S_ISREG(mode) ) 19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return "file"; 19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else if ( S_ISDIR(mode) ) 19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return "directory"; 19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else if ( S_ISLNK(mode) ) 19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return "link"; 19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else if ( S_ISSOCK(mode) ) 19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return "socket"; 19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else if ( S_ISFIFO(mode) ) 19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return "named pipe"; 20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else if ( S_ISCHR(mode) ) 20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return "char device"; 20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else if ( S_ISBLK(mode) ) 20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return "block device"; 20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else 20576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return "other"; 20676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 20776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 20876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 20976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* inode protection mode */ 21076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void push_st_mode (lua_State *L, STAT_STRUCT *info) { 21176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_pushstring (L, mode2string (info->st_mode)); 21276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 21376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* file size, in bytes */ 21476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void push_st_size (lua_State *L, STAT_STRUCT *info) { 21576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_pushnumber (L, (lua_Number)info->st_size); 21676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 21776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void push_invalid (lua_State *L, STAT_STRUCT *info) { 21876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luaL_error(L, "invalid attribute name"); 21976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman info->st_size = 0; /* never reached */ 22076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 22176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 22276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmantypedef void (*_push_function) (lua_State *L, STAT_STRUCT *info); 22376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 22476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct _stat_members { 22576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const char *name; 22676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman _push_function push; 22776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 22876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 22976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct _stat_members members[] = { 23076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { "mode", push_st_mode }, 23176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { "size", push_st_size }, 23276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { NULL, push_invalid } 23376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 23476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 23576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 23676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** Get file or symbolic link information 23776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman*/ 23876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int _file_info_ (lua_State *L, int (*st)(const char*, STAT_STRUCT*)) { 23976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int i; 24076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman STAT_STRUCT info; 24176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const char *file = luaL_checkstring (L, 1); 24276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 24376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (st(file, &info)) { 24476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_pushnil (L); 24576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_pushfstring (L, "cannot obtain information from file `%s'", file); 24676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 2; 24776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 24876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (lua_isstring (L, 2)) { 24976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int v; 25076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const char *member = lua_tostring (L, 2); 25176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (strcmp (member, "mode") == 0) v = 0; 25276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifndef _WIN32 25376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else if (strcmp (member, "blocks") == 0) v = 11; 25476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else if (strcmp (member, "blksize") == 0) v = 12; 25576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif 25676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else /* look for member */ 25776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (v = 1; members[v].name; v++) 25876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (*members[v].name == *member) 25976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman break; 26076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* push member value and return */ 26176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman members[v].push (L, &info); 26276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 1; 26376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else if (!lua_istable (L, 2)) 26476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* creates a table if none is given */ 26576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_newtable (L); 26676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* stores all members in table on top of the stack */ 26776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = 0; members[i].name; i++) { 26876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_pushstring (L, members[i].name); 26976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman members[i].push (L, &info); 27076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman lua_rawset (L, -3); 27176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 27276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 1; 27376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 27476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 27576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 27676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 27776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman** Get file information using stat. 27876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman*/ 27976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int file_info (lua_State *L) { 28076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return _file_info_ (L, STAT_FUNC); 28176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 28276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 28376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 28476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic const struct luaL_Reg fslib[] = { 28576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman {"attributes", file_info}, 28676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman {"chdir", change_dir}, 28776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman {"currentdir", get_dir}, 28876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman {"dir", dir_iter_factory}, 28976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman {NULL, NULL}, 29076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 29176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 29276d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanLUALIB_API int luaopen_lfs (lua_State *L) { 29376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dir_create_meta (L); 29476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman luaL_newlib (L, fslib); 29576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 1; 29676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 297