]>
Commit | Line | Data |
---|---|---|
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 |
26 | struct grub_term_autoload *grub_term_input_autoload = NULL; |
27 | struct grub_term_autoload *grub_term_output_autoload = NULL; | |
28 | ||
0aa63398 VS |
29 | grub_err_t |
30 | grub_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 | ||
186 | grub_err_t | |
187 | grub_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 | ||
344 | static grub_command_t cmd_terminal_input, cmd_terminal_output; | |
345 | ||
346 | GRUB_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 | ||
360 | GRUB_MOD_FINI(terminal) | |
361 | { | |
362 | grub_unregister_command (cmd_terminal_input); | |
363 | grub_unregister_command (cmd_terminal_output); | |
364 | } |