~ilya-yanok/ubuntu/precise/grub2/fix-for-948716

« back to all changes in this revision

Viewing changes to script/lua/grub_lib.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Millan
  • Date: 2009-07-25 19:00:53 UTC
  • mfrom: (1.6.3 upstream)
  • mto: (17.4.13 sid)
  • mto: This revision was merged to the branch mainline in revision 53.
  • Revision ID: james.westby@ubuntu.com-20090725190053-uv3lm6ya3zxs77ep
ImportĀ upstreamĀ versionĀ 1.96+20090725

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  GRUB  --  GRand Unified Bootloader
 
3
 *  Copyright (C) 2009  Free Software Foundation, Inc.
 
4
 *
 
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.
 
9
 *
 
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.
 
14
 *
 
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/>.
 
17
 */
 
18
 
 
19
#include "lua.h"
 
20
#include "lauxlib.h"
 
21
#include "lualib.h"
 
22
#include "grub_lib.h"
 
23
 
 
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>
 
30
 
 
31
static int
 
32
save_errno (lua_State *state)
 
33
{
 
34
  int saved_errno;
 
35
 
 
36
  saved_errno = grub_errno;
 
37
  grub_errno = 0;
 
38
 
 
39
  lua_pushinteger (state, saved_errno);
 
40
  lua_setfield (state, LUA_GLOBALSINDEX, "grub_errno");
 
41
 
 
42
  if (saved_errno)
 
43
    lua_pushstring (state, grub_errmsg);
 
44
  else
 
45
    lua_pushnil (state);
 
46
 
 
47
  lua_setfield (state, LUA_GLOBALSINDEX, "grub_errmsg");
 
48
 
 
49
  return saved_errno;
 
50
}
 
51
 
 
52
static int
 
53
push_result (lua_State *state)
 
54
{
 
55
  lua_pushinteger (state, save_errno (state));
 
56
  return 1;
 
57
}
 
58
 
 
59
static int
 
60
grub_lua_run (lua_State *state)
 
61
{
 
62
  int n;
 
63
  char **args;
 
64
  const char *s;
 
65
 
 
66
  s = luaL_checkstring (state, 1);
 
67
  if ((! grub_parser_split_cmdline (s, 0, &n, &args))
 
68
      && (n >= 0))
 
69
    {
 
70
      grub_command_t cmd;
 
71
 
 
72
      cmd = grub_command_find (args[0]);
 
73
      if (cmd)
 
74
        (cmd->func) (cmd, n, &args[1]);
 
75
      else
 
76
        grub_error (GRUB_ERR_FILE_NOT_FOUND, "command not found");
 
77
 
 
78
      grub_free (args[0]);
 
79
      grub_free (args);
 
80
    }
 
81
 
 
82
  return push_result (state);
 
83
}
 
84
 
 
85
static int
 
86
grub_lua_getenv (lua_State *state)
 
87
{
 
88
  int n, i;
 
89
 
 
90
  n = lua_gettop (state);
 
91
  for (i = 1; i <= n; i++)
 
92
    {
 
93
      const char *name, *value;
 
94
 
 
95
      name = luaL_checkstring (state, i);
 
96
      value = grub_env_get (name);
 
97
      if (value)
 
98
        lua_pushstring (state, value);
 
99
      else
 
100
        lua_pushnil (state);
 
101
    }
 
102
 
 
103
  return n;
 
104
}
 
105
 
 
106
static int
 
107
grub_lua_setenv (lua_State *state)
 
108
{
 
109
  const char *name, *value;
 
110
 
 
111
  name = luaL_checkstring (state, 1);
 
112
  value = luaL_checkstring (state, 2);
 
113
 
 
114
  if (name[0])
 
115
    grub_env_set (name, value);
 
116
 
 
117
  return 0;
 
118
}
 
119
 
 
120
static int
 
121
grub_lua_enum_device (lua_State *state)
 
