]> git.proxmox.com Git - grub2.git/blame - grub-core/commands/terminal.c
probe: Support probing for partition UUID with --part-uuid
[grub2.git] / grub-core / commands / terminal.c
CommitLineData
0aa63398
VS
1/*
2 * GRUB -- GRand Unified Bootloader
9444b678 3 * Copyright (C) 2009,2010 Free Software Foundation, Inc.
0aa63398
VS
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 <grub/mm.h>
20#include <grub/dl.h>
21#include <grub/command.h>
22#include <grub/term.h>
23#include <grub/i18n.h>
24#include <grub/misc.h>
25
e745cf0c
VS
26GRUB_MOD_LICENSE ("GPLv3+");
27
33c1ed4c
VS
28struct grub_term_autoload *grub_term_input_autoload = NULL;
29struct grub_term_autoload *grub_term_output_autoload = NULL;
30
6f8aaf68
VS
31struct abstract_terminal
32{
33 struct abstract_terminal *next;
87edb894 34 struct abstract_terminal *prev;
6f8aaf68 35 const char *name;
58664b94
VS
36 grub_err_t (*init) (struct abstract_terminal *term);
37 grub_err_t (*fini) (struct abstract_terminal *term);
6f8aaf68
VS
38};
39
d8a1cbbd 40static grub_err_t
6f8aaf68
VS
41handle_command (int argc, char **args, struct abstract_terminal **enabled,
42 struct abstract_terminal **disabled,
43 struct grub_term_autoload *autoloads,
44 const char *active_str,
45 const char *available_str)
0aa63398
VS
46{
47 int i;
6f8aaf68 48 struct abstract_terminal *term;
33c1ed4c 49 struct grub_term_autoload *aut;
0aa63398
VS
50
51 if (argc == 0)
52 {
6f8aaf68
VS
53 grub_puts_ (active_str);
54 for (term = *enabled; term; term = term->next)
55 grub_printf ("%s ", term->name);
0aa63398 56 grub_printf ("\n");
6f8aaf68
VS
57 grub_puts_ (available_str);
58 for (term = *disabled; term; term = term->next)
59 grub_printf ("%s ", term->name);
33c1ed4c 60 /* This is quadratic but we don't expect mode than 30 terminal
6f8aaf68
VS
61 modules ever. */
62 for (aut = autoloads; aut; aut = aut->next)
63 {
64 for (term = *disabled; term; term = term->next)
75eb7d11
VS
65 if (grub_strcmp (term->name, aut->name) == 0
66 || (aut->name[0] && aut->name[grub_strlen (aut->name) - 1] == '*'
67 && grub_memcmp (term->name, aut->name,
68 grub_strlen (aut->name) - 1) == 0))
6f8aaf68
VS
69 break;
70 if (!term)
71 for (term = *enabled; term; term = term->next)
75eb7d11
VS
72 if (grub_strcmp (term->name, aut->name) == 0
73 || (aut->name[0] && aut->name[grub_strlen (aut->name) - 1] == '*'
74 && grub_memcmp (term->name, aut->name,
75 grub_strlen (aut->name) - 1) == 0))
6f8aaf68
VS
76 break;
77 if (!term)
78 grub_printf ("%s ", aut->name);
79 }
0aa63398
VS
80 grub_printf ("\n");
81 return GRUB_ERR_NONE;
82 }
83 i = 0;
84
85 if (grub_strcmp (args[0], "--append") == 0
abd1cab3 86 || grub_strcmp (args[0], "--remove") == 0)
0aa63398
VS
87 i++;
88
89 if (i == argc)
90 return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no terminal specified"));
91
92 for (; i < argc; i++)
93 {
33c1ed4c
VS
94 int again = 0;
95 while (1)
6f8aaf68
VS
96 {
97 for (term = *disabled; term; term = term->next)
ca8c0baf
VS
98 if (grub_strcmp (args[i], term->name) == 0
99 || (grub_strcmp (args[i], "ofconsole") == 0
100 && grub_strcmp ("console", term->name) == 0))
6f8aaf68
VS
101 break;
102 if (term == 0)
103 for (term = *enabled; term; term = term->next)
ca8c0baf
VS
104 if (grub_strcmp (args[i], term->name) == 0
105 || (grub_strcmp (args[i], "ofconsole") == 0
106 && grub_strcmp ("console", term->name) == 0))
6f8aaf68
VS
107 break;
108 if (term)
109 break;
110 if (again)
d745dda7 111 return grub_error (GRUB_ERR_BAD_ARGUMENT,
d61386e2 112 N_("terminal `%s' isn't found"),
d745dda7 113 args[i]);
6f8aaf68 114 for (aut = autoloads; aut; aut = aut->next)
75eb7d11 115 if (grub_strcmp (args[i], aut->name) == 0
ca8c0baf
VS
116 || (grub_strcmp (args[i], "ofconsole") == 0
117 && grub_strcmp ("console", aut->name) == 0)
75eb7d11
VS
118 || (aut->name[0] && aut->name[grub_strlen (aut->name) - 1] == '*'
119 && grub_memcmp (args[i], aut->name,
120 grub_strlen (aut->name) - 1) == 0))
6f8aaf68
VS
121 {
122 grub_dl_t mod;
123 mod = grub_dl_load (aut->modname);
124 if (mod)
125 grub_dl_ref (mod);
126 grub_errno = GRUB_ERR_NONE;
127 break;
128 }
d745dda7
VS
129 if (grub_memcmp (args[i], "serial_usb",
130 sizeof ("serial_usb") - 1) == 0
131 && grub_term_poll_usb)
132 {
133 grub_term_poll_usb (1);
134 again = 1;
135 continue;
136 }
6f8aaf68 137 if (!aut)
d61386e2
VS
138 return grub_error (GRUB_ERR_BAD_ARGUMENT,
139 N_("terminal `%s' isn't found"),
6f8aaf68
VS
140 args[i]);
141 again = 1;
142 }
0aa63398
VS
143 }
144
145 if (grub_strcmp (args[0], "--append") == 0)
146 {
147 for (i = 1; i < argc; i++)
6f8aaf68
VS
148 {
149 for (term = *disabled; term; term = term->next)
ca8c0baf
VS
150 if (grub_strcmp (args[i], term->name) == 0
151 || (grub_strcmp (args[i], "ofconsole") == 0
152 && grub_strcmp ("console", term->name) == 0))
6f8aaf68
VS
153 break;
154 if (term)
155 {
58664b94 156 if (term->init && term->init (term) != GRUB_ERR_NONE)
cba98e8d
RM
157 return grub_errno;
158
87edb894 159 grub_list_remove (GRUB_AS_LIST (term));
6f8aaf68
VS
160 grub_list_push (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
161 }
162 }
0aa63398
VS
163 return GRUB_ERR_NONE;
164 }
165
166 if (grub_strcmp (args[0], "--remove") == 0)
167 {
168 for (i = 1; i < argc; i++)
6f8aaf68
VS
169 {
170 for (term = *enabled; term; term = term->next)
ca8c0baf
VS
171 if (grub_strcmp (args[i], term->name) == 0
172 || (grub_strcmp (args[i], "ofconsole") == 0
173 && grub_strcmp ("console", term->name) == 0))
6f8aaf68
VS
174 break;
175 if (term)
176 {
177 if (!term->next && term == *enabled)
178 return grub_error (GRUB_ERR_BAD_ARGUMENT,
179 "can't remove the last terminal");
87edb894 180 grub_list_remove (GRUB_AS_LIST (term));
6f8aaf68 181 if (term->fini)
58664b94 182 term->fini (term);
6f8aaf68
VS
183 grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
184 }
185 }
0aa63398
VS
186 return GRUB_ERR_NONE;
187 }
188 for (i = 0; i < argc; i++)
189 {
6f8aaf68 190 for (term = *disabled; term; term = term->next)
ca8c0baf
VS
191 if (grub_strcmp (args[i], term->name) == 0
192 || (grub_strcmp (args[i], "ofconsole") == 0
193 && grub_strcmp ("console", term->name) == 0))
6f8aaf68 194 break;
0aa63398 195 if (term)
6f8aaf68 196 {
58664b94 197 if (term->init && term->init (term) != GRUB_ERR_NONE)
6f8aaf68 198 return grub_errno;
cba98e8d 199
87edb894 200 grub_list_remove (GRUB_AS_LIST (term));
6f8aaf68
VS
201 grub_list_push (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
202 }
0aa63398 203 }
6f8aaf68 204
0aa63398 205 {
6f8aaf68
VS
206 struct abstract_terminal *next;
207 for (term = *enabled; term; term = next)
0aa63398 208 {
6f8aaf68
VS
209 next = term->next;
210 for (i = 0; i < argc; i++)
ca8c0baf
VS
211 if (grub_strcmp (args[i], term->name) == 0
212 || (grub_strcmp (args[i], "ofconsole") == 0
213 && grub_strcmp ("console", term->name) == 0))
6f8aaf68
VS
214 break;
215 if (i == argc)
216 {
217 if (!term->next && term == *enabled)
218 return grub_error (GRUB_ERR_BAD_ARGUMENT,
219 "can't remove the last terminal");
87edb894 220 grub_list_remove (GRUB_AS_LIST (term));
6f8aaf68 221 if (term->fini)
58664b94 222 term->fini (term);
6f8aaf68
VS
223 grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
224 }
0aa63398
VS
225 }
226 }
227
228 return GRUB_ERR_NONE;
229}
230
d8a1cbbd 231static grub_err_t
6f8aaf68 232grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)),
0aa63398
VS
233 int argc, char **args)
234{
6f8aaf68 235 (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, next);
87edb894 236 (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, prev);
6f8aaf68
VS
237 (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, name);
238 (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, init);
239 (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, fini);
240 return handle_command (argc, args,
fc836af9
VS
241 (struct abstract_terminal **) (void *) &grub_term_inputs,
242 (struct abstract_terminal **) (void *) &grub_term_inputs_disabled,
243 grub_term_input_autoload,
244 N_ ("Active input terminals:"),
245 N_ ("Available input terminals:"));
6f8aaf68 246}
0aa63398 247
6f8aaf68
VS
248static grub_err_t
249grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)),
250 int argc, char **args)
251{
252 (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, next);
87edb894 253 (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, prev);
6f8aaf68
VS
254 (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, name);
255 (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, init);
256 (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, fini);
fc836af9
VS
257 return handle_command (argc, args,
258 (struct abstract_terminal **) (void *) &grub_term_outputs,
259 (struct abstract_terminal **) (void *) &grub_term_outputs_disabled,
260 grub_term_output_autoload,
261 N_ ("Active output terminals:"),
262 N_ ("Available output terminals:"));
0aa63398
VS
263}
264
265static grub_command_t cmd_terminal_input, cmd_terminal_output;
266
267GRUB_MOD_INIT(terminal)
268{
269 cmd_terminal_input =
270 grub_register_command ("terminal_input", grub_cmd_terminal_input,
d8b5cd40
VS
271 N_("[--append|--remove] "
272 "[TERMINAL1] [TERMINAL2] ..."),
273 N_("List or select an input terminal."));
0aa63398
VS
274 cmd_terminal_output =
275 grub_register_command ("terminal_output", grub_cmd_terminal_output,
d8b5cd40
VS
276 N_("[--append|--remove] "
277 "[TERMINAL1] [TERMINAL2] ..."),
278 N_("List or select an output terminal."));
0aa63398
VS
279}
280
281GRUB_MOD_FINI(terminal)
282{
283 grub_unregister_command (cmd_terminal_input);
284 grub_unregister_command (cmd_terminal_output);
285}