]> git.proxmox.com Git - grub2.git/blame - commands/terminal.c
make serial use ANSI code recognition in terminfo.mod
[grub2.git] / 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
33c1ed4c
VS
26struct grub_term_autoload *grub_term_input_autoload = NULL;
27struct grub_term_autoload *grub_term_output_autoload = NULL;
28
6f8aaf68
VS
29struct abstract_terminal
30{
31 struct abstract_terminal *next;
32 const char *name;
33 grub_err_t (*init) (void);
34 grub_err_t (*fini) (void);
35};
36
d8a1cbbd 37static grub_err_t
6f8aaf68
VS
38handle_command (int argc, char **args, struct abstract_terminal **enabled,
39 struct abstract_terminal **disabled,
40 struct grub_term_autoload *autoloads,
41 const char *active_str,
42 const char *available_str)
0aa63398
VS
43{
44 int i;
6f8aaf68 45 struct abstract_terminal *term;
33c1ed4c 46 struct grub_term_autoload *aut;
0aa63398
VS
47
48 if (argc == 0)
49 {
6f8aaf68
VS
50 grub_puts_ (active_str);
51 for (term = *enabled; term; term = term->next)
52 grub_printf ("%s ", term->name);
0aa63398 53 grub_printf ("\n");
6f8aaf68
VS
54 grub_puts_ (available_str);
55 for (term = *disabled; term; term = term->next)
56 grub_printf ("%s ", term->name);
33c1ed4c 57 /* This is quadratic but we don't expect mode than 30 terminal
6f8aaf68
VS
58 modules ever. */
59 for (aut = autoloads; aut; aut = aut->next)
60 {
61 for (term = *disabled; term; term = term->next)
62 if (grub_strcmp (term->name, aut->name) == 0)
63 break;
64 if (!term)
65 for (term = *enabled; term; term = term->next)
66 if (grub_strcmp (term->name, aut->name) == 0)
67 break;
68 if (!term)
69 grub_printf ("%s ", aut->name);
70 }
0aa63398
VS
71 grub_printf ("\n");
72 return GRUB_ERR_NONE;
73 }
74 i = 0;
75
76 if (grub_strcmp (args[0], "--append") == 0
abd1cab3 77 || grub_strcmp (args[0], "--remove") == 0)
0aa63398
VS
78 i++;
79
80 if (i == argc)
81 return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no terminal specified"));
82
83 for (; i < argc; i++)
84 {
33c1ed4c
VS
85 int again = 0;
86 while (1)
6f8aaf68
VS
87 {
88 for (term = *disabled; term; term = term->next)
89 if (grub_strcmp (args[i], term->name) == 0)
90 break;
91 if (term == 0)
92 for (term = *enabled; term; term = term->next)
93 if (grub_strcmp (args[i], term->name) == 0)
94 break;
95 if (term)
96 break;
97 if (again)
98 return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
99 args[i]);
100 for (aut = autoloads; aut; aut = aut->next)
101 if (grub_strcmp (args[i], aut->name) == 0)
102 {
103 grub_dl_t mod;
104 mod = grub_dl_load (aut->modname);
105 if (mod)
106 grub_dl_ref (mod);
107 grub_errno = GRUB_ERR_NONE;
108 break;
109 }
110 if (!aut)
111 return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
112 args[i]);
113 again = 1;
114 }
0aa63398
VS
115 }
116
117 if (grub_strcmp (args[0], "--append") == 0)
118 {
119 for (i = 1; i < argc; i++)
6f8aaf68
VS
120 {
121 for (term = *disabled; term; term = term->next)
122 if (grub_strcmp (args[i], term->name) == 0)
123 break;
124 if (term)
125 {
cba98e8d
RM
126 if (term->init && term->init () != GRUB_ERR_NONE)
127 return grub_errno;
128
6f8aaf68
VS
129 grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
130 grub_list_push (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
131 }
132 }
0aa63398
VS
133 return GRUB_ERR_NONE;
134 }
135
136 if (grub_strcmp (args[0], "--remove") == 0)
137 {
138 for (i = 1; i < argc; i++)
6f8aaf68
VS
139 {
140 for (term = *enabled; term; term = term->next)
141 if (grub_strcmp (args[i], term->name) == 0)
142 break;
143 if (term)
144 {
145 if (!term->next && term == *enabled)
146 return grub_error (GRUB_ERR_BAD_ARGUMENT,
147 "can't remove the last terminal");
148 grub_list_remove (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
149 if (term->fini)
150 term->fini ();
151 grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
152 }
153 }
0aa63398
VS
154 return GRUB_ERR_NONE;
155 }
156 for (i = 0; i < argc; i++)
157 {
6f8aaf68
VS
158 for (term = *disabled; term; term = term->next)
159 if (grub_strcmp (args[i], term->name) == 0)
160 break;
0aa63398 161 if (term)
6f8aaf68
VS
162 {
163 if (term->init && term->init () != GRUB_ERR_NONE)
164 return grub_errno;
cba98e8d 165
6f8aaf68
VS
166 grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
167 grub_list_push (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
168 }
0aa63398 169 }
6f8aaf68 170
0aa63398 171 {
6f8aaf68
VS
172 struct abstract_terminal *next;
173 for (term = *enabled; term; term = next)
0aa63398 174 {
6f8aaf68
VS
175 next = term->next;
176 for (i = 0; i < argc; i++)
177 if (grub_strcmp (args[i], term->name) == 0)
178 break;
179 if (i == argc)
180 {
181 if (!term->next && term == *enabled)
182 return grub_error (GRUB_ERR_BAD_ARGUMENT,
183 "can't remove the last terminal");
184 grub_list_remove (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
185 if (term->fini)
186 term->fini ();
187 grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
188 }
0aa63398
VS
189 }
190 }
191
192 return GRUB_ERR_NONE;
193}
194
d8a1cbbd 195static grub_err_t
6f8aaf68 196grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)),
0aa63398
VS
197 int argc, char **args)
198{
6f8aaf68
VS
199 (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, next);
200 (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, name);
201 (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, init);
202 (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, fini);
203 return handle_command (argc, args,
204 (struct abstract_terminal **) &grub_term_inputs,
205 (struct abstract_terminal **) &grub_term_inputs_disabled,
206 grub_term_input_autoload,
207 N_ ("Active input terminals:"),
208 N_ ("Available input terminals:"));
209}
0aa63398 210
6f8aaf68
VS
211static grub_err_t
212grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)),
213 int argc, char **args)
214{
215 (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, next);
216 (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, name);
217 (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, init);
218 (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, fini);
219 return handle_command (argc, args, (struct abstract_terminal **) &grub_term_outputs,
220 (struct abstract_terminal **) &grub_term_outputs_disabled,
221 grub_term_output_autoload,
222 N_ ("Active output terminals:"),
223 N_ ("Available output terminals:"));
0aa63398
VS
224}
225
226static grub_command_t cmd_terminal_input, cmd_terminal_output;
227
228GRUB_MOD_INIT(terminal)
229{
230 cmd_terminal_input =
231 grub_register_command ("terminal_input", grub_cmd_terminal_input,
d8b5cd40
VS
232 N_("[--append|--remove] "
233 "[TERMINAL1] [TERMINAL2] ..."),
234 N_("List or select an input terminal."));
0aa63398
VS
235 cmd_terminal_output =
236 grub_register_command ("terminal_output", grub_cmd_terminal_output,
d8b5cd40
VS
237 N_("[--append|--remove] "
238 "[TERMINAL1] [TERMINAL2] ..."),
239 N_("List or select an output terminal."));
0aa63398
VS
240}
241
242GRUB_MOD_FINI(terminal)
243{
244 grub_unregister_command (cmd_terminal_input);
245 grub_unregister_command (cmd_terminal_output);
246}