/* minix.c - The minix filesystem, version 1 and 2. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2004,2005,2006,2007,2008 Free Software Foundation, Inc.
*
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
GRUB_MOD_LICENSE ("GPLv3+");
#ifdef MODE_MINIX3
#elif defined(MODE_MINIX2)
#else
#endif
#if defined(MODE_MINIX2) || defined(MODE_MINIX3)
#else
#endif
#ifdef MODE_MINIX3
#else
#endif
#ifndef MODE_MINIX3
#endif
#ifdef MODE_MINIX3
#else
#endif
#ifdef MODE_MINIX3
struct grub_minix_sblock
{
};
#else
struct grub_minix_sblock
{
};
#endif
#if defined(MODE_MINIX3) || defined(MODE_MINIX2)
struct grub_minix_inode
{
};
#else
struct grub_minix_inode
{
};
#endif
/* Information about a "mounted" minix filesystem. */
struct grub_minix_data
{
int ino;
int linknest;
int filename_size;
};
const char *path);
static grub_minix_uintn_t
{
/ GRUB_MINIX_INODE_BLKSZ (data));
/* Read the block pointer in ZONE, on the offset NUM. */
{
sizeof (grub_minix_uintn_t) * num,
sizeof (grub_minix_uintn_t), (char *) &indirn);
return grub_minix_le_to_cpu_n (indirn);
}
/* Direct block. */
if (blk < GRUB_MINIX_INODE_DIR_BLOCKS)
/* Indirect block. */
if (blk < block_per_zone)
{
return indir;
}
/* Double indirect block. */
blk -= block_per_zone;
{
blk / block_per_zone);
return indir;
}
#if defined (MODE_MINIX3) || defined (MODE_MINIX2)
* (grub_uint64_t) block_per_zone))
{
return indir;
}
#endif
/* This should never happen. */
return 0;
}
/* Read LEN bytes from the file described by DATA starting with byte
POS. Return the amount of read bytes in READ. */
static grub_ssize_t
{
/* Adjust len so it we can't read past the end of the file. */
>> data->log_block_size);
{
if (grub_errno)
return -1;
/* Last block. */
if (i == blockcnt - 1)
{
if (!blockend)
}
/* First block. */
if (i == posblock)
{
}
if (grub_errno)
return -1;
}
return len;
}
/* Read inode INO from the mounted filesystem described by DATA. This
inode is used by default now. */
static grub_err_t
{
/* Block in which the inode is stored. */
/* The first inode in minix is inode 1. */
ino--;
/ sizeof (struct grub_minix_inode))
* sizeof (struct grub_minix_inode));
return GRUB_ERR_NONE;
}
/* Lookup the symlink the current inode points to. INO is the inode
number of the directory the symlink is relative to. */
static grub_err_t
{
if (grub_minix_read_file (data, 0, 0,
return grub_errno;
/* The symlink is an absolute path, go back to the root inode. */
if (symlink[0] == '/')
/* Now load in the old inode. */
return grub_errno;
if (grub_errno)
return grub_errno;
}
/* Find the file with the pathname PATH on the filesystem described by
DATA. */
static grub_err_t
{
char *next;
unsigned int pos = 0;
int dirino;
/* Skip the first slash. */
if (name[0] == '/')
{
name++;
if (!*name)
return 0;
}
/* Extract the actual part from the pathname. */
if (next)
{
next[0] = '\0';
next++;
}
do
{
if (grub_strlen (name) == 0)
return GRUB_ERR_NONE;
(char *) &ino) < 0)
return grub_errno;
return grub_errno;
/* Check if the current direntry matches the current part of the
pathname. */
{
/* Follow the symlink. */
if ((GRUB_MINIX_INODE_MODE (data)
& GRUB_MINIX_IFLNK) == GRUB_MINIX_IFLNK)
{
if (grub_errno)
return grub_errno;
}
if (!next)
return 0;
pos = 0;
if (next)
{
next[0] = '\0';
next++;
}
if ((GRUB_MINIX_INODE_MODE (data)
& GRUB_MINIX_IFDIR) != GRUB_MINIX_IFDIR)
continue;
}
return grub_errno;
}
/* Mount the filesystem on the disk DISK. */
static struct grub_minix_data *
{
if (!data)
return 0;
/* Read the superblock. */
if (grub_errno)
goto fail;
{
#if !defined(MODE_MINIX3)
#else
#endif
}
#if !defined(MODE_MINIX3)
#endif
else
goto fail;
#ifdef MODE_MINIX3
/* These tests are endian-independent. No need to byteswap. */
else
{
goto fail;
data->log_block_size++);
}
#else
#endif
return data;
fail:
#if defined(MODE_MINIX3)
#elif defined(MODE_MINIX2)
#else
#endif
return 0;
}
static grub_err_t
const struct grub_dirhook_info *info))
{
unsigned int pos = 0;
if (!data)
return grub_errno;
if (grub_errno)
goto fail;
if (grub_errno)
goto fail;
{
goto fail;
}
{
(char *) &ino) < 0)
return grub_errno;
(char *) filename) < 0)
return grub_errno;
if (!ino)
{
continue;
}
& GRUB_MINIX_IFDIR) == GRUB_MINIX_IFDIR);
break;
/* Load the old inode back in. */
}
fail:
return grub_errno;
}
/* Open a file named NAME and initialize FILE. */
static grub_err_t
{
if (!data)
return grub_errno;
/* Open the inode op the root directory. */
if (grub_errno)
{
return grub_errno;
}
{
return grub_errno;
}
/* Traverse the directory tree to the node that should be
opened. */
if (grub_errno)
{
return grub_errno;
}
return GRUB_ERR_NONE;
}
static grub_ssize_t
{
}
static grub_err_t
{
return GRUB_ERR_NONE;
}
{
#if defined(MODE_MINIX3)
.name = "minix3",
#elif defined(MODE_MINIX2)
.name = "minix2",
#else
.name = "minix",
#endif
.dir = grub_minix_dir,
.open = grub_minix_open,
.read = grub_minix_read,
.next = 0
};
#if defined(MODE_MINIX3)
#elif defined(MODE_MINIX2)
#else
#endif
{
}
#if defined(MODE_MINIX3)
#elif defined(MODE_MINIX2)
#else
#endif
{
}