122
{
 
123
  auto int enum_device (const char *name);
 
124
  int enum_device (const char *name)
 
125
  {
 
126
    int result;
 
127
    grub_device_t dev;
 
128
 
 
129
    result = 0;
 
130
    dev = grub_device_open (name);
 
131
    if (dev)
 
132
      {
 
133
        grub_fs_t fs;
 
134
 
 
135
        fs = grub_fs_probe (dev);
 
136
        if (fs)
 
137
          {
 
138
            lua_pushvalue (state, 1);
 
139
            lua_pushstring (state, name);
 
140
            lua_pushstring (state, fs->name);
 
141
            if (! fs->uuid)
 
142
              lua_pushnil (state);
 
143
            else
 
144
              {
 
145
                int err;
 
146
                char *uuid;
 
147
 
 
148
                err = fs->uuid (dev, &uuid);
 
149
                if (err)
 
150
                  {
 
151
                    grub_errno = 0;
 
152
                    lua_pushnil (state);
 
153
                  }
 
154
                else
 
155
                  {
 
156
                    lua_pushstring (state, uuid);
 
157
                    grub_free (uuid);
 
158
                  }
 
159
              }
 
160
 
 
161
            lua_call (state, 3, 1);
 
162
            result = lua_tointeger (state, -1);
 
163
            lua_pop (state, 1);
 
164
          }
 
165
        else
 
166
          grub_errno = 0;
 
167
        grub_device_close (dev);
 
168
      }
 
169
    else
 
170
      grub_errno = 0;
 
171
 
 
172
    return result;
 
173
  }
 
174
 
 
175
  luaL_checktype (state, 1, LUA_TFUNCTION);
 
176
  grub_device_iterate (enum_device);
 
177
  return push_result (state);
 
178
}
 
179
 
 
180
static int
 
181
grub_lua_enum_file (lua_State *state)
 
182
{
 
183
  char *device_name;
 
184
  const char *arg;
 
185
  grub_device_t dev;
 
186
 
 
187
  auto int enum_file (const char *name, const struct grub_dirhook_info *info);
 
188
  int enum_file (const char *name, const struct grub_dirhook_info *info)
 
189
  {
 
190
    int result;
 
191
 
 
192
    lua_pushvalue (state, 1);
 
193
    lua_pushstring (state, name);
 
194
    lua_pushinteger (state, info->dir != 0);
 
195
    lua_call (state, 2, 1);
 
196
    result = lua_tointeger (state, -1);
 
197
    lua_pop (state, 1);
 
198
 
 
199
    return result;
 
200
  }
 
201
 
 
202
  luaL_checktype (state, 1, LUA_TFUNCTION);
 
203
  arg = luaL_checkstring (state, 2);
 
204
  device_name = grub_file_get_device_name (arg);
 
205
  dev = grub_device_open (device_name);
 
206
  if (dev)
 
207
    {
 
208
      grub_fs_t fs;
 
209
      const char *path;
 
210
 
 
211
      fs = grub_fs_probe (dev);
 
212
      path = grub_strchr (arg, ')');
 
213
      if (! path)
 
214
        path = arg;
 
215
      else
 
216
        path++;
 
217
 
 
218
      if (fs)
 
219
        {
 
220
          (fs->dir) (dev, path, enum_file);
 
221
        }
 
222
 
 
223
      grub_device_close (dev);
 
224
    }
 
225
 
 
226
  grub_free (device_name);
 
227
 
 
228
  return push_result (state);
 
229
}
 
230
 
 
231
static int
 
232
grub_lua_file_open (lua_State *state)
 
233
{
 
234
  grub_file_t file;
 
235
  const char *name;
 
236
 
 
237
  name = luaL_checkstring (state, 1);
 
238
  file = grub_file_open (name);
 
239
  save_errno (state);
 
240
 
 
241
  if (! file)
 
242
    return 0;
 
243
 
 
244
  lua_pushlightuserdata (state, file);
 
245
  return 1;
 
246
}
 
247
 
 
248
static int
 
249
grub_lua_file_close (lua_State *state)
 
250
{
 
251
  grub_file_t file;
 
252
 
 
253
  luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
 
254
  file = lua_touserdata (state, 1);
 
255
  grub_file_close (file);
 
256
 
 
257
  return push_result (state);
 
258
}
 
259
 
 
260
static int
 
261
grub_lua_file_seek (lua_State *state)
 
262
{
 
263
  grub_file_t file;
 
264
  grub_off_t offset;
 
265
 
 
266
  luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
 
267
  file = lua_touserdata (state, 1);
 
268
  offset = luaL_checkinteger (state, 2);
 
269
 
 
270
  offset = grub_file_seek (file, offset);
 
271
  save_errno (state);
 
272
 
 
273
  lua_pushinteger (state, offset);
 
274
  return 1;
 
275
}
 
276
 
 
277
static int
 
278
grub_lua_file_read (lua_State *state)
 
279
{
 
280
  grub_file_t file;
 
281
  luaL_Buffer b;
 
282
  int n;
 
283
 
 
284
  luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
 
285
  file = lua_touserdata (state, 1);
 
286
  n = luaL_checkinteger (state, 2);
 
287
 
 
288
  luaL_buffinit (state, &b);
 
289
  while (n)
 
290
    {
 
291
      char *p;
 
292
      int nr;
 
293
 
 
294
      nr = (n > LUAL_BUFFERSIZE) ? LUAL_BUFFERSIZE : n;
 
295
      p = luaL_prepbuffer (&b);
 
296
 
 
297
      nr = grub_file_read (file, p, nr);
 
298
      if (nr <= 0)
 
299
        break;
 
300
 
 
301
      luaL_addsize (&b, nr);
 
302
      n -= nr;
 
303
    }
 
304
 
 
305
  save_errno (state);
 
306
  luaL_pushresult (&b);
 
307
  return 1;
 
308
}
 
