This source file includes following definitions.
- os_pushresult
- os_execute
- os_remove
- os_rename
- os_tmpname
- os_getenv
- os_clock
- setfield
- setboolfield
- getboolfield
- getfield
- os_date
- os_time
- os_difftime
- os_difftime
- os_setlocale
- os_exit
- os_mkdir
- get_table_optbool
- os_listdir
- idir_iter
- idir_gc
- os_idir
- idir_register
- os_stat
- os_utime
- luaopen_os
1
2
3
4
5
6
7 #include <errno.h>
8 #include <locale.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <time.h>
12 #include <dirent.h>
13 #ifdef HOST_LUA
14 #include <sys/stat.h>
15 #include <utime.h>
16 #endif
17
18 #define loslib_c
19 #define LUA_LIB
20
21 #include "lua.h"
22
23 #include "lauxlib.h"
24 #include "lualib.h"
25
26
27 static int os_pushresult (lua_State *L, int i, const char *filename) {
28 int en = errno;
29 if (i) {
30 lua_pushboolean(L, 1);
31 return 1;
32 }
33 else {
34 lua_pushnil(L);
35 lua_pushfstring(L, "%s: %s", filename, strerror(en));
36 lua_pushinteger(L, en);
37 return 3;
38 }
39 }
40
41
42 #ifdef HOST_LUA
43 static int os_execute (lua_State *L) {
44 lua_pushinteger(L, system(luaL_optstring(L, 1, NULL)));
45 return 1;
46 }
47 #endif
48
49
50 static int os_remove (lua_State *L) {
51 const char *filename = luaL_checkstring(L, 1);
52 return os_pushresult(L, remove(filename) == 0, filename);
53 }
54
55
56 static int os_rename (lua_State *L) {
57 const char *fromname = luaL_checkstring(L, 1);
58 const char *toname = luaL_checkstring(L, 2);
59 return os_pushresult(L, rename(fromname, toname) == 0, fromname);
60 }
61
62
63
64 #if 0
65 static int os_tmpname (lua_State *L) {
66 char buff[LUA_TMPNAMBUFSIZE];
67 int err;
68 lua_tmpnam(buff, err);
69 if (err)
70 return luaL_error(L, "unable to generate a unique filename");
71 lua_pushstring(L, buff);
72 return 1;
73 }
74 #endif
75
76 #ifdef HOST_LUA
77 static int os_getenv (lua_State *L) {
78 lua_pushstring(L, getenv(luaL_checkstring(L, 1)));
79 return 1;
80 }
81 #endif
82
83 #if 0
84 static int os_clock (lua_State *L) {
85 lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
86 return 1;
87 }
88 #endif
89
90
91
92
93
94
95
96
97
98
99 static void setfield (lua_State *L, const char *key, int value) {
100 lua_pushinteger(L, value);
101 lua_setfield(L, -2, key);
102 }
103
104 static void setboolfield (lua_State *L, const char *key, int value) {
105 if (value < 0)
106 return;
107 lua_pushboolean(L, value);
108 lua_setfield(L, -2, key);
109 }
110
111 static int getboolfield (lua_State *L, const char *key) {
112 int res;
113 lua_getfield(L, -1, key);
114 res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1);
115 lua_pop(L, 1);
116 return res;
117 }
118
119
120 static int getfield (lua_State *L, const char *key, int d) {
121 int res;
122 lua_getfield(L, -1, key);
123 if (lua_isnumber(L, -1))
124 res = (int)lua_tointeger(L, -1);
125 else {
126 if (d < 0)
127 return luaL_error(L, "field " LUA_QS " missing in date table", key);
128 res = d;
129 }
130 lua_pop(L, 1);
131 return res;
132 }
133
134
135 static int os_date (lua_State *L) {
136 const char *s = luaL_optstring(L, 1, "%c");
137 time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL));
138 struct tm *stm;
139 if (*s == '!') {
140 #if 0
141
142
143
144 stm = gmtime(&t);
145 #endif
146 stm = localtime(&t);
147 s++;
148 }
149 else
150 stm = localtime(&t);
151 if (stm == NULL)
152 lua_pushnil(L);
153 else if (strcmp(s, "*t") == 0) {
154 lua_createtable(L, 0, 9);
155 setfield(L, "sec", stm->tm_sec);
156 setfield(L, "min", stm->tm_min);
157 setfield(L, "hour", stm->tm_hour);
158 setfield(L, "day", stm->tm_mday);
159 setfield(L, "month", stm->tm_mon+1);
160 setfield(L, "year", stm->tm_year+1900);
161 setfield(L, "wday", stm->tm_wday+1);
162 setfield(L, "yday", stm->tm_yday+1);
163 setboolfield(L, "isdst", stm->tm_isdst);
164 }
165 else {
166 char cc[3];
167 luaL_Buffer b;
168 cc[0] = '%'; cc[2] = '\0';
169 luaL_buffinit(L, &b);
170 for (; *s; s++) {
171 if (*s != '%' || *(s + 1) == '\0')
172 luaL_addchar(&b, *s);
173 else {
174 size_t reslen;
175 char buff[200];
176 cc[1] = *(++s);
177 reslen = strftime(buff, sizeof(buff), cc, stm);
178 luaL_addlstring(&b, buff, reslen);
179 }
180 }
181 luaL_pushresult(&b);
182 }
183 return 1;
184 }
185
186
187 static int os_time (lua_State *L) {
188 time_t t;
189 if (lua_isnoneornil(L, 1))
190 t = time(NULL);
191 else {
192 struct tm ts;
193 luaL_checktype(L, 1, LUA_TTABLE);
194 lua_settop(L, 1);
195 ts.tm_sec = getfield(L, "sec", 0);
196 ts.tm_min = getfield(L, "min", 0);
197 ts.tm_hour = getfield(L, "hour", 12);
198 ts.tm_mday = getfield(L, "day", -1);
199 ts.tm_mon = getfield(L, "month", -1) - 1;
200 ts.tm_year = getfield(L, "year", -1) - 1900;
201 ts.tm_isdst = getboolfield(L, "isdst");
202 t = mktime(&ts);
203 }
204 if (t == (time_t)(-1))
205 lua_pushnil(L);
206 else
207 lua_pushnumber(L, (lua_Number)t);
208 return 1;
209 }
210
211
212 #if 0
213 static int os_difftime (lua_State *L) {
214 lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
215 (time_t)(luaL_optnumber(L, 2, 0))));
216 return 1;
217 }
218 #endif
219 static int os_difftime (lua_State *L) {
220 lua_pushnumber(L, (time_t)(luaL_checknumber(L, 1) - (time_t)(luaL_optnumber(L, 2, 0))));
221 return 1;
222 }
223
224
225
226
227 #if 0
228 static int os_setlocale (lua_State *L) {
229 static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
230 LC_NUMERIC, LC_TIME};
231 static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
232 "numeric", "time", NULL};
233 const char *l = luaL_optstring(L, 1, NULL);
234 int op = luaL_checkoption(L, 2, "all", catnames);
235 lua_pushstring(L, setlocale(cat[op], l));
236 return 1;
237 }
238 #endif
239
240 #ifdef HOST_LUA
241 static int os_exit (lua_State *L) {
242 exit(luaL_optint(L, 1, EXIT_SUCCESS));
243 }
244 #endif
245
246
247 static int os_mkdir (lua_State *L) {
248 const char *dirname = luaL_checkstring(L, 1);
249 #if defined(HOST_LUA) && !defined(_WIN32)
250 return os_pushresult(L, mkdir(dirname,0777) == 0, dirname);
251 #else
252 return os_pushresult(L, mkdir(dirname) == 0, dirname);
253 #endif
254 }
255
256
257 static int get_table_optbool(lua_State *L, int narg, const char *fname, int d)
258 {
259 int r;
260 lua_getfield(L, narg, fname);
261
262 if(lua_isnil(L,-1)) {
263 r=d;
264 } else {
265 r=lua_toboolean(L,-1);
266 }
267 lua_pop(L,1);
268 return r;
269 }
270
271
272
273
274
275
276
277
278 static int os_listdir (lua_State *L) {
279 #ifdef HOST_LUA
280
281 (void)L;
282 return 0;
283 #else
284 DIR *dir;
285 struct dirent *de;
286 const char *dirname = luaL_checkstring(L, 1);
287 int all=0,od_flags=OPENDIR_FL_CHDK_LFN;
288 if(lua_istable(L,2)) {
289 all=get_table_optbool(L,2,"showall",0);
290 od_flags=(get_table_optbool(L,2,"chdklfn",1))?OPENDIR_FL_CHDK_LFN:OPENDIR_FL_NONE;
291 } else {
292 all=lua_toboolean(L, 2);
293 }
294 int i=1;
295 dir = opendir_chdk(dirname,od_flags);
296 if(!dir)
297 return os_pushresult(L, 0 , dirname);
298 lua_newtable(L);
299 while((de = readdir(dir))) {
300 if(!all && (de->d_name[0] == '\xE5' || (strcmp(de->d_name,".")==0) || (strcmp(de->d_name,"..")==0)))
301 continue;
302 lua_pushinteger(L, i);
303 lua_pushstring(L, de->d_name);
304 lua_settable(L,-3);
305 ++i;
306 }
307 closedir(dir);
308 return 1;
309 #endif
310 }
311
312 #define IDIR_META "chdk_idir_meta"
313
314 typedef struct {
315 DIR *dir;
316 int all;
317 } idir_udata_t;
318
319 static int idir_iter(lua_State *L) {
320 struct dirent *de;
321 idir_udata_t *ud = (idir_udata_t *)luaL_checkudata(L,1,IDIR_META);
322
323 if(!ud->dir) {
324 return 0;
325 }
326
327
328 if(lua_type(L, 2) == LUA_TBOOLEAN && lua_toboolean(L,2) == 0) {
329 closedir(ud->dir);
330 ud->dir=NULL;
331 return 0;
332 }
333 while((de = readdir(ud->dir))) {
334
335 if(!ud->all && (de->d_name[0] == '\xE5' || (strcmp(de->d_name,".")==0) || (strcmp(de->d_name,"..")==0))) {
336 continue;
337 }
338 break;
339 }
340 if(de) {
341 lua_pushstring(L, de->d_name);
342 return 1;
343 } else {
344 closedir(ud->dir);
345 ud->dir=NULL;
346 return 0;
347 }
348 }
349
350 static int idir_gc(lua_State *L) {
351 idir_udata_t *ud = (idir_udata_t *)luaL_checkudata(L,1,IDIR_META);
352 if(ud->dir) {
353 closedir(ud->dir);
354 }
355 return 0;
356 }
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387 static int os_idir (lua_State *L) {
388 #ifdef HOST_LUA
389
390 (void)L;
391 return 0;
392 #else
393 const char *dirname = luaL_checkstring(L, 1);
394 int all=0,od_flags=OPENDIR_FL_CHDK_LFN;
395 if(lua_istable(L,2)) {
396 all=get_table_optbool(L,2,"showall",0);
397 od_flags=(get_table_optbool(L,2,"chdklfn",1))?OPENDIR_FL_CHDK_LFN:OPENDIR_FL_NONE;
398 } else {
399 all=lua_toboolean(L, 2);
400 }
401
402 lua_pushcfunction(L, idir_iter);
403
404 idir_udata_t *ud = lua_newuserdata(L,sizeof(idir_udata_t));
405 ud->dir = opendir_chdk(dirname,od_flags);
406
407 ud->all = all;
408
409 luaL_getmetatable(L, IDIR_META);
410 lua_setmetatable(L, -2);
411 return 2;
412 #endif
413 }
414
415 static const luaL_Reg idir_meta_methods[] = {
416 {"__gc", idir_gc},
417 {NULL, NULL}
418 };
419 static void idir_register(lua_State *L) {
420 luaL_newmetatable(L,IDIR_META);
421 luaL_register(L, NULL, idir_meta_methods);
422 }
423
424
425
426 static int os_stat (lua_State *L) {
427 struct stat st;
428 const char *name = luaL_checkstring(L, 1);
429 int result = stat(name,&st);
430 if (result==0) {
431 lua_createtable(L, 0, 6);
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446 setfield(L,"size",st.st_size);
447
448
449
450 setfield(L,"mtime",st.st_mtime);
451 setfield(L,"ctime",st.st_ctime);
452 #ifdef HOST_LUA
453
454
455 #define DOS_ATTR_DIRECTORY 0x10
456 #ifndef CAM_DRYOS_2_3_R39
457 setfield(L,"blksize",512);
458 setfield(L,"blocks",(st.st_size/512) + (st.st_size%512)?1:0);
459 #endif
460 if ( S_ISDIR(st.st_mode) ) {
461 setfield(L,"attrib",DOS_ATTR_DIRECTORY);
462 setboolfield(L,"is_dir",1);
463 setboolfield(L,"is_file",0);
464 }
465 else {
466 setboolfield(L,"is_dir",0);
467 setfield(L,"attrib",0);
468 if S_ISREG(st.st_mode) {
469 setboolfield(L,"is_file",1);
470 }
471 }
472 #else
473
474
475
476
477 setfield(L,"attrib",st.st_attrib);
478
479
480 setboolfield(L,"is_dir",st.st_attrib & DOS_ATTR_DIRECTORY);
481 setboolfield(L,"is_file",!(st.st_attrib & (DOS_ATTR_DIRECTORY | DOS_ATTR_VOL_LABEL)));
482 #endif
483 #if 0
484 setfield(L,"reserved1",st.reserved1);
485 setfield(L,"reserved2",st.reserved2);
486 setfield(L,"reserved3",st.reserved3);
487 setfield(L,"reserved4",st.reserved4);
488 setfield(L,"reserved5",st.reserved5);
489 setfield(L,"reserved6",st.reserved6);
490 #endif
491 return 1;
492 }
493 else {
494 int en = errno;
495 lua_pushnil(L);
496 lua_pushfstring(L, "%s: %s", name, strerror(en));
497 lua_pushinteger(L, en);
498 return 3;
499 }
500 }
501
502
503
504
505 static int os_utime (lua_State *L) {
506 const char *name = luaL_checkstring(L, 1);
507 struct utimbuf t;
508 t.modtime = luaL_optnumber(L, 2, time(NULL));
509 t.actime = luaL_optnumber(L, 3, time(NULL));
510 return os_pushresult(L, utime(name,&t) == 0, name);
511 }
512
513 static const luaL_Reg syslib[] = {
514 #if 0
515 {"clock", os_clock},
516 #endif
517 {"date", os_date},
518 {"difftime", os_difftime},
519 #ifdef HOST_LUA
520 {"execute", os_execute},
521 {"exit", os_exit},
522 {"getenv", os_getenv},
523 #endif
524 {"mkdir", os_mkdir},
525 {"listdir", os_listdir},
526 {"idir", os_idir},
527 {"stat", os_stat},
528 {"utime", os_utime},
529 {"remove", os_remove},
530 {"rename", os_rename},
531 #if 0
532 {"setlocale", os_setlocale},
533 #endif
534 {"time", os_time},
535 #if 0
536 {"tmpname", os_tmpname},
537 #endif
538 {NULL, NULL}
539 };
540
541
542
543
544
545 LUALIB_API int luaopen_os (lua_State *L) {
546 idir_register(L);
547 luaL_register(L, LUA_OSLIBNAME, syslib);
548 return 1;
549 }
550