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
;
130 return grub_error (GRUB_ERR_BAD_ARGUMENT
,
131 N_("terminal `%s' isn't found"),
137 if (grub_strcmp (args
[0], "--append") == 0)
139 for (i
= 1; i
< argc
; i
++)
141 for (term
= *disabled
; term
; term
= term
->next
)
142 if (grub_strcmp (args
[i
], term
->name
) == 0
143 || (grub_strcmp (args
[i
], "ofconsole") == 0
144 && grub_strcmp ("console", term
->name
) == 0))
148 if (term
->init
&& term
->init (term
) != GRUB_ERR_NONE
)
151 grub_list_remove (GRUB_AS_LIST (term
));
152 grub_list_push (GRUB_AS_LIST_P (enabled
), GRUB_AS_LIST (term
));
155 return GRUB_ERR_NONE
;
158 if (grub_strcmp (args
[0], "--remove") == 0)
160 for (i
= 1; i
< argc
; i
++)
162 for (term
= *enabled
; term
; term
= term
->next
)
163 if (grub_strcmp (args
[i
], term
->name
) == 0
164 || (grub_strcmp (args
[i
], "ofconsole") == 0
165 && grub_strcmp ("console", term
->name
) == 0))
169 if (!term
->next
&& term
== *enabled
)
170 return grub_error (GRUB_ERR_BAD_ARGUMENT
,
171 "can't remove the last terminal");
172 grub_list_remove (GRUB_AS_LIST (term
));
175 grub_list_push (GRUB_AS_LIST_P (disabled
), GRUB_AS_LIST (term
));
178 return GRUB_ERR_NONE
;
180 for (i
= 0; i
< argc
; i
++)
182 for (term
= *disabled
; term
; term
= term
->next
)
183 if (grub_strcmp (args
[i
], term
->name
) == 0
184 || (grub_strcmp (args
[i
], "ofconsole") == 0
185 && grub_strcmp ("console", term
->name
) == 0))
189 if (term
->init
&& term
->init (term
) != GRUB_ERR_NONE
)
192 grub_list_remove (GRUB_AS_LIST (term
));
193 grub_list_push (GRUB_AS_LIST_P (enabled
), GRUB_AS_LIST (term
));
198 struct abstract_terminal
*next
;
199 for (term
= *enabled
; term
; term
= next
)
202 for (i
= 0; i
< argc
; i
++)
203 if (grub_strcmp (args
[i
], term
->name
) == 0
204 || (grub_strcmp (args
[i
], "ofconsole") == 0
205 && grub_strcmp ("console", term
->name
) == 0))
209 if (!term
->next
&& term
== *enabled
)
210 return grub_error (GRUB_ERR_BAD_ARGUMENT
,
211 "can't remove the last terminal");
212 grub_list_remove (GRUB_AS_LIST (term
));
215 grub_list_push (GRUB_AS_LIST_P (disabled
), GRUB_AS_LIST (term
));
220 return GRUB_ERR_NONE
;
224 grub_cmd_terminal_input (grub_command_t cmd
__attribute__ ((unused
)),
225 int argc
, char **args
)
227 (void) GRUB_FIELD_MATCH (grub_term_inputs
, struct abstract_terminal
*, next
);
228 (void) GRUB_FIELD_MATCH (grub_term_inputs
, struct abstract_terminal
*, prev
);
229 (void) GRUB_FIELD_MATCH (grub_term_inputs
, struct abstract_terminal
*, name
);
230 (void) GRUB_FIELD_MATCH (grub_term_inputs
, struct abstract_terminal
*, init
);
231 (void) GRUB_FIELD_MATCH (grub_term_inputs
, struct abstract_terminal
*, fini
);
232 return handle_command (argc
, args
,
233 (struct abstract_terminal
**) (void *) &grub_term_inputs
,
234 (struct abstract_terminal
**) (void *) &grub_term_inputs_disabled
,
235 grub_term_input_autoload
,
236 N_ ("Active input terminals:"),
237 N_ ("Available input terminals:"));
241 grub_cmd_terminal_output (grub_command_t cmd
__attribute__ ((unused
)),
242 int argc
, char **args
)
244 (void) GRUB_FIELD_MATCH (grub_term_outputs
, struct abstract_terminal
*, next
);
245 (void) GRUB_FIELD_MATCH (grub_term_outputs
, struct abstract_terminal
*, prev
);
246 (void) GRUB_FIELD_MATCH (grub_term_outputs
, struct abstract_terminal
*, name
);
247 (void) GRUB_FIELD_MATCH (grub_term_outputs
, struct abstract_terminal
*, init
);
248 (void) GRUB_FIELD_MATCH (grub_term_outputs
, struct abstract_terminal
*, fini
);
249 return handle_command (argc
, args
,
250 (struct abstract_terminal
**) (void *) &grub_term_outputs
,
251 (struct abstract_terminal
**) (void *) &grub_term_outputs_disabled
,
252 grub_term_output_autoload
,
253 N_ ("Active output terminals:"),
254 N_ ("Available output terminals:"));
257 static grub_command_t cmd_terminal_input
, cmd_terminal_output
;
259 GRUB_MOD_INIT(terminal
)
262 grub_register_command ("terminal_input", grub_cmd_terminal_input
,
263 N_("[--append|--remove] "
264 "[TERMINAL1] [TERMINAL2] ..."),
265 N_("List or select an input terminal."));
266 cmd_terminal_output
=
267 grub_register_command ("terminal_output", grub_cmd_terminal_output
,
268 N_("[--append|--remove] "
269 "[TERMINAL1] [TERMINAL2] ..."),
270 N_("List or select an output terminal."));
273 GRUB_MOD_FINI(terminal
)
275 grub_unregister_command (cmd_terminal_input
);
276 grub_unregister_command (cmd_terminal_output
);