]> git.proxmox.com Git - grub2.git/blob - grub-core/commands/minicmd.c
merge with mainline
[grub2.git] / grub-core / commands / minicmd.c
1 /* minicmd.c - commands for the rescue mode */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2003,2005,2006,2007,2009 Free Software Foundation, Inc.
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>
30 #include <grub/i18n.h>
31
32 /* cat FILE */
33 static grub_err_t
34 grub_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')
57 grub_printf ("%c", c);
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
67 grub_xputs ("\n");
68 grub_refresh ();
69 grub_file_close (file);
70
71 return 0;
72 }
73
74 /* help */
75 static grub_err_t
76 grub_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
92 static void
93 grub_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] */
112 static grub_err_t
113 grub_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
146 static void
147 grub_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] */
252 static grub_err_t
253 grub_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 */
279 static grub_err_t
280 grub_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 */
299 static grub_err_t
300 grub_mini_cmd_lsmod (struct grub_command *cmd __attribute__ ((unused)),
301 int argc __attribute__ ((unused)),
302 char *argv[] __attribute__ ((unused)))
303 {
304 grub_dl_t mod;
305
306 grub_printf ("Name\tRef Count\tDependencies\n");
307 FOR_DL_MODULES (mod)
308 {
309 grub_dl_dep_t dep;
310
311 grub_printf ("%s\t%d\t\t", mod->name, mod->ref_count);
312 for (dep = mod->dep; dep; dep = dep->next)
313 {
314 if (dep != mod->dep)
315 grub_xputs (",");
316
317 grub_printf ("%s", dep->mod->name);
318 }
319 grub_xputs ("\n");
320 }
321
322 return 0;
323 }
324
325 /* exit */
326 static grub_err_t
327 grub_mini_cmd_exit (struct grub_command *cmd __attribute__ ((unused)),
328 int argc __attribute__ ((unused)),
329 char *argv[] __attribute__ ((unused)))
330 {
331 grub_exit ();
332 return 0;
333 }
334
335 static grub_command_t cmd_cat, cmd_help, cmd_root;
336 static grub_command_t cmd_dump, cmd_rmmod, cmd_lsmod, cmd_exit;
337
338 GRUB_MOD_INIT(minicmd)
339 {
340 cmd_cat =
341 grub_register_command ("cat", grub_mini_cmd_cat,
342 N_("FILE"), N_("Show the contents of a file."));
343 cmd_help =
344 grub_register_command ("help", grub_mini_cmd_help,
345 0, N_("Show this message."));
346 cmd_root =
347 grub_register_command ("root", grub_mini_cmd_root,
348 N_("[DEVICE]"), N_("Set the root device."));
349 cmd_dump =
350 grub_register_command ("dump", grub_mini_cmd_dump,
351 N_("ADDR"), N_("Dump memory."));
352 cmd_rmmod =
353 grub_register_command ("rmmod", grub_mini_cmd_rmmod,
354 N_("MODULE"), N_("Remove a module."));
355 cmd_lsmod =
356 grub_register_command ("lsmod", grub_mini_cmd_lsmod,
357 0, N_("Show loaded modules."));
358 cmd_exit =
359 grub_register_command ("exit", grub_mini_cmd_exit,
360 0, N_("Exit from GRUB."));
361 }
362
363 GRUB_MOD_FINI(minicmd)
364 {
365 grub_unregister_command (cmd_cat);
366 grub_unregister_command (cmd_help);
367 grub_unregister_command (cmd_root);
368 grub_unregister_command (cmd_dump);
369 grub_unregister_command (cmd_rmmod);
370 grub_unregister_command (cmd_lsmod);
371 grub_unregister_command (cmd_exit);
372 }