]> git.proxmox.com Git - grub2.git/blame - commands/minicmd.c
merge mainline into bidi
[grub2.git] / commands / minicmd.c
CommitLineData
b1b797cb 1/* minicmd.c - commands for the rescue mode */
2/*
3 * GRUB -- GRand Unified Bootloader
0d5d5653 4 * Copyright (C) 2003,2005,2006,2007,2009 Free Software Foundation, Inc.
b1b797cb 5 *
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <grub/dl.h>
21#include <grub/mm.h>
22#include <grub/err.h>
23#include <grub/env.h>
24#include <grub/misc.h>
25#include <grub/file.h>
26#include <grub/disk.h>
27#include <grub/term.h>
28#include <grub/loader.h>
29#include <grub/command.h>
77a79592 30#include <grub/i18n.h>
b1b797cb 31
b1b797cb 32/* cat FILE */
33static grub_err_t
34grub_mini_cmd_cat (struct grub_command *cmd __attribute__ ((unused)),
35 int argc, char *argv[])
36{
37 grub_file_t file;
38 char buf[GRUB_DISK_SECTOR_SIZE];
39 grub_ssize_t size;
40
41 if (argc < 1)
42 return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
43
44 file = grub_file_open (argv[0]);
45 if (! file)
46 return grub_errno;
47
48 while ((size = grub_file_read (file, buf, sizeof (buf))) > 0)
49 {
50 int i;
51
52 for (i = 0; i < size; i++)
53 {
54 unsigned char c = buf[i];
55
56 if ((grub_isprint (c) || grub_isspace (c)) && c != '\r')
dfed5c6b 57 grub_printf ("%c", c);
b1b797cb 58 else
59 {
60 grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
61 grub_printf ("<%x>", (int) c);
62 grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
63 }
64 }
65 }
66
dfed5c6b 67 grub_xputs ("\n");
b1b797cb 68 grub_refresh ();
69 grub_file_close (file);
70
71 return 0;
72}
73
74/* help */
75static grub_err_t
76grub_mini_cmd_help (struct grub_command *cmd __attribute__ ((unused)),
77 int argc __attribute__ ((unused)),
78 char *argv[] __attribute__ ((unused)))
79{
80 grub_command_t p;
81
82 for (p = grub_command_list; p; p = p->next)
83 grub_printf ("%s (%d%c)\t%s\n", p->name,
84 p->prio & GRUB_PRIO_LIST_PRIO_MASK,
85 (p->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) ? '+' : '-',
86 p->description);
87
88 return 0;
89}
90
91#if 0
92static void
93grub_rescue_cmd_info (void)
94{
95 extern void grub_disk_cache_get_performance (unsigned long *,
96 unsigned long *);
97 unsigned long hits, misses;
98
99 grub_disk_cache_get_performance (&hits, &misses);
100 grub_printf ("Disk cache: hits = %u, misses = %u ", hits, misses);
101 if (hits + misses)
102 {
103 unsigned long ratio = hits * 10000 / (hits + misses);
104 grub_printf ("(%u.%u%%)\n", ratio / 100, ratio % 100);
105 }
106 else
107 grub_printf ("(N/A)\n");
108}
109#endif
110
111/* root [DEVICE] */
112static grub_err_t
113grub_mini_cmd_root (struct grub_command *cmd __attribute__ ((unused)),
114 int argc, char *argv[])
115{
116 grub_device_t dev;
117 grub_fs_t fs;
118
119 if (argc > 0)
120 {
121 char *device_name = grub_file_get_device_name (argv[0]);
122 if (! device_name)
123 return grub_errno;
124
125 grub_env_set ("root", device_name);
126 grub_free (device_name);
127 }
128
129 dev = grub_device_open (0);
130 if (! dev)
131 return grub_errno;
132
133 fs = grub_fs_probe (dev);
134 if (grub_errno == GRUB_ERR_UNKNOWN_FS)
135 grub_errno = GRUB_ERR_NONE;
136
137 grub_printf ("(%s): Filesystem is %s.\n",
138 grub_env_get ("root"), fs ? fs->name : "unknown");
139
140 grub_device_close (dev);
141
142 return 0;
143}
144
145#if 0
146static void
147grub_rescue_cmd_testload (int argc, char *argv[])
148{
149 grub_file_t file;
150 char *buf;
151 grub_ssize_t size;
152 grub_ssize_t pos;
153 auto void read_func (unsigned long sector, unsigned offset, unsigned len);
154
155 void read_func (unsigned long sector __attribute__ ((unused)),
156 unsigned offset __attribute__ ((unused)),
157 unsigned len __attribute__ ((unused)))
158 {
159 grub_putchar ('.');
160 grub_refresh ();
161 }
162
163 if (argc < 1)
164 {
165 grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
166 return;
167 }
168
169 file = grub_file_open (argv[0]);
170 if (! file)
171 return;
172
173 size = grub_file_size (file) & ~(GRUB_DISK_SECTOR_SIZE - 1);
174 if (size == 0)
175 {
176 grub_file_close (file);
177 return;
178 }
179
180 buf = grub_malloc (size);
181 if (! buf)
182 goto fail;
183
184 grub_printf ("Reading %s sequentially", argv[0]);
185 file->read_hook = read_func;
186 if (grub_file_read (file, buf, size) != size)
187 goto fail;
188 grub_printf (" Done.\n");
189
190 /* Read sequentially again. */
191 grub_printf ("Reading %s sequentially again", argv[0]);
192 if (grub_file_seek (file, 0) < 0)
193 goto fail;
194
195 for (pos = 0; pos < size; pos += GRUB_DISK_SECTOR_SIZE)
196 {
197 char sector[GRUB_DISK_SECTOR_SIZE];
198
199 if (grub_file_read (file, sector, GRUB_DISK_SECTOR_SIZE)
200 != GRUB_DISK_SECTOR_SIZE)
201 goto fail;
202
203 if (grub_memcmp (sector, buf + pos, GRUB_DISK_SECTOR_SIZE) != 0)
204 {
205 grub_printf ("\nDiffers in %d\n", pos);
206 goto fail;
207 }
208 }
209 grub_printf (" Done.\n");
210
211 /* Read backwards and compare. */
212 grub_printf ("Reading %s backwards", argv[0]);
213 pos = size;
214 while (pos > 0)
215 {
216 char sector[GRUB_DISK_SECTOR_SIZE];
217
218 pos -= GRUB_DISK_SECTOR_SIZE;
219
220 if (grub_file_seek (file, pos) < 0)
221 goto fail;
222
223 if (grub_file_read (file, sector, GRUB_DISK_SECTOR_SIZE)
224 != GRUB_DISK_SECTOR_SIZE)
225 goto fail;
226
227 if (grub_memcmp (sector, buf + pos, GRUB_DISK_SECTOR_SIZE) != 0)
228 {
229 int i;
230
231 grub_printf ("\nDiffers in %d\n", pos);
232
233 for (i = 0; i < GRUB_DISK_SECTOR_SIZE; i++)
234 grub_putchar (buf[pos + i]);
235
236 if (i)
237 grub_refresh ();
238
239 goto fail;
240 }
241 }
242 grub_printf (" Done.\n");
243
244 fail:
245
246 grub_file_close (file);
247 grub_free (buf);
248}
249#endif
250
251/* dump ADDRESS [SIZE] */
252static grub_err_t
253grub_mini_cmd_dump (struct grub_command *cmd __attribute__ ((unused)),
254 int argc, char *argv[])
255{
256 grub_uint8_t *addr;
257 grub_size_t size = 4;
258
259 if (argc == 0)
260 return grub_error (GRUB_ERR_BAD_ARGUMENT, "no address specified");
261
262 addr = (grub_uint8_t *) grub_strtoul (argv[0], 0, 0);
263 if (grub_errno)
264 return grub_errno;
265
266 if (argc > 1)
267 size = (grub_size_t) grub_strtoul (argv[1], 0, 0);
268
269 while (size--)
270 {
271 grub_printf ("%x%x ", *addr >> 4, *addr & 0xf);
272 addr++;
273 }
274
275 return 0;
276}
277
278/* rmmod MODULE */
279static grub_err_t
280grub_mini_cmd_rmmod (struct grub_command *cmd __attribute__ ((unused)),
281 int argc, char *argv[])
282{
283 grub_dl_t mod;
284
285 if (argc == 0)
286 return grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
287
288 mod = grub_dl_get (argv[0]);
289 if (! mod)
290 return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such module");
291
292 if (grub_dl_unref (mod) <= 0)
293 grub_dl_unload (mod);
294
295 return 0;
296}
297
298/* lsmod */
299static grub_err_t
300grub_mini_cmd_lsmod (struct grub_command *cmd __attribute__ ((unused)),
301 int argc __attribute__ ((unused)),
302 char *argv[] __attribute__ ((unused)))
303{
304 auto int print_module (grub_dl_t mod);
305
306 int print_module (grub_dl_t mod)
307 {
308 grub_dl_dep_t dep;
309
310 grub_printf ("%s\t%d\t\t", mod->name, mod->ref_count);
311 for (dep = mod->dep; dep; dep = dep->next)
312 {
313 if (dep != mod->dep)
dfed5c6b 314 grub_xputs (",");
b1b797cb 315
316 grub_printf ("%s", dep->mod->name);
317 }
dfed5c6b 318 grub_xputs ("\n");
b1b797cb 319
320 return 0;
321 }
322
323 grub_printf ("Name\tRef Count\tDependencies\n");
324 grub_dl_iterate (print_module);
325
326 return 0;
327}
328
329/* exit */
330static grub_err_t
331grub_mini_cmd_exit (struct grub_command *cmd __attribute__ ((unused)),
332 int argc __attribute__ ((unused)),
333 char *argv[] __attribute__ ((unused)))
334{
335 grub_exit ();
336 return 0;
337}
338
cd4f42b0
RM
339/* clear */
340static grub_err_t
341grub_mini_cmd_clear (struct grub_command *cmd __attribute__ ((unused)),
342 int argc __attribute__ ((unused)),
343 char *argv[] __attribute__ ((unused)))
344{
345 grub_cls ();
346 return 0;
347}
348
0d5d5653 349static grub_command_t cmd_cat, cmd_help, cmd_root;
b1b797cb 350static grub_command_t cmd_dump, cmd_rmmod, cmd_lsmod, cmd_exit;
cd4f42b0 351static grub_command_t cmd_clear;
b1b797cb 352
353GRUB_MOD_INIT(minicmd)
354{
b1b797cb 355 cmd_cat =
356 grub_register_command ("cat", grub_mini_cmd_cat,
77a79592 357 N_("FILE"), N_("Show the contents of a file."));
b1b797cb 358 cmd_help =
359 grub_register_command ("help", grub_mini_cmd_help,
77a79592 360 0, N_("Show this message."));
b1b797cb 361 cmd_root =
362 grub_register_command ("root", grub_mini_cmd_root,
77a79592 363 N_("[DEVICE]"), N_("Set the root device."));
b1b797cb 364 cmd_dump =
365 grub_register_command ("dump", grub_mini_cmd_dump,
77a79592 366 N_("ADDR"), N_("Dump memory."));
b1b797cb 367 cmd_rmmod =
368 grub_register_command ("rmmod", grub_mini_cmd_rmmod,
77a79592 369 N_("MODULE"), N_("Remove a module."));
b1b797cb 370 cmd_lsmod =
371 grub_register_command ("lsmod", grub_mini_cmd_lsmod,
77a79592 372 0, N_("Show loaded modules."));
b1b797cb 373 cmd_exit =
374 grub_register_command ("exit", grub_mini_cmd_exit,
77a79592 375 0, N_("Exit from GRUB."));
cd4f42b0
RM
376 cmd_clear =
377 grub_register_command ("clear", grub_mini_cmd_clear,
77a79592 378 0, N_("Clear the screen."));
b1b797cb 379}
380
381GRUB_MOD_FINI(minicmd)
382{
b1b797cb 383 grub_unregister_command (cmd_cat);
384 grub_unregister_command (cmd_help);
385 grub_unregister_command (cmd_root);
386 grub_unregister_command (cmd_dump);
387 grub_unregister_command (cmd_rmmod);
388 grub_unregister_command (cmd_lsmod);
389 grub_unregister_command (cmd_exit);
cd4f42b0 390 grub_unregister_command (cmd_clear);
b1b797cb 391}