From 70052678b19e026a8db3ecb58824d6aa770ea589 Mon Sep 17 00:00:00 2001 From: tomas Date: Thu, 29 Jul 2004 14:26:33 +0000 Subject: Substituicao nos nomes dos arquivos. --- src/lfs.c | 351 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lfs.h | 10 ++ 2 files changed, 361 insertions(+) create mode 100644 src/lfs.c create mode 100644 src/lfs.h (limited to 'src') diff --git a/src/lfs.c b/src/lfs.c new file mode 100644 index 0000000..d494dd3 --- /dev/null +++ b/src/lfs.c @@ -0,0 +1,351 @@ +/* +** File system manipulation library. +** This library offers these functions: +** lfs.attributes (filepath [, attributename]) +** lfs.chdir (path) +** lfs.currentdir () +** lfs.dir (path) +** lfs.mkdir (path) +** lfs.lock (fh, mode) +** lfs.unlock (fh) +** +** $Id: lfs.c,v 1.1 2004/07/29 14:26:33 tomas Exp $ +*/ + +#include +#include +#include +#include + +#ifdef WIN32 +#include +#include +#include +#else +#include +#include +#include +#include +#include +#endif + +#include +#include +#include + +#include "lfs.h" + +/* Define 'strerror' for systems that do not implement it */ +#ifdef NO_STRERROR +#define strerror(_) "System unable to describe the error" +#endif + +/* Define 'getcwd' for systems that do not implement it */ +#ifdef NO_GETCWD +#define getcwd(p,s) NULL +#define getcwd_error "Function 'getcwd' not provided by system" +#else +#define getcwd_error strerror(errno) +#endif + +#define DIR_METATABLE "directory metatable" +#define MAX_DIR_LENGTH 1023 +#ifdef _WIN32 +typedef struct dir_data { + long hFile; + char pattern[MAX_DIR_LENGTH+1]; +} dir_data; +#endif + + +/* +** This function changes the working (current) directory +*/ +static int change_dir (lua_State *L) { + const char *path = luaL_checkstring(L, 1); + if (chdir(path)) + luaL_error(L,"Unable to change working directory to '%s'\n%s\n", + path, chdir_error); + return 0; +} + +/* +** This function returns the current directory +** If unable to get the current directory, it returns nil +** and a string describing the error +*/ +static int get_dir (lua_State *L) { + char path[255+2]; + if (getcwd(path, 255) == NULL) { + lua_pushnil(L); + lua_pushstring(L, getcwd_error); + return 2; + } + else { + lua_pushstring(L, path); + return 1; + } +} + +/* +** Check if the given element on the stack is a file and returns it. +*/ +static FILE *check_file (lua_State *L, int idx, const char *funcname) { + FILE **fh = (FILE **)luaL_checkudata (L, idx, "FILE*"); + if (fh == NULL) { + luaL_error (L, "%s: not a file", funcname); + return 0; + } else if (*fh == NULL) { + luaL_error (L, "%s: closed file", funcname); + return 0; + } else + return *fh; +} + + +/* +** +*/ +static int _file_lock (lua_State *L, FILE *fh, const char *mode, const long start, long len, const char *funcname) { + int code; +#ifdef WIN32 + /* lkmode valid values are: + _LK_LOCK Locks the specified bytes. If the bytes cannot be locked, the program immediately tries again after 1 second. If, after 10 attempts, the bytes cannot be locked, the constant returns an error. + _LK_NBLCK Locks the specified bytes. If the bytes cannot be locked, the constant returns an error. + _LK_NBRLCK Same as _LK_NBLCK. + _LK_RLCK Same as _LK_LOCK. + _LK_UNLCK Unlocks the specified bytes, which must have been previously locked. + + Regions should be locked only briefly and should be unlocked before closing a file or exiting the program. + + http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt__locking.asp + */ + int lkmode; + switch (*mode) { + case 'r': lkmode = _LK_NBLCK; break; + case 'w': lkmode = _LK_NBLCK; break; + case 'u': lkmode = _LK_UNLCK; break; + default : luaL_error (L, "%s: invalid mode", funcname); + } + if (!len) { + fseek (fh, 0L, SEEK_END); + len = ftell (fh); + } + fseek (fh, start, SEEK_SET); + code = _locking (fileno(fh), lkmode, len); +#else + struct flock f; + switch (*mode) { + case 'w': f.l_type = F_WRLCK; break; + case 'r': f.l_type = F_RDLCK; break; + case 'u': f.l_type = F_UNLCK; break; + default : luaL_error (L, "%s: invalid mode", funcname); + } + f.l_whence = SEEK_SET; + f.l_start = (off_t)start; + f.l_len = (off_t)len; + code = fcntl (fileno(fh), F_SETLK, &f); +#endif + return (code != -1); +} + + +/* +** Locks a file. +** @param #1 File handle. +** @param #2 String with lock mode ('w'rite, 'r'ead). +** @param #3 Number with start position (optional). +** @param #4 Number with length (optional). +*/ +static int file_lock (lua_State *L) { + FILE *fh = check_file (L, 1, "lock"); + const char *mode = luaL_checkstring (L, 2); + const long start = luaL_optlong (L, 3, 0); + long len = luaL_optlong (L, 4, 0); + if (_file_lock (L, fh, mode, start, len, "lock")) { + lua_pushboolean (L, 1); + return 1; + } else { + lua_pushboolean (L, 0); + lua_pushfstring (L, "%s", strerror(errno)); + return 2; + } +} + + +/* +** Unlocks a file. +** @param #1 File handle. +** @param #2 Number with start position (optional). +** @param #3 Number with length (optional). +*/ +static int file_unlock (lua_State *L) { + FILE *fh = check_file (L, 1, "unlock"); + const long start = luaL_optlong (L, 2, 0); + long len = luaL_optlong (L, 3, 0); + if (_file_lock (L, fh, "u", start, len, "unlock")) { + lua_pushboolean (L, 1); + return 1; + } else { + lua_pushboolean (L, 0); + lua_pushfstring (L, "%s", strerror(errno)); + return 2; + } +} + + +/* +static void cgilua_sleep( lua_State *L ) +{ + unsigned int usec = (unsigned int)luaL_check_number( L, 1 ); + +#ifndef WIN32 + sleep( (unsigned int)ceil( usec/1000.0 )); +#else + Sleep( (DWORD)usec ); +#endif +} + +static void cgilua_filesize( lua_State *L ) +{ + struct stat info; + char *file = luaL_check_string( L, 1 ); + + if (stat(file, &info)) + { + lua_pushnil( L ); + lua_pushstring( L, "Cannot retrieve stat info from file" ); + return; + } + lua_pushnumber(L, info.st_size); +} +*/ + +static int make_dir (lua_State *L) { + const char *path = luaL_checkstring (L, 1); + int fail; +#ifdef WIN32 + int oldmask = umask (0); + fail = _mkdir (path); +#else + mode_t oldmask = umask( (mode_t)0 ); + fail = mkdir (path, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | + S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH ); +#endif + lua_pushboolean (L, fail); + umask (oldmask); + return 1; +} + + +/* +** Directory iterator +*/ +static int dir_iter (lua_State *L) { +#ifdef _WIN32 + dir_data *d = (dir_data *)lua_touserdata (L, lua_upvalueindex (1)); + struct _finddata_t c_file; + if (d->hFile == 0L) { /* first entry */ + if ((d->hFile = _findfirst (d->pattern, &c_file)) == -1L) { + lua_pushnil (L); + lua_pushstring (L, strerror (errno)); + return 2; + } else { + lua_pushstring (L, c_file.name); + return 1; + } + } else { /* next entry */ + if (_findnext (d->hFile, &c_file) == -1L) + return 0; + else { + lua_pushstring (L, c_file.name); + return 1; + } + } +#else + DIR *d = *(DIR **) lua_touserdata (L, lua_upvalueindex (1)); + struct dirent *entry; + if ((entry = readdir (d)) != NULL) { + lua_pushstring (L, entry->d_name); + return 1; + } + else + return 0; +#endif +} + + +/* +** Closes directory iterators +*/ +static int dir_close (lua_State *L) { +#ifdef _WIN32 + dir_data *d = (dir_data *)lua_touserdata (L, 1); + if (d->hFile) { + _findclose (d->hFile); + } +#else + DIR *d = *(DIR **)lua_touserdata (L, 1); + if (d) + closedir (d); +#endif + return 0; +} + + +/* +** Factory of directory iterators +*/ +static int dir_iter_factory (lua_State *L) { + const char *path = luaL_checkstring (L, 1); +#ifdef _WIN32 + dir_data *dir = (dir_data *) lua_newuserdata (L, sizeof(dir_data)); + dir->hFile = 0L; + if (strlen(path) > MAX_DIR_LENGTH) + luaL_error (L, "path too long: %s", path); + else + sprintf (dir->pattern, "%s/*", path); + luaL_getmetatable (L, DIR_METATABLE); + lua_setmetatable (L, -2); +#else + DIR **d = (DIR **) lua_newuserdata (L, sizeof(DIR *)); + luaL_getmetatable (L, DIR_METATABLE); + lua_setmetatable (L, -2); + *d = opendir (path); + if (*d == NULL) + luaL_error (L, "cannot open %s: %s", path, strerror (errno)); +#endif + lua_pushcclosure (L, dir_iter, 1); + return 1; +} + + +/* +** Creates directory metatable. +*/ +static int dir_create_meta (lua_State *L) { + luaL_newmetatable (L, DIR_METATABLE); + /* set its __gc field */ + lua_pushstring (L, "__gc"); + lua_pushcfunction (L, dir_close); + lua_settable (L, -3); + + return 1; +} + + +static const struct luaL_reg fslib[] = { + {"chdir", change_dir}, + {"currentdir", get_dir}, + {"dir", dir_iter_factory}, + {"lock", file_lock}, + {"mkdir", make_dir}, + {"unlock", file_unlock}, + {NULL, NULL}, +}; + +int luaopen_lfs (lua_State *L) { + dir_create_meta (L); + luaL_openlib (L, "lfs", fslib, 0); + return 1; +} diff --git a/src/lfs.h b/src/lfs.h new file mode 100644 index 0000000..67871f2 --- /dev/null +++ b/src/lfs.h @@ -0,0 +1,10 @@ +/* Define 'chdir' for systems that do not implement it */ +/* $Id: lfs.h,v 1.1 2004/07/29 14:26:33 tomas Exp $ */ +#ifdef NO_CHDIR +#define chdir(p) (-1) +#define chdir_error "Function 'chdir' not provided by system" +#else +#define chdir_error strerror(errno) +#endif + +int luaopen_lfs (lua_State *L); -- cgit v1.2.3-55-g6feb