15b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
25b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  GRUB  --  GRand Unified Bootloader
35b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  Copyright (C) 2000, 2001  Free Software Foundation, Inc.
45b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
55b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  This program is free software; you can redistribute it and/or modify
65b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  it under the terms of the GNU General Public License as published by
75b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  the Free Software Foundation; either version 2 of the License, or
85b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  (at your option) any later version.
95b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  This program is distributed in the hope that it will be useful,
115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  but WITHOUT ANY WARRANTY; without even the implied warranty of
125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  GNU General Public License for more details.
145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  You should have received a copy of the GNU General Public License
165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  along with this program; if not, write to the Free Software
175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Elements of this file were originally from the FreeBSD "biosboot"
225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * bootloader file "disk.c" dated 4/12/95.
235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * The license and header comments from that file are included here.
255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Mach Operating System
295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Copyright (c) 1992, 1991 Carnegie Mellon University
305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * All Rights Reserved.
315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Permission to use, copy, modify and distribute this software and its
335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * documentation is hereby granted, provided that both the copyright
345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * notice and this permission notice appear in all copies of the
355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * software, derivative works or modified versions, and any portions
365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * thereof, and that both notices appear in supporting documentation.
375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Carnegie Mellon requests users of this software to return to
435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  School of Computer Science
465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  Carnegie Mellon University
475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  Pittsburgh PA 15213-3890
485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * any improvements or extensions that they make and grant Carnegie Mellon
505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * the rights to redistribute these changes.
515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *	from: Mach, Revision 2.2  92/04/04  11:35:49  rpd
535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *	$Id: fsys_ffs.c,v 1.10 2001/11/12 06:57:29 okuji Exp $
545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef FSYS_FFS
575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "shared.h"
595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "filesys.h"
615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "defs.h"
635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "disk_inode.h"
645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "disk_inode_ffs.h"
655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "dir.h"
665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "fs.h"
675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* used for filesystem map blocks */
695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int mapblock;
705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int mapblock_offset;
715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int mapblock_bsize;
725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* pointer to superblock */
745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define SUPERBLOCK ((struct fs *) ( FSYS_BUF + 8192 ))
755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define INODE ((struct icommon *) ( FSYS_BUF + 16384 ))
765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define MAPBUF ( FSYS_BUF + 24576 )
775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define MAPBUF_LEN 8192
785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint
815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectffs_mount (void)
825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int retval = 1;
845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if ((((current_drive & 0x80) || (current_slice != 0))
865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project       && ! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_BSDFFS))
875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      || part_length < (SBLOCK + (SBSIZE / DEV_BSIZE))
885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      || !devread (SBLOCK, 0, SBSIZE, (char *) SUPERBLOCK)
895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      || SUPERBLOCK->fs_magic != FS_MAGIC)
905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    retval = 0;
915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  mapblock = -1;
935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  mapblock_offset = -1;
945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return retval;
965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int
995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectblock_map (int file_block)
1005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
1015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int bnum, offset, bsize;
1025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (file_block < NDADDR)
1045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return (INODE->i_db[file_block]);
1055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* If the blockmap loaded does not include FILE_BLOCK,
1075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project     load a new blockmap.  */
1085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if ((bnum = fsbtodb (SUPERBLOCK, INODE->i_ib[0])) != mapblock
1095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      || (mapblock_offset <= bnum && bnum <= mapblock_offset + mapblock_bsize))
1105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
1115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (MAPBUF_LEN < SUPERBLOCK->fs_bsize)
1125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
1135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  offset = ((file_block - NDADDR) % NINDIR (SUPERBLOCK));
1145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  bsize = MAPBUF_LEN;
1155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (offset + MAPBUF_LEN > SUPERBLOCK->fs_bsize)
1175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    offset = (SUPERBLOCK->fs_bsize - MAPBUF_LEN) / sizeof (int);
1185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
1195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      else
1205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
1215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  bsize = SUPERBLOCK->fs_bsize;
1225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  offset = 0;
1235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
1245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (! devread (bnum, offset * sizeof (int), bsize, (char *) MAPBUF))
1265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
1275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  mapblock = -1;
1285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  mapblock_bsize = -1;
1295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  mapblock_offset = -1;
1305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  errnum = ERR_FSYS_CORRUPT;
1315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  return -1;
1325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
1335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      mapblock = bnum;
1355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      mapblock_bsize = bsize;
1365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      mapblock_offset = offset;
1375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
1385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return (((int *) MAPBUF)[((file_block - NDADDR) % NINDIR (SUPERBLOCK))
1405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			  - mapblock_offset]);
1415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
1425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint
1455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectffs_read (char *buf, int len)
1465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
1475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int logno, off, size, map, ret = 0;
1485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  while (len && !errnum)
1505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
1515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      off = blkoff (SUPERBLOCK, filepos);
1525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      logno = lblkno (SUPERBLOCK, filepos);
1535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      size = blksize (SUPERBLOCK, INODE, logno);
1545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if ((map = block_map (logno)) < 0)
1565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	break;
1575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      size -= off;
1595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (size > len)
1615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	size = len;
1625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      disk_read_func = disk_read_hook;
1645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      devread (fsbtodb (SUPERBLOCK, map), off, size, buf);
1665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      disk_read_func = NULL;
1685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      buf += size;
1705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      len -= size;
1715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      filepos += size;
1725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      ret += size;
1735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
1745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (errnum)
1765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    ret = 0;
1775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return ret;
1795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
1805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint
1835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectffs_dir (char *dirname)
1845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
1855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  char *rest, ch;
1865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int block, off, loc, map, ino = ROOTINO;
1875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  struct direct *dp;
1885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* main loop to find destination inode */
1905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectloop:
1915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* load current inode (defaults to the root inode) */
1935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (!devread (fsbtodb (SUPERBLOCK, itod (SUPERBLOCK, ino)),
1955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project								ino % (SUPERBLOCK->fs_inopb) * sizeof (struct dinode),
1965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project								sizeof (struct dinode), (char *) INODE))
1975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			return 0;			/* XXX what return value? */
1985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* if we have a real file (and we're not just printing possibilities),
2005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project     then this is where we want to exit */
2015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (!*dirname || isspace (*dirname))
2035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
2045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if ((INODE->i_mode & IFMT) != IFREG)
2055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
2065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  errnum = ERR_BAD_FILETYPE;
2075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  return 0;
2085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
2095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      filemax = INODE->i_size;
2115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* incomplete implementation requires this! */
2135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      fsmax = (NDADDR + NINDIR (SUPERBLOCK)) * SUPERBLOCK->fs_bsize;
2145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return 1;
2155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
2165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* continue with file/directory name interpretation */
2185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  while (*dirname == '/')
2205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    dirname++;
2215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (!(INODE->i_size) || ((INODE->i_mode & IFMT) != IFDIR))
2235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
2245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      errnum = ERR_BAD_FILETYPE;
2255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return 0;
2265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
2275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; rest++);
2295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  *rest = 0;
2315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  loc = 0;
2325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* loop for reading a the entries in a directory */
2345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  do
2365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    {
2375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (loc >= INODE->i_size)
2385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
2395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if 0
2405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  putchar ('\n');
2415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
2425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (print_possibilities < 0)
2445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    return 1;
2455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  errnum = ERR_FILE_NOT_FOUND;
2475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  *rest = ch;
2485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  return 0;
2495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
2505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (!(off = blkoff (SUPERBLOCK, loc)))
2525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
2535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  block = lblkno (SUPERBLOCK, loc);
2545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if ((map = block_map (block)) < 0
2565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      || !devread (fsbtodb (SUPERBLOCK, map), 0,
2575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			   blksize (SUPERBLOCK, INODE, block),
2585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			   (char *) FSYS_BUF))
2595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    {
2605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      errnum = ERR_FSYS_CORRUPT;
2615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      *rest = ch;
2625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	      return 0;
2635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    }
2645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
2655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      dp = (struct direct *) (FSYS_BUF + off);
2675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      loc += dp->d_reclen;
2685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef STAGE1_5
2705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (dp->d_ino && print_possibilities && ch != '/'
2715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  && (!*dirname || substring (dirname, dp->d_name) <= 0))
2725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
2735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  if (print_possibilities > 0)
2745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    print_possibilities = -print_possibilities;
2755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  print_a_completion (dp->d_name);
2775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
2785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* STAGE1_5 */
2795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
2805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  while (!dp->d_ino || (substring (dirname, dp->d_name) != 0
2815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			|| (print_possibilities && ch != '/')));
2825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* only get here if we have a matching directory entry */
2845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  ino = dp->d_ino;
2865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  *(dirname = rest) = ch;
2875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* go back to main loop at top of function */
2895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  goto loop;
2905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
2915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint
2935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectffs_embed (int *start_sector, int needed_sectors)
2945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
2955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* XXX: I don't know if this is really correct. Someone who is
2965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project     familiar with BSD should check for this.  */
2975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (needed_sectors > 14)
2985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return 0;
2995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  *start_sector = 1;
3015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if 1
3025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* FIXME: Disable the embedding in FFS until someone checks if
3035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project     the code above is correct.  */
3045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return 0;
3055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#else
3065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return 1;
3075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
3085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
3095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* FSYS_FFS */
311