]> git.proxmox.com Git - grub2.git/blame - commands/terminal.c
always_inline cl_print to avoid regparm=3 bug
[grub2.git] / commands / terminal.c
CommitLineData
0aa63398
VS
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 <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
33c1ed4c
VS
26struct grub_term_autoload *grub_term_input_autoload = NULL;
27struct grub_term_autoload *grub_term_output_autoload = NULL;
28
0aa63398
VS
29grub_err_t
30grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)),
31 int argc, char **args)
32{
33 int i;
34 grub_term_input_t term;
33c1ed4c 35 struct grub_term_autoload *aut;
0aa63398
VS
36
37 if (argc == 0)
38 {
39 grub_puts_ (N_ ("Active input terminals:"));
40 FOR_ACTIVE_TERM_INPUTS(term)
41 grub_printf ("%s ", term->name);
42 grub_printf ("\n");
43 grub_puts_ (N_ ("Available input terminals:"));
44 FOR_DISABLED_TERM_INPUTS(term)
45 grub_printf ("%s ", term->name);
33c1ed4c
VS
46 /* This is quadratic but we don't expect mode than 30 terminal
47 modules ever. */
48 for (aut = grub_term_input_autoload; aut; aut = aut->next)
49 {
50 FOR_DISABLED_TERM_INPUTS(term)
51 if (grub_strcmp (term->name, aut->name) == 0)
52 break;
53 if (!term)
54 FOR_ACTIVE_TERM_INPUTS(term)
55 if (grub_strcmp (term->name, aut->name) == 0)
56 break;
57 if (!term)
58 grub_printf ("%s ", aut->name);
59 }
0aa63398
VS
60 grub_printf ("\n");
61 return GRUB_ERR_NONE;
62 }
63 i = 0;
64
65 if (grub_strcmp (args[0], "--append") == 0
abd1cab3 66 || grub_strcmp (args[0], "--remove") == 0)
0aa63398
VS
67 i++;
68
69 if (i == argc)
70 return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no terminal specified"));
71
72 for (; i < argc; i++)
73 {
33c1ed4c
VS
74 int again = 0;
75 while (1)
76 {
77 FOR_DISABLED_TERM_INPUTS(term)
78 if (grub_strcmp (args[i], term->name) == 0)
79 break;
80 if (term == 0)
81 FOR_ACTIVE_TERM_INPUTS(term)
82 if (grub_strcmp (args[i], term->name) == 0)
83 break;
84 if (term)
0aa63398 85 break;
33c1ed4c
VS
86 if (again)
87 return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
88 args[i]);
89 for (aut = grub_term_input_autoload; aut; aut = aut->next)
90 if (grub_strcmp (args[i], aut->name) == 0)
91 {
92 grub_dl_t mod;
93 mod = grub_dl_load (aut->modname);
94 if (mod)
95 grub_dl_ref (mod);
96 grub_errno = GRUB_ERR_NONE;
97 break;
98 }
99 if (!aut)
100 return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
101 args[i]);
102 again = 1;
103 }
0aa63398
VS
104 }
105
106 if (grub_strcmp (args[0], "--append") == 0)
107 {
108 for (i = 1; i < argc; i++)
109 {
110 FOR_DISABLED_TERM_INPUTS(term)
111 if (grub_strcmp (args[i], term->name) == 0)
112 break;
113 if (term)
114 {
115 grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs_disabled)),
116 GRUB_AS_LIST (term));
117 if (term->init)
118 term->init ();
119 grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs),
120 GRUB_AS_LIST (term));
121 }
122 }
123 return GRUB_ERR_NONE;
124 }
125
126 if (grub_strcmp (args[0], "--remove") == 0)
127 {
128 for (i = 1; i < argc; i++)
129 {
130 FOR_ACTIVE_TERM_INPUTS(term)
131 if (grub_strcmp (args[i], term->name) == 0)
132 break;
133 if (term)
134 {
135 if (!term->next && term == grub_term_inputs)
136 return grub_error (GRUB_ERR_BAD_ARGUMENT,
137 "can't remove the last terminal");
138 grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs)),
139 GRUB_AS_LIST (term));
140 if (term->fini)
141 term->fini ();
142 grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled),
143 GRUB_AS_LIST (term));
144 }
145 }
146 return GRUB_ERR_NONE;
147 }
148 for (i = 0; i < argc; i++)
149 {
150 FOR_DISABLED_TERM_INPUTS(term)
151 if (grub_strcmp (args[i], term->name) == 0)
152 break;
153 if (term)
154 {
155 grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs_disabled)),
156 GRUB_AS_LIST (term));
157 if (term->init)
158 term->init ();
159 grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs),
160 GRUB_AS_LIST (term));
161 }
162 }
163
164 FOR_ACTIVE_TERM_INPUTS(term)
165 {
166 for (i = 0; i < argc; i++)
167 if (grub_strcmp (args[i], term->name) == 0)
168 break;
abd1cab3 169 if (i == argc)
0aa63398
VS
170 {
171 if (!term->next && term == grub_term_inputs)
172 return grub_error (GRUB_ERR_BAD_ARGUMENT,
173 "can't remove the last terminal");
174 grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs)),
175 GRUB_AS_LIST (term));
176 if (term->fini)
177 term->fini ();
178 grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled),
179 GRUB_AS_LIST (term));
180 }
181 }
182
183 return GRUB_ERR_NONE;
184}
185
186grub_err_t
187grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)),
188 int argc, char **args)
189{
190 int i;
191 grub_term_output_t term;
33c1ed4c 192 struct grub_term_autoload *aut;
0aa63398
VS
193
194 if (argc == 0)
195 {
196 grub_puts_ (N_ ("Active output terminals:"));
197 FOR_ACTIVE_TERM_OUTPUTS(term)
198 grub_printf ("%s ", term->name);
199 grub_printf ("\n");
200 grub_puts_ (N_ ("Available output terminals:"));
201 FOR_DISABLED_TERM_OUTPUTS(term)
202 grub_printf ("%s ", term->name);
33c1ed4c
VS
203 /* This is quadratic but we don't expect mode than 30 terminal
204 modules ever. */
205 for (aut = grub_term_output_autoload; aut; aut = aut->next)
206 {
207 FOR_DISABLED_TERM_OUTPUTS(term)
208 if (grub_strcmp (term->name, aut->name) == 0)
209 break;
210 if (!term)
211 FOR_ACTIVE_TERM_OUTPUTS(term)
212 if (grub_strcmp (term->name, aut->name) == 0)
213 break;
214 if (!term)
215 grub_printf ("%s ", aut->name);
216 }
0aa63398
VS
217 grub_printf ("\n");
218 return GRUB_ERR_NONE;
219 }
220 i = 0;
221
222 if (grub_strcmp (args[0], "--append") == 0
abd1cab3 223 || grub_strcmp (args[0], "--remove") == 0)
0aa63398
VS
224 i++;
225
226 if (i == argc)
227 return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no terminal specified"));
228
229 for (; i < argc; i++)
230 {
33c1ed4c
VS
231 int again = 0;
232 while (1)
233 {
234 FOR_DISABLED_TERM_OUTPUTS(term)
235 if (grub_strcmp (args[i], term->name) == 0)
236 break;
237 if (term == 0)
238 FOR_ACTIVE_TERM_OUTPUTS(term)
239 if (grub_strcmp (args[i], term->name) == 0)
240 break;
241 if (term)
0aa63398 242 break;
33c1ed4c
VS
243 if (again)
244 return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
245 args[i]);
246 for (aut = grub_term_output_autoload; aut; aut = aut->next)
247 if (grub_strcmp (args[i], aut->name) == 0)
248 {
249 grub_dl_t mod;
250 mod = grub_dl_load (aut->modname);
251 if (mod)
252 grub_dl_ref (mod);
253 grub_errno = GRUB_ERR_NONE;
254 break;
255 }
256 if (!aut)
257 return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
258 args[i]);
259 again = 1;
260 }
0aa63398
VS
261 }
262
263 if (grub_strcmp (args[0], "--append") == 0)
264 {
265 for (i = 1; i < argc; i++)
266 {
267 FOR_DISABLED_TERM_OUTPUTS(term)
268 if (grub_strcmp (args[i], term->name) == 0)
269 break;
270 if (term)
271 {
272 grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)),
273 GRUB_AS_LIST (term));
274 if (term->init)
275 term->init ();
276 grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs),
277 GRUB_AS_LIST (term));
278 }
279 }
280 return GRUB_ERR_NONE;
281 }
282
283 if (grub_strcmp (args[0], "--remove") == 0)
284 {
285 for (i = 1; i < argc; i++)
286 {
287 FOR_ACTIVE_TERM_OUTPUTS(term)
288 if (grub_strcmp (args[i], term->name) == 0)
289 break;
290 if (term)
291 {
292 if (!term->next && term == grub_term_outputs)
293 return grub_error (GRUB_ERR_BAD_ARGUMENT,
294 "can't remove the last terminal");
295 grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs)),
296 GRUB_AS_LIST (term));
297 if (term->fini)
298 term->fini ();
299 grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled),
300 GRUB_AS_LIST (term));
301 }
302 }
303 return GRUB_ERR_NONE;
304 }
abd1cab3 305
0aa63398
VS
306 for (i = 0; i < argc; i++)
307 {
308 FOR_DISABLED_TERM_OUTPUTS(term)
309 if (grub_strcmp (args[i], term->name) == 0)
310 break;
311 if (term)
312 {
313 grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)),
314 GRUB_AS_LIST (term));
315 if (term->init)
316 term->init ();
317 grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs),
318 GRUB_AS_LIST (term));
319 }
320 }
321
322 FOR_ACTIVE_TERM_OUTPUTS(term)
323 {
324 for (i = 0; i < argc; i++)
325 if (grub_strcmp (args[i], term->name) == 0)
326 break;
abd1cab3 327 if (i == argc)
0aa63398
VS
328 {
329 if (!term->next && term == grub_term_outputs)
330 return grub_error (GRUB_ERR_BAD_ARGUMENT,
331 "can't remove the last terminal");
332 grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs)),
333 GRUB_AS_LIST (term));
334 if (term->fini)
335 term->fini ();
336 grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled),
337 GRUB_AS_LIST (term));
338 }
339 }
340
341 return GRUB_ERR_NONE;
342}
343
344static grub_command_t cmd_terminal_input, cmd_terminal_output;
345
346GRUB_MOD_INIT(terminal)
347{
348 cmd_terminal_input =
349 grub_register_command ("terminal_input", grub_cmd_terminal_input,
350 "terminal_input [--append|--remove] "
351 "[TERMINAL1] [TERMINAL2] ...",
352 "List or select an input terminal.");
353 cmd_terminal_output =
354 grub_register_command ("terminal_output", grub_cmd_terminal_output,
355 "terminal_output [--append|--remove] "
356 "[TERMINAL1] [TERMINAL2] ...",
357 "List or select an output terminal.");
358}
359
360GRUB_MOD_FINI(terminal)
361{
362 grub_unregister_command (cmd_terminal_input);
363 grub_unregister_command (cmd_terminal_output);
364}