]> git.proxmox.com Git - grub2.git/blame - normal/dyncmd.c
* normal/autofs.c (read_fs_list): New parameter 'prefix'.
[grub2.git] / normal / dyncmd.c
CommitLineData
d558e6b5 1/* dyncmd.c - support dynamic command */
2/*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2009 Free Software Foundation, Inc.
5 *
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <grub/dl.h>
21#include <grub/mm.h>
22#include <grub/env.h>
23#include <grub/misc.h>
24#include <grub/command.h>
25#include <grub/normal.h>
ec5f98ab 26#include <grub/i18n.h>
d558e6b5 27
28static grub_err_t
29grub_dyncmd_dispatcher (struct grub_command *cmd,
30 int argc, char **args)
31{
32 char *modname = cmd->data;
33 grub_dl_t mod;
34 grub_err_t ret;
35
36 mod = grub_dl_load (modname);
37 if (mod)
38 {
39 char *name;
40
41 grub_free (modname);
42 grub_dl_ref (mod);
43
44 name = (char *) cmd->name;
45 grub_unregister_command (cmd);
46
47 cmd = grub_command_find (name);
48 if (cmd)
49 ret = (cmd->func) (cmd, argc, args);
50 else
51 ret = grub_errno;
52
53 grub_free (name);
54 }
55 else
56 ret = grub_errno;
57
58 return ret;
59}
60
61/* Read the file command.lst for auto-loading. */
62void
027de555 63read_command_list (const char *prefix)
d558e6b5 64{
d558e6b5 65 if (prefix)
66 {
67 char *filename;
68
61eb45ee 69 filename = grub_xasprintf ("%s/command.lst", prefix);
d558e6b5 70 if (filename)
71 {
72 grub_file_t file;
73
d558e6b5 74 file = grub_file_open (filename);
75 if (file)
76 {
34f4a5b0 77 char *buf = NULL;
024478a2 78 grub_command_t ptr, last = 0, next;
e880248e
RM
79
80 /* Override previous commands.lst. */
024478a2 81 for (ptr = grub_command_list; ptr; ptr = next)
e880248e 82 {
024478a2
VS
83 next = ptr->next;
84 if (ptr->func == grub_dyncmd_dispatcher)
85 {
86 if (last)
87 last->next = ptr->next;
88 else
89 grub_command_list = ptr->next;
90 grub_free (ptr);
91 }
92 else
93 last = ptr;
e880248e
RM
94 }
95
ac451143 96 for (;; grub_free (buf))
d558e6b5 97 {
98 char *p, *name, *modname;
99 grub_command_t cmd;
100 int prio = 0;
101
102 buf = grub_file_getline (file);
103
104 if (! buf)
105 break;
106
107 name = buf;
108 if (*name == '*')
109 {
110 name++;
111 prio++;
112 }
113
114 if (! grub_isgraph (name[0]))
115 continue;
116
117 p = grub_strchr (name, ':');
118 if (! p)
119 continue;
120
121 *p = '\0';
122 while (*++p == ' ')
123 ;
124
125 if (! grub_isgraph (*p))
126 continue;
127
128 if (grub_dl_get (p))
129 continue;
130
131 name = grub_strdup (name);
132 if (! name)
133 continue;
134
135 modname = grub_strdup (p);
136 if (! modname)
137 {
138 grub_free (name);
139 continue;
140 }
141
142 cmd = grub_register_command_prio (name,
143 grub_dyncmd_dispatcher,
ec5f98ab 144 0, N_("not loaded"), prio);
d558e6b5 145 if (! cmd)
146 {
147 grub_free (name);
148 grub_free (modname);
149 continue;
150 }
151 cmd->flags |= GRUB_COMMAND_FLAG_DYNCMD;
152 cmd->data = modname;
153
154 /* Update the active flag. */
155 grub_command_find (name);
156 }
157
158 grub_file_close (file);
159 }
160
161 grub_free (filename);
162 }
163 }
164
165 /* Ignore errors. */
166 grub_errno = GRUB_ERR_NONE;
167}