309
 
 
310
static int
 
311
grub_lua_file_getline (lua_State *state)
 
312
{
 
313
  grub_file_t file;
 
314
  char *line;
 
315
 
 
316
  luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
 
317
  file = lua_touserdata (state, 1);
 
318
 
 
319
  line = grub_file_getline (file);
 
320
  save_errno (state);
 
321
 
 
322
  if (! line)
 
323
    return 0;
 
324
 
 
325
  lua_pushstring (state, line);
 
326
  grub_free (line);
 
327
  return 1;
 
328
}
 
329
 
 
330
static int
 
331
grub_lua_file_getsize (lua_State *state)
 
332
{
 
333
  grub_file_t file;
 
334
 
 
335
  luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
 
336
  file = lua_touserdata (state, 1);
 
337
 
 
338
  lua_pushinteger (state, file->size);
 
339
  return 1;
 
340
}
 
341
 
 
342
static int
 
343
grub_lua_file_getpos (lua_State *state)
 
344
{
 
345
  grub_file_t file;
 
346
 
 
347
  luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
 
348
  file = lua_touserdata (state, 1);
 
349
 
 
350
  lua_pushinteger (state, file->offset);
 
351
  return 1;
 
352
}
 
353
 
 
354
static int
 
355
grub_lua_file_eof (lua_State *state)
 
356
{
 
357
  grub_file_t file;
 
358
 
 
359
  luaL_checktype (state, 1, LUA_TLIGHTUSERDATA);
 
360
  file = lua_touserdata (state, 1);
 
361
 
 
362
  lua_pushboolean (state, file->offset >= file->size);
 
363
  return 1;
 
364
}
 
365
 
 
366
static int
 
367
grub_lua_file_exist (lua_State *state)
 
368
{
 
369
  grub_file_t file;
 
370
  const char *name;
 
371
  int result;
 
372
 
 
373
  result = 0;
 
374
  name = luaL_checkstring (state, 1);
 
375
  file = grub_file_open (name);
 
376
  if (file)
 
377
    {
 
378
      result++;
 
379
      grub_file_close (file);
 
380
    }
 
381
  else
 
382
    grub_errno = 0;
 
383
 
 
384
  lua_pushboolean (state, result);
 
385
  return 1;
 
386
}
 
387
 
 
388
static int
 
389
grub_lua_add_menu (lua_State *state)
 
390
{
 
391
  int n;
 
392
  const char *source;
 
393
 
 
394
  source = luaL_checklstring (state, 1, 0);
 
395
  n = lua_gettop (state) - 1;
 
396
  if (n > 0)
 
397
    {
 
398
      const char *args[sizeof (char *) * n];
 
399
      char *p;
 
400
      int i;
 
401
 
 
402
      for (i = 0; i < n; i++)
 
403
        args[i] = luaL_checkstring (state, 2 + i);
 
404
 
 
405
      p = grub_strdup (source);
 
406
      if (! p)
 
407
        return push_result (state);
 
408
 
 
409
      grub_normal_add_menu_entry (n, args, p);
 
410
    }
 
411
  else
 
412
    {
 
413
      lua_pushstring (state, "not enough parameter");
 
414
      lua_error (state);
 
415
    }
 
416
 
 
417
  return push_result (state);
 
418
}
 
419
 
 
420
luaL_Reg grub_lua_lib[] =
 
421
  {
 
422
    {"run", grub_lua_run},
 
423
    {"getenv", grub_lua_getenv},
 
424
    {"setenv", grub_lua_setenv},
 
425
    {"enum_device", grub_lua_enum_device},
 
426
    {"enum_file", grub_lua_enum_file},
 
427
    {"file_open", grub_lua_file_open},
 
428
    {"file_close", grub_lua_file_close},
 
429
    {"file_seek", grub_lua_file_seek},
 
430
    {"file_read", grub_lua_file_read},
 
431
    {"file_getline", grub_lua_file_getline},
 
432
    {"file_getsize", grub_lua_file_getsize},
 
433
    {"file_getpos", grub_lua_file_getpos},
 
434
    {"file_eof", grub_lua_file_eof},
 
435
    {"file_exist", grub_lua_file_exist},
 
436
    {"add_menu", grub_lua_add_menu},
 
437
    {0, 0}
 
438
  };