aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortomas <tomas>2004-07-29 14:26:33 +0000
committertomas <tomas>2004-07-29 14:26:33 +0000
commit70052678b19e026a8db3ecb58824d6aa770ea589 (patch)
treeb68dfb62ee1eaf1b788ade7ba91a551118f5834c /src
parent8addf14a396466982f62503a6dfa5793a53b1b8e (diff)
downloadluafilesystem-70052678b19e026a8db3ecb58824d6aa770ea589.tar.gz
luafilesystem-70052678b19e026a8db3ecb58824d6aa770ea589.tar.bz2
luafilesystem-70052678b19e026a8db3ecb58824d6aa770ea589.zip
Substituicao nos nomes dos arquivos.
Diffstat (limited to 'src')
-rw-r--r--src/lfs.c351
-rw-r--r--src/lfs.h10
2 files changed, 361 insertions, 0 deletions
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 @@
1/*
2** File system manipulation library.
3** This library offers these functions:
4** lfs.attributes (filepath [, attributename])
5** lfs.chdir (path)
6** lfs.currentdir ()
7** lfs.dir (path)
8** lfs.mkdir (path)
9** lfs.lock (fh, mode)
10** lfs.unlock (fh)
11**
12** $Id: lfs.c,v 1.1 2004/07/29 14:26:33 tomas Exp $
13*/
14
15#include <errno.h>
16#include <stdio.h>
17#include <string.h>
18#include <time.h>
19
20#ifdef WIN32
21#include <direct.h>
22#include <io.h>
23#include <sys/locking.h>
24#else
25#include <unistd.h>
26#include <dirent.h>
27#include <fcntl.h>
28#include <sys/types.h>
29#include <sys/stat.h>
30#endif
31
32#include <lua.h>
33#include <lauxlib.h>
34#include <lualib.h>
35
36#include "lfs.h"
37
38/* Define 'strerror' for systems that do not implement it */
39#ifdef NO_STRERROR
40#define strerror(_) "System unable to describe the error"
41#endif
42
43/* Define 'getcwd' for systems that do not implement it */
44#ifdef NO_GETCWD
45#define getcwd(p,s) NULL
46#define getcwd_error "Function 'getcwd' not provided by system"
47#else
48#define getcwd_error strerror(errno)
49#endif
50
51#define DIR_METATABLE "directory metatable"
52#define MAX_DIR_LENGTH 1023
53#ifdef _WIN32
54typedef struct dir_data {
55 long hFile;
56 char pattern[MAX_DIR_LENGTH+1];
57} dir_data;
58#endif
59
60
61/*
62** This function changes the working (current) directory
63*/
64static int change_dir (lua_State *L) {
65 const char *path = luaL_checkstring(L, 1);
66 if (chdir(path))
67 luaL_error(L,"Unable to change working directory to '%s'\n%s\n",
68 path, chdir_error);
69 return 0;
70}
71
72/*
73** This function returns the current directory
74** If unable to get the current directory, it returns nil
75** and a string describing the error
76*/
77static int get_dir (lua_State *L) {
78 char path[255+2];
79 if (getcwd(path, 255) == NULL) {
80 lua_pushnil(L);
81 lua_pushstring(L, getcwd_error);
82 return 2;
83 }
84 else {
85 lua_pushstring(L, path);
86 return 1;
87 }
88}
89
90/*
91** Check if the given element on the stack is a file and returns it.
92*/
93static FILE *check_file (lua_State *L, int idx, const char *funcname) {
94 FILE **fh = (FILE **)luaL_checkudata (L, idx, "FILE*");
95 if (fh == NULL) {
96 luaL_error (L, "%s: not a file", funcname);
97 return 0;
98 } else if (*fh == NULL) {
99 luaL_error (L, "%s: closed file", funcname);
100 return 0;
101 } else
102 return *fh;
103}
104
105
106/*
107**
108*/
109static int _file_lock (lua_State *L, FILE *fh, const char *mode, const long start, long len, const char *funcname) {
110 int code;
111#ifdef WIN32
112 /* lkmode valid values are:
113 _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.
114 _LK_NBLCK Locks the specified bytes. If the bytes cannot be locked, the constant returns an error.
115 _LK_NBRLCK Same as _LK_NBLCK.
116 _LK_RLCK Same as _LK_LOCK.
117 _LK_UNLCK Unlocks the specified bytes, which must have been previously locked.
118
119 Regions should be locked only briefly and should be unlocked before closing a file or exiting the program.
120
121 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt__locking.asp
122 */
123 int lkmode;
124 switch (*mode) {
125 case 'r': lkmode = _LK_NBLCK; break;
126 case 'w': lkmode = _LK_NBLCK; break;
127 case 'u': lkmode = _LK_UNLCK; break;
128 default : luaL_error (L, "%s: invalid mode", funcname);
129 }
130 if (!len) {
131 fseek (fh, 0L, SEEK_END);
132 len = ftell (fh);
133 }
134 fseek (fh, start, SEEK_SET);
135 code = _locking (fileno(fh), lkmode, len);
136#else
137 struct flock f;
138 switch (*mode) {
139 case 'w': f.l_type = F_WRLCK; break;
140 case 'r': f.l_type = F_RDLCK; break;
141 case 'u': f.l_type = F_UNLCK; break;
142 default : luaL_error (L, "%s: invalid mode", funcname);
143 }
144 f.l_whence = SEEK_SET;
145 f.l_start = (off_t)start;
146 f.l_len = (off_t)len;
147 code = fcntl (fileno(fh), F_SETLK, &f);
148#endif
149 return (code != -1);
150}
151
152
153/*
154** Locks a file.
155** @param #1 File handle.
156** @param #2 String with lock mode ('w'rite, 'r'ead).
157** @param #3 Number with start position (optional).
158** @param #4 Number with length (optional).
159*/
160static int file_lock (lua_State *L) {
161 FILE *fh = check_file (L, 1, "lock");
162 const char *mode = luaL_checkstring (L, 2);
163 const long start = luaL_optlong (L, 3, 0);
164 long len = luaL_optlong (L, 4, 0);
165 if (_file_lock (L, fh, mode, start, len, "lock")) {
166 lua_pushboolean (L, 1);
167 return 1;
168 } else {
169 lua_pushboolean (L, 0);
170 lua_pushfstring (L, "%s", strerror(errno));
171 return 2;
172 }
173}
174
175
176/*
177** Unlocks a file.
178** @param #1 File handle.
179** @param #2 Number with start position (optional).
180** @param #3 Number with length (optional).
181*/
182static int file_unlock (lua_State *L) {
183 FILE *fh = check_file (L, 1, "unlock");
184 const long start = luaL_optlong (L, 2, 0);
185 long len = luaL_optlong (L, 3, 0);
186 if (_file_lock (L, fh, "u", start, len, "unlock")) {
187 lua_pushboolean (L, 1);
188 return 1;
189 } else {
190 lua_pushboolean (L, 0);
191 lua_pushfstring (L, "%s", strerror(errno));
192 return 2;
193 }
194}
195
196
197/*
198static void cgilua_sleep( lua_State *L )
199{
200 unsigned int usec = (unsigned int)luaL_check_number( L, 1 );
201
202#ifndef WIN32
203 sleep( (unsigned int)ceil( usec/1000.0 ));
204#else
205 Sleep( (DWORD)usec );
206#endif
207}
208
209static void cgilua_filesize( lua_State *L )
210{
211 struct stat info;
212 char *file = luaL_check_string( L, 1 );
213
214 if (stat(file, &info))
215 {
216 lua_pushnil( L );
217 lua_pushstring( L, "Cannot retrieve stat info from file" );
218 return;
219 }
220 lua_pushnumber(L, info.st_size);
221}
222*/
223
224static int make_dir (lua_State *L) {
225 const char *path = luaL_checkstring (L, 1);
226 int fail;
227#ifdef WIN32
228 int oldmask = umask (0);
229 fail = _mkdir (path);
230#else
231 mode_t oldmask = umask( (mode_t)0 );
232 fail = mkdir (path, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP |
233 S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH );
234#endif
235 lua_pushboolean (L, fail);
236 umask (oldmask);
237 return 1;
238}
239
240
241/*
242** Directory iterator
243*/
244static int dir_iter (lua_State *L) {
245#ifdef _WIN32
246 dir_data *d = (dir_data *)lua_touserdata (L, lua_upvalueindex (1));
247 struct _finddata_t c_file;
248 if (d->hFile == 0L) { /* first entry */
249 if ((d->hFile = _findfirst (d->pattern, &c_file)) == -1L) {
250 lua_pushnil (L);
251 lua_pushstring (L, strerror (errno));
252 return 2;
253 } else {
254 lua_pushstring (L, c_file.name);
255 return 1;
256 }
257 } else { /* next entry */
258 if (_findnext (d->hFile, &c_file) == -1L)
259 return 0;
260 else {
261 lua_pushstring (L, c_file.name);
262 return 1;
263 }
264 }
265#else
266 DIR *d = *(DIR **) lua_touserdata (L, lua_upvalueindex (1));
267 struct dirent *entry;
268 if ((entry = readdir (d)) != NULL) {
269 lua_pushstring (L, entry->d_name);
270 return 1;
271 }
272 else
273 return 0;
274#endif
275}
276
277
278/*
279** Closes directory iterators
280*/
281static int dir_close (lua_State *L) {
282#ifdef _WIN32
283 dir_data *d = (dir_data *)lua_touserdata (L, 1);
284 if (d->hFile) {
285 _findclose (d->hFile);
286 }
287#else
288 DIR *d = *(DIR **)lua_touserdata (L, 1);
289 if (d)
290 closedir (d);
291#endif
292 return 0;
293}
294
295
296/*
297** Factory of directory iterators
298*/
299static int dir_iter_factory (lua_State *L) {
300 const char *path = luaL_checkstring (L, 1);
301#ifdef _WIN32
302 dir_data *dir = (dir_data *) lua_newuserdata (L, sizeof(dir_data));
303 dir->hFile = 0L;
304 if (strlen(path) > MAX_DIR_LENGTH)
305 luaL_error (L, "path too long: %s", path);
306 else
307 sprintf (dir->pattern, "%s/*", path);
308 luaL_getmetatable (L, DIR_METATABLE);
309 lua_setmetatable (L, -2);
310#else
311 DIR **d = (DIR **) lua_newuserdata (L, sizeof(DIR *));
312 luaL_getmetatable (L, DIR_METATABLE);
313 lua_setmetatable (L, -2);
314 *d = opendir (path);
315 if (*d == NULL)
316 luaL_error (L, "cannot open %s: %s", path, strerror (errno));
317#endif
318 lua_pushcclosure (L, dir_iter, 1);
319 return 1;
320}
321
322
323/*
324** Creates directory metatable.
325*/
326static int dir_create_meta (lua_State *L) {
327 luaL_newmetatable (L, DIR_METATABLE);
328 /* set its __gc field */
329 lua_pushstring (L, "__gc");
330 lua_pushcfunction (L, dir_close);
331 lua_settable (L, -3);
332
333 return 1;
334}
335
336
337static const struct luaL_reg fslib[] = {
338 {"chdir", change_dir},
339 {"currentdir", get_dir},
340 {"dir", dir_iter_factory},
341 {"lock", file_lock},
342 {"mkdir", make_dir},
343 {"unlock", file_unlock},
344 {NULL, NULL},
345};
346
347int luaopen_lfs (lua_State *L) {
348 dir_create_meta (L);
349 luaL_openlib (L, "lfs", fslib, 0);
350 return 1;
351}
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 @@
1/* Define 'chdir' for systems that do not implement it */
2/* $Id: lfs.h,v 1.1 2004/07/29 14:26:33 tomas Exp $ */
3#ifdef NO_CHDIR
4#define chdir(p) (-1)
5#define chdir_error "Function 'chdir' not provided by system"
6#else
7#define chdir_error strerror(errno)
8#endif
9
10int luaopen_lfs (lua_State *L);