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
);
193 err
= fs
->label (dev
, &label
);
207 lua_pushstring (state
, label
);
213 lua_call (state
, 4, 1);
214 result
= lua_tointeger (state
, -1);
219 grub_device_close (dev
);
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
);
236 enum_file (const char *name
, const struct grub_dirhook_info
*info
,
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);
253 grub_lua_enum_file (lua_State
*state
)
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
);
268 fs
= grub_fs_probe (dev
);
269 path
= grub_strchr (arg
, ')');
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. */
291 grub_lua_enum_pci_iter (grub_pci_device_t dev
, grub_pci_id_t pciid
, void *data
)
293 lua_State
*state
= data
;
295 grub_pci_address_t addr
;
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);
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
);
325 grub_lua_file_open (lua_State
*state
)
330 name
= luaL_checkstring (state
, 1);
331 file
= grub_file_open (name
);
337 lua_pushlightuserdata (state
, file
);
342 grub_lua_file_close (lua_State
*state
)
346 luaL_checktype (state
, 1, LUA_TLIGHTUSERDATA
);
347 file
= lua_touserdata (state
, 1);
348 grub_file_close (file
);
350 return push_result (state
);
354 grub_lua_file_seek (lua_State
*state
)
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
);
366 lua_pushinteger (state
, offset
);
371 grub_lua_file_read (lua_State
*state
)
377 luaL_checktype (state
, 1, LUA_TLIGHTUSERDATA
);
378 file
= lua_touserdata (state
, 1);
379 n
= luaL_checkinteger (state
, 2);
381 luaL_buffinit (state
, &b
);
387 nr
= (n
> LUAL_BUFFERSIZE
) ? LUAL_BUFFERSIZE
: n
;
388 p
= luaL_prepbuffer (&b
);
390 nr
= grub_file_read (file
, p
, nr
);
394 luaL_addsize (&b
, nr
);
399 luaL_pushresult (&b
);
404 grub_lua_file_getline (lua_State
*state
)
409 luaL_checktype (state
, 1, LUA_TLIGHTUSERDATA
);
410 file
= lua_touserdata (state
, 1);
412 line
= grub_file_getline (file
);
418 lua_pushstring (state
, line
);
424 grub_lua_file_getsize (lua_State
*state
)
428 luaL_checktype (state
, 1, LUA_TLIGHTUSERDATA
);
429 file
= lua_touserdata (state
, 1);
431 lua_pushinteger (state
, file
->size
);
436 grub_lua_file_getpos (lua_State
*state
)
440 luaL_checktype (state
, 1, LUA_TLIGHTUSERDATA
);
441 file
= lua_touserdata (state
, 1);
443 lua_pushinteger (state
, file
->offset
);
448 grub_lua_file_eof (lua_State
*state
)
452 luaL_checktype (state
, 1, LUA_TLIGHTUSERDATA
);
453 file
= lua_touserdata (state
, 1);
455 lua_pushboolean (state
, file
->offset
>= file
->size
);
460 grub_lua_file_exist (lua_State
*state
)
467 name
= luaL_checkstring (state
, 1);
468 file
= grub_file_open (name
);
472 grub_file_close (file
);
477 lua_pushboolean (state
, result
);
482 grub_lua_add_menu (lua_State
*state
)
487 source
= luaL_checklstring (state
, 1, 0);
488 n
= lua_gettop (state
) - 1;
495 args
= grub_malloc (n
* sizeof (args
[0]));
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
);
503 return push_result (state
);
505 grub_normal_add_menu_entry (n
, args
, NULL
, NULL
, NULL
, NULL
, NULL
, p
, 0);
509 lua_pushstring (state
, "not enough parameter");
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
},
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
},