xref: /csrg-svn/sys/hp300/stand/sys.c (revision 44826)
141488Smckusick /*
241488Smckusick  * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
341488Smckusick  * All rights reserved.
441488Smckusick  *
541488Smckusick  * %sccs.include.redist.c%
641488Smckusick  *
7*44826Skarels  *	@(#)sys.c	7.2 (Berkeley) 07/01/90
841488Smckusick  */
941488Smckusick 
1041488Smckusick #include "saio.h"
1141488Smckusick #include "ufs/dir.h"
1241488Smckusick #ifndef SMALL
1341488Smckusick #include "sys/stat.h"
1441488Smckusick #endif
1541488Smckusick 
1641488Smckusick ino_t	dlook();
1741488Smckusick 
1841488Smckusick struct dirstuff {
1941488Smckusick 	int loc;
2041488Smckusick 	struct iob *io;
2141488Smckusick };
2241488Smckusick 
2341488Smckusick static
openi(n,io)2441488Smckusick openi(n, io)
2541488Smckusick 	register struct iob *io;
2641488Smckusick {
2741488Smckusick 	register struct dinode *dp;
2841488Smckusick 	int cc;
2941488Smckusick 
3041488Smckusick 	io->i_offset = 0;
3141488Smckusick 	io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff;
3241488Smckusick 	io->i_cc = io->i_fs.fs_bsize;
3341488Smckusick 	io->i_ma = io->i_buf;
3441488Smckusick 	cc = devread(io);
3541488Smckusick 	dp = (struct dinode *)io->i_buf;
36*44826Skarels 	io->i_ino = dp[itoo(&io->i_fs, n)];
3741488Smckusick 	return (cc);
3841488Smckusick }
3941488Smckusick 
4041488Smckusick static
find(path,file)4141488Smckusick find(path, file)
4241488Smckusick 	register char *path;
4341488Smckusick 	struct iob *file;
4441488Smckusick {
4541488Smckusick 	register char *q;
4641488Smckusick 	char c;
4741488Smckusick 	int n;
4841488Smckusick 
4941488Smckusick 	if (path==NULL || *path=='\0') {
5041488Smckusick 		printf("null path\n");
5141488Smckusick 		return (0);
5241488Smckusick 	}
5341488Smckusick 
5441488Smckusick 	if (openi((ino_t) ROOTINO, file) < 0) {
5541488Smckusick 		printf("can't read root inode\n");
5641488Smckusick 		return (0);
5741488Smckusick 	}
5841488Smckusick 	while (*path) {
5941488Smckusick 		while (*path == '/')
6041488Smckusick 			path++;
6141488Smckusick 		q = path;
6241488Smckusick 		while(*q != '/' && *q != '\0')
6341488Smckusick 			q++;
6441488Smckusick 		c = *q;
6541488Smckusick 		*q = '\0';
6641488Smckusick 		if (q == path) path = "." ;	/* "/" means "/." */
6741488Smckusick 
6841488Smckusick 		if ((n = dlook(path, file)) != 0) {
6941488Smckusick 			if (c == '\0')
7041488Smckusick 				break;
7141488Smckusick 			if (openi(n, file) < 0)
7241488Smckusick 				return (0);
7341488Smckusick 			*q = c;
7441488Smckusick 			path = q;
7541488Smckusick 			continue;
7641488Smckusick 		} else {
7741488Smckusick 			printf("%s: not found\n", path);
7841488Smckusick 			return (0);
7941488Smckusick 		}
8041488Smckusick 	}
8141488Smckusick 	return (n);
8241488Smckusick }
8341488Smckusick 
8441488Smckusick static daddr_t
sbmap(io,bn)8541488Smckusick sbmap(io, bn)
8641488Smckusick 	register struct iob *io;
8741488Smckusick 	daddr_t bn;
8841488Smckusick {
89*44826Skarels 	register struct dinode *ip;
9041488Smckusick 	int i, j, sh;
9141488Smckusick 	daddr_t nb, *bap;
9241488Smckusick 
9341488Smckusick 	ip = &io->i_ino;
9441488Smckusick 	if (bn < 0) {
9541488Smckusick 		printf("bn negative\n");
9641488Smckusick 		return ((daddr_t)0);
9741488Smckusick 	}
9841488Smckusick 
9941488Smckusick 	/*
10041488Smckusick 	 * blocks 0..NDADDR are direct blocks
10141488Smckusick 	 */
10241488Smckusick 	if(bn < NDADDR) {
103*44826Skarels 		nb = ip->di_db[bn];
10441488Smckusick 		return (nb);
10541488Smckusick 	}
10641488Smckusick 
10741488Smckusick 	/*
10841488Smckusick 	 * addresses NIADDR have single and double indirect blocks.
10941488Smckusick 	 * the first step is to determine how many levels of indirection.
11041488Smckusick 	 */
11141488Smckusick 	sh = 1;
11241488Smckusick 	bn -= NDADDR;
11341488Smckusick 	for (j = NIADDR; j > 0; j--) {
11441488Smckusick 		sh *= NINDIR(&io->i_fs);
11541488Smckusick 		if (bn < sh)
11641488Smckusick 			break;
11741488Smckusick 		bn -= sh;
11841488Smckusick 	}
11941488Smckusick 	if (j == 0) {
12041488Smckusick 		printf("bn ovf %D\n", bn);
12141488Smckusick 		return ((daddr_t)0);
12241488Smckusick 	}
12341488Smckusick 
12441488Smckusick 	/*
12541488Smckusick 	 * fetch the first indirect block address from the inode
12641488Smckusick 	 */
127*44826Skarels 	nb = ip->di_ib[NIADDR - j];
12841488Smckusick 	if (nb == 0) {
12941488Smckusick 		printf("bn void %D\n",bn);
13041488Smckusick 		return ((daddr_t)0);
13141488Smckusick 	}
13241488Smckusick 
13341488Smckusick 	/*
13441488Smckusick 	 * fetch through the indirect blocks
13541488Smckusick 	 */
13641488Smckusick 	for (; j <= NIADDR; j++) {
13741488Smckusick 		if (blknos[j] != nb) {
13841488Smckusick 			io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff;
13941488Smckusick 			io->i_ma = b[j];
14041488Smckusick 			io->i_cc = io->i_fs.fs_bsize;
14141488Smckusick 			if (devread(io) != io->i_fs.fs_bsize) {
14241488Smckusick 				if (io->i_error)
14341488Smckusick 					errno = io->i_error;
14441488Smckusick 				printf("bn %D: read error\n", io->i_bn);
14541488Smckusick 				return ((daddr_t)0);
14641488Smckusick 			}
14741488Smckusick 			blknos[j] = nb;
14841488Smckusick 		}
14941488Smckusick 		bap = (daddr_t *)b[j];
15041488Smckusick 		sh /= NINDIR(&io->i_fs);
15141488Smckusick 		i = (bn / sh) % NINDIR(&io->i_fs);
15241488Smckusick 		nb = bap[i];
15341488Smckusick 		if(nb == 0) {
15441488Smckusick 			printf("bn void %D\n",bn);
15541488Smckusick 			return ((daddr_t)0);
15641488Smckusick 		}
15741488Smckusick 	}
15841488Smckusick 	return (nb);
15941488Smckusick }
16041488Smckusick 
16141488Smckusick static ino_t
dlook(s,io)16241488Smckusick dlook(s, io)
16341488Smckusick 	char *s;
16441488Smckusick 	register struct iob *io;
16541488Smckusick {
16641488Smckusick 	register struct direct *dp;
167*44826Skarels 	struct direct *readdir();
168*44826Skarels 	register struct dinode *ip;
16941488Smckusick 	struct dirstuff dirp;
17041488Smckusick 	int len;
17141488Smckusick 
17241488Smckusick 	if (s == NULL || *s == '\0')
17341488Smckusick 		return (0);
17441488Smckusick 	ip = &io->i_ino;
175*44826Skarels 	if ((ip->di_mode&IFMT) != IFDIR) {
17641488Smckusick 		printf("not a directory\n");
17741488Smckusick 		printf("%s: not a directory\n", s);
17841488Smckusick 		return (0);
17941488Smckusick 	}
180*44826Skarels 	if (ip->di_size == 0) {
18141488Smckusick 		printf("%s: zero length directory\n", s);
18241488Smckusick 		return (0);
18341488Smckusick 	}
18441488Smckusick 	len = strlen(s);
18541488Smckusick 	dirp.loc = 0;
18641488Smckusick 	dirp.io = io;
18741488Smckusick 	for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
18841488Smckusick 		if(dp->d_ino == 0)
18941488Smckusick 			continue;
19041488Smckusick 		if (dp->d_namlen == len && !strcmp(s, dp->d_name))
19141488Smckusick 			return (dp->d_ino);
19241488Smckusick 	}
19341488Smckusick 	return (0);
19441488Smckusick }
19541488Smckusick 
19641488Smckusick /*
19741488Smckusick  * get next entry in a directory.
19841488Smckusick  */
19941488Smckusick struct direct *
readdir(dirp)20041488Smckusick readdir(dirp)
20141488Smckusick 	register struct dirstuff *dirp;
20241488Smckusick {
20341488Smckusick 	register struct direct *dp;
20441488Smckusick 	register struct iob *io;
20541488Smckusick 	daddr_t lbn, d;
20641488Smckusick 	int off;
20741488Smckusick 
20841488Smckusick 	io = dirp->io;
20941488Smckusick 	for(;;) {
210*44826Skarels 		if (dirp->loc >= io->i_ino.di_size)
21141488Smckusick 			return (NULL);
21241488Smckusick 		off = blkoff(&io->i_fs, dirp->loc);
21341488Smckusick 		if (off == 0) {
21441488Smckusick 			lbn = lblkno(&io->i_fs, dirp->loc);
21541488Smckusick 			d = sbmap(io, lbn);
21641488Smckusick 			if(d == 0)
21741488Smckusick 				return NULL;
21841488Smckusick 			io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff;
21941488Smckusick 			io->i_ma = io->i_buf;
220*44826Skarels 			io->i_cc = dblksize(&io->i_fs, &io->i_ino, lbn);
22141488Smckusick 			if (devread(io) < 0) {
22241488Smckusick 				errno = io->i_error;
22341488Smckusick 				printf("bn %D: directory read error\n",
22441488Smckusick 					io->i_bn);
22541488Smckusick 				return (NULL);
22641488Smckusick 			}
22741488Smckusick 		}
22841488Smckusick 		dp = (struct direct *)(io->i_buf + off);
22941488Smckusick 		dirp->loc += dp->d_reclen;
23041488Smckusick 		if (dp->d_ino == 0)
23141488Smckusick 			continue;
23241488Smckusick 		return (dp);
23341488Smckusick 	}
23441488Smckusick }
23541488Smckusick 
lseek(fdesc,addr,ptr)23641488Smckusick lseek(fdesc, addr, ptr)
23741488Smckusick 	int fdesc, ptr;
23841488Smckusick 	off_t addr;
23941488Smckusick {
24041488Smckusick 	register struct iob *io;
24141488Smckusick 
24241488Smckusick #ifndef	SMALL
24341488Smckusick 	if (ptr != 0) {
24441488Smckusick 		printf("Seek not from beginning of file\n");
24541488Smckusick 		errno = EOFFSET;
24641488Smckusick 		return (-1);
24741488Smckusick 	}
24841488Smckusick #endif SMALL
24941488Smckusick 	fdesc -= 3;
25041488Smckusick 	if (fdesc < 0 || fdesc >= NFILES ||
25141488Smckusick 	    ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) {
25241488Smckusick 		errno = EBADF;
25341488Smckusick 		return (-1);
25441488Smckusick 	}
25541488Smckusick 	io->i_offset = addr;
25641488Smckusick 	io->i_bn = addr / DEV_BSIZE;
25741488Smckusick 	io->i_cc = 0;
25841488Smckusick 	return (0);
25941488Smckusick }
26041488Smckusick 
getc(fdesc)26141488Smckusick getc(fdesc)
26241488Smckusick 	int fdesc;
26341488Smckusick {
26441488Smckusick 	register struct iob *io;
26541488Smckusick 	register struct fs *fs;
26641488Smckusick 	register char *p;
26741488Smckusick 	int c, lbn, off, size, diff;
26841488Smckusick 
26941488Smckusick 
27041488Smckusick 	if (fdesc >= 0 && fdesc <= 2)
27141488Smckusick 		return (getchar());
27241488Smckusick 	fdesc -= 3;
27341488Smckusick 	if (fdesc < 0 || fdesc >= NFILES ||
27441488Smckusick 	    ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
27541488Smckusick 		errno = EBADF;
27641488Smckusick 		return (-1);
27741488Smckusick 	}
27841488Smckusick 	p = io->i_ma;
27941488Smckusick 	if (io->i_cc <= 0) {
28041488Smckusick 		if ((io->i_flgs & F_FILE) != 0) {
281*44826Skarels 			diff = io->i_ino.di_size - io->i_offset;
28241488Smckusick 			if (diff <= 0)
28341488Smckusick 				return (-1);
28441488Smckusick 			fs = &io->i_fs;
28541488Smckusick 			lbn = lblkno(fs, io->i_offset);
28641488Smckusick 			io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff;
28741488Smckusick 			off = blkoff(fs, io->i_offset);
288*44826Skarels 			size = dblksize(fs, &io->i_ino, lbn);
28941488Smckusick 		} else {
29041488Smckusick 			io->i_bn = io->i_offset / DEV_BSIZE;
29141488Smckusick 			off = 0;
29241488Smckusick 			size = DEV_BSIZE;
29341488Smckusick 		}
29441488Smckusick 		io->i_ma = io->i_buf;
29541488Smckusick 		io->i_cc = size;
29641488Smckusick 		if (devread(io) < 0) {
29741488Smckusick 			errno = io->i_error;
29841488Smckusick 			return (-1);
29941488Smckusick 		}
30041488Smckusick 		if ((io->i_flgs & F_FILE) != 0) {
301*44826Skarels 			if (io->i_offset - off + size >= io->i_ino.di_size)
30241488Smckusick 				io->i_cc = diff + off;
30341488Smckusick 			io->i_cc -= off;
30441488Smckusick 		}
30541488Smckusick 		p = &io->i_buf[off];
30641488Smckusick 	}
30741488Smckusick 	io->i_cc--;
30841488Smckusick 	io->i_offset++;
30941488Smckusick 	c = (unsigned)*p++;
31041488Smckusick 	io->i_ma = p;
31141488Smckusick 	return (c);
31241488Smckusick }
31341488Smckusick 
31441488Smckusick int	errno;
31541488Smckusick 
read(fdesc,buf,count)31641488Smckusick read(fdesc, buf, count)
31741488Smckusick 	int fdesc, count;
31841488Smckusick 	char *buf;
31941488Smckusick {
32041488Smckusick 	register i, size;
32141488Smckusick 	register struct iob *file;
32241488Smckusick 	register struct fs *fs;
32341488Smckusick 	int lbn, off;
32441488Smckusick 
32541488Smckusick 	errno = 0;
32641488Smckusick 	if (fdesc >= 0 & fdesc <= 2) {
32741488Smckusick 		i = count;
32841488Smckusick 		do {
32941488Smckusick 			*buf = getchar();
33041488Smckusick 		} while (--i && *buf++ != '\n');
33141488Smckusick 		return (count - i);
33241488Smckusick 	}
33341488Smckusick 	fdesc -= 3;
33441488Smckusick 	if (fdesc < 0 || fdesc >= NFILES ||
33541488Smckusick 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
33641488Smckusick 		errno = EBADF;
33741488Smckusick 		return (-1);
33841488Smckusick 	}
33941488Smckusick 	if ((file->i_flgs&F_READ) == 0) {
34041488Smckusick 		errno = EBADF;
34141488Smckusick 		return (-1);
34241488Smckusick 	}
34341488Smckusick #ifndef	SMALL
34441488Smckusick 	if ((file->i_flgs & F_FILE) == 0) {
34541488Smckusick 		file->i_cc = count;
34641488Smckusick 		file->i_ma = buf;
34741488Smckusick 		file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
34841488Smckusick 		i = devread(file);
34941488Smckusick 		file->i_offset += count;
35041488Smckusick 		if (i < 0)
35141488Smckusick 			errno = file->i_error;
35241488Smckusick 		return (i);
35341488Smckusick 	}
35441488Smckusick #endif SMALL
355*44826Skarels 	if (file->i_offset+count > file->i_ino.di_size)
356*44826Skarels 		count = file->i_ino.di_size - file->i_offset;
35741488Smckusick 	if ((i = count) <= 0)
35841488Smckusick 		return (0);
35941488Smckusick 	/*
36041488Smckusick 	 * While reading full blocks, do I/O into user buffer.
36141488Smckusick 	 * Anything else uses getc().
36241488Smckusick 	 */
36341488Smckusick 	fs = &file->i_fs;
36441488Smckusick 	while (i) {
36541488Smckusick 		off = blkoff(fs, file->i_offset);
36641488Smckusick 		lbn = lblkno(fs, file->i_offset);
367*44826Skarels 		size = dblksize(fs, &file->i_ino, lbn);
36841488Smckusick 		if (off == 0 && size <= i) {
36941488Smckusick 			file->i_bn = fsbtodb(fs, sbmap(file, lbn)) +
37041488Smckusick 			    file->i_boff;
37141488Smckusick 			file->i_cc = size;
37241488Smckusick 			file->i_ma = buf;
37341488Smckusick 			if (devread(file) < 0) {
37441488Smckusick 				errno = file->i_error;
37541488Smckusick 				return (-1);
37641488Smckusick 			}
37741488Smckusick 			file->i_offset += size;
37841488Smckusick 			file->i_cc = 0;
37941488Smckusick 			buf += size;
38041488Smckusick 			i -= size;
38141488Smckusick 		} else {
38241488Smckusick 			size -= off;
38341488Smckusick 			if (size > i)
38441488Smckusick 				size = i;
38541488Smckusick 			i -= size;
38641488Smckusick 			do {
38741488Smckusick 				*buf++ = getc(fdesc+3);
38841488Smckusick 			} while (--size);
38941488Smckusick 		}
39041488Smckusick 	}
39141488Smckusick 	return (count);
39241488Smckusick }
39341488Smckusick 
39441488Smckusick #ifndef	SMALL
write(fdesc,buf,count)39541488Smckusick write(fdesc, buf, count)
39641488Smckusick 	int fdesc, count;
39741488Smckusick 	char *buf;
39841488Smckusick {
39941488Smckusick 	register i;
40041488Smckusick 	register struct iob *file;
40141488Smckusick 
40241488Smckusick 	errno = 0;
40341488Smckusick 	if (fdesc >= 0 && fdesc <= 2) {
40441488Smckusick 		i = count;
40541488Smckusick 		while (i--)
40641488Smckusick 			putchar(0, *buf++);
40741488Smckusick 		return (count);
40841488Smckusick 	}
40941488Smckusick 	fdesc -= 3;
41041488Smckusick 	if (fdesc < 0 || fdesc >= NFILES ||
41141488Smckusick 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
41241488Smckusick 		errno = EBADF;
41341488Smckusick 		return (-1);
41441488Smckusick 	}
41541488Smckusick 	if ((file->i_flgs&F_WRITE) == 0) {
41641488Smckusick 		errno = EBADF;
41741488Smckusick 		return (-1);
41841488Smckusick 	}
41941488Smckusick 	file->i_cc = count;
42041488Smckusick 	file->i_ma = buf;
42141488Smckusick 	file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
42241488Smckusick 	i = devwrite(file);
42341488Smckusick 	file->i_offset += count;
42441488Smckusick 	if (i < 0)
42541488Smckusick 		errno = file->i_error;
42641488Smckusick 	return (i);
42741488Smckusick }
42841488Smckusick #endif SMALL
42941488Smckusick 
43041488Smckusick int	openfirst = 1;
43141488Smckusick #ifdef notyet
43241488Smckusick int	opendev;	/* last device opened; for boot to set bootdev */
43341488Smckusick extern	int bootdev;
43441488Smckusick #endif notyet
43541488Smckusick 
open(str,how)43641488Smckusick open(str, how)
43741488Smckusick 	char *str;
43841488Smckusick 	int how;
43941488Smckusick {
44041488Smckusick 	register char *cp;
44141488Smckusick 	int i;
44241488Smckusick 	register struct iob *file;
44341488Smckusick 	register struct devsw *dp;
44441488Smckusick 	int fdesc;
44541488Smckusick 	long atol();
44641488Smckusick 
44741488Smckusick 	if (openfirst) {
44841488Smckusick 		for (i = 0; i < NFILES; i++)
44941488Smckusick 			iob[i].i_flgs = 0;
45041488Smckusick 		openfirst = 0;
45141488Smckusick 	}
45241488Smckusick 
45341488Smckusick 	for (fdesc = 0; fdesc < NFILES; fdesc++)
45441488Smckusick 		if (iob[fdesc].i_flgs == 0)
45541488Smckusick 			goto gotfile;
45641488Smckusick 	_stop("No more file slots");
45741488Smckusick gotfile:
45841488Smckusick 	(file = &iob[fdesc])->i_flgs |= F_ALLOC;
45941488Smckusick 
46041488Smckusick #ifdef notyet
46141488Smckusick 	for (cp = str; *cp && *cp != '/' && *cp != ':'; cp++)
46241488Smckusick 			;
46341488Smckusick 	if (*cp != ':') {
46441488Smckusick 		/* default bootstrap unit and device */
465*44826Skarels 		file->i_dev = bootdev;
46641488Smckusick 		cp = str;
46741488Smckusick 	} else {
46841488Smckusick # define isdigit(n)	((n>='0') && (n<='9'))
46941488Smckusick 		/*
47041488Smckusick 	 	 * syntax for possible device name:
47141488Smckusick 	 	 *	<alpha-string><digit-string><letter>:
47241488Smckusick 	 	 */
47341488Smckusick 		for (cp = str; *cp != ':' && !isdigit(*cp); cp++)
47441488Smckusick 			;
47541488Smckusick 		for (dp = devsw; dp->dv_name; dp++) {
47641488Smckusick 			if (!strncmp(str, dp->dv_name,cp-str))
47741488Smckusick 				goto gotdev;
47841488Smckusick 		}
47941488Smckusick 		printf("unknown device\n");
48041488Smckusick 		file->i_flgs = 0;
48141488Smckusick 		errno = EDEV;
48241488Smckusick 		return (-1);
48341488Smckusick 	gotdev:
48441488Smckusick 		i = 0;
48541488Smckusick 		while (*cp >= '0' && *cp <= '9')
48641488Smckusick 			i = i * 10 + *cp++ - '0';
48741488Smckusick 		if (i < 0 || i > 255) {
48841488Smckusick 			printf("minor device number out of range (0-255)\n");
48941488Smckusick 			file->i_flgs = 0;
49041488Smckusick 			errno = EUNIT;
49141488Smckusick 			return (-1);
49241488Smckusick 		}
49341488Smckusick 		if (*cp >= 'a' && *cp <= 'h') {
49441488Smckusick 			if (i > 31) {
49541488Smckusick 				printf("unit number out of range (0-31)\n");
49641488Smckusick 				file->i_flgs = 0;
49741488Smckusick 				errno = EUNIT;
49841488Smckusick 				return (-1);
49941488Smckusick 			}
50041488Smckusick 			i = make_minor(i, *cp++ - 'a');
50141488Smckusick 		}
50241488Smckusick 
50341488Smckusick 		if (*cp++ != ':') {
50441488Smckusick 			printf("incorrect device specification\n");
50541488Smckusick 			file->i_flgs = 0;
50641488Smckusick 			errno = EOFFSET;
50741488Smckusick 			return (-1);
50841488Smckusick 		}
509*44826Skarels 		opendev = file->i_dev = makedev(dp-devsw, i);
51041488Smckusick 	}
51141488Smckusick 	file->i_boff = 0;
51241488Smckusick 	devopen(file);
51341488Smckusick 	if (cp != str && *cp == '\0') {
51441488Smckusick 		file->i_flgs |= how+1;
51541488Smckusick 		file->i_cc = 0;
51641488Smckusick 		file->i_offset = 0;
51741488Smckusick 		return (fdesc+3);
51841488Smckusick 	}
51941488Smckusick #else notyet
52041488Smckusick 	for (cp = str; *cp && *cp != '('; cp++)
52141488Smckusick 			;
52241488Smckusick 	if (*cp != '(') {
52341488Smckusick 		printf("Bad device\n");
52441488Smckusick 		file->i_flgs = 0;
52541488Smckusick 		errno = EDEV;
52641488Smckusick 		return (-1);
52741488Smckusick 	}
52841488Smckusick 	*cp = '\0';
52941488Smckusick 	for (dp = devsw; dp->dv_name; dp++)
53041488Smckusick 		if (!strcmp(str, dp->dv_name))
53141488Smckusick 			break;
53241488Smckusick 	*cp++ = '(';
53341488Smckusick 	if (dp->dv_name == NULL) {
53441488Smckusick 		printf("Unknown device\n");
53541488Smckusick 		file->i_flgs = 0;
53641488Smckusick 		errno = ENXIO;
53741488Smckusick 		return (-1);
53841488Smckusick 	}
539*44826Skarels 	file->i_dev = dp-devsw;
54041488Smckusick 	file->i_unit = *cp++ - '0';
54141488Smckusick 	if (*cp >= '0' && *cp <= '9')
54241488Smckusick 		file->i_unit = file->i_unit * 10 + *cp++ - '0';
54341488Smckusick 	if (file->i_unit < 0 || file->i_unit > 63) {
54441488Smckusick 		printf("Bad unit specifier\n");
54541488Smckusick 		file->i_flgs = 0;
54641488Smckusick 		errno = EUNIT;
54741488Smckusick 		return (-1);
54841488Smckusick 	}
54941488Smckusick 	if (*cp++ != ',') {
55041488Smckusick badoff:
55141488Smckusick 		printf("Missing offset specification\n");
55241488Smckusick 		file->i_flgs = 0;
55341488Smckusick 		errno = EOFFSET;
55441488Smckusick 		return (-1);
55541488Smckusick 	}
55641488Smckusick 	file->i_boff = atol(cp);
55741488Smckusick 	for (;;) {
55841488Smckusick 		if (*cp == ')')
55941488Smckusick 			break;
56041488Smckusick 		if (*cp++)
56141488Smckusick 			continue;
56241488Smckusick 		goto badoff;
56341488Smckusick 	}
56441488Smckusick 	devopen(file);
56541488Smckusick 	if (*++cp == '\0') {
56641488Smckusick 		file->i_flgs |= how+1;
56741488Smckusick 		file->i_cc = 0;
56841488Smckusick 		file->i_offset = 0;
56941488Smckusick 		return (fdesc+3);
57041488Smckusick 	}
57141488Smckusick #endif notyet
57241488Smckusick 	file->i_ma = (char *)(&file->i_fs);
57341488Smckusick 	file->i_cc = SBSIZE;
57441488Smckusick 	file->i_bn = SBLOCK + file->i_boff;
57541488Smckusick 	file->i_offset = 0;
57641488Smckusick 	if (devread(file) < 0) {
57741488Smckusick 		errno = file->i_error;
57841488Smckusick 		printf("super block read error\n");
57941488Smckusick 		return (-1);
58041488Smckusick 	}
58141488Smckusick 	if ((i = find(cp, file)) == 0) {
58241488Smckusick 		file->i_flgs = 0;
58341488Smckusick 		errno = ESRCH;
58441488Smckusick 		return (-1);
58541488Smckusick 	}
58641488Smckusick #ifndef	SMALL
58741488Smckusick 	if (how != 0) {
58841488Smckusick 		printf("Can't write files yet.. Sorry\n");
58941488Smckusick 		file->i_flgs = 0;
59041488Smckusick 		errno = EIO;
59141488Smckusick 		return (-1);
59241488Smckusick 	}
59341488Smckusick #endif SMALL
59441488Smckusick 	if (openi(i, file) < 0) {
59541488Smckusick 		errno = file->i_error;
59641488Smckusick 		return (-1);
59741488Smckusick 	}
59841488Smckusick 	file->i_offset = 0;
59941488Smckusick 	file->i_cc = 0;
60041488Smckusick 	file->i_flgs |= F_FILE | (how+1);
60141488Smckusick 	return (fdesc+3);
60241488Smckusick }
60341488Smckusick 
close(fdesc)60441488Smckusick close(fdesc)
60541488Smckusick 	int fdesc;
60641488Smckusick {
60741488Smckusick 	struct iob *file;
60841488Smckusick 
60941488Smckusick 	fdesc -= 3;
61041488Smckusick 	if (fdesc < 0 || fdesc >= NFILES ||
61141488Smckusick 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
61241488Smckusick 		errno = EBADF;
61341488Smckusick 		return (-1);
61441488Smckusick 	}
61541488Smckusick 	if ((file->i_flgs&F_FILE) == 0)
61641488Smckusick 		devclose(file);
61741488Smckusick 	file->i_flgs = 0;
61841488Smckusick 	return (0);
61941488Smckusick }
62041488Smckusick 
exit()62141488Smckusick exit()
62241488Smckusick {
62341488Smckusick 	_stop("Exit called");
62441488Smckusick }
62541488Smckusick 
_stop(s)62641488Smckusick _stop(s)
62741488Smckusick 	char *s;
62841488Smckusick {
62941488Smckusick 	static int stopped = 0;
63041488Smckusick 	int i;
63141488Smckusick 
63241488Smckusick 	if (!stopped) {
63341488Smckusick 		stopped++;
63441488Smckusick 		for (i = 0; i < NFILES; i++)
63541488Smckusick 			if (iob[i].i_flgs != 0)
63641488Smckusick 				close(i);
63741488Smckusick 	}
63841488Smckusick 	printf("%s\n", s);
63941488Smckusick 	_rtt();
64041488Smckusick }
64141488Smckusick 
64241488Smckusick #ifndef	SMALL
ioctl(fdesc,cmd,arg)64341488Smckusick ioctl(fdesc, cmd, arg)
64441488Smckusick 	int fdesc, cmd;
64541488Smckusick 	char *arg;
64641488Smckusick {
64741488Smckusick 	register struct iob *file;
64841488Smckusick 	int error = 0;
64941488Smckusick 
65041488Smckusick 	fdesc -= 3;
65141488Smckusick 	if (fdesc < 0 || fdesc >= NFILES ||
65241488Smckusick 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
65341488Smckusick 		errno = EBADF;
65441488Smckusick 		return (-1);
65541488Smckusick 	}
65641488Smckusick 	switch (cmd) {
65741488Smckusick 
65841488Smckusick 	case SAIOHDR:
65941488Smckusick 		file->i_flgs |= F_HDR;
66041488Smckusick 		break;
66141488Smckusick 
66241488Smckusick 	case SAIOCHECK:
66341488Smckusick 		file->i_flgs |= F_CHECK;
66441488Smckusick 		break;
66541488Smckusick 
66641488Smckusick 	case SAIOHCHECK:
66741488Smckusick 		file->i_flgs |= F_HCHECK;
66841488Smckusick 		break;
66941488Smckusick 
67041488Smckusick 	case SAIONOBAD:
67141488Smckusick 		file->i_flgs |= F_NBSF;
67241488Smckusick 		break;
67341488Smckusick 
67441488Smckusick 	case SAIODOBAD:
67541488Smckusick 		file->i_flgs &= ~F_NBSF;
67641488Smckusick 		break;
67741488Smckusick 
67841488Smckusick 	default:
67941488Smckusick 		error = devioctl(file, cmd, arg);
68041488Smckusick 		break;
68141488Smckusick 	}
68241488Smckusick 	if (error < 0)
68341488Smckusick 		errno = file->i_error;
68441488Smckusick 	return (error);
68541488Smckusick }
68641488Smckusick 
68741488Smckusick extern char end;
68841488Smckusick static caddr_t theend = 0;
68941488Smckusick 
69041488Smckusick caddr_t
brk(addr)69141488Smckusick brk(addr)
69241488Smckusick  char *addr;
69341488Smckusick {
69441488Smckusick 	char stkloc;
69541488Smckusick 
69641488Smckusick 	if (theend == (caddr_t)0)
69741488Smckusick 		theend = &end;
69841488Smckusick 	if (addr > &stkloc || addr < &end)
69941488Smckusick 		return((caddr_t)-1);
70041488Smckusick 	if (addr > theend)
70141488Smckusick 		bzero(theend, addr-theend);
70241488Smckusick 	theend = addr;
70341488Smckusick 	return(0);
70441488Smckusick }
70541488Smckusick 
70641488Smckusick caddr_t
sbrk(incr)70741488Smckusick sbrk(incr)
70841488Smckusick  int incr;
70941488Smckusick {
71041488Smckusick 	caddr_t obrk, brk();
71141488Smckusick 
71241488Smckusick 	if (theend == (caddr_t)0)
71341488Smckusick 		theend = &end;
71441488Smckusick 	obrk = theend;
71541488Smckusick 	if (brk(theend+incr) == (caddr_t)-1)
71641488Smckusick 		return((caddr_t)-1);
71741488Smckusick 	return(obrk);
71841488Smckusick }
71941488Smckusick 
getpagesize()72041488Smckusick getpagesize()
72141488Smckusick {
72241488Smckusick 	return(NBPG);
72341488Smckusick }
72441488Smckusick 
getdtablesize()72541488Smckusick getdtablesize()
72641488Smckusick {
72741488Smckusick 	return(NFILES);
72841488Smckusick }
72941488Smckusick 
73041488Smckusick fstat(fdesc, sb)
73141488Smckusick 	struct stat *sb;
73241488Smckusick {
73341488Smckusick 	register struct iob *io;
73441488Smckusick 
73541488Smckusick 	fdesc -= 3;
73641488Smckusick 	if (fdesc < 0 || fdesc >= NFILES ||
73741488Smckusick 	    ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) {
73841488Smckusick 		errno = EBADF;
73941488Smckusick 		return (-1);
74041488Smckusick 	}
74141488Smckusick 	/* only important stuff */
742*44826Skarels 	sb->st_mode = io->i_ino.di_mode;
743*44826Skarels 	sb->st_uid = io->i_ino.di_uid;
744*44826Skarels 	sb->st_gid = io->i_ino.di_gid;
745*44826Skarels 	sb->st_size = io->i_ino.di_size;
74641488Smckusick 	return (0);
74741488Smckusick }
74841488Smckusick 
stat(str,sb)74941488Smckusick stat(str, sb)
75041488Smckusick {
75141488Smckusick 	/* the easy way */
75241488Smckusick 	int f, rv = 0;
75341488Smckusick 
75441488Smckusick 	f = open(str, 0);
75541488Smckusick 	if (f < 0 || fstat(f, sb) < 0)
75641488Smckusick 		rv = -1;
75741488Smckusick 	(void) close(f);
75841488Smckusick 	return(rv);
75941488Smckusick }
76041488Smckusick 
76141488Smckusick #endif SMALL
762