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, &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
);
147 grub_lua_enum_device (lua_State
*state
)
149 auto int enum_device (const char *name
);
150 int enum_device (const char *name
)
156 dev
= grub_device_open (name
);
161 fs
= grub_fs_probe (dev
);
164 lua_pushvalue (state
, 1);
165 lua_pushstring (state
, name
);
166 lua_pushstring (state
, fs
->name
);
174 err
= fs
->uuid (dev
, &uuid
);
182 lua_pushstring (state
, uuid
);
187 lua_call (state
, 3, 1);
188 result
= lua_tointeger (state
, -1);
193 grub_device_close (dev
);
201 luaL_checktype (state
, 1, LUA_TFUNCTION
);
202 grub_device_iterate (enum_device
);
203 return push_result (state
);
207 grub_lua_enum_file (lua_State
*state
)
213 auto int enum_file (const char *name
, const struct grub_dirhook_info
*info
);
214 int enum_file (const char *name
, const struct grub_dirhook_info
*info
)
218 lua_pushvalue (state
, 1);
219 lua_pushstring (state
, name
);
220 lua_pushinteger (state
, info
->dir
!= 0);
221 lua_call (state
, 2, 1);
222 result
= lua_tointeger (state
, -1);
228 luaL_checktype (state
, 1, LUA_TFUNCTION
);
229 arg
= luaL_checkstring (state
, 2);
230 device_name
= grub_file_get_device_name (arg
);
231 dev
= grub_device_open (device_name
);
237 fs
= grub_fs_probe (dev
);
238 path
= grub_strchr (arg
, ')');
246 (fs
->dir
) (dev
, path
, enum_file
);
249 grub_device_close (dev
);
252 grub_free (device_name
);
254 return push_result (state
);
257 #ifdef ENABLE_LUA_PCI
258 /* Helper for grub_lua_enum_pci. */
260 grub_lua_enum_pci_iter (grub_pci_device_t dev
, grub_pci_id_t pciid
, void *data
)
262 lua_State
*state
= data
;
264 grub_pci_address_t addr
;
267 lua_pushvalue (state
, 1);
268 lua_pushinteger (state
, grub_pci_get_bus (dev
));
269 lua_pushinteger (state
, grub_pci_get_device (dev
));
270 lua_pushinteger (state
, grub_pci_get_function (dev
));
271 lua_pushinteger (state
, pciid
);
273 addr
= grub_pci_make_address (dev
, GRUB_PCI_REG_CLASS
);
274 class = grub_pci_read (addr
);
275 lua_pushinteger (state
, class);
277 lua_call (state
, 5, 1);
278 result
= lua_tointeger (state
, -1);
285 grub_lua_enum_pci (lua_State
*state
)
287 luaL_checktype (state
, 1, LUA_TFUNCTION
);
288 grub_pci_iterate (grub_lua_enum_pci_iter
, state
);
289 return push_result (state
);
294 grub_lua_file_open (lua_State
*state
)
299 name
= luaL_checkstring (state
, 1);
300 file
= grub_file_open (name
);
306 lua_pushlightuserdata (state
, file
);
311 grub_lua_file_close (lua_State
*state
)
315 luaL_checktype (state
, 1, LUA_TLIGHTUSERDATA
);
316 file
= lua_touserdata (state
, 1);
317 grub_file_close (file
);
319 return push_result (state
);
323 grub_lua_file_seek (lua_State
*state
)
328 luaL_checktype (state
, 1, LUA_TLIGHTUSERDATA
);
329 file
= lua_touserdata (state
, 1);
330 offset
= luaL_checkinteger (state
, 2);
332 offset
= grub_file_seek (file
, offset
);
335 lua_pushinteger (state
, offset
);
340 grub_lua_file_read (lua_State
*state
)
346 luaL_checktype (state
, 1, LUA_TLIGHTUSERDATA
);
347 file
= lua_touserdata (state
, 1);
348 n
= luaL_checkinteger (state
, 2);
350 luaL_buffinit (state
, &b
);
356 nr
= (n
> LUAL_BUFFERSIZE
) ? LUAL_BUFFERSIZE
: n
;
357 p
= luaL_prepbuffer (&b
);
359 nr
= grub_file_read (file
, p
, nr
);
363 luaL_addsize (&b
, nr
);
368 luaL_pushresult (&b
);
373 grub_lua_file_getline (lua_State
*state
)
378 luaL_checktype (state
, 1, LUA_TLIGHTUSERDATA
);
379 file
= lua_touserdata (state
, 1);
381 line
= grub_file_getline (file
);
387 lua_pushstring (state
, line
);
393 grub_lua_file_getsize (lua_State
*state
)
397 luaL_checktype (state
, 1, LUA_TLIGHTUSERDATA
);
398 file
= lua_touserdata (state
, 1);
400 lua_pushinteger (state
, file
->size
);
405 grub_lua_file_getpos (lua_State
*state
)
409 luaL_checktype (state
, 1, LUA_TLIGHTUSERDATA
);
410 file
= lua_touserdata (state
, 1);
412 lua_pushinteger (state
, file
->offset
);
417 grub_lua_file_eof (lua_State
*state
)
421 luaL_checktype (state
, 1, LUA_TLIGHTUSERDATA
);
422 file
= lua_touserdata (state
, 1);
424 lua_pushboolean (state
, file
->offset
>= file
->size
);
429 grub_lua_file_exist (lua_State
*state
)
436 name
= luaL_checkstring (state
, 1);
437 file
= grub_file_open (name
);
441 grub_file_close (file
);
446 lua_pushboolean (state
, result
);
451 grub_lua_add_menu (lua_State
*state
)
456 source
= luaL_checklstring (state
, 1, 0);
457 n
= lua_gettop (state
) - 1;
460 const char *args
[sizeof (char *) * n
];
464 for (i
= 0; i
< n
; i
++)
465 args
[i
] = luaL_checkstring (state
, 2 + i
);
467 p
= grub_strdup (source
);
469 return push_result (state
);
471 grub_normal_add_menu_entry (n
, args
, NULL
, NULL
, NULL
, NULL
, NULL
, p
, 0);
475 lua_pushstring (state
, "not enough parameter");
479 return push_result (state
);
482 luaL_Reg grub_lua_lib
[] =
484 {"run", grub_lua_run
},
485 {"getenv", grub_lua_getenv
},
486 {"setenv", grub_lua_setenv
},
487 {"enum_device", grub_lua_enum_device
},
488 {"enum_file", grub_lua_enum_file
},
489 #ifdef ENABLE_LUA_PCI
490 {"enum_pci", grub_lua_enum_pci
},
492 {"file_open", grub_lua_file_open
},
493 {"file_close", grub_lua_file_close
},
494 {"file_seek", grub_lua_file_seek
},
495 {"file_read", grub_lua_file_read
},
496 {"file_getline", grub_lua_file_getline
},
497 {"file_getsize", grub_lua_file_getsize
},
498 {"file_getpos", grub_lua_file_getpos
},
499 {"file_eof", grub_lua_file_eof
},
500 {"file_exist", grub_lua_file_exist
},
501 {"add_menu", grub_lua_add_menu
},