xref: /csrg-svn/sys/tahoe/stand/sys.c (revision 30308)
1*30308Skarels /*
2*30308Skarels  * Copyright (c) 1982, 1986 Regents of the University of California.
3*30308Skarels  * All rights reserved.  The Berkeley software License Agreement
4*30308Skarels  * specifies the terms and conditions for redistribution.
5*30308Skarels  *
6*30308Skarels  *	sys.c	1.2	86/12/18
7*30308Skarels  *
8*30308Skarels  * from	@(#)sys.c	7.1 (Berkeley) 6/5/86
9*30308Skarels  */
1025871Ssam 
1125871Ssam #include "../machine/mtpr.h"
1225871Ssam 
1325871Ssam #include "param.h"
1425871Ssam #include "inode.h"
1525871Ssam #include "fs.h"
1625871Ssam #include "dir.h"
1725871Ssam #include "saio.h"
1825871Ssam 
1925871Ssam ino_t	dlook();
2025871Ssam 
2125871Ssam struct dirstuff {
2225871Ssam 	int loc;
2325871Ssam 	struct iob *io;
2425871Ssam };
2525871Ssam 
2625871Ssam static
2725871Ssam openi(n, io)
2825871Ssam 	register struct iob *io;
2925871Ssam {
3025871Ssam 	register struct dinode *dp;
3125871Ssam 	int cc;
3225871Ssam 
3325871Ssam 	io->i_offset = 0;
3425871Ssam 	io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff;
3525871Ssam 	io->i_cc = io->i_fs.fs_bsize;
3625871Ssam 	io->i_ma = io->i_buf;
3725871Ssam 	cc = devread(io);
3825871Ssam 	dp = (struct dinode *)io->i_buf;
3925871Ssam 	io->i_ino.i_ic = dp[itoo(&io->i_fs, n)].di_ic;
4025871Ssam 	return (cc);
4125871Ssam }
4225871Ssam 
4325871Ssam static
4425871Ssam find(path, file)
4525871Ssam 	register char *path;
4625871Ssam 	struct iob *file;
4725871Ssam {
4825871Ssam 	register char *q;
4925871Ssam 	char c;
5025871Ssam 	int n;
5125871Ssam 
5225871Ssam 	if (path==NULL || *path=='\0') {
5325871Ssam 		printf("null path\n");
5425871Ssam 		return (0);
5525871Ssam 	}
5625871Ssam 
5725871Ssam 	if (openi((ino_t) ROOTINO, file) < 0) {
5825871Ssam 		printf("can't read root inode\n");
5925871Ssam 		return (0);
6025871Ssam 	}
6125871Ssam 	while (*path) {
6225871Ssam 		while (*path == '/')
6325871Ssam 			path++;
6425871Ssam 		q = path;
6525871Ssam 		while(*q != '/' && *q != '\0')
6625871Ssam 			q++;
6725871Ssam 		c = *q;
6825871Ssam 		*q = '\0';
69*30308Skarels 		if (q == path) path = "." ;	/* "/" means "/." */
7025871Ssam 
7125871Ssam 		if ((n = dlook(path, file)) != 0) {
7225871Ssam 			if (c == '\0')
7325871Ssam 				break;
7425871Ssam 			if (openi(n, file) < 0)
7525871Ssam 				return (0);
7625871Ssam 			*q = c;
7725871Ssam 			path = q;
7825871Ssam 			continue;
7925871Ssam 		} else {
80*30308Skarels 			printf("%s: not found\n", path);
8125871Ssam 			return (0);
8225871Ssam 		}
8325871Ssam 	}
8425871Ssam 	return (n);
8525871Ssam }
8625871Ssam 
8725871Ssam static daddr_t
8825871Ssam sbmap(io, bn)
8925871Ssam 	register struct iob *io;
9025871Ssam 	daddr_t bn;
9125871Ssam {
9225871Ssam 	register struct inode *ip;
9325871Ssam 	int i, j, sh;
9425871Ssam 	daddr_t nb, *bap;
9525871Ssam 
9625871Ssam 	ip = &io->i_ino;
9725871Ssam 	if (bn < 0) {
9825871Ssam 		printf("bn negative\n");
9925871Ssam 		return ((daddr_t)0);
10025871Ssam 	}
10125871Ssam 
10225871Ssam 	/*
10325871Ssam 	 * blocks 0..NDADDR are direct blocks
10425871Ssam 	 */
10525871Ssam 	if(bn < NDADDR) {
10625871Ssam 		nb = ip->i_db[bn];
10725871Ssam 		return (nb);
10825871Ssam 	}
10925871Ssam 
11025871Ssam 	/*
11125871Ssam 	 * addresses NIADDR have single and double indirect blocks.
11225871Ssam 	 * the first step is to determine how many levels of indirection.
11325871Ssam 	 */
11425871Ssam 	sh = 1;
11525871Ssam 	bn -= NDADDR;
11625871Ssam 	for (j = NIADDR; j > 0; j--) {
11725871Ssam 		sh *= NINDIR(&io->i_fs);
11825871Ssam 		if (bn < sh)
11925871Ssam 			break;
12025871Ssam 		bn -= sh;
12125871Ssam 	}
12225871Ssam 	if (j == 0) {
12325871Ssam 		printf("bn ovf %D\n", bn);
12425871Ssam 		return ((daddr_t)0);
12525871Ssam 	}
12625871Ssam 
12725871Ssam 	/*
12825871Ssam 	 * fetch the first indirect block address from the inode
12925871Ssam 	 */
13025871Ssam 	nb = ip->i_ib[NIADDR - j];
13125871Ssam 	if (nb == 0) {
13225871Ssam 		printf("bn void %D\n",bn);
13325871Ssam 		return ((daddr_t)0);
13425871Ssam 	}
13525871Ssam 
13625871Ssam 	/*
13725871Ssam 	 * fetch through the indirect blocks
13825871Ssam 	 */
13925871Ssam 	for (; j <= NIADDR; j++) {
14025871Ssam 		if (blknos[j] != nb) {
14125871Ssam 			io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff;
14225871Ssam 			io->i_ma = b[j];
14325871Ssam 			io->i_cc = io->i_fs.fs_bsize;
14425871Ssam 			if (devread(io) != io->i_fs.fs_bsize) {
14525871Ssam 				if (io->i_error)
14625871Ssam 					errno = io->i_error;
14725871Ssam 				printf("bn %D: read error\n", io->i_bn);
14825871Ssam 				return ((daddr_t)0);
14925871Ssam 			}
15025871Ssam 			blknos[j] = nb;
15125871Ssam 		}
15225871Ssam 		bap = (daddr_t *)b[j];
15325871Ssam 		sh /= NINDIR(&io->i_fs);
15425871Ssam 		i = (bn / sh) % NINDIR(&io->i_fs);
15525871Ssam 		nb = bap[i];
15625871Ssam 		if(nb == 0) {
15725871Ssam 			printf("bn void %D\n",bn);
15825871Ssam 			return ((daddr_t)0);
15925871Ssam 		}
16025871Ssam 	}
16125871Ssam 	return (nb);
16225871Ssam }
16325871Ssam 
16425871Ssam static ino_t
16525871Ssam dlook(s, io)
16625871Ssam 	char *s;
16725871Ssam 	register struct iob *io;
16825871Ssam {
16925871Ssam 	register struct direct *dp;
17025871Ssam 	register struct inode *ip;
17125871Ssam 	struct dirstuff dirp;
17225871Ssam 	int len;
17325871Ssam 
17425871Ssam 	if (s == NULL || *s == '\0')
17525871Ssam 		return (0);
17625871Ssam 	ip = &io->i_ino;
17725871Ssam 	if ((ip->i_mode&IFMT) != IFDIR) {
17825871Ssam 		printf("not a directory\n");
179*30308Skarels 		printf("%s: not a directory\n", s);
18025871Ssam 		return (0);
18125871Ssam 	}
18225871Ssam 	if (ip->i_size == 0) {
183*30308Skarels 		printf("%s: zero length directory\n", s);
18425871Ssam 		return (0);
18525871Ssam 	}
18625871Ssam 	len = strlen(s);
18725871Ssam 	dirp.loc = 0;
18825871Ssam 	dirp.io = io;
18925871Ssam 	for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
19025871Ssam 		if(dp->d_ino == 0)
19125871Ssam 			continue;
19225871Ssam 		if (dp->d_namlen == len && !strcmp(s, dp->d_name))
19325871Ssam 			return (dp->d_ino);
19425871Ssam 	}
19525871Ssam 	return (0);
19625871Ssam }
19725871Ssam 
19825871Ssam /*
19925871Ssam  * get next entry in a directory.
20025871Ssam  */
20125871Ssam struct direct *
20225871Ssam readdir(dirp)
20325871Ssam 	register struct dirstuff *dirp;
20425871Ssam {
20525871Ssam 	register struct direct *dp;
20625871Ssam 	register struct iob *io;
20725871Ssam 	daddr_t lbn, d;
20825871Ssam 	int off;
20925871Ssam 
21025871Ssam 	io = dirp->io;
21125871Ssam 	for(;;) {
21225871Ssam 		if (dirp->loc >= io->i_ino.i_size)
21325871Ssam 			return (NULL);
21425871Ssam 		off = blkoff(&io->i_fs, dirp->loc);
21525871Ssam 		if (off == 0) {
21625871Ssam 			lbn = lblkno(&io->i_fs, dirp->loc);
21725871Ssam 			d = sbmap(io, lbn);
21825871Ssam 			if(d == 0)
21925871Ssam 				return NULL;
22025871Ssam 			io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff;
22125871Ssam 			io->i_ma = io->i_buf;
22225871Ssam 			io->i_cc = blksize(&io->i_fs, &io->i_ino, lbn);
22325871Ssam 			if (devread(io) < 0) {
22425871Ssam 				errno = io->i_error;
225*30308Skarels 				printf("bn %D: directory read error\n",
226*30308Skarels 					io->i_bn);
22725871Ssam 				return (NULL);
22825871Ssam 			}
22925871Ssam 		}
23025871Ssam 		dp = (struct direct *)(io->i_buf + off);
23125871Ssam 		dirp->loc += dp->d_reclen;
23225871Ssam 		if (dp->d_ino == 0)
23325871Ssam 			continue;
23425871Ssam 		return (dp);
23525871Ssam 	}
23625871Ssam }
23725871Ssam 
23825871Ssam lseek(fdesc, addr, ptr)
23925871Ssam 	int fdesc, ptr;
24025871Ssam 	off_t addr;
24125871Ssam {
24225871Ssam 	register struct iob *io;
24325871Ssam 
244*30308Skarels #ifndef	SMALL
24525871Ssam 	if (ptr != 0) {
24625871Ssam 		printf("Seek not from beginning of file\n");
24725871Ssam 		errno = EOFFSET;
24825871Ssam 		return (-1);
24925871Ssam 	}
250*30308Skarels #endif SMALL
25125871Ssam 	fdesc -= 3;
25225871Ssam 	if (fdesc < 0 || fdesc >= NFILES ||
25325871Ssam 	    ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) {
25425871Ssam 		errno = EBADF;
25525871Ssam 		return (-1);
25625871Ssam 	}
25725871Ssam 	io->i_offset = addr;
25825871Ssam 	io->i_bn = addr / DEV_BSIZE;
25925871Ssam 	io->i_cc = 0;
26025871Ssam 	return (0);
26125871Ssam }
26225871Ssam 
26325871Ssam getc(fdesc)
26425871Ssam 	int fdesc;
26525871Ssam {
26625871Ssam 	register struct iob *io;
26725871Ssam 	register struct fs *fs;
26825871Ssam 	register char *p;
26925871Ssam 	int c, lbn, off, size, diff;
27025871Ssam 
27125871Ssam 
27225871Ssam 	if (fdesc >= 0 && fdesc <= 2)
27325871Ssam 		return (getchar());
27425871Ssam 	fdesc -= 3;
27525871Ssam 	if (fdesc < 0 || fdesc >= NFILES ||
27625871Ssam 	    ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
27725871Ssam 		errno = EBADF;
27825871Ssam 		return (-1);
27925871Ssam 	}
28025871Ssam 	p = io->i_ma;
28125871Ssam 	if (io->i_cc <= 0) {
28225871Ssam 		if ((io->i_flgs & F_FILE) != 0) {
28325871Ssam 			diff = io->i_ino.i_size - io->i_offset;
28425871Ssam 			if (diff <= 0)
28525871Ssam 				return (-1);
28625871Ssam 			fs = &io->i_fs;
28725871Ssam 			lbn = lblkno(fs, io->i_offset);
28825871Ssam 			io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff;
28925871Ssam 			off = blkoff(fs, io->i_offset);
29025871Ssam 			size = blksize(fs, &io->i_ino, lbn);
29125871Ssam 		} else {
29225871Ssam 			io->i_bn = io->i_offset / DEV_BSIZE;
29325871Ssam 			off = 0;
29425871Ssam 			size = DEV_BSIZE;
29525871Ssam 		}
29625871Ssam 		io->i_ma = io->i_buf;
29725871Ssam 		io->i_cc = size;
29825871Ssam 		if (devread(io) < 0) {
29925871Ssam 			errno = io->i_error;
30025871Ssam 			return (-1);
30125871Ssam 		}
30225871Ssam 		if ((io->i_flgs & F_FILE) != 0) {
30325871Ssam 			if (io->i_offset - off + size >= io->i_ino.i_size)
30425871Ssam 				io->i_cc = diff + off;
30525871Ssam 			io->i_cc -= off;
30625871Ssam 		}
30725871Ssam 		p = &io->i_buf[off];
30825871Ssam 	}
30925871Ssam 	io->i_cc--;
31025871Ssam 	io->i_offset++;
31125871Ssam 	c = (unsigned)*p++;
31225871Ssam 	io->i_ma = p;
31325871Ssam 	return (c);
31425871Ssam }
31525871Ssam 
31625871Ssam int	errno;
31725871Ssam 
31825871Ssam read(fdesc, buf, count)
31925871Ssam 	int fdesc, count;
32025871Ssam 	char *buf;
32125871Ssam {
322*30308Skarels 	register i, size;
32325871Ssam 	register struct iob *file;
324*30308Skarels 	register struct fs *fs;
325*30308Skarels 	int lbn, off;
32625871Ssam 
32725871Ssam 	errno = 0;
328*30308Skarels 	if (fdesc >= 0 & fdesc <= 2) {
32925871Ssam 		i = count;
33025871Ssam 		do {
33125871Ssam 			*buf = getchar();
33225871Ssam 		} while (--i && *buf++ != '\n');
33325871Ssam 		return (count - i);
33425871Ssam 	}
33525871Ssam 	fdesc -= 3;
33625871Ssam 	if (fdesc < 0 || fdesc >= NFILES ||
33725871Ssam 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
33825871Ssam 		errno = EBADF;
33925871Ssam 		return (-1);
34025871Ssam 	}
34125871Ssam 	if ((file->i_flgs&F_READ) == 0) {
34225871Ssam 		errno = EBADF;
34325871Ssam 		return (-1);
34425871Ssam 	}
345*30308Skarels #ifndef	SMALL
34625871Ssam 	if ((file->i_flgs & F_FILE) == 0) {
34725871Ssam 		file->i_cc = count;
34825871Ssam 		file->i_ma = buf;
34925871Ssam 		file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
35025871Ssam 		i = devread(file);
35125871Ssam 		if (i < 0)
35225871Ssam 			errno = file->i_error;
353*30308Skarels 		else
354*30308Skarels 			file->i_offset += i;
35525871Ssam 		return (i);
35625871Ssam 	}
357*30308Skarels #endif SMALL
358*30308Skarels 	if (file->i_offset+count > file->i_ino.i_size)
359*30308Skarels 		count = file->i_ino.i_size - file->i_offset;
360*30308Skarels 	if ((i = count) <= 0)
361*30308Skarels 		return (0);
362*30308Skarels 	/*
363*30308Skarels 	 * While reading full blocks, do I/O into user buffer.
364*30308Skarels 	 * Anything else uses getc().
365*30308Skarels 	 */
366*30308Skarels 	fs = &file->i_fs;
367*30308Skarels 	while (i) {
368*30308Skarels 		off = blkoff(fs, file->i_offset);
369*30308Skarels 		lbn = lblkno(fs, file->i_offset);
370*30308Skarels 		size = blksize(fs, &file->i_ino, lbn);
371*30308Skarels 		if (off == 0 && size <= i) {
372*30308Skarels 			file->i_bn = fsbtodb(fs, sbmap(file, lbn)) +
373*30308Skarels 			    file->i_boff;
374*30308Skarels 			file->i_cc = size;
375*30308Skarels 			file->i_ma = buf;
376*30308Skarels 			if (devread(file) < 0) {
377*30308Skarels 				errno = file->i_error;
378*30308Skarels 				return (-1);
379*30308Skarels 			}
380*30308Skarels 			file->i_offset += size;
381*30308Skarels 			file->i_cc = 0;
382*30308Skarels 			buf += size;
383*30308Skarels 			i -= size;
384*30308Skarels 		} else {
385*30308Skarels 			size -= off;
386*30308Skarels 			if (size > i)
387*30308Skarels 				size = i;
388*30308Skarels 			i -= size;
389*30308Skarels 			do {
390*30308Skarels 				*buf++ = getc(fdesc+3);
391*30308Skarels 			} while (--size);
392*30308Skarels 		}
393*30308Skarels 	}
394*30308Skarels 	return (count);
39525871Ssam }
39625871Ssam 
397*30308Skarels #ifndef	SMALL
39825871Ssam write(fdesc, buf, count)
39925871Ssam 	int fdesc, count;
40025871Ssam 	char *buf;
40125871Ssam {
40225871Ssam 	register i;
40325871Ssam 	register struct iob *file;
40425871Ssam 
40525871Ssam 	errno = 0;
40625871Ssam 	if (fdesc >= 0 && fdesc <= 2) {
40725871Ssam 		i = count;
40825871Ssam 		while (i--)
40925871Ssam 			putchar(*buf++);
41025871Ssam 		return (count);
41125871Ssam 	}
41225871Ssam 	fdesc -= 3;
41325871Ssam 	if (fdesc < 0 || fdesc >= NFILES ||
41425871Ssam 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
41525871Ssam 		errno = EBADF;
41625871Ssam 		return (-1);
41725871Ssam 	}
41825871Ssam 	if ((file->i_flgs&F_WRITE) == 0) {
41925871Ssam 		errno = EBADF;
42025871Ssam 		return (-1);
42125871Ssam 	}
42225871Ssam 	file->i_cc = count;
42325871Ssam 	file->i_ma = buf;
42425871Ssam 	file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
42525871Ssam 	i = devwrite(file);
42625871Ssam 	file->i_offset += count;
42725871Ssam 	if (i < 0)
42825871Ssam 		errno = file->i_error;
42925871Ssam 	return (i);
43025871Ssam }
431*30308Skarels #endif SMALL
43225871Ssam 
43325871Ssam int	openfirst = 1;
434*30308Skarels #ifdef notyet
435*30308Skarels int	opendev;	/* last device opened; for boot to set bootdev */
436*30308Skarels extern	int bootdev;
437*30308Skarels #endif notyet
43825871Ssam 
43925871Ssam open(str, how)
44025871Ssam 	char *str;
44125871Ssam 	int how;
44225871Ssam {
44325871Ssam 	register char *cp;
44425871Ssam 	int i;
44525871Ssam 	register struct iob *file;
44625871Ssam 	register struct devsw *dp;
44725871Ssam 	int fdesc;
44825871Ssam 	long atol();
44925871Ssam 
45025871Ssam 	if (openfirst) {
45125871Ssam 		for (i = 0; i < NFILES; i++)
45225871Ssam 			iob[i].i_flgs = 0;
45325871Ssam 		openfirst = 0;
45425871Ssam 	}
45525871Ssam 
45625871Ssam 	for (fdesc = 0; fdesc < NFILES; fdesc++)
45725871Ssam 		if (iob[fdesc].i_flgs == 0)
45825871Ssam 			goto gotfile;
45925871Ssam 	_stop("No more file slots");
46025871Ssam gotfile:
46125871Ssam 	(file = &iob[fdesc])->i_flgs |= F_ALLOC;
46225871Ssam 
463*30308Skarels #ifdef notyet
464*30308Skarels 	for (cp = str; *cp && *cp != '/' && *cp != ':'; cp++)
465*30308Skarels 			;
466*30308Skarels 	if (*cp != ':') {
467*30308Skarels 		/* default bootstrap unit and device */
468*30308Skarels 		file->i_ino.i_dev = bootdev;
469*30308Skarels 		cp = str;
470*30308Skarels 	} else {
471*30308Skarels # define isdigit(n)	((n>='0') && (n<='9'))
472*30308Skarels 		/*
473*30308Skarels 	 	 * syntax for possible device name:
474*30308Skarels 	 	 *	<alpha-string><digit-string><letter>:
475*30308Skarels 	 	 */
476*30308Skarels 		for (cp = str; *cp != ':' && !isdigit(*cp); cp++)
477*30308Skarels 			;
478*30308Skarels 		for (dp = devsw; dp->dv_name; dp++) {
479*30308Skarels 			if (!strncmp(str, dp->dv_name,cp-str))
480*30308Skarels 				goto gotdev;
481*30308Skarels 		}
482*30308Skarels 		printf("unknown device\n");
483*30308Skarels 		file->i_flgs = 0;
484*30308Skarels 		errno = EDEV;
485*30308Skarels 		return (-1);
486*30308Skarels 	gotdev:
487*30308Skarels 		i = 0;
488*30308Skarels 		while (*cp >= '0' && *cp <= '9')
489*30308Skarels 			i = i * 10 + *cp++ - '0';
490*30308Skarels 		if (i < 0 || i > 255) {
491*30308Skarels 			printf("minor device number out of range (0-255)\n");
492*30308Skarels 			file->i_flgs = 0;
493*30308Skarels 			errno = EUNIT;
494*30308Skarels 			return (-1);
495*30308Skarels 		}
496*30308Skarels 		if (*cp >= 'a' && *cp <= 'h') {
497*30308Skarels 			if (i > 31) {
498*30308Skarels 				printf("unit number out of range (0-31)\n");
499*30308Skarels 				file->i_flgs = 0;
500*30308Skarels 				errno = EUNIT;
501*30308Skarels 				return (-1);
502*30308Skarels 			}
503*30308Skarels 			i = make_minor(i, *cp++ - 'a');
504*30308Skarels 		}
505*30308Skarels 
506*30308Skarels 		if (*cp++ != ':') {
507*30308Skarels 			printf("incorrect device specification\n");
508*30308Skarels 			file->i_flgs = 0;
509*30308Skarels 			errno = EOFFSET;
510*30308Skarels 			return (-1);
511*30308Skarels 		}
512*30308Skarels 		opendev = file->i_ino.i_dev = makedev(dp-devsw, i);
513*30308Skarels 	}
514*30308Skarels 	file->i_boff = 0;
515*30308Skarels 	devopen(file);
516*30308Skarels 	if (cp != str && *cp == '\0') {
517*30308Skarels 		file->i_flgs |= how+1;
518*30308Skarels 		file->i_cc = 0;
519*30308Skarels 		file->i_offset = 0;
520*30308Skarels 		return (fdesc+3);
521*30308Skarels 	}
522*30308Skarels #else notyet
52325871Ssam 	for (cp = str; *cp && *cp != '('; cp++)
52425871Ssam 			;
52525871Ssam 	if (*cp != '(') {
52625871Ssam 		printf("Bad device\n");
52725871Ssam 		file->i_flgs = 0;
52825871Ssam 		errno = EDEV;
52925871Ssam 		return (-1);
53025871Ssam 	}
53125871Ssam 	*cp++ = '\0';
53225871Ssam 	for (dp = devsw; dp->dv_name; dp++) {
53325871Ssam 		if (!strcmp(str, dp->dv_name))
53425871Ssam 			goto gotdev;
53525871Ssam 	}
53625871Ssam 	printf("Unknown device\n");
53725871Ssam 	file->i_flgs = 0;
53825871Ssam 	errno = ENXIO;
53925871Ssam 	return (-1);
54025871Ssam gotdev:
54125871Ssam 	*(cp-1) = '(';
54225871Ssam 	file->i_ino.i_dev = dp-devsw;
54325871Ssam 	file->i_unit = *cp++ - '0';
54425871Ssam 	if (*cp >= '0' && *cp <= '9')
54525871Ssam 		file->i_unit = file->i_unit * 10 + *cp++ - '0';
54625871Ssam 	if (file->i_unit < 0 || file->i_unit > 63) {
54725871Ssam 		printf("Bad unit specifier\n");
54825871Ssam 		file->i_flgs = 0;
54925871Ssam 		errno = EUNIT;
55025871Ssam 		return (-1);
55125871Ssam 	}
55225871Ssam 	if (*cp++ != ',') {
55325871Ssam badoff:
55425871Ssam 		printf("Missing offset specification\n");
55525871Ssam 		file->i_flgs = 0;
55625871Ssam 		errno = EOFFSET;
55725871Ssam 		return (-1);
55825871Ssam 	}
55925871Ssam 	file->i_boff = atol(cp);
56025871Ssam 	for (;;) {
56125871Ssam 		if (*cp == ')')
56225871Ssam 			break;
56325871Ssam 		if (*cp++)
56425871Ssam 			continue;
56525871Ssam 		goto badoff;
56625871Ssam 	}
56725871Ssam 	file->i_flgs |= how+1;
56825871Ssam 	devopen(file);
56925871Ssam 	if (*++cp == '\0') {
57025871Ssam 		file->i_cc = 0;
57125871Ssam 		file->i_offset = 0;
57225871Ssam 		return (fdesc+3);
57325871Ssam 	}
574*30308Skarels #endif notyet
57525871Ssam 	file->i_ma = (char *)(&file->i_fs);
57625871Ssam 	file->i_cc = SBSIZE;
57725871Ssam 	file->i_bn = SBLOCK + file->i_boff;
57825871Ssam 	file->i_offset = 0;
57925871Ssam 	if (devread(file) < 0) {
58025871Ssam 		errno = file->i_error;
58125871Ssam 		printf("super block read error\n");
58225871Ssam 		return (-1);
58325871Ssam 	}
58425871Ssam 	if ((i = find(cp, file)) == 0) {
58525871Ssam 		file->i_flgs = 0;
58625871Ssam 		errno = ESRCH;
58725871Ssam 		return (-1);
58825871Ssam 	}
589*30308Skarels #ifndef	SMALL
59025871Ssam 	if (how != 0) {
59125871Ssam 		printf("Can't write files yet.. Sorry\n");
59225871Ssam 		file->i_flgs = 0;
59325871Ssam 		errno = EIO;
59425871Ssam 		return (-1);
59525871Ssam 	}
596*30308Skarels #endif SMALL
59725871Ssam 	if (openi(i, file) < 0) {
59825871Ssam 		errno = file->i_error;
59925871Ssam 		return (-1);
60025871Ssam 	}
60125871Ssam 	file->i_offset = 0;
60225871Ssam 	file->i_cc = 0;
603*30308Skarels 	file->i_flgs |= F_FILE;
60425871Ssam 	return (fdesc+3);
60525871Ssam }
60625871Ssam 
60725871Ssam close(fdesc)
60825871Ssam 	int fdesc;
60925871Ssam {
61025871Ssam 	struct iob *file;
61125871Ssam 
61225871Ssam 	fdesc -= 3;
61325871Ssam 	if (fdesc < 0 || fdesc >= NFILES ||
61425871Ssam 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
61525871Ssam 		errno = EBADF;
61625871Ssam 		return (-1);
61725871Ssam 	}
61825871Ssam 	if ((file->i_flgs&F_FILE) == 0)
61925871Ssam 		devclose(file);
62025871Ssam 	file->i_flgs = 0;
62125871Ssam 	return (0);
62225871Ssam }
62325871Ssam 
624*30308Skarels #ifndef	SMALL
625*30308Skarels ioctl(fdesc, cmd, arg)
626*30308Skarels 	int fdesc, cmd;
627*30308Skarels 	char *arg;
628*30308Skarels {
629*30308Skarels 	register struct iob *file;
630*30308Skarels 	int error = 0;
63125871Ssam 
632*30308Skarels 	fdesc -= 3;
633*30308Skarels 	if (fdesc < 0 || fdesc >= NFILES ||
634*30308Skarels 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
635*30308Skarels 		errno = EBADF;
636*30308Skarels 		return (-1);
637*30308Skarels 	}
638*30308Skarels 	switch (cmd) {
639*30308Skarels 
640*30308Skarels 	case SAIOHDR:
641*30308Skarels 		file->i_flgs |= F_HDR;
642*30308Skarels 		break;
643*30308Skarels 
644*30308Skarels 	case SAIOCHECK:
645*30308Skarels 		file->i_flgs |= F_CHECK;
646*30308Skarels 		break;
647*30308Skarels 
648*30308Skarels 	case SAIOHCHECK:
649*30308Skarels 		file->i_flgs |= F_HCHECK;
650*30308Skarels 		break;
651*30308Skarels 
652*30308Skarels 	case SAIONOBAD:
653*30308Skarels 		file->i_flgs |= F_NBSF;
654*30308Skarels 		break;
655*30308Skarels 
656*30308Skarels 	case SAIODOBAD:
657*30308Skarels 		file->i_flgs &= ~F_NBSF;
658*30308Skarels 		break;
659*30308Skarels 
660*30308Skarels 	default:
661*30308Skarels 		error = devioctl(file, cmd, arg);
662*30308Skarels 		break;
663*30308Skarels 	}
664*30308Skarels 	if (error < 0)
665*30308Skarels 		errno = file->i_error;
666*30308Skarels 	return (error);
667*30308Skarels }
668*30308Skarels #endif SMALL
669*30308Skarels 
67025871Ssam exit()
67125871Ssam {
67225871Ssam 	_stop("Exit called");
67325871Ssam }
67425871Ssam 
67525871Ssam _stop(s)
67625871Ssam 	char *s;
67725871Ssam {
67825871Ssam 	int i;
67925871Ssam 
68025871Ssam 	for (i = 0; i < NFILES; i++)
68125871Ssam 		if (iob[i].i_flgs != 0)
68225871Ssam 			close(i);
68325871Ssam 	printf("%s\n", s);
68425871Ssam 	_rtt();
68525871Ssam }
68625871Ssam 
687*30308Skarels #ifdef tahoe
68825871Ssam trap(ps)
68925871Ssam 	int ps;
69025871Ssam {
69125871Ssam 	printf("Trap %o\n", ps);
69225871Ssam 	for (;;)
69325871Ssam 		;
69425871Ssam }
69525871Ssam 
69625871Ssam uncache (addr)
69725871Ssam 	char *addr;
69825871Ssam {
69925871Ssam 	/* Return *(addr-0x4000); DIRTY assumes this address is valid */
70025871Ssam 	mtpr(PDCS, addr);
70125871Ssam }
702*30308Skarels #endif
703