diff options
Diffstat (limited to 'apps/plugins/lua/luadir.c')
-rw-r--r-- | apps/plugins/lua/luadir.c | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/apps/plugins/lua/luadir.c b/apps/plugins/lua/luadir.c new file mode 100644 index 0000000000..730c40ce22 --- /dev/null +++ b/apps/plugins/lua/luadir.c | |||
@@ -0,0 +1,138 @@ | |||
1 | /* | ||
2 | * Based on LuaFileSystem : http://www.keplerproject.org/luafilesystem | ||
3 | * | ||
4 | * Copyright © 2003 Kepler Project. | ||
5 | * | ||
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
7 | * of this software and associated documentation files (the "Software"), | ||
8 | * to deal in the Software without restriction, including without limitation | ||
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
10 | * and/or sell copies of the Software, and to permit persons to whom the | ||
11 | * Software is furnished to do so, subject to the following conditions: | ||
12 | * | ||
13 | * The above copyright notice and this permission notice shall be included in | ||
14 | * all copies or substantial portions of the Software. | ||
15 | * | ||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
22 | * OTHER DEALINGS IN THE SOFTWARE. | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | #include "plugin.h" | ||
27 | #include "rocklibc.h" | ||
28 | |||
29 | #include "lauxlib.h" | ||
30 | #include "luadir.h" | ||
31 | |||
32 | #define DIR_METATABLE "directory metatable" | ||
33 | typedef struct dir_data { | ||
34 | int closed; | ||
35 | DIR *dir; | ||
36 | } dir_data; | ||
37 | |||
38 | static int make_dir (lua_State *L) { | ||
39 | const char *path = luaL_checkstring (L, 1); | ||
40 | lua_pushboolean (L, !rb->mkdir(path)); | ||
41 | return 1; | ||
42 | } | ||
43 | |||
44 | static int remove_dir (lua_State *L) { | ||
45 | const char *path = luaL_checkstring (L, 1); | ||
46 | lua_pushboolean (L, !rb->rmdir (path)); | ||
47 | return 1; | ||
48 | } | ||
49 | |||
50 | /* | ||
51 | ** Directory iterator | ||
52 | */ | ||
53 | static int dir_iter (lua_State *L) { | ||
54 | struct dirent *entry; | ||
55 | dir_data *d = (dir_data *)luaL_checkudata (L, 1, DIR_METATABLE); | ||
56 | luaL_argcheck (L, !d->closed, 1, "closed directory"); | ||
57 | |||
58 | if ((entry = rb->readdir (d->dir)) != NULL) { | ||
59 | lua_pushstring (L, entry->d_name); | ||
60 | lua_pushboolean (L, entry->attribute & ATTR_DIRECTORY); | ||
61 | return 2; | ||
62 | } else { | ||
63 | /* no more entries => close directory */ | ||
64 | rb->closedir (d->dir); | ||
65 | d->closed = 1; | ||
66 | return 0; | ||
67 | } | ||
68 | } | ||
69 | |||
70 | |||
71 | /* | ||
72 | ** Closes directory iterators | ||
73 | */ | ||
74 | static int dir_close (lua_State *L) { | ||
75 | dir_data *d = (dir_data *)lua_touserdata (L, 1); | ||
76 | |||
77 | if (!d->closed && d->dir) { | ||
78 | rb->closedir (d->dir); | ||
79 | d->closed = 1; | ||
80 | } | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | |||
86 | /* | ||
87 | ** Factory of directory iterators | ||
88 | */ | ||
89 | static int dir_iter_factory (lua_State *L) { | ||
90 | const char *path = luaL_checkstring (L, 1); | ||
91 | dir_data *d; | ||
92 | lua_pushcfunction (L, dir_iter); | ||
93 | d = (dir_data *) lua_newuserdata (L, sizeof(dir_data)); | ||
94 | d->closed = 0; | ||
95 | |||
96 | luaL_getmetatable (L, DIR_METATABLE); | ||
97 | lua_setmetatable (L, -2); | ||
98 | d->dir = rb->opendir (path); | ||
99 | if (d->dir == NULL) | ||
100 | luaL_error (L, "cannot open %s: %d", path, errno); | ||
101 | |||
102 | return 2; | ||
103 | } | ||
104 | |||
105 | |||
106 | /* | ||
107 | ** Creates directory metatable. | ||
108 | */ | ||
109 | static int dir_create_meta (lua_State *L) { | ||
110 | luaL_newmetatable (L, DIR_METATABLE); | ||
111 | /* set its __gc field */ | ||
112 | lua_pushstring (L, "__index"); | ||
113 | lua_newtable(L); | ||
114 | lua_pushstring (L, "next"); | ||
115 | lua_pushcfunction (L, dir_iter); | ||
116 | lua_settable(L, -3); | ||
117 | lua_pushstring (L, "close"); | ||
118 | lua_pushcfunction (L, dir_close); | ||
119 | lua_settable(L, -3); | ||
120 | lua_settable (L, -3); | ||
121 | lua_pushstring (L, "__gc"); | ||
122 | lua_pushcfunction (L, dir_close); | ||
123 | lua_settable (L, -3); | ||
124 | return 1; | ||
125 | } | ||
126 | |||
127 | static const struct luaL_reg fslib[] = { | ||
128 | {"dir", dir_iter_factory}, | ||
129 | {"mkdir", make_dir}, | ||
130 | {"rmdir", remove_dir}, | ||
131 | {NULL, NULL}, | ||
132 | }; | ||
133 | |||
134 | int luaopen_luadir (lua_State *L) { | ||
135 | dir_create_meta (L); | ||
136 | luaL_register (L, LUA_DIRLIBNAME, fslib); | ||
137 | return 1; | ||
138 | } | ||