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/>.
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>
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
40 push_result (lua_State
*state
)
45 saved_errno
= grub_errno
;
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");
55 /* Push once for setfield, and again to leave on the stack */
56 lua_pushstring (state
, grub_errmsg
);
57 lua_pushstring (state
, grub_errmsg
);
66 lua_setfield (state
, LUA_GLOBALSINDEX
, "grub_errmsg");
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
75 save_errno (lua_State
*state
)
79 saved_errno
= grub_errno
;
80 lua_pop(state
, push_result(state
));
86 grub_lua_run (lua_State
*state
)
92 s
= luaL_checkstring (state
, 1);
93 if ((! grub_parser_split_cmdline (s
, 0, 0, &n
, &args
))
98 cmd
= grub_command_find (args
[0]);
100 (cmd
->func
) (cmd
, n
-1, &args
[1]);
102 grub_error (GRUB_ERR_FILE_NOT_FOUND
, "command not found");
108 return push_result (state
);
112 grub_lua_getenv (lua_State
*state
)
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
);
124 lua_pushstring (state
, value
);
133 grub_lua_setenv (lua_State
*state
)
135 const char *name
, *value
;
137 name
= luaL_checkstring (state
, 1);
138 value
= luaL_checkstring (state
, 2);
141 grub_env_set (name
, value
);
146 /* Helper for grub_lua_enum_device. */
148 grub_lua_enum_device_iter (const char *name
, void *data
)
150 lua_State
*state
= data
;
155 dev
= grub_device_open (name
);
160 fs
= grub_fs_probe (dev
);
163 lua_pushvalue (state
, 1);
164 lua_pushstring (state
, name
);
165 lua_pushstring (state
, fs
->name
);
173 err
= fs
->uuid (dev
, &uuid
);
181 lua_pushstring (state
, uuid
);
186 lua_call (state
, 3, 1);
187 result
= lua_tointeger (state
, -1);
192 grub_device_close (dev
);
201 grub_lua_enum_device (lua_State
*state
)
203 luaL_checktype (state
, 1, LUA_TFUNCTION
);
204 grub_device_iterate (grub_lua_enum_device_iter
, state
);
205 return push_result (state
);
209 enum_file (const char *name
, const struct grub_dirhook_info
*info
,
213 lua_State
*state
= data
;
215 lua_pushvalue (state
, 1);
216 lua_pushstring (state
, name
);
217 lua_pushinteger (state
, info
->dir
!= 0);
218 lua_call (state
, 2, 1);
219 result
= lua_tointeger (state
, -1);
226 grub_lua_enum_file (lua_State
*state
)
232 luaL_checktype (state
, 1, LUA_TFUNCTION
);
233 arg
= luaL_checkstring (state
, 2);
234 device_name
= grub_file_get_device_name (arg
);
235 dev
= grub_device_open (device_name
);
241 fs
= grub_fs_probe (dev
);
242 path
= grub_strchr (arg
, ')');
250 (fs
->dir
) (dev
, path
, enum_file
, state
);
253 grub_device_close (dev
);
256 grub_free (device_name
);
258 return push_result (state
);
261 #ifdef ENABLE_LUA_PCI
262 /* Helper for grub_lua_enum_pci. */
264 grub_lua_enum_pci_iter (grub_pci_device_t dev
, grub_pci_id_t pciid
, void *data
)
266 lua_State
*state
= data
;
268 grub_pci_address_t addr
;
271 lua_pushvalue (state
, 1);
272 lua_pushinteger (state
, grub_pci_get_bus (dev
));
273 lua_pushinteger (state
, grub_pci_get_device (dev
));
274 lua_pushinteger (state
, grub_pci_get_function (dev
));
275 lua_pushinteger (state
, pciid
);
277 addr
= grub_pci_make_address (dev
, GRUB_PCI_REG_CLASS
);
278 class = grub_pci_read (addr
);
279 lua_pushinteger (state
, class);
281 lua_call (state
, 5, 1);
282 result
= lua_tointeger (state
, -1);
289 grub_lua_enum_pci (lua_State
*state
)
291 luaL_checktype (state
, 1, LUA_TFUNCTION
);
292 grub_pci_iterate (grub_lua_enum_pci_iter
, state
);
293 return push_result (state
);
298 grub_lua_file_open (lua_State
*state
)
303 name
= luaL_checkstring (state
, 1);
304 file
= grub_file_open (name
);
310 lua_pushlightuserdata (state
, file
);
315 grub_lua_file_close (lua_State
*state
)
319 luaL_checktype (state
, 1, LUA_TLIGHTUSERDATA
);
320 file
= lua_touserdata (state
, 1);
321 grub_file_close (file
);
323 return push_result (state
);
327 grub_lua_file_seek (lua_State
*state
)
332 luaL_checktype (state
, 1, LUA_TLIGHTUSERDATA
);
333 file
= lua_touserdata (state
, 1);
334 offset
= luaL_checkinteger (state
, 2);
336 offset
= grub_file_seek (file
, offset
);
339 lua_pushinteger (state
, offset
);
344 grub_lua_file_read (lua_State
*state
)
350 luaL_checktype (state
, 1, LUA_TLIGHTUSERDATA
);
351 file
= lua_touserdata (state
, 1);
352 n
= luaL_checkinteger (state
, 2);
354 luaL_buffinit (state
, &b
);
360 nr
= (n
> LUAL_BUFFERSIZE
) ? LUAL_BUFFERSIZE
: n
;
361 p
= luaL_prepbuffer (&b
);
363 nr
= grub_file_read (file
, p
, nr
);
367 luaL_addsize (&b
, nr
);
372 luaL_pushresult (&b
);
377 grub_lua_file_getline (lua_State
*state
)
382 luaL_checktype (state
, 1, LUA_TLIGHTUSERDATA
);
383 file
= lua_touserdata (state
, 1);
385 line
= grub_file_getline (file
);
391 lua_pushstring (state
, line
);
397 grub_lua_file_getsize (lua_State
*state
)
401 luaL_checktype (state
, 1, LUA_TLIGHTUSERDATA
);
402 file
= lua_touserdata (state
, 1);
404 lua_pushinteger (state
, file
->size
);
409 grub_lua_file_getpos (lua_State
*state
)
413 luaL_checktype (state
, 1, LUA_TLIGHTUSERDATA
);
414 file
= lua_touserdata (state
, 1);
416 lua_pushinteger (state
, file
->offset
);
421 grub_lua_file_eof (lua_State
*state
)
425 luaL_checktype (state
, 1, LUA_TLIGHTUSERDATA
);
426 file
= lua_touserdata (state
, 1);
428 lua_pushboolean (state
, file
->offset
>= file
->size
);
433 grub_lua_file_exist (lua_State
*state
)
440 name
= luaL_checkstring (state
, 1);
441 file
= grub_file_open (name
);
445 grub_file_close (file
);
450 lua_pushboolean (state
, result
);
455 grub_lua_add_menu (lua_State
*state
)
460 source
= luaL_checklstring (state
, 1, 0);
461 n
= lua_gettop (state
) - 1;
464 const char *args
[sizeof (char *) * n
];
468 for (i
= 0; i
< n
; i
++)
469 args
[i
] = luaL_checkstring (state
, 2 + i
);
471 p
= grub_strdup (source
);
473 return push_result (state
);
475 grub_normal_add_menu_entry (n
, args
, NULL
, NULL
, NULL
, NULL
, NULL
, p
, 0);
479 lua_pushstring (state
, "not enough parameter");
483 return push_result (state
);
486 luaL_Reg grub_lua_lib
[] =
488 {"run", grub_lua_run
},
489 {"getenv", grub_lua_getenv
},
490 {"setenv", grub_lua_setenv
},
491 {"enum_device", grub_lua_enum_device
},
492 {"enum_file", grub_lua_enum_file
},
493 #ifdef ENABLE_LUA_PCI
494 {"enum_pci", grub_lua_enum_pci
},
496 {"file_open", grub_lua_file_open
},
497 {"file_close", grub_lua_file_close
},
498 {"file_seek", grub_lua_file_seek
},
499 {"file_read", grub_lua_file_read
},
500 {"file_getline", grub_lua_file_getline
},
501 {"file_getsize", grub_lua_file_getsize
},
502 {"file_getpos", grub_lua_file_getpos
},
503 {"file_eof", grub_lua_file_eof
},
504 {"file_exist", grub_lua_file_exist
},
505 {"add_menu", grub_lua_add_menu
},