15b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* mbchk - a simple checker for the format of a Multiboot kernel */
25b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
35b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  Copyright (C) 1999,2001,2002  Free Software Foundation, Inc.
45b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
55b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  This program is free software; you can redistribute it and/or modify
65b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  it under the terms of the GNU General Public License as published by
75b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  the Free Software Foundation; either version 2 of the License, or
85b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  (at your option) any later version.
95b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  This program is distributed in the hope that it will be useful,
115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  but WITHOUT ANY WARRANTY; without even the implied warranty of
125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  GNU General Public License for more details.
145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  You should have received a copy of the GNU General Public License
165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  along with this program; if not, write to the Free Software
175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include <config.h>
215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include <stdio.h>
235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include <stdlib.h>
245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include <getopt.h>
255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include <multiboot.h>
265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int quiet = 0;
285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic char *optstring = "hvq";
295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic struct option longopts[] =
305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  {"help", no_argument, 0, 'h'},
325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  {"version", no_argument, 0, 'v'},
335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  {"quiet", no_argument, 0, 'q'},
345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  {0}
355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void
385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectusage (int status)
395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (status)
415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    fprintf (stderr, "Try ``mbchk --help'' for more information.\n");
425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  else
435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    printf ("Usage: mbchk [OPTION]... [FILE]...\n"
445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    "Check if the format of FILE complies with the Multiboot Specification.\n"
455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    "\n"
465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    "-q, --quiet                suppress all normal output\n"
475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    "-h, --help                 display this help and exit\n"
485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    "-v, --version              output version information and exit.\n"
495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    "\n"
505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    "Report bugs to <bug-grub@gnu.org>.\n");
515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  exit (status);
535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int
565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectcheck_multiboot (const char *filename, FILE *fp)
575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  multiboot_header_t *mbh = 0;
595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int i;
605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  char buf[8192];
615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (fread (buf, 1, 8192, fp) < 0)
635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      fprintf (stderr, "%s: Read error.\n", filename);
655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return 0;
665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  for (i = 0; i < 8192 - sizeof (multiboot_header_t); i++)
695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      unsigned long magic = *((unsigned long *) (buf + i));
715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (magic == MULTIBOOT_HEADER_MAGIC)
735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  mbh = (multiboot_header_t *) (buf + i);
755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  break;
765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (! mbh)
805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      fprintf (stderr, "%s: No Multiboot header.\n", filename);
825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return 0;
835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (! quiet)
865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    printf ("%s: The Multiboot header is found at the offset %d.\n",
875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    filename, i);
885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Check for the checksum.  */
905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (mbh->magic + mbh->flags + mbh->checksum != 0)
915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      fprintf (stderr,
935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	       "%s: Bad checksum (0x%lx).\n",
945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	       filename, mbh->checksum);
955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return 0;
965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Reserved flags must be zero.  */
995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (mbh->flags & ~0x00010003)
1005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
1015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      fprintf (stderr,
1025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	       "%s: Non-zero is found in reserved flags (0x%lx).\n",
1035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	       filename, mbh->flags);
1045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return 0;
1055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
1065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (! quiet)
1085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
1095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      printf ("%s: Page alignment is turned %s.\n",
1105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      filename, (mbh->flags & 0x1)? "on" : "off");
1115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      printf ("%s: Memory information is turned %s.\n",
1125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      filename, (mbh->flags & 0x2)? "on" : "off");
1135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      printf ("%s: Address fields is turned %s.\n",
1145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      filename, (mbh->flags & 0x10000)? "on" : "off");
1155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
1165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Check for the address fields.  */
1185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (mbh->flags & 0x10000)
1195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
1205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (mbh->header_addr < mbh->load_addr)
1215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
1225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  fprintf (stderr,
1235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   "%s: header_addr is less than "
1245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   "load_addr (0x%lx > 0x%lx).\n",
1255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   filename, mbh->header_addr, mbh->load_addr);
1265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  return 0;
1275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
1285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (mbh->load_end_addr && mbh->load_addr >= mbh->load_end_addr)
1305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
1315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  fprintf (stderr,
1325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   "%s: load_addr is not less than load_end_addr"
1335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   " (0x%lx >= 0x%lx).\n",
1345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   filename, mbh->load_addr, mbh->load_end_addr);
1355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  return 0;
1365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
1375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (mbh->bss_end_addr && mbh->load_end_addr > mbh->bss_end_addr)
1395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
1405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  fprintf (stderr,
1415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   "%s: load_end_addr is greater than bss_end_addr"
1425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   " (0x%lx > 0x%lx).\n",
1435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   filename, mbh->load_end_addr, mbh->bss_end_addr);
1445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  return 0;
1455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
1465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (mbh->load_addr > mbh->entry_addr)
1485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
1495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  fprintf (stderr,
1505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   "%s: load_addr is greater than entry_addr"
1515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   " (0x%lx > 0x%lx).\n",
1525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   filename, mbh->load_addr, mbh->entry_addr);
1535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  return 0;
1545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
1555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* FIXME: It is better to check if the entry address is within the
1575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	 file, especially when the load end address is zero.  */
1585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (mbh->load_end_addr && mbh->load_end_addr <= mbh->entry_addr)
1595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
1605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  fprintf (stderr,
1615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   "%s: load_end_addr is not greater than entry_addr"
1625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   " (0x%lx <= 0x%lx).\n",
1635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   filename, mbh->load_end_addr, mbh->entry_addr);
1645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  return 0;
1655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
1665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* This is a GRUB-specific limitation.  */
1685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (mbh->load_addr < 0x100000)
1695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
1705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  fprintf (stderr,
1715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   "%s: Cannot be loaded at less than 1MB by GRUB"
1725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   " (0x%lx).\n",
1735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   filename, mbh->load_addr);
1745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  return 0;
1755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
1765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
1775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (! quiet)
1795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    printf ("%s: All checks passed.\n", filename);
1805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return 1;
1825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
1835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint
1855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectmain (int argc, char *argv[])
1865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
1875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int c;
1885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  do
1905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
1915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      c = getopt_long (argc, argv, optstring, longopts, 0);
1925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      switch (c)
1935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
1945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	case EOF:
1955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  break;
1965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	case 'h':
1985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  usage (0);
1995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  break;
2005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	case 'v':
2025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  printf ("mbchk (GNU GRUB " VERSION ")\n");
2035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  exit (0);
2045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  break;
2055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	case 'q':
2075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  quiet = 1;
2085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  break;
2095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	default:
2115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  usage (1);
2125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  break;
2135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
2145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
2155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  while (c != EOF);
2165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (optind < argc)
2185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
2195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      while (optind < argc)
2205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
2215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  FILE *fp;
2225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  fp = fopen (argv[optind], "r");
2245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (! fp)
2255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
2265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      fprintf (stderr, "%s: No such file.\n", argv[optind]);
2275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      exit (1);
2285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
2295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (! check_multiboot (argv[optind], fp))
2315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    exit (1);
2325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  fclose (fp);
2345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  optind++;
2355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
2365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
2375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  else
2385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
2395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (! check_multiboot ("<stdin>", stdin))
2405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	exit (1);
2415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
2425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return 0;
2445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
245