hsfs_small.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 1991-1994, Sun Microsystems, Inc.
* All rights reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Basic file system reading code for standalone I/O system.
*/
/*
* This code must be kept very small. If space allows, you can
* turn on the ability to handle continuations (and other signatures)
* by #defining HANDLE_CONTINUATION.
*/
#include "iob.h"
#include "cbootblk.h"
#include "hsfs_sig.h"
#define NULL 0
#define TRUE 1
#define FALSE 0
#ifdef DEBUG
/* debugging printfs */
#define DEBUG_PRINTF0(s) \
#define DEBUG_PRINTF1(s, a1) \
#else
#define DEBUG_PRINTF0(s)
#define DEBUG_PRINTF1(s, a1)
#endif
char fscompname[] = "hsfsboot";
static int
{
#ifdef DEBUG
static char *msg = "rs:[%c] o=%d b=%d c=%d n=%d\n";
#endif
} else {
}
return (0);
}
return (1);
}
/*
* Look up a file, pathname component by pathname component.
* Return lbn of file if found, 0 otherwise.
*/
static u_int
{
char *q;
char c;
u_int n;
return (0);
while (*path) {
while (*path == '/')
path++;
q = path;
while (*q != '/' && *q != '\0')
q++;
c = *q;
*q = '\0';
DEBUG_PRINTF1("fnd: n=%d\n", n);
if (c == '\0')
break;
return (0);
*q = c;
path = q;
continue;
} else {
return (0);
}
}
return (n);
}
/*
* Look up the file in the directory.
* Return lbn of file extent on success, 0 on failure.
*/
static u_int
{
if (s == NULL || *s == '\0')
return (0);
return (0);
dirloc = 0;
while (dirloc < ISO_SECTOR_SIZE) {
altnm = 0;
if (!reclen)
break;
if (altnm) {
continue;
} else {
continue;
}
}
return (0);
}
}
return (0);
}
static int
{
if (diff <= 0)
return (-1);
return (-1);
return (0);
}
int
{
int i, j;
if ((i = count) <= 0)
return (0);
while (i > 0) {
return (0);
}
buf += j;
i -= j;
}
return (count);
}
/*
* Open a file. For the bootblock, we assume one file can be opened
* on a hsfs filesystem. The underlying device is the one we rode in on.
*/
int
{
register char *bufp;
DEBUG_PRINTF0("open\n");
return (-1); /* if devopen fails, open fails */
/*
* Pseudo-mount a file system; read the superblock.
*/
goto failed;
/* Make sure we start with a clean slate. */
/* Since RRIP is based on ISO9660, that's where we start */
ISO_ID_STRLEN) != 0 ||
puts("bootblk: not an ISO9660 file system.\n");
goto failed;
}
/* Now we fill in the volume descriptor */
/* Make sure we have a valid logical block size */
DEBUG_PRINTF1("%d byte logical block size invalid.",
goto failed;
}
/* Read the ROOT directory */
goto failed;
/* Extract the ROOT directory information from the directory block */
goto failed;
return (0); /* only one open file! */
return (-1);
}
int
{
}
/*
* This version of seek() only performs absolute seeks (whence == 0).
*/
void
{
}
/*
* Return the next directory entry.
* Return 0 if no next entry, length of directory entry otherwise.
*/
static int
int offset, /* dir entry offset into dir blk */
{
u_char c;
if (!dir_len)
/* zero length directory, done */
return (0);
if (IDE_REGULAR_FILE(c)) {
} else if (IDE_REGULAR_DIR(c)) {
} else {
DEBUG_PRINTF1("pd: ftype=0x%x unknown.\n", c);
return (-1);
}
/*
* Massage hsfs name, recognizing special entries for . and ..
* else lopping off version junk.
*/
/* Some initial conditions */
/* Special Case: Current Directory */
nmbuf[0] = '.';
nmlen = 1;
/* Special Case: Parent Directory */
nmbuf[0] = '.';
nmlen = 2;
/* Other file name */
} else {
register int l = nmlen;
register int i;
nmlen = 0;
for (i = 0; i < l; i++) {
if (c == ';')
break;
else if (c == ' ')
continue;
else
}
}
DEBUG_PRINTF0("pd bf sua");
#ifdef HANDLE_CONTINUATION
/* System Use Fields */
if (ce_len) {
/* there is an SUA for this dir entry; go parse it */
while (ce_lbn) {
/*
* Process continuation of SUA,
* saving current position in dir,
* as will be using iobuf to read SUA continuation.
*/
int rd_ok;
if (!rd_ok)
return (0);
&altnm);
}
if (altnm)
}
#else /* HANDLE_CONTINUATION */
/* System Use Fields */
if (ce_len) {
/* there is an SUA for this dir entry; go parse it */
if (altnm)
}
#endif /* HANDLE_CONTINUATION */
DEBUG_PRINTF0("pd af sua");
/* assert(namelen >= nmlen) */
}
#ifdef DEBUG
if (altnm)
#endif /* DEBUG */
DEBUG_PRINTF0("pd end\n");
return (dir_len);
}
#ifdef HANDLE_CONTINUATION
/*
* Parse the System Use Fields in the System Use Area.
* Return block number of continuation (if any),
* or 0 if no continuation.
*/
static u_int
{
u_int i;
/*
* A null entry, or an entry with zero length
* terminates the SUSP.
*/
break;
/* Compare current entry to all known signatures */
for (i = 0; i < HSFS_NUM_SIG; i++) {
break;
}
}
switch (i) {
case SUSP_CE_IX:
/*
* CE signature: continuation of SUSP.
* will want to return new lbn, len.
*/
break;
case SUSP_ST_IX:
/* ST signature: terminates SUSP */
return (ce_lbn);
case RRIP_RR_IX:
/* XXX do we want to break when we see a RR? */
break;
case RRIP_NM_IX:
/* NM signature: POSIX-style file name */
DEBUG_PRINTF0(" NM\n");
if (!RRIP_NAME_FLAGS(susp)) {
/* copy out new name if requested */
if (*nmlen) {
/* assert(old(nmlen) >= new(nmlen)) */
*altnm = 1;
}
}
break;
case HSFS_NUM_SIG:
/* couldn't find a legit susp, complain and continue */
(*printf_p)("parse_susp(): Bad SUSP\n");
break;
default:
break;
}
}
return (ce_lbn);
}
#else /* HANDLE_CONTINUATION */
/*
* Parse the System Use Fields in the System Use Area.
* Return block number of continuation (if any),
* or 0 if no continuation.
*/
static u_int
{
/*
* A null entry, or an entry with zero length
* terminates the SUSP.
*/
break;
/* Compare current entry to all known signatures */
!RRIP_NAME_FLAGS(susp)) {
/* copy out new name if requested */
if (*nmlen) {
/* assert(old(nmlen) >= new(nmlen)) */
*nmlen);
*altnm = 1;
}
return (0);
}
}
return (0);
}
#endif /* HANDLE_CONTINUATION */