NetBSD/sys/arch/i386/boot/sys.c

247 lines
5.8 KiB
C
Raw Normal View History

/* $NetBSD: sys.c,v 1.14 1996/06/18 06:10:35 mycroft Exp $ */
1994-10-27 07:14:23 +03:00
1993-03-21 21:04:42 +03:00
/*
* Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
*
* Mach Operating System
* Copyright (c) 1992, 1991 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
#include "boot.h"
1993-12-17 03:41:23 +03:00
#include <sys/dirent.h>
1993-03-21 21:04:42 +03:00
#include <sys/reboot.h>
char mapbuf[MAXBSIZE], iobuf[MAXBSIZE], fsbuf[SBSIZE];
int mapblock = 0;
char pathname[MAXPATHLEN + 1];
1993-03-21 21:04:42 +03:00
void bcopy(), pcpy();
1993-03-21 21:04:42 +03:00
read(buffer, count)
char *buffer;
int count;
1993-03-21 21:04:42 +03:00
{
_read(buffer, count, bcopy);
1993-03-21 21:04:42 +03:00
}
xread(buffer, count)
char *buffer;
1993-03-21 21:04:42 +03:00
int count;
{
_read(buffer, count, pcpy);
}
_read(buffer, count, copy)
1993-03-21 21:04:42 +03:00
char *buffer;
int count;
void (*copy)();
1993-03-21 21:04:42 +03:00
{
int logno, off, size;
int cnt2;
1993-03-21 21:04:42 +03:00
while (count) {
off = blkoff(fs, poff);
logno = lblkno(fs, poff);
cnt2 = size = blksize(fs, &inode, logno);
bnum = fsbtodb(fs, block_map(logno)) + boff;
1993-03-21 21:04:42 +03:00
cnt = cnt2;
iodest = iobuf;
devread();
size -= off;
if (size > count)
size = count;
copy(iodest + off, buffer, size);
1993-03-21 21:04:42 +03:00
buffer += size;
count -= size;
poff += size;
}
}
find(path)
1994-01-11 17:24:11 +03:00
char *path;
1993-03-21 21:04:42 +03:00
{
char *rest, ch;
int block, off, loc, ino = ROOTINO, parent;
1993-12-17 03:41:23 +03:00
struct dirent *dp;
int nlinks = 0;
1994-01-11 17:24:11 +03:00
loop:
iodest = iobuf;
1993-03-21 21:04:42 +03:00
cnt = fs->fs_bsize;
bnum = fsbtodb(fs, ino_to_fsba(fs,ino)) + boff;
1993-03-21 21:04:42 +03:00
devread();
bcopy(&((struct dinode *)iodest)[ino_to_fsbo(fs,ino)],
1993-03-21 21:04:42 +03:00
&inode.i_din,
1994-01-11 17:24:11 +03:00
sizeof(struct dinode));
if ((inode.i_mode & IFMT) == IFLNK) {
int link_len = inode.i_size;
int len = strlen(path);
if (link_len + len > MAXPATHLEN ||
++ nlinks > MAXSYMLINKS)
return 0;
bcopy(path, &pathname[link_len], len + 1);
if (link_len < fs->fs_maxsymlinklen)
bcopy(inode.i_shortlink, pathname, link_len);
else {
poff = 0;
read(pathname,link_len);
}
path = pathname;
if (*pathname == '/')
ino = ROOTINO;
else
ino = parent;
goto loop;
}
1993-03-21 21:04:42 +03:00
if (!*path)
return 1;
while (*path == '/')
path++;
1994-01-11 17:24:11 +03:00
if (!inode.i_size || ((inode.i_mode & IFMT) != IFDIR))
1993-03-21 21:04:42 +03:00
return 0;
parent = ino;
1994-01-11 17:24:11 +03:00
for (rest = path; (ch = *rest) && ch != '/'; rest++);
1993-03-21 21:04:42 +03:00
*rest = 0;
loc = 0;
do {
if (loc >= inode.i_size)
return 0;
if (!(off = blkoff(fs, loc))) {
int cnt2;
1993-03-21 21:04:42 +03:00
block = lblkno(fs, loc);
cnt2 = blksize(fs, &inode, block);
1993-03-21 21:04:42 +03:00
bnum = fsbtodb(fs, block_map(block)) + boff;
cnt = cnt2;
1993-03-21 21:04:42 +03:00
iodest = iobuf;
devread();
}
1993-12-17 03:41:23 +03:00
dp = (struct dirent *)(iodest + off);
if (dp->d_reclen < 8) {
printf("directory corrupted (possible geometry mismatch)\n");
return 0;
}
1993-03-21 21:04:42 +03:00
loc += dp->d_reclen;
1993-12-17 03:41:23 +03:00
} while (!dp->d_fileno || strcmp(path, dp->d_name));
ino = dp->d_fileno;
1993-03-21 21:04:42 +03:00
*(path = rest) = ch;
goto loop;
}
block_map(file_block)
1994-01-11 17:24:11 +03:00
int file_block;
1993-03-21 21:04:42 +03:00
{
if (file_block < NDADDR)
return(inode.i_db[file_block]);
1994-01-11 17:24:11 +03:00
if ((bnum = fsbtodb(fs, inode.i_ib[0]) + boff) != mapblock) {
1993-03-21 21:04:42 +03:00
iodest = mapbuf;
cnt = fs->fs_bsize;
devread();
mapblock = bnum;
}
return (((int *)mapbuf)[(file_block - NDADDR) % NINDIR(fs)]);
}
openrd()
{
char **devp, *cp = name;
/*******************************************************\
* If bracket given look for preceding device name *
\*******************************************************/
while (*cp && *cp!='(')
cp++;
1994-01-11 17:24:11 +03:00
if (!*cp) {
1993-03-21 21:04:42 +03:00
cp = name;
1994-01-11 17:24:11 +03:00
} else {
if (cp != name) {
*cp = '\0';
1993-03-21 21:04:42 +03:00
for (devp = devs; *devp; devp++)
if (!strcmp(name, *devp))
1993-03-21 21:04:42 +03:00
break;
1994-01-11 17:24:11 +03:00
if (!*devp) {
1993-03-21 21:04:42 +03:00
printf("Unknown device\n");
return 1;
}
maj = devp-devs;
}
/*******************************************************\
* Look inside brackets for unit number, and partition *
\*******************************************************/
cp++;
1993-03-21 21:04:42 +03:00
if (*cp >= '0' && *cp <= '9')
1994-01-11 17:24:11 +03:00
if ((unit = *cp++ - '0') > 1) {
1993-03-21 21:04:42 +03:00
printf("Bad unit\n");
return 1;
}
if (!*cp || (*cp == ',' && !*++cp))
return 1;
if (*cp >= 'a' && *cp <= 'p')
part = *cp++ - 'a';
while (*cp && *cp++!=')') ;
if (!*cp)
return 1;
}
if (maj == 1) {
1993-03-21 21:04:42 +03:00
dosdev = unit | 0x80;
unit = 0;
} else if (maj == 0 || maj == 4)
1993-03-21 21:04:42 +03:00
dosdev = unit | 0x80;
else if (maj == 2)
1993-03-21 21:04:42 +03:00
dosdev = unit;
inode.i_dev = dosdev;
/***********************************************\
* Now we know the disk unit and part, *
* Load disk info, (open the device) *
\***********************************************/
if (devopen())
return 1;
/***********************************************\
* Load Filesystem info (mount the device) *
\***********************************************/
iodest = (char *)(fs = (struct fs *)fsbuf);
cnt = SBSIZE;
bnum = SBLOCK + boff;
devread();
1994-07-22 00:25:17 +04:00
/*
* Deal with old file system format. This is borrowed from
* ffs_oldfscompat() in ufs/ffs/ffs_vfsops.c.
*/
if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */
fs->fs_qbmask = ~fs->fs_bmask; /* XXX */
fs->fs_qfmask = ~fs->fs_fmask; /* XXX */
} /* XXX */
1993-03-21 21:04:42 +03:00
/***********************************************\
* Find the actual FILE on the mounted device *
\***********************************************/
if (!find(cp))
1993-03-21 21:04:42 +03:00
return 1;
1993-03-21 21:04:42 +03:00
poff = 0;
name = cp;
return 0;
}