grub_lib.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730
  1. /*
  2. * BURG - Brand-new Universal loadeR from GRUB
  3. * Copyright 2009 Bean Lee - All Rights Reserved
  4. *
  5. * BURG 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.
  9. *
  10. * BURG 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.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with BURG. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "lua.h"
  19. #include "lauxlib.h"
  20. #include "lualib.h"
  21. #include "grub_lib.h"
  22. #include <grub/env.h>
  23. #include <grub/lib.h>
  24. #include <grub/parser.h>
  25. #include <grub/command.h>
  26. #include <grub/file.h>
  27. #include <grub/menu.h>
  28. #include <grub/device.h>
  29. #include <grub/term.h>
  30. static int
  31. save_errno (lua_State *state)
  32. {
  33. int saved_errno;
  34. saved_errno = grub_errno;
  35. grub_errno = 0;
  36. lua_pushinteger (state, saved_errno);
  37. lua_setfield (state, LUA_GLOBALSINDEX, "grub_errno");
  38. if (saved_errno)
  39. lua_pushstring (state, grub_errmsg);
  40. else
  41. lua_pushnil (state);
  42. lua_setfield (state, LUA_GLOBALSINDEX, "grub_errmsg");
  43. return saved_errno;
  44. }
  45. static int
  46. push_result (lua_State *state)
  47. {
  48. lua_pushinteger (state, save_errno (state));
  49. return 1;
  50. }
  51. static int
  52. grub_lua_run (lua_State *state)
  53. {
  54. int n;
  55. char **args;
  56. const char *s;
  57. s = luaL_checkstring (state, 1);
  58. if ((! grub_parser_split_cmdline (s, 0, 0, &n, &args))
  59. && (n > 0))
  60. {
  61. grub_command_t cmd;
  62. cmd = grub_command_find (args[0]);
  63. if (cmd)
  64. (cmd->func) (cmd, n - 1, &args[1]);
  65. else
  66. grub_error (GRUB_ERR_FILE_NOT_FOUND, "command not found");
  67. grub_free (args[0]);
  68. grub_free (args);
  69. }
  70. return push_result (state);
  71. }
  72. static int
  73. grub_lua_getenv (lua_State *state)
  74. {
  75. int n, i;
  76. n = lua_gettop (state);
  77. for (i = 1; i <= n; i++)
  78. {
  79. const char *name, *value;
  80. name = luaL_checkstring (state, i);
  81. value = grub_env_get (name);
  82. if (value)
  83. lua_pushstring (state, value);
  84. else
  85. lua_pushnil (state);
  86. }
  87. return n;
  88. }
  89. static int
  90. grub_lua_setenv (lua_State *state)
  91. {
  92. const char *name, *value;
  93. name = luaL_checkstring (state, 1);
  94. value = luaL_checkstring (state, 2);
  95. if (name[0])
  96. grub_env_set (name, value);
  97. return 0;
  98. }
  99. static int
  100. enum_device (const char *name, void *closure)
  101. {
  102. lua_State *state = closure;
  103. int result;
  104. grub_device_t dev;
  105. result = 0;
  106. dev = grub_device_open (name);
  107. if (dev)
  108. {
  109. grub_fs_t fs;
  110. fs = grub_fs_probe (dev);
  111. if (fs)
  112. {
  113. lua_pushvalue (state, 1);
  114. lua_pushstring (state, name);
  115. lua_pushstring (state, fs->name);
  116. if (! fs->uuid)
  117. lua_pushnil (state);
  118. else
  119. {
  120. int err;
  121. char *uuid;
  122. err = fs->uuid (dev, &uuid);
  123. if (err)
  124. {
  125. grub_errno = 0;
  126. lua_pushnil (state);
  127. }
  128. else
  129. {
  130. lua_pushstring (state, uuid);
  131. grub_free (uuid);
  132. }
  133. }
  134. lua_call (state, 3, 1);
  135. result = lua_tointeger (state, -1);
  136. lua_pop (state, 1);
  137. }
  138. else
  139. grub_errno = 0;
  140. grub_device_close (dev);
  141. }
  142. else
  143. grub_errno = 0;
  144. return result;
  145. }
  146. static int
  147. grub_lua_enum_device (lua_State *state)
  148. {
  149. luaL_checktype (state, 1, LUA_TFUNCTION);
  150. grub_device_iterate (enum_device, state);
  151. return push_result (state);
  152. }
  153. static int
  154. enum_file (const char *name, const struct grub_dirhook_info *info,
  155. void *closure)
  156. {
  157. lua_State *state = closure;
  158. int result;
  159. lua_pushvalue (state, 1);
  160. lua_pushstring (state, name);
  161. lua_pushinteger (state, info->dir != 0);
  162. lua_call (state, 2, 1);
  163. result = lua_tointeger (state, -1);
  164. lua_pop (state, 1);
  165. return result;
  166. }
  167. static int
  168. grub_lua_enum_file (lua_State *state)
  169. {
  170. char *device_name;
  171. const char *arg;
  172. grub_device_t dev;
  173. luaL_checktype (state, 1, LUA_TFUNCTION);
  174. arg = luaL_checkstring (state, 2);
  175. device_name = grub_file_get_device_name (arg);
  176. dev = grub_device_open (device_name);
  177. if (dev)
  178. {
  179. grub_fs_t fs;
  180. const char *path;
  181. fs = grub_fs_probe (dev);
  182. path = grub_strchr (arg, ')');
  183. if (! path)
  184. path = arg;
  185. else
  186. path++;
  187. if (fs)
  188. {
  189. (fs->dir) (dev, path, enum_file, state);
  190. }
  191. grub_device_close (dev);
  192. }
  193. grub_free (device_name);
  194. return push_result (state);
  195. }
  196. static int
  197. grub_lua_file_open (lua_State *state)
  198. {
  199. grub_file_t file;
  200. const char *name;
  201. const char *flag;
  202. name = luaL_checkstring (state, 1);
  203. flag = (lua_gettop (state) > 1) ? luaL_checkstring (state, 2) : 0;
  204. file = grub_file_open (name);
  205. save_errno (state);
  206. if (! file)
  207. return 0;
  208. if (grub_strchr (flag, 'w'))
  209. grub_blocklist_convert (file);
  210. lua_pushlightuserdata (state, file);
  211. return 1;
  212. }
  213. static int
  214. grub_lua_file_close (lua_State *state)
  215. {
  216. grub_file_t file;
  217. luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
  218. file = lua_touserdata (state, 1);
  219. grub_file_close (file);
  220. return push_result (state);
  221. }
  222. static int
  223. grub_lua_file_seek (lua_State *state)
  224. {
  225. grub_file_t file;
  226. grub_off_t offset;
  227. luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
  228. file = lua_touserdata (state, 1);
  229. offset = luaL_checkinteger (state, 2);
  230. offset = grub_file_seek (file, offset);
  231. save_errno (state);
  232. lua_pushinteger (state, offset);
  233. return 1;
  234. }
  235. static int
  236. grub_lua_file_read (lua_State *state)
  237. {
  238. grub_file_t file;
  239. luaL_Buffer b;
  240. int n;
  241. luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
  242. file = lua_touserdata (state, 1);
  243. n = luaL_checkinteger (state, 2);
  244. luaL_buffinit (state, &b);
  245. while (n)
  246. {
  247. char *p;
  248. int nr;
  249. nr = (n > LUAL_BUFFERSIZE) ? LUAL_BUFFERSIZE : n;
  250. p = luaL_prepbuffer (&b);
  251. nr = grub_file_read (file, p, nr);
  252. if (nr <= 0)
  253. break;
  254. luaL_addsize (&b, nr);
  255. n -= nr;
  256. }
  257. save_errno (state);
  258. luaL_pushresult (&b);
  259. return 1;
  260. }
  261. static int
  262. grub_lua_file_write (lua_State *state)
  263. {
  264. grub_file_t file;
  265. grub_ssize_t ret;
  266. grub_size_t len;
  267. const char *buf;
  268. luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
  269. file = lua_touserdata (state, 1);
  270. buf = lua_tolstring (state, 2, &len);
  271. ret = grub_blocklist_write (file, buf, len);
  272. if (ret > 0)
  273. file->offset += ret;
  274. save_errno (state);
  275. lua_pushinteger (state, ret);
  276. return 1;
  277. }
  278. static int
  279. grub_lua_file_getline (lua_State *state)
  280. {
  281. grub_file_t file;
  282. char *line;
  283. luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
  284. file = lua_touserdata (state, 1);
  285. line = grub_getline (file);
  286. save_errno (state);
  287. if (! line)
  288. return 0;
  289. lua_pushstring (state, line);
  290. grub_free (line);
  291. return 1;
  292. }
  293. static int
  294. grub_lua_file_getsize (lua_State *state)
  295. {
  296. grub_file_t file;
  297. luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
  298. file = lua_touserdata (state, 1);
  299. lua_pushinteger (state, file->size);
  300. return 1;
  301. }
  302. static int
  303. grub_lua_file_getpos (lua_State *state)
  304. {
  305. grub_file_t file;
  306. luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
  307. file = lua_touserdata (state, 1);
  308. lua_pushinteger (state, file->offset);
  309. return 1;
  310. }
  311. static int
  312. grub_lua_file_eof (lua_State *state)
  313. {
  314. grub_file_t file;
  315. luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
  316. file = lua_touserdata (state, 1);
  317. lua_pushboolean (state, file->offset >= file->size);
  318. return 1;
  319. }
  320. static int
  321. grub_lua_file_exist (lua_State *state)
  322. {
  323. grub_file_t file;
  324. const char *name;
  325. int result;
  326. result = 0;
  327. name = luaL_checkstring (state, 1);
  328. file = grub_file_open (name);
  329. if (file)
  330. {
  331. result++;
  332. grub_file_close (file);
  333. }
  334. else
  335. grub_errno = 0;
  336. lua_pushboolean (state, result);
  337. return 1;
  338. }
  339. static int
  340. grub_lua_add_menu (lua_State *state)
  341. {
  342. int n;
  343. const char *source;
  344. source = luaL_checklstring (state, 1, 0);
  345. n = lua_gettop (state) - 1;
  346. if (n > 0)
  347. {
  348. const char *args[sizeof (char *) * n];
  349. char *p;
  350. int i;
  351. for (i = 0; i < n; i++)
  352. args[i] = luaL_checkstring (state, 2 + i);
  353. p = grub_strdup (source);
  354. if (! p)
  355. return push_result (state);
  356. grub_menu_entry_add (n, args, p);
  357. }
  358. else
  359. {
  360. lua_pushstring (state, "not enough parameter");
  361. lua_error (state);
  362. }
  363. return push_result (state);
  364. }
  365. static int
  366. grub_lua_read_byte (lua_State *state)
  367. {
  368. grub_addr_t addr;
  369. addr = luaL_checkinteger (state, 1);
  370. lua_pushinteger (state, *((grub_uint8_t *) addr));
  371. return 1;
  372. }
  373. static int
  374. grub_lua_read_word (lua_State *state)
  375. {
  376. grub_addr_t addr;
  377. addr = luaL_checkinteger (state, 1);
  378. lua_pushinteger (state, *((grub_uint16_t *) addr));
  379. return 1;
  380. }
  381. static int
  382. grub_lua_read_dword (lua_State *state)
  383. {
  384. grub_addr_t addr;
  385. addr = luaL_checkinteger (state, 1);
  386. lua_pushinteger (state, *((grub_uint32_t *) addr));
  387. return 1;
  388. }
  389. static int
  390. grub_lua_write_byte (lua_State *state)
  391. {
  392. grub_addr_t addr;
  393. addr = luaL_checkinteger (state, 1);
  394. *((grub_uint8_t *) addr) = luaL_checkinteger (state, 2);
  395. return 1;
  396. }
  397. static int
  398. grub_lua_write_word (lua_State *state)
  399. {
  400. grub_addr_t addr;
  401. addr = luaL_checkinteger (state, 1);
  402. *((grub_uint16_t *) addr) = luaL_checkinteger (state, 2);
  403. return 1;
  404. }
  405. static int
  406. grub_lua_write_dword (lua_State *state)
  407. {
  408. grub_addr_t addr;
  409. addr = luaL_checkinteger (state, 1);
  410. *((grub_uint32_t *) addr) = luaL_checkinteger (state, 2);
  411. return 1;
  412. }
  413. static int
  414. grub_lua_getkey (lua_State *state)
  415. {
  416. lua_pushinteger (state, grub_getkey ());
  417. return 1;
  418. }
  419. static int
  420. grub_lua_checkkey (lua_State *state)
  421. {
  422. lua_pushboolean (state, grub_checkkey () >= 0);
  423. return 1;
  424. }
  425. static int
  426. grub_lua_getkeystatus (lua_State *state)
  427. {
  428. lua_pushinteger (state, grub_getkeystatus ());
  429. return 1;
  430. }
  431. static int
  432. grub_lua_cls (lua_State *state __attribute__ ((unused)))
  433. {
  434. grub_cls ();
  435. return 0;
  436. }
  437. static int
  438. grub_lua_setcolorstate (lua_State *state)
  439. {
  440. grub_setcolorstate (luaL_checkinteger (state, 1));
  441. return 0;
  442. }
  443. static int
  444. grub_lua_refresh (lua_State *state __attribute__ ((unused)))
  445. {
  446. grub_refresh ();
  447. return 0;
  448. }
  449. static int
  450. grub_lua_name2key (lua_State *state)
  451. {
  452. const char *s;
  453. s = luaL_checkstring (state, 1);
  454. lua_pushinteger (state, grub_menu_name2key (s));
  455. return 1;
  456. }
  457. static int
  458. grub_lua_key2name (lua_State *state)
  459. {
  460. int key;
  461. key = luaL_checkinteger (state, 1);
  462. lua_pushstring (state, grub_menu_key2name (GRUB_TERM_ASCII_CHAR (key)));
  463. return 1;
  464. }
  465. static int
  466. grub_lua_enum_term (lua_State *state)
  467. {
  468. struct grub_term_output *term;
  469. luaL_checktype (state, 1, LUA_TFUNCTION);
  470. FOR_ACTIVE_TERM_OUTPUTS(term)
  471. {
  472. lua_pushvalue (state, 1);
  473. lua_pushlightuserdata (state, term);
  474. lua_pushstring (state, term->name);
  475. lua_call (state, 2, 0);
  476. lua_pop (state, 1);
  477. }
  478. return 0;
  479. }
  480. static int
  481. grub_lua_term_width (lua_State *state)
  482. {
  483. struct grub_term_output *term;
  484. luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
  485. term = lua_touserdata (state, 1);
  486. lua_pushinteger (state, grub_term_width (term));
  487. return 1;
  488. }
  489. static int
  490. grub_lua_term_height (lua_State *state)
  491. {
  492. struct grub_term_output *term;
  493. luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
  494. term = lua_touserdata (state, 1);
  495. lua_pushinteger (state, grub_term_height (term));
  496. return 1;
  497. }
  498. static int
  499. grub_lua_term_getxy (lua_State *state)
  500. {
  501. struct grub_term_output *term;
  502. grub_uint16_t xy;
  503. luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
  504. term = lua_touserdata (state, 1);
  505. xy = grub_term_getxy (term);
  506. lua_pushinteger (state, xy >> 8);
  507. lua_pushinteger (state, xy & 0xff);
  508. return 2;
  509. }
  510. static int
  511. grub_lua_term_gotoxy (lua_State *state)
  512. {
  513. struct grub_term_output *term;
  514. luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
  515. term = lua_touserdata (state, 1);
  516. grub_term_gotoxy (term, luaL_checkinteger (state, 2),
  517. luaL_checkinteger (state, 3));
  518. return 0;
  519. }
  520. static int
  521. grub_lua_term_setcolorstate (lua_State *state)
  522. {
  523. struct grub_term_output *term;
  524. luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
  525. term = lua_touserdata (state, 1);
  526. grub_term_setcolorstate (term, luaL_checkinteger (state, 2));
  527. return 0;
  528. }
  529. static int
  530. grub_lua_term_setcolor (lua_State *state)
  531. {
  532. struct grub_term_output *term;
  533. luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
  534. term = lua_touserdata (state, 1);
  535. grub_term_setcolor (term, luaL_checkinteger (state, 2),
  536. luaL_checkinteger (state, 3));
  537. return 0;
  538. }
  539. static int
  540. grub_lua_term_setcursor (lua_State *state)
  541. {
  542. struct grub_term_output *term;
  543. luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
  544. term = lua_touserdata (state, 1);
  545. grub_term_setcursor (term, lua_toboolean (state, 2));
  546. return 0;
  547. }
  548. static int
  549. grub_lua_term_getcolor (lua_State *state)
  550. {
  551. struct grub_term_output *term;
  552. grub_uint8_t normal_color, highlight_color;
  553. luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
  554. term = lua_touserdata (state, 1);
  555. grub_term_getcolor (term, &normal_color, &highlight_color);
  556. lua_pushinteger (state, normal_color);
  557. lua_pushinteger (state, highlight_color);
  558. return 2;
  559. }
  560. luaL_Reg grub_lua_lib[] =
  561. {
  562. {"run", grub_lua_run},
  563. {"getenv", grub_lua_getenv},
  564. {"setenv", grub_lua_setenv},
  565. {"enum_device", grub_lua_enum_device},
  566. {"enum_file", grub_lua_enum_file},
  567. {"file_open", grub_lua_file_open},
  568. {"file_close", grub_lua_file_close},
  569. {"file_seek", grub_lua_file_seek},
  570. {"file_read", grub_lua_file_read},
  571. {"file_write", grub_lua_file_write},
  572. {"file_getline", grub_lua_file_getline},
  573. {"file_getsize", grub_lua_file_getsize},
  574. {"file_getpos", grub_lua_file_getpos},
  575. {"file_eof", grub_lua_file_eof},
  576. {"file_exist", grub_lua_file_exist},
  577. {"add_menu", grub_lua_add_menu},
  578. {"read_byte", grub_lua_read_byte},
  579. {"read_word", grub_lua_read_word},
  580. {"read_dword", grub_lua_read_dword},
  581. {"write_byte", grub_lua_write_byte},
  582. {"write_word", grub_lua_write_word},
  583. {"write_dword", grub_lua_write_dword},
  584. {"getkey", grub_lua_getkey},
  585. {"checkkey", grub_lua_checkkey},
  586. {"getkeystatus", grub_lua_getkeystatus},
  587. {"cls", grub_lua_cls},
  588. {"setcolorstate", grub_lua_setcolorstate},
  589. {"refresh", grub_lua_refresh},
  590. {"name2key", grub_lua_name2key},
  591. {"key2name", grub_lua_key2name},
  592. {"enum_term", grub_lua_enum_term},
  593. {"term_width", grub_lua_term_width},
  594. {"term_height", grub_lua_term_height},
  595. {"term_getxy", grub_lua_term_getxy},
  596. {"term_gotoxy", grub_lua_term_gotoxy},
  597. {"term_setcolorstate", grub_lua_term_setcolorstate},
  598. {"term_setcolor", grub_lua_term_setcolor},
  599. {"term_setcursor", grub_lua_term_setcursor},
  600. {"term_getcolor", grub_lua_term_getcolor},
  601. {0, 0}
  602. };