15b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* disk_io.c - implement abstract BIOS disk input and output */
25b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
35b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  GRUB  --  GRand Unified Bootloader
45b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
55b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
65b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  This program is free software; you can redistribute it and/or modify
75b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  it under the terms of the GNU General Public License as published by
85b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  the Free Software Foundation; either version 2 of the License, or
95b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  (at your option) any later version.
105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  This program is distributed in the hope that it will be useful,
125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  but WITHOUT ANY WARRANTY; without even the implied warranty of
135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  GNU General Public License for more details.
155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  You should have received a copy of the GNU General Public License
175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  along with this program; if not, write to the Free Software
185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include <shared.h>
235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include <filesys.h>
245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef SUPPORT_NETBOOT
265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# define GRUB	1
275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# include <etherboot.h>
285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef GRUB_UTIL
315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# include <device.h>
325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* instrumentation variables */
355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectvoid (*disk_read_hook) (int, int, int) = NULL;
365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectvoid (*disk_read_func) (int, int, int) = NULL;
375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef STAGE1_5
395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint print_possibilities;
405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int do_completion;
425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int unique;
435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic char *unique_string;
445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint fsmax;
485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct fsys_entry fsys_table[NUM_FSYS + 1] =
495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* TFTP should come first because others don't handle net device.  */
515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# ifdef FSYS_TFTP
525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  {"tftp", tftp_mount, tftp_read, tftp_dir, tftp_close, 0},
535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# endif
545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# ifdef FSYS_FAT
555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  {"fat", fat_mount, fat_read, fat_dir, 0, 0},
565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# endif
575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# ifdef FSYS_EXT2FS
585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  {"ext2fs", ext2fs_mount, ext2fs_read, ext2fs_dir, 0, 0},
595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# endif
605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# ifdef FSYS_MINIX
615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  {"minix", minix_mount, minix_read, minix_dir, 0, 0},
625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# endif
635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# ifdef FSYS_REISERFS
645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  {"reiserfs", reiserfs_mount, reiserfs_read, reiserfs_dir, 0, reiserfs_embed},
655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# endif
665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# ifdef FSYS_VSTAFS
675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  {"vstafs", vstafs_mount, vstafs_read, vstafs_dir, 0, 0},
685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# endif
695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# ifdef FSYS_JFS
705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  {"jfs", jfs_mount, jfs_read, jfs_dir, 0, jfs_embed},
715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# endif
725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# ifdef FSYS_XFS
735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  {"xfs", xfs_mount, xfs_read, xfs_dir, 0, 0},
745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# endif
755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# ifdef FSYS_UFS2
765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  {"ufs2", ufs2_mount, ufs2_read, ufs2_dir, 0, ufs2_embed},
775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# endif
785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# ifdef FSYS_ISO9660
795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  {"iso9660", iso9660_mount, iso9660_read, iso9660_dir, 0, 0},
805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# endif
815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* XX FFS should come last as it's superblock is commonly crossing tracks
825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project     on floppies from track 1 to 2, while others only use 1.  */
835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# ifdef FSYS_FFS
845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  {"ffs", ffs_mount, ffs_read, ffs_dir, 0, ffs_embed},
855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# endif
865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  {0, 0, 0, 0, 0, 0}
875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* These have the same format as "boot_drive" and "install_partition", but
915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   are meant to be working values. */
925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectunsigned long current_drive = GRUB_INVALID_DRIVE;
935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectunsigned long current_partition;
945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef STAGE1_5
965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* The register ESI should contain the address of the partition to be
975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   used for loading a chain-loader when chain-loading the loader.  */
985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectunsigned long boot_part_addr = 0;
995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
1005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
1025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  Global variables describing details of the filesystem
1035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
1045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* FIXME: BSD evil hack */
1065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "freebsd.h"
1075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint bsd_evil_hack;
1085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* filesystem type */
1105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint fsys_type = NUM_FSYS;
1115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef NO_BLOCK_FILES
1125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int block_file = 0;
1135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* NO_BLOCK_FILES */
1145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* these are the translated numbers for the open partition */
1165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectunsigned long part_start;
1175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectunsigned long part_length;
1185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint current_slice;
1205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* disk buffer parameters */
1225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint buf_drive = -1;
1235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint buf_track;
1245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct geometry buf_geom;
1255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* filesystem common variables */
1275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint filepos;
1285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint filemax;
1295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic inline unsigned long
1315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectlog2 (unsigned long word)
1325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
1335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  asm volatile ("bsfl %1,%0"
1345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		: "=r" (word)
1355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		: "r" (word));
1365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return word;
1375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
1385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint
1405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectrawread (int drive, int sector, int byte_offset, int byte_len, char *buf)
1415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
1425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int slen, sectors_per_vtrack;
1435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int sector_size_bits = log2 (buf_geom.sector_size);
1445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (byte_len <= 0)
1465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return 1;
1475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  while (byte_len > 0 && !errnum)
1495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
1505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      int soff, num_sect, track, size = byte_len;
1515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      char *bufaddr;
1525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /*
1545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project       *  Check track buffer.  If it isn't valid or it is from the
1555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project       *  wrong disk, then reset the disk geometry.
1565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project       */
1575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (buf_drive != drive)
1585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
1595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (get_diskinfo (drive, &buf_geom))
1605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
1615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      errnum = ERR_NO_DISK;
1625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      return 0;
1635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
1645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  buf_drive = drive;
1655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  buf_track = -1;
1665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  sector_size_bits = log2 (buf_geom.sector_size);
1675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
1685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* Make sure that SECTOR is valid.  */
1705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (sector < 0 || sector >= buf_geom.total_sectors)
1715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
1725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  errnum = ERR_GEOM;
1735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  return 0;
1745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
1755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      slen = ((byte_offset + byte_len + buf_geom.sector_size - 1)
1775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      >> sector_size_bits);
1785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* Eliminate a buffer overflow.  */
1805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if ((buf_geom.sectors << sector_size_bits) > BUFFERLEN)
1815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	sectors_per_vtrack = (BUFFERLEN >> sector_size_bits);
1825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      else
1835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	sectors_per_vtrack = buf_geom.sectors;
1845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* Get the first sector of track.  */
1865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      soff = sector % sectors_per_vtrack;
1875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      track = sector - soff;
1885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      num_sect = sectors_per_vtrack - soff;
1895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      bufaddr = ((char *) BUFFERADDR
1905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		 + (soff << sector_size_bits) + byte_offset);
1915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (track != buf_track)
1935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
1945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  int bios_err, read_start = track, read_len = sectors_per_vtrack;
1955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /*
1975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	   *  If there's more than one read in this entire loop, then
1985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	   *  only make the earlier reads for the portion needed.  This
1995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	   *  saves filling the buffer with data that won't be used!
2005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	   */
2015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (slen > num_sect)
2025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
2035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      read_start = sector;
2045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      read_len = num_sect;
2055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      bufaddr = (char *) BUFFERADDR + byte_offset;
2065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
2075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  bios_err = biosdisk (BIOSDISK_READ, drive, &buf_geom,
2095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			       read_start, read_len, BUFFERSEG);
2105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (bios_err)
2115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
2125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      buf_track = -1;
2135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if (bios_err == BIOSDISK_ERROR_GEOMETRY)
2155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		errnum = ERR_GEOM;
2165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      else
2175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
2185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  /*
2195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   *  If there was an error, try to load only the
2205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   *  required sector(s) rather than failing completely.
2215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   */
2225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  if (slen > num_sect
2235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      || biosdisk (BIOSDISK_READ, drive, &buf_geom,
2245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				   sector, slen, BUFFERSEG))
2255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    errnum = ERR_READ;
2265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  bufaddr = (char *) BUFFERADDR + byte_offset;
2285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
2295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
2305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  else
2315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    buf_track = track;
2325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if ((buf_track == 0 || sector == 0)
2345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      && (PC_SLICE_TYPE (BUFFERADDR, 0) == PC_SLICE_TYPE_EZD
2355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  || PC_SLICE_TYPE (BUFFERADDR, 1) == PC_SLICE_TYPE_EZD
2365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  || PC_SLICE_TYPE (BUFFERADDR, 2) == PC_SLICE_TYPE_EZD
2375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  || PC_SLICE_TYPE (BUFFERADDR, 3) == PC_SLICE_TYPE_EZD))
2385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
2395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      /* This is a EZD disk map sector 0 to sector 1 */
2405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if (buf_track == 0 || slen >= 2)
2415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
2425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  /* We already read the sector 1, copy it to sector 0 */
2435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  memmove ((char *) BUFFERADDR,
2445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			   (char *) BUFFERADDR + buf_geom.sector_size,
2455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			   buf_geom.sector_size);
2465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
2475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      else
2485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
2495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  if (biosdisk (BIOSDISK_READ, drive, &buf_geom,
2505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				1, 1, BUFFERSEG))
2515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    errnum = ERR_READ;
2525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
2535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
2545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
2555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (size > ((num_sect << sector_size_bits) - byte_offset))
2575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	size = (num_sect << sector_size_bits) - byte_offset;
2585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /*
2605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project       *  Instrumentation to tell which sectors were read and used.
2615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project       */
2625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (disk_read_func)
2635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
2645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  int sector_num = sector;
2655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  int length = buf_geom.sector_size - byte_offset;
2665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (length > size)
2675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    length = size;
2685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  (*disk_read_func) (sector_num++, byte_offset, length);
2695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  length = size - length;
2705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (length > 0)
2715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
2725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      while (length > buf_geom.sector_size)
2735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
2745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  (*disk_read_func) (sector_num++, 0, buf_geom.sector_size);
2755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  length -= buf_geom.sector_size;
2765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
2775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      (*disk_read_func) (sector_num, 0, length);
2785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
2795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
2805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      grub_memmove (buf, bufaddr, size);
2825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      buf += size;
2845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      byte_len -= size;
2855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      sector += num_sect;
2865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      byte_offset = 0;
2875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
2885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return (!errnum);
2905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
2915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint
2945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectdevread (int sector, int byte_offset, int byte_len, char *buf)
2955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
2965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /*
2975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   *  Check partition boundaries
2985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   */
2995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (sector < 0
3005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      || ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS))
3015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  >= part_length))
3025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
3035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      errnum = ERR_OUTSIDE_PART;
3045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return 0;
3055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
3065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /*
3085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   *  Get the read to the beginning of a partition.
3095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   */
3105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  sector += byte_offset >> SECTOR_BITS;
3115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  byte_offset &= SECTOR_SIZE - 1;
3125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if !defined(STAGE1_5)
3145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (disk_read_hook && debug)
3155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    printf ("<%d, %d, %d>", sector, byte_offset, byte_len);
3165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* !STAGE1_5 */
3175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /*
3195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   *  Call RAWREAD, which is very similar, but:
3205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   *
3215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   *    --  It takes an extra parameter, the drive number.
3225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   *    --  It requires that "sector" is relative to the beginning
3235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   *            of the disk.
3245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   *    --  It doesn't handle offsets of more than 511 bytes into the
3255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   *            sector.
3265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   */
3275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return rawread (current_drive, part_start + sector, byte_offset,
3285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  byte_len, buf);
3295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
3305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef STAGE1_5
3325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint
3335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectrawwrite (int drive, int sector, char *buf)
3345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
3355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (sector == 0)
3365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
3375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (biosdisk (BIOSDISK_READ, drive, &buf_geom, 0, 1, SCRATCHSEG))
3385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
3395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  errnum = ERR_WRITE;
3405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  return 0;
3415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
3425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (PC_SLICE_TYPE (SCRATCHADDR, 0) == PC_SLICE_TYPE_EZD
3445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  || PC_SLICE_TYPE (SCRATCHADDR, 1) == PC_SLICE_TYPE_EZD
3455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  || PC_SLICE_TYPE (SCRATCHADDR, 2) == PC_SLICE_TYPE_EZD
3465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  || PC_SLICE_TYPE (SCRATCHADDR, 3) == PC_SLICE_TYPE_EZD)
3475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	sector = 1;
3485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
3495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  memmove ((char *) SCRATCHADDR, buf, SECTOR_SIZE);
3515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (biosdisk (BIOSDISK_WRITE, drive, &buf_geom,
3525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		sector, 1, SCRATCHSEG))
3535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
3545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      errnum = ERR_WRITE;
3555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return 0;
3565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
3575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (sector - sector % buf_geom.sectors == buf_track)
3595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    /* Clear the cache.  */
3605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    buf_track = -1;
3615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return 1;
3635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
3645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint
3665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectdevwrite (int sector, int sector_count, char *buf)
3675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
3685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if defined(GRUB_UTIL) && defined(__linux__)
3695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (current_partition != 0xFFFFFF
3705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      && is_disk_device (device_map, current_drive))
3715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
3725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* If the grub shell is running under Linux and the user wants to
3735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	 embed a Stage 1.5 into a partition instead of a MBR, use system
3745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	 calls directly instead of biosdisk, because of the bug in
3755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	 Linux. *sigh*  */
3765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return write_to_partition (device_map, current_drive, current_partition,
3775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				 sector, sector_count, buf);
3785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
3795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  else
3805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* GRUB_UTIL && __linux__ */
3815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
3825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      int i;
3835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      for (i = 0; i < sector_count; i++)
3855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
3865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (! rawwrite (current_drive, part_start + sector + i,
3875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			  buf + (i << SECTOR_BITS)))
3885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      return 0;
3895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
3915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return 1;
3925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
3935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
3945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int
3965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectsane_partition (void)
3975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
3985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* network drive */
3995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (current_drive == NETWORK_DRIVE)
4005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return 1;
4015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (!(current_partition & 0xFF000000uL)
4035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      && ((current_drive & 0xFFFFFF7F) < 8
4045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  || current_drive == cdrom_drive)
4055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      && (current_partition & 0xFF) == 0xFF
4065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      && ((current_partition & 0xFF00) == 0xFF00
4075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  || (current_partition & 0xFF00) < 0x800)
4085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      && ((current_partition >> 16) == 0xFF
4095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  || (current_drive & 0x80)))
4105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return 1;
4115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  errnum = ERR_DEV_VALUES;
4135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return 0;
4145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
4155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* ! STAGE1_5 */
4165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void
4185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectattempt_mount (void)
4195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
4205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef STAGE1_5
4215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  for (fsys_type = 0; fsys_type < NUM_FSYS; fsys_type++)
4225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    if ((fsys_table[fsys_type].mount_func) ())
4235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      break;
4245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (fsys_type == NUM_FSYS && errnum == ERR_NONE)
4265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    errnum = ERR_FSYS_MOUNT;
4275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#else
4285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  fsys_type = 0;
4295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if ((*(fsys_table[fsys_type].mount_func)) () != 1)
4305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
4315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      fsys_type = NUM_FSYS;
4325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      errnum = ERR_FSYS_MOUNT;
4335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
4345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
4355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
4365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef STAGE1_5
4395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Turn on the active flag for the partition SAVED_PARTITION in the
4405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   drive SAVED_DRIVE. If an error occurs, return zero, otherwise return
4415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   non-zero.  */
4425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint
4435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectmake_saved_active (void)
4445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
4455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  char mbr[512];
4465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (saved_drive & 0x80)
4485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
4495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* Hard disk */
4505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      int part = saved_partition >> 16;
4515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* If the partition is not a primary partition, the active flag is
4535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	 meaningless. (XXX: Really?)  */
4545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (part > 3)
4555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
4565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  errnum = ERR_DEV_VALUES;
4575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  return 0;
4585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
4595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* Read the MBR in the scratch space.  */
4615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (! rawread (saved_drive, 0, 0, SECTOR_SIZE, mbr))
4625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return 0;
4635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* If the partition is an extended partition, setting the active
4655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	 flag violates the specification by IBM.  */
4665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (IS_PC_SLICE_TYPE_EXTENDED (PC_SLICE_TYPE (mbr, part)))
4675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
4685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  errnum = ERR_DEV_VALUES;
4695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  return 0;
4705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
4715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* Check if the active flag is disabled.  */
4735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (PC_SLICE_FLAG (mbr, part) != PC_SLICE_FLAG_BOOTABLE)
4745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
4755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  int i;
4765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* Clear all the active flags in this table.  */
4785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  for (i = 0; i < 4; i++)
4795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    PC_SLICE_FLAG (mbr, i) = 0;
4805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* Set the flag.  */
4825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  PC_SLICE_FLAG (mbr, part) = PC_SLICE_FLAG_BOOTABLE;
4835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* Write back the MBR.  */
4855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (! rawwrite (saved_drive, 0, mbr))
4865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    return 0;
4875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
4885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
4895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  else
4905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
4915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* If the drive is not a hard disk drive, you shouldn't call this
4925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	 function. (XXX: Should I just ignore this error?)  */
4935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      errnum = ERR_DEV_VALUES;
4945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return 0;
4955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
4965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return 1;
4985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
4995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Hide/Unhide CURRENT_PARTITION.  */
5015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint
5025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectset_partition_hidden_flag (int hidden)
5035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
5045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned long part = 0xFFFFFF;
5055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned long start, len, offset, ext_offset;
5065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int entry, type;
5075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  char mbr[512];
5085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* The drive must be a hard disk.  */
5105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (! (current_drive & 0x80))
5115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
5125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      errnum = ERR_BAD_ARGUMENT;
5135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return 1;
5145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
5155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* The partition must be a PC slice.  */
5175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if ((current_partition >> 16) == 0xFF
5185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      || (current_partition & 0xFFFF) != 0xFFFF)
5195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
5205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      errnum = ERR_BAD_ARGUMENT;
5215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return 1;
5225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
5235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Look for the partition.  */
5255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  while (next_partition (current_drive, 0xFFFFFF, &part, &type,
5265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			 &start, &len, &offset, &entry,
5275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			 &ext_offset, mbr))
5285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
5295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (part == current_partition)
5305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
5315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* Found.  */
5325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (hidden)
5335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    PC_SLICE_TYPE (mbr, entry) |= PC_SLICE_TYPE_HIDDEN_FLAG;
5345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  else
5355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    PC_SLICE_TYPE (mbr, entry) &= ~PC_SLICE_TYPE_HIDDEN_FLAG;
5365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* Write back the MBR to the disk.  */
5385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  buf_track = -1;
5395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (! rawwrite (current_drive, offset, mbr))
5405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    return 1;
5415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* Succeed.  */
5435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  return 0;
5445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
5455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
5465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return 1;
5485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
5495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void
5525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectcheck_and_print_mount (void)
5535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
5545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  attempt_mount ();
5555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (errnum == ERR_FSYS_MOUNT)
5565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    errnum = ERR_NONE;
5575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (!errnum)
5585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    print_fsys_type ();
5595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  print_error ();
5605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
5615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* STAGE1_5 */
5625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Get the information on next partition on the drive DRIVE.
5655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   The caller must not modify the contents of the arguments when
5665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   iterating this function. The partition representation in GRUB will
5675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   be stored in *PARTITION. Likewise, the partition type in *TYPE, the
5685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   start sector in *START, the length in *LEN, the offset of the
5695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   partition table in *OFFSET, the entry number in the table in *ENTRY,
5705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   the offset of the extended partition in *EXT_OFFSET.
5715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   BUF is used to store a MBR, the boot sector of a partition, or
5725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   a BSD label sector, and it must be at least 512 bytes length.
5735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   When calling this function first, *PARTITION must be initialized to
5745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   0xFFFFFF. The return value is zero if fails, otherwise non-zero.  */
5755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint
5765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectnext_partition (unsigned long drive, unsigned long dest,
5775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		unsigned long *partition, int *type,
5785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		unsigned long *start, unsigned long *len,
5795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		unsigned long *offset, int *entry,
5805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		unsigned long *ext_offset, char *buf)
5815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
5825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Forward declarations.  */
5835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  auto int next_bsd_partition (void);
5845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  auto int next_pc_slice (void);
5855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Get next BSD partition in current PC slice.  */
5875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int next_bsd_partition (void)
5885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
5895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      int i;
5905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      int bsd_part_no = (*partition & 0xFF00) >> 8;
5915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* If this is the first time...  */
5935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (bsd_part_no == 0xFF)
5945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
5955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* Check if the BSD label is within current PC slice.  */
5965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (*len < BSD_LABEL_SECTOR + 1)
5975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
5985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      errnum = ERR_BAD_PART_TABLE;
5995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      return 0;
6005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
6015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* Read the BSD label.  */
6035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (! rawread (drive, *start + BSD_LABEL_SECTOR,
6045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			 0, SECTOR_SIZE, buf))
6055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    return 0;
6065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* Check if it is valid.  */
6085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (! BSD_LABEL_CHECK_MAG (buf))
6095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
6105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      errnum = ERR_BAD_PART_TABLE;
6115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      return 0;
6125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
6135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  bsd_part_no = -1;
6155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
6165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* Search next valid BSD partition.  */
6185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      for (i = bsd_part_no + 1; i < BSD_LABEL_NPARTS (buf); i++)
6195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
6205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (BSD_PART_TYPE (buf, i))
6215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
6225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      /* Note that *TYPE and *PARTITION were set
6235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		 for current PC slice.  */
6245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      *type = (BSD_PART_TYPE (buf, i) << 8) | (*type & 0xFF);
6255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      *start = BSD_PART_START (buf, i);
6265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      *len = BSD_PART_LENGTH (buf, i);
6275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      *partition = (*partition & 0xFF00FF) | (i << 8);
6285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef STAGE1_5
6305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      /* XXX */
6315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if ((drive & 0x80) && BSD_LABEL_DTYPE (buf) == DTYPE_SCSI)
6325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		bsd_evil_hack = 4;
6335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* ! STAGE1_5 */
6345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      return 1;
6365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
6375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
6385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      errnum = ERR_NO_PART;
6405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return 0;
6415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
6425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Get next PC slice. Be careful of that this function may return
6445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project     an empty PC slice (i.e. a partition whose type is zero) as well.  */
6455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int next_pc_slice (void)
6465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
6475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      int pc_slice_no = (*partition & 0xFF0000) >> 16;
6485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* If this is the first time...  */
6505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (pc_slice_no == 0xFF)
6515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
6525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  *offset = 0;
6535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  *ext_offset = 0;
6545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  *entry = -1;
6555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  pc_slice_no = -1;
6565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
6575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* Read the MBR or the boot sector of the extended partition.  */
6595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (! rawread (drive, *offset, 0, SECTOR_SIZE, buf))
6605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return 0;
6615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* Check if it is valid.  */
6635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (! PC_MBR_CHECK_SIG (buf))
6645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
6655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  errnum = ERR_BAD_PART_TABLE;
6665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  return 0;
6675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
6685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* Increase the entry number.  */
6705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      (*entry)++;
6715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* If this is out of current partition table...  */
6735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (*entry == PC_SLICE_MAX)
6745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
6755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  int i;
6765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* Search the first extended partition in current table.  */
6785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  for (i = 0; i < PC_SLICE_MAX; i++)
6795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
6805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if (IS_PC_SLICE_TYPE_EXTENDED (PC_SLICE_TYPE (buf, i)))
6815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
6825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  /* Found. Set the new offset and the entry number,
6835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		     and restart this function.  */
6845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  *offset = *ext_offset + PC_SLICE_START (buf, i);
6855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  if (! *ext_offset)
6865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    *ext_offset = *offset;
6875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  *entry = -1;
6885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  return next_pc_slice ();
6895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
6905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
6915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  errnum = ERR_NO_PART;
6935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  return 0;
6945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
6955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      *type = PC_SLICE_TYPE (buf, *entry);
6975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      *start = *offset + PC_SLICE_START (buf, *entry);
6985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      *len = PC_SLICE_LENGTH (buf, *entry);
6995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* The calculation of a PC slice number is complicated, because of
7015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	 the rather odd definition of extended partitions. Even worse,
7025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	 there is no guarantee that this is consistent with every
7035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	 operating systems. Uggh.  */
7045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (pc_slice_no < PC_SLICE_MAX
7055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  || (! IS_PC_SLICE_TYPE_EXTENDED (*type)
7065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      && *type != PC_SLICE_TYPE_NONE))
7075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	pc_slice_no++;
7085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      *partition = (pc_slice_no << 16) | 0xFFFF;
7105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return 1;
7115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
7125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Start the body of this function.  */
7145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef STAGE1_5
7165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (current_drive == NETWORK_DRIVE)
7175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return 0;
7185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
7195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* If previous partition is a BSD partition or a PC slice which
7215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project     contains BSD partitions...  */
7225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if ((*partition != 0xFFFFFF && IS_PC_SLICE_TYPE_BSD (*type & 0xff))
7235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      || ! (drive & 0x80))
7245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
7255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (*type == PC_SLICE_TYPE_NONE)
7265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	*type = PC_SLICE_TYPE_FREEBSD;
7275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* Get next BSD partition, if any.  */
7295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (next_bsd_partition ())
7305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return 1;
7315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* If the destination partition is a BSD partition and current
7335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	 BSD partition has any error, abort the operation.  */
7345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if ((dest & 0xFF00) != 0xFF00
7355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  && ((dest & 0xFF0000) == 0xFF0000
7365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      || (dest & 0xFF0000) == (*partition & 0xFF0000)))
7375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return 0;
7385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* Ignore the error.  */
7405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      errnum = ERR_NONE;
7415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
7425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return next_pc_slice ();
7445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
7455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef STAGE1_5
7475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned long cur_part_offset;
7485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned long cur_part_addr;
7495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
7505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Open a partition.  */
7525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint
7535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectreal_open_partition (int flags)
7545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
7555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned long dest_partition = current_partition;
7565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned long part_offset;
7575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned long ext_offset;
7585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int entry;
7595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  char buf[SECTOR_SIZE];
7605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int bsd_part, pc_slice;
7615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* For simplicity.  */
7635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  auto int next (void);
7645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int next (void)
7655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
7665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      int ret = next_partition (current_drive, dest_partition,
7675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				&current_partition, &current_slice,
7685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				&part_start, &part_length,
7695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				&part_offset, &entry, &ext_offset, buf);
7705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      bsd_part = (current_partition >> 8) & 0xFF;
7715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      pc_slice = current_partition >> 16;
7725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return ret;
7735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
7745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef STAGE1_5
7765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* network drive */
7775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (current_drive == NETWORK_DRIVE)
7785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return 1;
7795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (! sane_partition ())
7815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return 0;
7825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
7835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  bsd_evil_hack = 0;
7855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  current_slice = 0;
7865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  part_start = 0;
7875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Make sure that buf_geom is valid. */
7895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (buf_drive != current_drive)
7905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
7915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (get_diskinfo (current_drive, &buf_geom))
7925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
7935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  errnum = ERR_NO_DISK;
7945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  return 0;
7955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
7965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      buf_drive = current_drive;
7975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      buf_track = -1;
7985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
7995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  part_length = buf_geom.total_sectors;
8005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* If this is the whole disk, return here.  */
8025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (! flags && current_partition == 0xFFFFFF)
8035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return 1;
8045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (flags)
8065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    dest_partition = 0xFFFFFF;
8075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Initialize CURRENT_PARTITION for next_partition.  */
8095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  current_partition = 0xFFFFFF;
8105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  while (next ())
8125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
8135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef STAGE1_5
8145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    loop_start:
8155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      cur_part_offset = part_offset;
8175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      cur_part_addr = BOOT_PART_TABLE + (entry << 4);
8185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* ! STAGE1_5 */
8195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* If this is a valid partition...  */
8215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (current_slice)
8225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
8235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef STAGE1_5
8245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* Display partition information.  */
8255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (flags && ! IS_PC_SLICE_TYPE_EXTENDED (current_slice))
8265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
8275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if (! do_completion)
8285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
8295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  if (current_drive & 0x80)
8305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    grub_printf ("   Partition num: %d, ",
8315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				 current_partition >> 16);
8325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  if (! IS_PC_SLICE_TYPE_BSD (current_slice))
8345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    check_and_print_mount ();
8355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  else
8365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    {
8375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      int got_part = 0;
8385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      int saved_slice = current_slice;
8395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      while (next ())
8415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			{
8425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			  if (bsd_part == 0xFF)
8435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			    break;
8445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			  if (! got_part)
8465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			    {
8475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			      grub_printf ("[BSD sub-partitions immediately follow]\n");
8485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			      got_part = 1;
8495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			    }
8505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			  grub_printf ("     BSD Partition num: \'%c\', ",
8525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				       bsd_part + 'a');
8535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			  check_and_print_mount ();
8545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			}
8555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      if (! got_part)
8575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			grub_printf (" No BSD sub-partition found, partition type 0x%x\n",
8585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				     saved_slice);
8595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      if (errnum)
8615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			{
8625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			  errnum = ERR_NONE;
8635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			  break;
8645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			}
8655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      goto loop_start;
8675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    }
8685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
8695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      else
8705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
8715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  if (bsd_part != 0xFF)
8725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    {
8735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      char str[16];
8745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      if (! (current_drive & 0x80)
8765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			  || (dest_partition >> 16) == pc_slice)
8775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			grub_sprintf (str, "%c)", bsd_part + 'a');
8785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      else
8795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			grub_sprintf (str, "%d,%c)",
8805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				      pc_slice, bsd_part + 'a');
8815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      print_a_completion (str);
8825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    }
8835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  else if (! IS_PC_SLICE_TYPE_BSD (current_slice))
8845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    {
8855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      char str[8];
8865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      grub_sprintf (str, "%d)", pc_slice);
8885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      print_a_completion (str);
8895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    }
8905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
8915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
8925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  errnum = ERR_NONE;
8945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* ! STAGE1_5 */
8955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* Check if this is the destination partition.  */
8975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (! flags
8985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      && (dest_partition == current_partition
8995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  || ((dest_partition >> 16) == 0xFF
9005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      && ((dest_partition >> 8) & 0xFF) == bsd_part)))
9015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    return 1;
9025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
9035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
9045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef STAGE1_5
9065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (flags)
9075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
9085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (! (current_drive & 0x80))
9095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
9105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  current_partition = 0xFFFFFF;
9115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  check_and_print_mount ();
9125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
9135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      errnum = ERR_NONE;
9155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return 1;
9165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
9175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* ! STAGE1_5 */
9185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return 0;
9205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
9215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint
9245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectopen_partition (void)
9255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
9265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return real_open_partition (0);
9275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
9285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef STAGE1_5
9315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* XX used for device completion in 'set_device' and 'print_completions' */
9325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int incomplete, disk_choice;
9335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic enum
9345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
9355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  PART_UNSPECIFIED = 0,
9365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  PART_DISK,
9375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  PART_CHOSEN,
9385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
9395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectpart_choice;
9405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* ! STAGE1_5 */
9415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectchar *
9435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectset_device (char *device)
9445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
9455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef STAGE1_5
9465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    /* In Stage 1.5, the first 4 bytes of FILENAME has a device number.  */
9475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned long dev = *((unsigned long *) device);
9485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int drive = (dev >> 24) & 0xFF;
9495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int partition = dev & 0xFFFFFF;
9505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* If DRIVE is disabled, use SAVED_DRIVE instead.  */
9525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (drive == GRUB_INVALID_DRIVE)
9535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    current_drive = saved_drive;
9545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  else
9555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    current_drive = drive;
9565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* The `partition' part must always have a valid number.  */
9585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  current_partition = partition;
9595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return device + sizeof (unsigned long);
9615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#else /* ! STAGE1_5 */
9635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int result = 0;
9655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  incomplete = 0;
9675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  disk_choice = 1;
9685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  part_choice = PART_UNSPECIFIED;
9695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  current_drive = saved_drive;
9705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  current_partition = 0xFFFFFF;
9715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (*device == '(' && !*(device + 1))
9735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    /* user has given '(' only, let disk_choice handle what disks we have */
9745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return device + 1;
9755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
9765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (*device == '(' && *(++device))
9775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
9785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (*device != ',' && *device != ')')
9795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
9805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  char ch = *device;
9815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef SUPPORT_NETBOOT
9825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (*device == 'f' || *device == 'h'
9835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      || (*device == 'n' && network_ready)
9845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      || (*device == 'c' && cdrom_drive != GRUB_INVALID_DRIVE))
9855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#else
9865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (*device == 'f' || *device == 'h'
9875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      || (*device == 'c' && cdrom_drive != GRUB_INVALID_DRIVE))
9885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* SUPPORT_NETBOOT */
9895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
9905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      /* user has given '([fhn]', check for resp. add 'd' and
9915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		 let disk_choice handle what disks we have */
9925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if (!*(device + 1))
9935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
9945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  device++;
9955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  *device++ = 'd';
9965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  *device = '\0';
9975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  return device;
9985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
9995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      else if (*(device + 1) == 'd' && !*(device + 2))
10005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return device + 2;
10015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
10025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if ((*device == 'f'
10045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	       || *device == 'h'
10055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef SUPPORT_NETBOOT
10065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	       || (*device == 'n' && network_ready)
10075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
10085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	       || (*device == 'c' && cdrom_drive != GRUB_INVALID_DRIVE))
10095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      && (device += 2, (*(device - 1) != 'd')))
10105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    errnum = ERR_NUMBER_PARSING;
10115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef SUPPORT_NETBOOT
10135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (ch == 'n' && network_ready)
10145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    current_drive = NETWORK_DRIVE;
10155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  else
10165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* SUPPORT_NETBOOT */
10175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
10185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if (ch == 'c' && cdrom_drive != GRUB_INVALID_DRIVE)
10195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		current_drive = cdrom_drive;
10205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      else
10215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
10225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  safe_parse_maxint (&device, (int *) &current_drive);
10235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  disk_choice = 0;
10255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  if (ch == 'h')
10265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    current_drive += 0x80;
10275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
10285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
10295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
10305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (errnum)
10325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return 0;
10335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (*device == ')')
10355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
10365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  part_choice = PART_CHOSEN;
10375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  result = 1;
10385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
10395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      else if (*device == ',')
10405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
10415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* Either an absolute PC or BSD partition. */
10425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  disk_choice = 0;
10435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  part_choice ++;
10445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  device++;
10455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (*device >= '0' && *device <= '9')
10475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
10485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      part_choice ++;
10495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      current_partition = 0;
10505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if (!(current_drive & 0x80)
10525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  || !safe_parse_maxint (&device, (int *) &current_partition)
10535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  || current_partition > 254)
10545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
10555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  errnum = ERR_DEV_FORMAT;
10565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  return 0;
10575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
10585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      current_partition = (current_partition << 16) + 0xFFFF;
10605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if (*device == ',')
10625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		device++;
10635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if (*device >= 'a' && *device <= 'h')
10655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
10665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  current_partition = (((*(device++) - 'a') << 8)
10675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				       | (current_partition & 0xFF00FF));
10685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
10695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
10705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  else if (*device >= 'a' && *device <= 'h')
10715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
10725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      part_choice ++;
10735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      current_partition = ((*(device++) - 'a') << 8) | 0xFF00FF;
10745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
10755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (*device == ')')
10775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
10785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if (part_choice == PART_DISK)
10795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
10805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  current_partition = saved_partition;
10815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  part_choice ++;
10825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
10835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      result = 1;
10855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
10865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
10875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
10885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (! sane_partition ())
10905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return 0;
10915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
10925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (result)
10935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return device + 1;
10945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  else
10955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
10965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (!*device)
10975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	incomplete = 1;
10985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      errnum = ERR_DEV_FORMAT;
10995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
11005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return 0;
11025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* ! STAGE1_5 */
11045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
11055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
11075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  This performs a "mount" on the current device, both drive and partition
11085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  number.
11095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
11105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint
11125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectopen_device (void)
11135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
11145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (open_partition ())
11155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    attempt_mount ();
11165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (errnum != ERR_NONE)
11185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return 0;
11195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return 1;
11215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
11225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef STAGE1_5
11255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint
11265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectset_bootdev (int hdbias)
11275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
11285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int i, j;
11295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Copy the boot partition information to 0x7be-0x7fd for chain-loading.  */
11315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if ((saved_drive & 0x80) && cur_part_addr)
11325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
11335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (rawread (saved_drive, cur_part_offset,
11345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   0, SECTOR_SIZE, (char *) SCRATCHADDR))
11355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
11365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  char *dst, *src;
11375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* Need only the partition table.
11395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	     XXX: We cannot use grub_memmove because BOOT_PART_TABLE
11405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	     (0x07be) is less than 0x1000.  */
11415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  dst = (char *) BOOT_PART_TABLE;
11425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  src = (char *) SCRATCHADDR + BOOTSEC_PART_OFFSET;
11435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  while (dst < (char *) BOOT_PART_TABLE + BOOTSEC_PART_LENGTH)
11445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    *dst++ = *src++;
11455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* Set the active flag of the booted partition.  */
11475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  for (i = 0; i < 4; i++)
11485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    PC_SLICE_FLAG (BOOT_PART_TABLE, i) = 0;
11495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  *((unsigned char *) cur_part_addr) = PC_SLICE_FLAG_BOOTABLE;
11515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  boot_part_addr = cur_part_addr;
11525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
11535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      else
11545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return 0;
11555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
11565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /*
11585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   *  Set BSD boot device.
11595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   */
11605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  i = (saved_partition >> 16) + 2;
11615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (saved_partition == 0xFFFFFF)
11625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    i = 1;
11635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  else if ((saved_partition >> 16) == 0xFF)
11645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    i = 0;
11655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* FIXME: extremely evil hack!!! */
11675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  j = 2;
11685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (saved_drive & 0x80)
11695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    j = bsd_evil_hack;
11705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return MAKEBOOTDEV (j, (i >> 4), (i & 0xF),
11725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      ((saved_drive - hdbias) & 0x7F),
11735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      ((saved_partition >> 8) & 0xFF));
11745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
11755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* STAGE1_5 */
11765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic char *
11795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectsetup_part (char *filename)
11805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
11815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef STAGE1_5
11825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (! (filename = set_device (filename)))
11845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
11855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      current_drive = GRUB_INVALID_DRIVE;
11865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return 0;
11875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
11885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# ifndef NO_BLOCK_FILES
11905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (*filename != '/')
11915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    open_partition ();
11925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  else
11935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# endif /* ! NO_BLOCK_FILES */
11945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    open_device ();
11955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#else /* ! STAGE1_5 */
11975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
11985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (*filename == '(')
11995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
12005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if ((filename = set_device (filename)) == 0)
12015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
12025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  current_drive = GRUB_INVALID_DRIVE;
12035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  return 0;
12045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
12055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# ifndef NO_BLOCK_FILES
12065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (*filename != '/')
12075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	open_partition ();
12085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      else
12095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# endif /* ! NO_BLOCK_FILES */
12105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	open_device ();
12115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
12125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  else if (saved_drive != current_drive
12135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	   || saved_partition != current_partition
12145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	   || (*filename == '/' && fsys_type == NUM_FSYS)
12155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	   || buf_drive == -1)
12165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
12175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      current_drive = saved_drive;
12185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      current_partition = saved_partition;
12195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* allow for the error case of "no filesystem" after the partition
12205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project         is found.  This makes block files work fine on no filesystem */
12215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# ifndef NO_BLOCK_FILES
12225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (*filename != '/')
12235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	open_partition ();
12245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      else
12255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# endif /* ! NO_BLOCK_FILES */
12265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	open_device ();
12275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
12285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
12295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* ! STAGE1_5 */
12305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
12315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (errnum && (*filename == '/' || errnum != ERR_FSYS_MOUNT))
12325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return 0;
12335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  else
12345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    errnum = 0;
12355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
12365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef STAGE1_5
12375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (!sane_partition ())
12385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return 0;
12395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
12405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
12415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return filename;
12425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
12435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
12445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
12455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef STAGE1_5
12465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
12475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  This prints the filesystem type or gives relevant information.
12485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
12495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
12505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectvoid
12515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectprint_fsys_type (void)
12525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
12535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (! do_completion)
12545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
12555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      printf (" Filesystem type ");
12565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
12575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (fsys_type != NUM_FSYS)
12585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	printf ("is %s, ", fsys_table[fsys_type].name);
12595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      else
12605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	printf ("unknown, ");
12615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
12625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (current_partition == 0xFFFFFF)
12635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	printf ("using whole disk\n");
12645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      else
12655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	printf ("partition type 0x%x\n", current_slice & 0xFF);
12665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
12675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
12685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* STAGE1_5 */
12695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
12705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef STAGE1_5
12715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* If DO_COMPLETION is true, just print NAME. Otherwise save the unique
12725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   part into UNIQUE_STRING.  */
12735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectvoid
12745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectprint_a_completion (char *name)
12755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
12765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* If NAME is "." or "..", do not count it.  */
12775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (grub_strcmp (name, ".") == 0 || grub_strcmp (name, "..") == 0)
12785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return;
12795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
12805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (do_completion)
12815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
12825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      char *buf = unique_string;
12835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
12845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (! unique)
12855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	while ((*buf++ = *name++))
12865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  ;
12875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      else
12885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
12895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  while (*buf && (*buf == *name))
12905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
12915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      buf++;
12925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      name++;
12935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
12945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* mismatch, strip it.  */
12955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  *buf = '\0';
12965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
12975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
12985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  else
12995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    grub_printf (" %s", name);
13005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
13015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unique++;
13025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
13035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
13045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
13055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  This lists the possible completions of a device string, filename, or
13065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  any sane combination of the two.
13075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
13085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
13095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint
13105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectprint_completions (int is_filename, int is_completion)
13115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
13125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  char *buf = (char *) COMPLETION_BUF;
13135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  char *ptr = buf;
13145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
13155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unique_string = (char *) UNIQUE_BUF;
13165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  *unique_string = 0;
13175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unique = 0;
13185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  do_completion = is_completion;
13195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
13205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (! is_filename)
13215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
13225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* Print the completions of builtin commands.  */
13235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      struct builtin **builtin;
13245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
13255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (! is_completion)
13265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	grub_printf (" Possible commands are:");
13275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
13285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      for (builtin = builtin_table; (*builtin); builtin++)
13295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
13305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* If *BUILTIN cannot be run in the command-line, skip it.  */
13315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (! ((*builtin)->flags & BUILTIN_CMDLINE))
13325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    continue;
13335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
13345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (substring (buf, (*builtin)->name) <= 0)
13355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    print_a_completion ((*builtin)->name);
13365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
13375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
13385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (is_completion && *unique_string)
13395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
13405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (unique == 1)
13415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
13425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      char *u = unique_string + grub_strlen (unique_string);
13435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
13445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      *u++ = ' ';
13455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      *u = 0;
13465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
13475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
13485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  grub_strcpy (buf, unique_string);
13495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
13505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
13515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (! is_completion)
13525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	grub_putchar ('\n');
13535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
13545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      print_error ();
13555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      do_completion = 0;
13565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (errnum)
13575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return -1;
13585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      else
13595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return unique - 1;
13605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
13615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
13625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (*buf == '/' || (ptr = set_device (buf)) || incomplete)
13635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
13645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      errnum = 0;
13655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
13665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (*buf == '(' && (incomplete || ! *ptr))
13675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
13685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (! part_choice)
13695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
13705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      /* disk completions */
13715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      int disk_no, i, j;
13725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      struct geometry geom;
13735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
13745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if (! is_completion)
13755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		grub_printf (" Possible disks are: ");
13765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
13775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if (!ptr
13785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  || *(ptr-1) != 'd'
13795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef SUPPORT_NETBOOT
13805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  || *(ptr-2) != 'n'
13815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* SUPPORT_NETBOOT */
13825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  || *(ptr-2) != 'c')
13835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
13845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  for (i = (ptr && (*(ptr-1) == 'd' && *(ptr-2) == 'h') ? 1:0);
13855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		       i < (ptr && (*(ptr-1) == 'd' && *(ptr-2) == 'f') ? 1:2);
13865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		       i++)
13875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    {
13885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      for (j = 0; j < 8; j++)
13895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			{
13905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			  disk_no = (i * 0x80) + j;
13915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			  if ((disk_choice || disk_no == current_drive)
13925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			      && ! get_diskinfo (disk_no, &geom))
13935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			    {
13945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			      char dev_name[8];
13955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
13965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			      grub_sprintf (dev_name, "%cd%d", i ? 'h':'f', j);
13975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			      print_a_completion (dev_name);
13985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			    }
13995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			}
14005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    }
14015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
14025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
14035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if (cdrom_drive != GRUB_INVALID_DRIVE
14045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  && (disk_choice || cdrom_drive == current_drive)
14055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  && (!ptr
14065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      || *(ptr-1) == '('
14075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      || (*(ptr-1) == 'd' && *(ptr-2) == 'c')))
14085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		print_a_completion ("cd");
14095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
14105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# ifdef SUPPORT_NETBOOT
14115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if (network_ready
14125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  && (disk_choice || NETWORK_DRIVE == current_drive)
14135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  && (!ptr
14145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      || *(ptr-1) == '('
14155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      || (*(ptr-1) == 'd' && *(ptr-2) == 'n')))
14165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		print_a_completion ("nd");
14175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# endif /* SUPPORT_NETBOOT */
14185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
14195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if (is_completion && *unique_string)
14205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
14215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  ptr = buf;
14225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  while (*ptr != '(')
14235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    ptr--;
14245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  ptr++;
14255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  grub_strcpy (ptr, unique_string);
14265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  if (unique == 1)
14275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    {
14285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      ptr += grub_strlen (ptr);
14295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      if (*unique_string == 'h')
14305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			{
14315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			  *ptr++ = ',';
14325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			  *ptr = 0;
14335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			}
14345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      else
14355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			{
14365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			  *ptr++ = ')';
14375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			  *ptr = 0;
14385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			}
14395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    }
14405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
14415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
14425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if (! is_completion)
14435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		grub_putchar ('\n');
14445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
14455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  else
14465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
14475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      /* partition completions */
14485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if (part_choice == PART_CHOSEN
14495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  && open_partition ()
14505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  && ! IS_PC_SLICE_TYPE_BSD (current_slice))
14515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
14525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  unique = 1;
14535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  ptr = buf + grub_strlen (buf);
14545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  if (*(ptr - 1) != ')')
14555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    {
14565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      *ptr++ = ')';
14575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      *ptr = 0;
14585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    }
14595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
14605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      else
14615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
14625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  if (! is_completion)
14635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    grub_printf (" Possible partitions are:\n");
14645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  real_open_partition (1);
14655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
14665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  if (is_completion && *unique_string)
14675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    {
14685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      ptr = buf;
14695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      while (*ptr++ != ',')
14705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			;
14715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      grub_strcpy (ptr, unique_string);
14725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    }
14735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
14745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
14755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
14765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      else if (ptr && *ptr == '/')
14775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
14785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* filename completions */
14795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (! is_completion)
14805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    grub_printf (" Possible files are:");
14815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
14825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  dir (buf);
14835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
14845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (is_completion && *unique_string)
14855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
14865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      ptr += grub_strlen (ptr);
14875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      while (*ptr != '/')
14885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		ptr--;
14895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      ptr++;
14905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
14915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      grub_strcpy (ptr, unique_string);
14925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
14935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if (unique == 1)
14945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
14955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  ptr += grub_strlen (unique_string);
14965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
14975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  /* Check if the file UNIQUE_STRING is a directory.  */
14985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  *ptr = '/';
14995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  *(ptr + 1) = 0;
15005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
15015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  dir (buf);
15025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
15035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  /* Restore the original unique value.  */
15045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  unique = 1;
15055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
15065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  if (errnum)
15075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    {
15085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      /* Regular file */
15095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      errnum = 0;
15105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      *ptr = ' ';
15115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      *(ptr + 1) = 0;
15125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    }
15135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
15145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
15155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
15165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (! is_completion)
15175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    grub_putchar ('\n');
15185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
15195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      else
15205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	errnum = ERR_BAD_FILENAME;
15215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
15225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
15235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  print_error ();
15245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  do_completion = 0;
15255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (errnum)
15265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return -1;
15275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  else
15285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return unique - 1;
15295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
15305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* STAGE1_5 */
15315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
15325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
15335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
15345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  This is the generic file open function.
15355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
15365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
15375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint
15385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectgrub_open (char *filename)
15395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
15405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef NO_DECOMPRESSION
15415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  compressed_file = 0;
15425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* NO_DECOMPRESSION */
15435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
15445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* if any "dir" function uses/sets filepos, it must
15455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project     set it to zero before returning if opening a file! */
15465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  filepos = 0;
15475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
15485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (!(filename = setup_part (filename)))
15495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return 0;
15505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
15515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef NO_BLOCK_FILES
15525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  block_file = 0;
15535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* NO_BLOCK_FILES */
15545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
15555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* This accounts for partial filesystem implementations. */
15565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  fsmax = MAXINT;
15575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
15585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (*filename != '/')
15595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
15605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef NO_BLOCK_FILES
15615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      char *ptr = filename;
15625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      int tmp, list_addr = BLK_BLKLIST_START;
15635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      filemax = 0;
15645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
15655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      while (list_addr < BLK_MAX_ADDR)
15665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
15675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  tmp = 0;
15685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  safe_parse_maxint (&ptr, &tmp);
15695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  errnum = 0;
15705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
15715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (*ptr != '+')
15725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
15735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if ((*ptr && *ptr != '/' && !isspace (*ptr))
15745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  || tmp == 0 || tmp > filemax)
15755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		errnum = ERR_BAD_FILENAME;
15765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      else
15775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		filemax = tmp;
15785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
15795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      break;
15805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
15815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
15825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* since we use the same filesystem buffer, mark it to
15835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	     be remounted */
15845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  fsys_type = NUM_FSYS;
15855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
15865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  BLK_BLKSTART (list_addr) = tmp;
15875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  ptr++;
15885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
15895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (!safe_parse_maxint (&ptr, &tmp)
15905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      || tmp == 0
15915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      || (*ptr && *ptr != ',' && *ptr != '/' && !isspace (*ptr)))
15925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
15935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      errnum = ERR_BAD_FILENAME;
15945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      break;
15955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
15965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
15975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  BLK_BLKLENGTH (list_addr) = tmp;
15985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
15995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  filemax += (tmp * SECTOR_SIZE);
16005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  list_addr += BLK_BLKLIST_INC_VAL;
16015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
16025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (*ptr != ',')
16035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    break;
16045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
16055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  ptr++;
16065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
16075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
16085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (list_addr < BLK_MAX_ADDR && ptr != filename && !errnum)
16095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
16105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  block_file = 1;
16115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  BLK_CUR_FILEPOS = 0;
16125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  BLK_CUR_BLKLIST = BLK_BLKLIST_START;
16135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  BLK_CUR_BLKNUM = 0;
16145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
16155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef NO_DECOMPRESSION
16165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  return gunzip_test_header ();
16175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#else /* NO_DECOMPRESSION */
16185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  return 1;
16195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* NO_DECOMPRESSION */
16205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
16215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#else /* NO_BLOCK_FILES */
16225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      errnum = ERR_BAD_FILENAME;
16235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* NO_BLOCK_FILES */
16245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
16255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
16265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (!errnum && fsys_type == NUM_FSYS)
16275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    errnum = ERR_FSYS_MOUNT;
16285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
16295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# ifndef STAGE1_5
16305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* set "dir" function to open a file */
16315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  print_possibilities = 0;
16325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project# endif
16335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
16345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (!errnum && (*(fsys_table[fsys_type].dir_func)) (filename))
16355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
16365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef NO_DECOMPRESSION
16375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return gunzip_test_header ();
16385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#else /* NO_DECOMPRESSION */
16395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return 1;
16405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* NO_DECOMPRESSION */
16415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
16425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
16435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return 0;
16445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
16455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
16465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
16475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint
16485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectgrub_read (char *buf, int len)
16495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
16505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Make sure "filepos" is a sane value */
16515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if ((filepos < 0) || (filepos > filemax))
16525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    filepos = filemax;
16535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
16545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Make sure "len" is a sane value */
16555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if ((len < 0) || (len > (filemax - filepos)))
16565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    len = filemax - filepos;
16575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
16585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* if target file position is past the end of
16595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project     the supported/configured filesize, then
16605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project     there is an error */
16615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (filepos + len > fsmax)
16625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
16635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      errnum = ERR_FILELENGTH;
16645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return 0;
16655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
16665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
16675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef NO_DECOMPRESSION
16685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (compressed_file)
16695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return gunzip_read (buf, len);
16705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* NO_DECOMPRESSION */
16715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
16725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef NO_BLOCK_FILES
16735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (block_file)
16745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
16755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      int size, off, ret = 0;
16765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
16775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      while (len && !errnum)
16785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
16795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* we may need to look for the right block in the list(s) */
16805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (filepos < BLK_CUR_FILEPOS)
16815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
16825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      BLK_CUR_FILEPOS = 0;
16835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      BLK_CUR_BLKLIST = BLK_BLKLIST_START;
16845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      BLK_CUR_BLKNUM = 0;
16855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
16865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
16875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* run BLK_CUR_FILEPOS up to filepos */
16885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  while (filepos > BLK_CUR_FILEPOS)
16895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
16905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      if ((filepos - (BLK_CUR_FILEPOS & ~(SECTOR_SIZE - 1)))
16915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  >= SECTOR_SIZE)
16925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
16935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  BLK_CUR_FILEPOS += SECTOR_SIZE;
16945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  BLK_CUR_BLKNUM++;
16955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
16965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  if (BLK_CUR_BLKNUM >= BLK_BLKLENGTH (BLK_CUR_BLKLIST))
16975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    {
16985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      BLK_CUR_BLKLIST += BLK_BLKLIST_INC_VAL;
16995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		      BLK_CUR_BLKNUM = 0;
17005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    }
17015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
17025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      else
17035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		BLK_CUR_FILEPOS = filepos;
17045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
17055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
17065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  off = filepos & (SECTOR_SIZE - 1);
17075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  size = ((BLK_BLKLENGTH (BLK_CUR_BLKLIST) - BLK_CUR_BLKNUM)
17085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		  * SECTOR_SIZE) - off;
17095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (size > len)
17105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    size = len;
17115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
17125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  disk_read_func = disk_read_hook;
17135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
17145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  /* read current block and put it in the right place in memory */
17155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  devread (BLK_BLKSTART (BLK_CUR_BLKLIST) + BLK_CUR_BLKNUM,
17165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		   off, size, buf);
17175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
17185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  disk_read_func = NULL;
17195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
17205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  len -= size;
17215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  filepos += size;
17225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  ret += size;
17235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  buf += size;
17245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
17255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
17265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (errnum)
17275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	ret = 0;
17285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
17295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return ret;
17305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
17315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* NO_BLOCK_FILES */
17325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
17335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (fsys_type == NUM_FSYS)
17345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
17355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      errnum = ERR_FSYS_MOUNT;
17365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return 0;
17375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
17385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
17395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return (*(fsys_table[fsys_type].read_func)) (buf, len);
17405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
17415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
17425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef STAGE1_5
17435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Reposition a file offset.  */
17445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint
17455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectgrub_seek (int offset)
17465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
17475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (offset > filemax || offset < 0)
17485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return -1;
17495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
17505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  filepos = offset;
17515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return offset;
17525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
17535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
17545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint
17555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectdir (char *dirname)
17565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
17575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef NO_DECOMPRESSION
17585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  compressed_file = 0;
17595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* NO_DECOMPRESSION */
17605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
17615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (!(dirname = setup_part (dirname)))
17625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return 0;
17635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
17645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (*dirname != '/')
17655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    errnum = ERR_BAD_FILENAME;
17665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
17675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (fsys_type == NUM_FSYS)
17685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    errnum = ERR_FSYS_MOUNT;
17695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
17705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (errnum)
17715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return 0;
17725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
17735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* set "dir" function to list completions */
17745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  print_possibilities = 1;
17755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
17765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return (*(fsys_table[fsys_type].dir_func)) (dirname);
17775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
17785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* STAGE1_5 */
17795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
17805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectvoid
17815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectgrub_close (void)
17825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
17835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef NO_BLOCK_FILES
17845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (block_file)
17855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return;
17865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* NO_BLOCK_FILES */
17875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
17885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (fsys_table[fsys_type].close_func != 0)
17895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    (*(fsys_table[fsys_type].close_func)) ();
17905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
1791