2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2009,2010 Free Software Foundation, Inc.
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.
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.
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/>.
21 #include <grub/command.h>
22 #include <grub/term.h>
23 #include <grub/i18n.h>
24 #include <grub/misc.h>
26 GRUB_MOD_LICENSE ("GPLv3+");
28 struct grub_term_autoload
*grub_term_input_autoload
= NULL
;
29 struct grub_term_autoload
*grub_term_output_autoload
= NULL
;
31 struct abstract_terminal
33 struct abstract_terminal
*next
;
34 struct abstract_terminal
*prev
;
36 grub_err_t (*init
) (struct abstract_terminal
*term
);
37 grub_err_t (*fini
) (struct abstract_terminal
*term
);
41 handle_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
)
48 struct abstract_terminal
*term
;
49 struct grub_term_autoload
*aut
;
53 grub_puts_ (active_str
);
54 for (term
= *enabled
; term
; term
= term
->next
)
55 grub_printf ("%s ", term
->name
);
57 grub_puts_ (available_str
);
58 for (term
= *disabled
; term
; term
= term
->next
)
59 grub_printf ("%s ", term
->name
);
60 /* This is quadratic but we don't expect mode than 30 terminal
62 for (aut
= autoloads
; aut
; aut
= aut
->next
)
64 for (term
= *disabled
; term
; term
= term
->next
)
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))
71 for (term
= *enabled
; term
; term
= term
->next
)
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))
78 grub_printf ("%s ", aut
->name
);
85 if (grub_strcmp (args
[0], "--append") == 0
86 || grub_strcmp (args
[0], "--remove") == 0)
90 return grub_error (GRUB_ERR_BAD_ARGUMENT
, N_ ("no terminal specified"));
97 for (term
= *disabled
; term
; term
= term
->next
)
98 if (grub_strcmp (args
[i
], term
->name
) == 0
99 || (grub_strcmp (args
[i
], "ofconsole") == 0
100 && grub_strcmp ("console", term
->name
) == 0))
103 for (term
= *enabled
; term
; term
= term
->next
)
104 if (grub_strcmp (args
[i
], term
->name
) == 0
105 || (grub_strcmp (args
[i
], "ofconsole") == 0
106 && grub_strcmp ("console", term
->name
) == 0))
111 return grub_error (GRUB_ERR_BAD_ARGUMENT
,
112 N_("terminal `%s' isn't found"),
114 for (aut
= autoloads
; aut
; aut
= aut
->next
)
115 if (grub_strcmp (args
[i
], aut
->name
) == 0
116 || (grub_strcmp (args
[i
], "ofconsole") == 0
117 && grub_strcmp ("console", aut
->name
) == 0)
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))
123 mod
= grub_dl_load (aut
->modname
);
126 grub_errno
= GRUB_ERR_NONE
;
129 if (grub_memcmp (args
[i
], "serial_usb",
130 sizeof ("serial_usb") - 1) == 0
131 && grub_term_poll_usb
)
133 grub_term_poll_usb (1);
138 return grub_error (GRUB_ERR_BAD_ARGUMENT
,
139 N_("terminal `%s' isn't found"),
145 if (grub_strcmp (args
[0], "--append") == 0)
147 for (i
= 1; i
< argc
; i
++)
149 for (term
= *disabled
; term
; term
= term
->next
)
150 if (grub_strcmp (args
[i
], term
->name
) == 0
151 || (grub_strcmp (args
[i
], "ofconsole") == 0
152 && grub_strcmp ("console", term
->name
) == 0))
156 if (term
->init
&& term
->init (term
) != GRUB_ERR_NONE
)
159 grub_list_remove (GRUB_AS_LIST (term
));
160 grub_list_push (GRUB_AS_LIST_P (enabled
), GRUB_AS_LIST (term
));
163 return GRUB_ERR_NONE
;
166 if (grub_strcmp (args
[0], "--remove") == 0)
168 for (i
= 1; i
< argc
; i
++)
170 for (term
= *enabled
; term
; term
= term
->next
)
171 if (grub_strcmp (args
[i
], term
->name
) == 0
172 || (grub_strcmp (args
[i
], "ofconsole") == 0
173 && grub_strcmp ("console", term
->name
) == 0))
177 if (!term
->next
&& term
== *enabled
)
178 return grub_error (GRUB_ERR_BAD_ARGUMENT
,
179 "can't remove the last terminal");
180 grub_list_remove (GRUB_AS_LIST (term
));
183 grub_list_push (GRUB_AS_LIST_P (disabled
), GRUB_AS_LIST (term
));
186 return GRUB_ERR_NONE
;
188 for (i
= 0; i
< argc
; i
++)
190 for (term
= *disabled
; term
; term
= term
->next
)
191 if (grub_strcmp (args
[i
], term
->name
) == 0
192 || (grub_strcmp (args
[i
], "ofconsole") == 0
193 && grub_strcmp ("console", term
->name
) == 0))
197 if (term
->init
&& term
->init (term
) != GRUB_ERR_NONE
)
200 grub_list_remove (GRUB_AS_LIST (term
));
201 grub_list_push (GRUB_AS_LIST_P (enabled
), GRUB_AS_LIST (term
));
206 struct abstract_terminal
*next
;
207 for (term
= *enabled
; term
; term
= next
)
210 for (i
= 0; i
< argc
; i
++)
211 if (grub_strcmp (args
[i
], term
->name
) == 0
212 || (grub_strcmp (args
[i
], "ofconsole") == 0
213 && grub_strcmp ("console", term
->name
) == 0))
217 if (!term
->next
&& term
== *enabled
)
218 return grub_error (GRUB_ERR_BAD_ARGUMENT
,
219 "can't remove the last terminal");
220 grub_list_remove (GRUB_AS_LIST (term
));
223 grub_list_push (GRUB_AS_LIST_P (disabled
), GRUB_AS_LIST (term
));
228 return GRUB_ERR_NONE
;
232 grub_cmd_terminal_input (grub_command_t cmd
__attribute__ ((unused
)),
233 int argc
, char **args
)
235 (void) GRUB_FIELD_MATCH (grub_term_inputs
, struct abstract_terminal
*, next
);
236 (void) GRUB_FIELD_MATCH (grub_term_inputs
, struct abstract_terminal
*, prev
);
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
,
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:"));
249 grub_cmd_terminal_output (grub_command_t cmd
__attribute__ ((unused
)),
250 int argc
, char **args
)
252 (void) GRUB_FIELD_MATCH (grub_term_outputs
, struct abstract_terminal
*, next
);
253 (void) GRUB_FIELD_MATCH (grub_term_outputs
, struct abstract_terminal
*, prev
);
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
);
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:"));
265 static grub_command_t cmd_terminal_input
, cmd_terminal_output
;
267 GRUB_MOD_INIT(terminal
)
270 grub_register_command ("terminal_input", grub_cmd_terminal_input
,
271 N_("[--append|--remove] "
272 "[TERMINAL1] [TERMINAL2] ..."),
273 N_("List or select an input terminal."));
274 cmd_terminal_output
=
275 grub_register_command ("terminal_output", grub_cmd_terminal_output
,
276 N_("[--append|--remove] "
277 "[TERMINAL1] [TERMINAL2] ..."),
278 N_("List or select an output terminal."));
281 GRUB_MOD_FINI(terminal
)
283 grub_unregister_command (cmd_terminal_input
);
284 grub_unregister_command (cmd_terminal_output
);