Fix fprintf 64-bit format specifiers
[grub-extras.git] / lua / grub_lib.c
blob3d25d0208b14b768f4b0b1cbff5371b9970eadc8
1 /*
2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2009 Free Software Foundation, Inc.
5 * GRUB is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * GRUB is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
19 #include "lua.h"
20 #include "lauxlib.h"
21 #include "lualib.h"
22 #include "grub_lib.h"
24 #include <grub/env.h>
25 #include <grub/parser.h>
26 #include <grub/command.h>
27 #include <grub/normal.h>
28 #include <grub/file.h>
29 #include <grub/device.h>
31 #ifdef ENABLE_LUA_PCI
32 #include <grub/pci.h>
33 #endif
35 /* Updates the globals grub_errno and grub_msg, leaving their values on the
36 top of the stack, and clears grub_errno. When grub_errno is zero, grub_msg
37 is not left on the stack. The value returned is the number of values left on
38 the stack. */
39 static int
40 push_result (lua_State *state)
42 int saved_errno;
43 int num_results;
45 saved_errno = grub_errno;
46 grub_errno = 0;
48 /* Push once for setfield, and again to leave on the stack */
49 lua_pushinteger (state, saved_errno);
50 lua_pushinteger (state, saved_errno);
51 lua_setfield (state, LUA_GLOBALSINDEX, "grub_errno");
53 if (saved_errno)
55 /* Push once for setfield, and again to leave on the stack */
56 lua_pushstring (state, grub_errmsg);
57 lua_pushstring (state, grub_errmsg);
58 num_results = 2;
60 else
62 lua_pushnil (state);
63 num_results = 1;
66 lua_setfield (state, LUA_GLOBALSINDEX, "grub_errmsg");
68 return num_results;
71 /* Updates the globals grub_errno and grub_msg ( without leaving them on the
72 stack ), clears grub_errno, and returns the value of grub_errno before it
73 was cleared. */
74 static int
75 save_errno (lua_State *state)
77 int saved_errno;
79 saved_errno = grub_errno;
80 lua_pop(state, push_result(state));
82 return saved_errno;
85 static int
86 grub_lua_run (lua_State *state)
88 int n;
89 char **args;
90 const char *s;
92 s = luaL_checkstring (state, 1);
93 if ((! grub_parser_split_cmdline (s, 0, 0, &n, &args))
94 && (n >= 0))
96 grub_command_t cmd;
98 cmd = grub_command_find (args[0]);
99 if (cmd)
100 (cmd->func) (cmd, n-1, &args[1]);
101 else
102 grub_error (GRUB_ERR_FILE_NOT_FOUND, "command not found");
104 grub_free (args[0]);
105 grub_free (args);
108 return push_result (state);
111 static int
112 grub_lua_getenv (lua_State *state)
114 int n, i;
116 n = lua_gettop (state);
117 for (i = 1; i <= n; i++)
119 const char *name, *value;
121 name = luaL_checkstring (state, i);
122 value = grub_env_get (name);
123 if (value)
124 lua_pushstring (state, value);
125 else
126 lua_pushnil (state);
129 return n;
132 static int
133 grub_lua_setenv (lua_State *state)
135 const char *name, *value;
137 name = luaL_checkstring (state, 1);
138 value = luaL_checkstring (state, 2);
140 if (name[0])
141 grub_env_set (name, value);
143 return 0;
146 /* Helper for grub_lua_enum_device. */
147 static int
148 grub_lua_enum_device_iter (const char *name, void *data)
150 lua_State *state = data;
151 int result;
152 grub_device_t dev;
154 result = 0;
155 dev = grub_device_open (name);
156 if (dev)
158 grub_fs_t fs;
160 fs = grub_fs_probe (dev);
161 if (fs)
163 lua_pushvalue (state, 1);
164 lua_pushstring (state, name);
165 lua_pushstring (state, fs->name);
166 if (! fs->uuid)
167 lua_pushnil (state);
168 else
170 int err;
171 char *uuid;
173 err = fs->uuid (dev, &uuid);
174 if (err)
176 grub_errno = 0;
177 lua_pushnil (state);
179 else
181 lua_pushstring (state, uuid);
182 grub_free (uuid);
186 if (! fs->label)
187 lua_pushnil (state);
188 else
190 int err;
191 char *label = NULL;
193 err = fs->label (dev, &label);
194 if (err)
196 grub_errno = 0;
197 lua_pushnil (state);
199 else
201 if (label == NULL)
203 lua_pushnil (state);
205 else
207 lua_pushstring (state, label);
209 grub_free (label);
213 lua_call (state, 4, 1);
214 result = lua_tointeger (state, -1);
215 lua_pop (state, 1);
217 else
218 grub_errno = 0;
219 grub_device_close (dev);
221 else
222 grub_errno = 0;
224 return result;
227 static int
228 grub_lua_enum_device (lua_State *state)
230 luaL_checktype (state, 1, LUA_TFUNCTION);
231 grub_device_iterate (grub_lua_enum_device_iter, state);
232 return push_result (state);
235 static int
236 enum_file (const char *name, const struct grub_dirhook_info *info,
237 void *data)
239 int result;
240 lua_State *state = data;
242 lua_pushvalue (state, 1);
243 lua_pushstring (state, name);
244 lua_pushinteger (state, info->dir != 0);
245 lua_call (state, 2, 1);
246 result = lua_tointeger (state, -1);
247 lua_pop (state, 1);
249 return result;
252 static int
253 grub_lua_enum_file (lua_State *state)
255 char *device_name;
256 const char *arg;
257 grub_device_t dev;
259 luaL_checktype (state, 1, LUA_TFUNCTION);
260 arg = luaL_checkstring (state, 2);
261 device_name = grub_file_get_device_name (arg);
262 dev = grub_device_open (device_name);
263 if (dev)
265 grub_fs_t fs;
266 const char *path;
268 fs = grub_fs_probe (dev);
269 path = grub_strchr (arg, ')');
270 if (! path)
271 path = arg;
272 else
273 path++;
275 if (fs)
277 (fs->dir) (dev, path, enum_file, state);
280 grub_device_close (dev);
283 grub_free (device_name);
285 return push_result (state);
288 #ifdef ENABLE_LUA_PCI
289 /* Helper for grub_lua_enum_pci. */
290 static int
291 grub_lua_enum_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, void *data)
293 lua_State *state = data;
294 int result;
295 grub_pci_address_t addr;
296 grub_uint32_t class;
298 lua_pushvalue (state, 1);
299 lua_pushinteger (state, grub_pci_get_bus (dev));
300 lua_pushinteger (state, grub_pci_get_device (dev));
301 lua_pushinteger (state, grub_pci_get_function (dev));
302 lua_pushinteger (state, pciid);
304 addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
305 class = grub_pci_read (addr);
306 lua_pushinteger (state, class);
308 lua_call (state, 5, 1);
309 result = lua_tointeger (state, -1);
310 lua_pop (state, 1);
312 return result;
315 static int
316 grub_lua_enum_pci (lua_State *state)
318 luaL_checktype (state, 1, LUA_TFUNCTION);
319 grub_pci_iterate (grub_lua_enum_pci_iter, state);
320 return push_result (state);
322 #endif
324 static int
325 grub_lua_file_open (lua_State *state)
327 grub_file_t file;
328 const char *name;
330 name = luaL_checkstring (state, 1);
331 file = grub_file_open (name);
332 save_errno (state);
334 if (! file)
335 return 0;
337 lua_pushlightuserdata (state, file);
338 return 1;
341 static int
342 grub_lua_file_close (lua_State *state)
344 grub_file_t file;
346 luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
347 file = lua_touserdata (state, 1);
348 grub_file_close (file);
350 return push_result (state);
353 static int
354 grub_lua_file_seek (lua_State *state)
356 grub_file_t file;
357 grub_off_t offset;
359 luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
360 file = lua_touserdata (state, 1);
361 offset = luaL_checkinteger (state, 2);
363 offset = grub_file_seek (file, offset);
364 save_errno (state);
366 lua_pushinteger (state, offset);
367 return 1;
370 static int
371 grub_lua_file_read (lua_State *state)
373 grub_file_t file;
374 luaL_Buffer b;
375 int n;
377 luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
378 file = lua_touserdata (state, 1);
379 n = luaL_checkinteger (state, 2);
381 luaL_buffinit (state, &b);
382 while (n)
384 char *p;
385 int nr;
387 nr = (n > LUAL_BUFFERSIZE) ? LUAL_BUFFERSIZE : n;
388 p = luaL_prepbuffer (&b);
390 nr = grub_file_read (file, p, nr);
391 if (nr <= 0)
392 break;
394 luaL_addsize (&b, nr);
395 n -= nr;
398 save_errno (state);
399 luaL_pushresult (&b);
400 return 1;
403 static int
404 grub_lua_file_getline (lua_State *state)
406 grub_file_t file;
407 char *line;
409 luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
410 file = lua_touserdata (state, 1);
412 line = grub_file_getline (file);
413 save_errno (state);
415 if (! line)
416 return 0;
418 lua_pushstring (state, line);
419 grub_free (line);
420 return 1;
423 static int
424 grub_lua_file_getsize (lua_State *state)
426 grub_file_t file;
428 luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
429 file = lua_touserdata (state, 1);
431 lua_pushinteger (state, file->size);
432 return 1;
435 static int
436 grub_lua_file_getpos (lua_State *state)
438 grub_file_t file;
440 luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
441 file = lua_touserdata (state, 1);
443 lua_pushinteger (state, file->offset);
444 return 1;
447 static int
448 grub_lua_file_eof (lua_State *state)
450 grub_file_t file;
452 luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
453 file = lua_touserdata (state, 1);
455 lua_pushboolean (state, file->offset >= file->size);
456 return 1;
459 static int
460 grub_lua_file_exist (lua_State *state)
462 grub_file_t file;
463 const char *name;
464 int result;
466 result = 0;
467 name = luaL_checkstring (state, 1);
468 file = grub_file_open (name);
469 if (file)
471 result++;
472 grub_file_close (file);
474 else
475 grub_errno = 0;
477 lua_pushboolean (state, result);
478 return 1;
481 static int
482 grub_lua_add_menu (lua_State *state)
484 int n;
485 const char *source;
487 source = luaL_checklstring (state, 1, 0);
488 n = lua_gettop (state) - 1;
489 if (n > 0)
491 const char **args;
492 char *p;
493 int i;
495 args = grub_malloc (n * sizeof (args[0]));
496 if (!args)
497 return push_result (state);
498 for (i = 0; i < n; i++)
499 args[i] = luaL_checkstring (state, 2 + i);
501 p = grub_strdup (source);
502 if (! p)
503 return push_result (state);
505 grub_normal_add_menu_entry (n, args, NULL, NULL, NULL, NULL, NULL, p, 0);
507 else
509 lua_pushstring (state, "not enough parameter");
510 lua_error (state);
513 return push_result (state);
516 luaL_Reg grub_lua_lib[] =
518 {"run", grub_lua_run},
519 {"getenv", grub_lua_getenv},
520 {"setenv", grub_lua_setenv},
521 {"enum_device", grub_lua_enum_device},
522 {"enum_file", grub_lua_enum_file},
523 #ifdef ENABLE_LUA_PCI
524 {"enum_pci", grub_lua_enum_pci},
525 #endif
526 {"file_open", grub_lua_file_open},
527 {"file_close", grub_lua_file_close},
528 {"file_seek", grub_lua_file_seek},
529 {"file_read", grub_lua_file_read},
530 {"file_getline", grub_lua_file_getline},
531 {"file_getsize", grub_lua_file_getsize},
532 {"file_getpos", grub_lua_file_getpos},
533 {"file_eof", grub_lua_file_eof},
534 {"file_exist", grub_lua_file_exist},
535 {"add_menu", grub_lua_add_menu},
536 {0, 0}