xref: /csrg-svn/sys/stand.att/sys.c (revision 49117)
1*49117Sbostic /*-
2*49117Sbostic  * Copyright (c) 1982, 1988 The Regents of the University of California.
3*49117Sbostic  * All rights reserved.
423243Smckusick  *
5*49117Sbostic  * %sccs.include.proprietary.c%
6*49117Sbostic  *
7*49117Sbostic  *	@(#)sys.c	7.15 (Berkeley) 05/04/91
823243Smckusick  */
9327Sbill 
10*49117Sbostic #include <sys/param.h>
11*49117Sbostic #include <sys/reboot.h>
12*49117Sbostic #include <ufs/dir.h>
13*49117Sbostic #include <stand/saio.h>		/* used from machine/stand dir */
14327Sbill 
15327Sbill ino_t	dlook();
16327Sbill 
176068Smckusic struct dirstuff {
186068Smckusic 	int loc;
196068Smckusic 	struct iob *io;
206068Smckusic };
216068Smckusic 
22*49117Sbostic struct iob iob[SOPEN_MAX];
2334463Sbostic 
24327Sbill static
2510022Ssam openi(n, io)
266068Smckusic 	register struct iob *io;
27327Sbill {
28327Sbill 	register struct dinode *dp;
2911083Ssam 	int cc;
30327Sbill 
31327Sbill 	io->i_offset = 0;
326068Smckusic 	io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff;
336068Smckusic 	io->i_cc = io->i_fs.fs_bsize;
34327Sbill 	io->i_ma = io->i_buf;
3511083Ssam 	cc = devread(io);
36327Sbill 	dp = (struct dinode *)io->i_buf;
3740500Smckusick 	io->i_ino = dp[itoo(&io->i_fs, n)];
3811083Ssam 	return (cc);
39327Sbill }
40327Sbill 
41327Sbill static
42327Sbill find(path, file)
436068Smckusic 	register char *path;
446068Smckusic 	struct iob *file;
45327Sbill {
46327Sbill 	register char *q;
4734463Sbostic 	char *dir, c;
48327Sbill 	int n;
49327Sbill 
5034463Sbostic 	if (path == NULL || *path == '\0') {
51327Sbill 		printf("null path\n");
5210022Ssam 		return (0);
53327Sbill 	}
54327Sbill 
5511083Ssam 	if (openi((ino_t) ROOTINO, file) < 0) {
5611083Ssam 		printf("can't read root inode\n");
5711083Ssam 		return (0);
5811083Ssam 	}
5930768Skarels 	dir = path;
60327Sbill 	while (*path) {
61327Sbill 		while (*path == '/')
62327Sbill 			path++;
63327Sbill 		q = path;
64327Sbill 		while(*q != '/' && *q != '\0')
65327Sbill 			q++;
66327Sbill 		c = *q;
67327Sbill 		*q = '\0';
6825166Skarels 		if (q == path) path = "." ;	/* "/" means "/." */
69327Sbill 
7030768Skarels 		if ((n = dlook(path, file, dir)) != 0) {
7111083Ssam 			if (c == '\0')
72327Sbill 				break;
7311083Ssam 			if (openi(n, file) < 0)
7411083Ssam 				return (0);
75327Sbill 			*q = c;
76327Sbill 			path = q;
77327Sbill 			continue;
78327Sbill 		} else {
7925166Skarels 			printf("%s: not found\n", path);
8010022Ssam 			return (0);
81327Sbill 		}
82327Sbill 	}
8310022Ssam 	return (n);
84327Sbill }
85327Sbill 
8634463Sbostic #define	NBUFS	4
8734463Sbostic static char	b[NBUFS][MAXBSIZE];
8834463Sbostic static daddr_t	blknos[NBUFS];
8934463Sbostic 
90327Sbill static daddr_t
91327Sbill sbmap(io, bn)
926068Smckusic 	register struct iob *io;
936068Smckusic 	daddr_t bn;
94327Sbill {
9540500Smckusick 	register struct dinode *ip;
966068Smckusic 	int i, j, sh;
97327Sbill 	daddr_t nb, *bap;
98327Sbill 
99327Sbill 	ip = &io->i_ino;
1006068Smckusic 	if (bn < 0) {
101327Sbill 		printf("bn negative\n");
10210022Ssam 		return ((daddr_t)0);
103327Sbill 	}
104327Sbill 
105*49117Sbostic 	/* The first NDADDR blocks are direct blocks. */
1066068Smckusic 	if(bn < NDADDR) {
10740500Smckusick 		nb = ip->di_db[bn];
10810022Ssam 		return (nb);
109327Sbill 	}
110327Sbill 
111*49117Sbostic 	/* Determine the number of levels of indirection. */
1126068Smckusic 	sh = 1;
1136068Smckusic 	bn -= NDADDR;
1146068Smckusic 	for (j = NIADDR; j > 0; j--) {
1156068Smckusic 		sh *= NINDIR(&io->i_fs);
1166068Smckusic 		if (bn < sh)
117327Sbill 			break;
1186068Smckusic 		bn -= sh;
119327Sbill 	}
1206068Smckusic 	if (j == 0) {
1216068Smckusic 		printf("bn ovf %D\n", bn);
1226068Smckusic 		return ((daddr_t)0);
123327Sbill 	}
124327Sbill 
125*49117Sbostic 	/* Get the first indirect block address. */
12640500Smckusick 	nb = ip->di_ib[NIADDR - j];
1276068Smckusic 	if (nb == 0) {
128327Sbill 		printf("bn void %D\n",bn);
12910022Ssam 		return ((daddr_t)0);
130327Sbill 	}
131327Sbill 
132*49117Sbostic 	/* Get the indirect blocks. */
1336068Smckusic 	for (; j <= NIADDR; j++) {
134327Sbill 		if (blknos[j] != nb) {
1356068Smckusic 			io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff;
136327Sbill 			io->i_ma = b[j];
1376068Smckusic 			io->i_cc = io->i_fs.fs_bsize;
13811083Ssam 			if (devread(io) != io->i_fs.fs_bsize) {
13911083Ssam 				if (io->i_error)
14011083Ssam 					errno = io->i_error;
14111083Ssam 				printf("bn %D: read error\n", io->i_bn);
14211083Ssam 				return ((daddr_t)0);
14311083Ssam 			}
144327Sbill 			blknos[j] = nb;
145327Sbill 		}
146327Sbill 		bap = (daddr_t *)b[j];
1476068Smckusic 		sh /= NINDIR(&io->i_fs);
1486068Smckusic 		i = (bn / sh) % NINDIR(&io->i_fs);
149327Sbill 		nb = bap[i];
150327Sbill 		if(nb == 0) {
151327Sbill 			printf("bn void %D\n",bn);
15210022Ssam 			return ((daddr_t)0);
153327Sbill 		}
154327Sbill 	}
15510022Ssam 	return (nb);
156327Sbill }
157327Sbill 
1586068Smckusic struct direct *
1596068Smckusic readdir(dirp)
1606068Smckusic 	register struct dirstuff *dirp;
161327Sbill {
1626068Smckusic 	register struct direct *dp;
1636068Smckusic 	register struct iob *io;
1646068Smckusic 	daddr_t lbn, d;
1656068Smckusic 	int off;
166327Sbill 
1676068Smckusic 	io = dirp->io;
1686068Smckusic 	for(;;) {
16940500Smckusick 		if (dirp->loc >= io->i_ino.di_size)
17011083Ssam 			return (NULL);
1716068Smckusic 		off = blkoff(&io->i_fs, dirp->loc);
1726068Smckusic 		if (off == 0) {
1736068Smckusic 			lbn = lblkno(&io->i_fs, dirp->loc);
1746068Smckusic 			d = sbmap(io, lbn);
1756068Smckusic 			if(d == 0)
17634463Sbostic 				return (NULL);
1776068Smckusic 			io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff;
1786068Smckusic 			io->i_ma = io->i_buf;
17940500Smckusick 			io->i_cc = dblksize(&io->i_fs, &io->i_ino, lbn);
18011083Ssam 			if (devread(io) < 0) {
18111083Ssam 				errno = io->i_error;
18225166Skarels 				printf("bn %D: directory read error\n",
18325166Skarels 					io->i_bn);
18411083Ssam 				return (NULL);
18511083Ssam 			}
1866068Smckusic 		}
1876068Smckusic 		dp = (struct direct *)(io->i_buf + off);
1886068Smckusic 		dirp->loc += dp->d_reclen;
1896068Smckusic 		if (dp->d_ino == 0)
1906068Smckusic 			continue;
1916068Smckusic 		return (dp);
192327Sbill 	}
193327Sbill }
194327Sbill 
19540500Smckusick static ino_t
19640500Smckusick dlook(s, io, dir)
19740500Smckusick 	char *s;
19840500Smckusick 	register struct iob *io;
19940500Smckusick 	char *dir;
20040500Smckusick {
20140500Smckusick 	register struct direct *dp;
20240500Smckusick 	register struct dinode *ip;
20340500Smckusick 	struct dirstuff dirp;
20440500Smckusick 	int len;
20540500Smckusick 
20640500Smckusick 	if (s == NULL || *s == '\0')
20740500Smckusick 		return (0);
20840500Smckusick 	ip = &io->i_ino;
20940500Smckusick 	if ((ip->di_mode&IFMT) != IFDIR) {
21040500Smckusick 		printf("%s: not a directory\n", dir);
21140500Smckusick 		return (0);
21240500Smckusick 	}
21340500Smckusick 	if (ip->di_size == 0) {
21440500Smckusick 		printf("%s: zero length directory\n", dir);
21540500Smckusick 		return (0);
21640500Smckusick 	}
21740500Smckusick 	len = strlen(s);
21840500Smckusick 	dirp.loc = 0;
21940500Smckusick 	dirp.io = io;
22040500Smckusick 	for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
22140500Smckusick 		if(dp->d_ino == 0)
22240500Smckusick 			continue;
22340500Smckusick 		if (dp->d_namlen == len && !strcmp(s, dp->d_name))
22440500Smckusick 			return (dp->d_ino);
22540500Smckusick 	}
22640500Smckusick 	return (0);
22740500Smckusick }
22840500Smckusick 
229327Sbill lseek(fdesc, addr, ptr)
23010022Ssam 	int fdesc, ptr;
23110022Ssam 	off_t addr;
232327Sbill {
233327Sbill 	register struct iob *io;
234327Sbill 
23534463Sbostic #ifndef SMALL
23634463Sbostic 	if (ptr != L_SET) {
237327Sbill 		printf("Seek not from beginning of file\n");
23810022Ssam 		errno = EOFFSET;
23910022Ssam 		return (-1);
240327Sbill 	}
24134463Sbostic #endif
242327Sbill 	fdesc -= 3;
24348826Swilliam #ifndef SMALL
244*49117Sbostic 	if (fdesc < 0 || fdesc >= SOPEN_MAX ||
24510022Ssam 	    ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) {
24610022Ssam 		errno = EBADF;
24710022Ssam 		return (-1);
24810022Ssam 	}
24948826Swilliam #endif
250327Sbill 	io->i_offset = addr;
2516068Smckusic 	io->i_bn = addr / DEV_BSIZE;
252327Sbill 	io->i_cc = 0;
25310022Ssam 	return (0);
254327Sbill }
255327Sbill 
256327Sbill getc(fdesc)
25710022Ssam 	int fdesc;
258327Sbill {
259327Sbill 	register struct iob *io;
2606068Smckusic 	register struct fs *fs;
261327Sbill 	register char *p;
2626068Smckusic 	int c, lbn, off, size, diff;
263327Sbill 
264327Sbill 
26548826Swilliam #ifndef SMALL
266327Sbill 	if (fdesc >= 0 && fdesc <= 2)
26710022Ssam 		return (getchar());
26848826Swilliam #endif
269327Sbill 	fdesc -= 3;
270*49117Sbostic 	if (fdesc < 0 || fdesc >= SOPEN_MAX ||
27110022Ssam 	    ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
27210022Ssam 		errno = EBADF;
27310022Ssam 		return (-1);
27410022Ssam 	}
275327Sbill 	p = io->i_ma;
276327Sbill 	if (io->i_cc <= 0) {
2776068Smckusic 		if ((io->i_flgs & F_FILE) != 0) {
27840500Smckusick 			diff = io->i_ino.di_size - io->i_offset;
2796068Smckusic 			if (diff <= 0)
2806068Smckusic 				return (-1);
2816068Smckusic 			fs = &io->i_fs;
2826068Smckusic 			lbn = lblkno(fs, io->i_offset);
2836068Smckusic 			io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff;
2846068Smckusic 			off = blkoff(fs, io->i_offset);
28540500Smckusick 			size = dblksize(fs, &io->i_ino, lbn);
2866068Smckusic 		} else {
28748826Swilliam 			io->i_bn = io->i_offset / DEV_BSIZE + io->i_boff;
2886068Smckusic 			off = 0;
2896068Smckusic 			size = DEV_BSIZE;
2906068Smckusic 		}
291327Sbill 		io->i_ma = io->i_buf;
2926068Smckusic 		io->i_cc = size;
29311083Ssam 		if (devread(io) < 0) {
29411083Ssam 			errno = io->i_error;
29511083Ssam 			return (-1);
29611083Ssam 		}
2976068Smckusic 		if ((io->i_flgs & F_FILE) != 0) {
29840500Smckusick 			if (io->i_offset - off + size >= io->i_ino.di_size)
2996068Smckusic 				io->i_cc = diff + off;
300327Sbill 			io->i_cc -= off;
3016068Smckusic 		}
302327Sbill 		p = &io->i_buf[off];
303327Sbill 	}
304327Sbill 	io->i_cc--;
305327Sbill 	io->i_offset++;
306327Sbill 	c = (unsigned)*p++;
307327Sbill 	io->i_ma = p;
30810022Ssam 	return (c);
309327Sbill }
3106068Smckusic 
31110022Ssam int	errno;
312327Sbill 
313327Sbill read(fdesc, buf, count)
31410022Ssam 	int fdesc, count;
31510022Ssam 	char *buf;
316327Sbill {
31725166Skarels 	register i, size;
318327Sbill 	register struct iob *file;
31925166Skarels 	register struct fs *fs;
32025166Skarels 	int lbn, off;
321327Sbill 
32210022Ssam 	errno = 0;
32348826Swilliam #ifndef SMALL
32445352Sbostic 	if (fdesc >= 0 && fdesc <= 2) {
325327Sbill 		i = count;
326327Sbill 		do {
327327Sbill 			*buf = getchar();
328327Sbill 		} while (--i && *buf++ != '\n');
32910022Ssam 		return (count - i);
330327Sbill 	}
33148826Swilliam #endif
332327Sbill 	fdesc -= 3;
333*49117Sbostic 	if (fdesc < 0 || fdesc >= SOPEN_MAX ||
33410022Ssam 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
33510022Ssam 		errno = EBADF;
33610022Ssam 		return (-1);
33710022Ssam 	}
33810022Ssam 	if ((file->i_flgs&F_READ) == 0) {
33910022Ssam 		errno = EBADF;
34010022Ssam 		return (-1);
34110022Ssam 	}
34234463Sbostic #ifndef SMALL
3436068Smckusic 	if ((file->i_flgs & F_FILE) == 0) {
344327Sbill 		file->i_cc = count;
345327Sbill 		file->i_ma = buf;
3467446Sroot 		file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
347327Sbill 		i = devread(file);
34810022Ssam 		if (i < 0)
34910022Ssam 			errno = file->i_error;
35030547Skarels 		else
35130547Skarels 			file->i_offset += i;
35210022Ssam 		return (i);
353327Sbill 	}
35434463Sbostic #endif
35540500Smckusick 	if (file->i_offset+count > file->i_ino.di_size)
35640500Smckusick 		count = file->i_ino.di_size - file->i_offset;
35725166Skarels 	if ((i = count) <= 0)
35825166Skarels 		return (0);
35925166Skarels 	/*
36025166Skarels 	 * While reading full blocks, do I/O into user buffer.
36125166Skarels 	 * Anything else uses getc().
36225166Skarels 	 */
36325166Skarels 	fs = &file->i_fs;
36425166Skarels 	while (i) {
36525166Skarels 		off = blkoff(fs, file->i_offset);
36625166Skarels 		lbn = lblkno(fs, file->i_offset);
36740500Smckusick 		size = dblksize(fs, &file->i_ino, lbn);
36848826Swilliam #ifndef SMALL
36925166Skarels 		if (off == 0 && size <= i) {
37025166Skarels 			file->i_bn = fsbtodb(fs, sbmap(file, lbn)) +
37125166Skarels 			    file->i_boff;
37225166Skarels 			file->i_cc = size;
37325166Skarels 			file->i_ma = buf;
37425166Skarels 			if (devread(file) < 0) {
37525166Skarels 				errno = file->i_error;
37625166Skarels 				return (-1);
37725166Skarels 			}
37825166Skarels 			file->i_offset += size;
37925166Skarels 			file->i_cc = 0;
38025166Skarels 			buf += size;
38125166Skarels 			i -= size;
38225166Skarels 		} else {
38348826Swilliam #endif
38425166Skarels 			size -= off;
38525166Skarels 			if (size > i)
38625166Skarels 				size = i;
38725166Skarels 			i -= size;
38825166Skarels 			do {
38925166Skarels 				*buf++ = getc(fdesc+3);
39025166Skarels 			} while (--size);
39148826Swilliam #ifndef	SMALL
39225166Skarels 		}
39348826Swilliam #endif
39425166Skarels 	}
39525166Skarels 	return (count);
396327Sbill }
397327Sbill 
39834463Sbostic #ifndef SMALL
399327Sbill write(fdesc, buf, count)
40010022Ssam 	int fdesc, count;
40110022Ssam 	char *buf;
402327Sbill {
403327Sbill 	register i;
404327Sbill 	register struct iob *file;
405327Sbill 
40610022Ssam 	errno = 0;
407327Sbill 	if (fdesc >= 0 && fdesc <= 2) {
408327Sbill 		i = count;
409327Sbill 		while (i--)
410327Sbill 			putchar(*buf++);
41110022Ssam 		return (count);
412327Sbill 	}
413327Sbill 	fdesc -= 3;
414*49117Sbostic 	if (fdesc < 0 || fdesc >= SOPEN_MAX ||
41510022Ssam 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
41610022Ssam 		errno = EBADF;
41710022Ssam 		return (-1);
41810022Ssam 	}
41910022Ssam 	if ((file->i_flgs&F_WRITE) == 0) {
42010022Ssam 		errno = EBADF;
42110022Ssam 		return (-1);
42210022Ssam 	}
423327Sbill 	file->i_cc = count;
424327Sbill 	file->i_ma = buf;
4257446Sroot 	file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
426327Sbill 	i = devwrite(file);
4277446Sroot 	file->i_offset += count;
42810022Ssam 	if (i < 0)
42910022Ssam 		errno = file->i_error;
43010022Ssam 	return (i);
431327Sbill }
43234463Sbostic #endif
433327Sbill 
4343349Swnj int	openfirst = 1;
43534463Sbostic u_int	opendev;		/* last device opened */
43634463Sbostic extern u_int bootdev;
4373349Swnj 
438327Sbill open(str, how)
4396068Smckusic 	char *str;
44010022Ssam 	int how;
441327Sbill {
44234463Sbostic 	register char *t;
44334463Sbostic 	register int cnt;
444327Sbill 	register struct iob *file;
44534463Sbostic 	int fdesc, args[8], *argp;
446327Sbill 
4473349Swnj 	if (openfirst) {
448*49117Sbostic 		for (cnt = 0; cnt < SOPEN_MAX; cnt++)
44934463Sbostic 			iob[cnt].i_flgs = 0;
4503349Swnj 		openfirst = 0;
451327Sbill 	}
452327Sbill 
45334463Sbostic 	for (fdesc = 0;; fdesc++) {
454*49117Sbostic 		if (fdesc == SOPEN_MAX)
45534463Sbostic 			_stop("No more file slots");
45634463Sbostic 		if (iob[fdesc].i_flgs == 0) {
45734463Sbostic 			file = &iob[fdesc];
45834463Sbostic 			file->i_flgs |= F_ALLOC;
45934463Sbostic 			file->i_adapt = file->i_ctlr = file->i_unit =
46034463Sbostic 			    file->i_part = 0;
46134463Sbostic 			break;
46234463Sbostic 		}
46334463Sbostic 	}
464327Sbill 
46534463Sbostic 	for (cnt = 0; cnt < sizeof(args)/sizeof(args[0]); args[cnt++] = 0);
46634463Sbostic #ifndef SMALL
46734463Sbostic 	for (t = str; *t && *t != '/' && *t != ':' && *t != '('; ++t)
46834463Sbostic 		if (isupper(*t))
46934463Sbostic 			*t = tolower(*t);
47034463Sbostic 	switch(*t) {
47134463Sbostic 	case '(':	/* type(adapt, ctlr, drive, partition)file */
47240500Smckusick 		if ((file->i_dev = getdev(str, t - str)) == -1)
47330547Skarels 			goto bad;
47434463Sbostic 		for (argp = args + 4, cnt = 0; *t != ')'; ++cnt) {
47534463Sbostic 			for (++t; isspace(*t); ++t);
47634463Sbostic 			if (*t == ')')
47734463Sbostic 				break;
47834463Sbostic 			if (!isdigit(*t))
47930547Skarels 				goto badspec;
48034463Sbostic 			*argp++ = atoi(t);
48134463Sbostic 			for (++t; isdigit(*t); ++t);
48234463Sbostic 			if (*t != ',' && *t != ')' || cnt == 4)
48334463Sbostic 				goto badspec;
48430547Skarels 		}
48534463Sbostic 		for (++t; isspace(*t); ++t);
48634463Sbostic 		argp -= 4;
48734463Sbostic 		file->i_adapt = *argp++;
48834463Sbostic 		file->i_ctlr = *argp++;
48934463Sbostic 		file->i_unit = *argp++;
49034463Sbostic 		file->i_part = *argp;
49134463Sbostic 		break;
49234463Sbostic 	case ':':	/* [A-Za-z]*[0-9]*[A-Za-z]:file */
49334463Sbostic 		for (t = str; *t != ':' && !isdigit(*t); ++t);
49440500Smckusick 		if ((file->i_dev = getdev(str, t - str)) == -1)
49530547Skarels 			goto bad;
49634463Sbostic 		if ((file->i_unit = getunit(t)) == -1)
49730547Skarels 			goto bad;
49834463Sbostic 		for (; isdigit(*t); ++t);
49934463Sbostic 		if (*t >= 'a' && *t <= 'h')
50034463Sbostic 			file->i_part = *t++ - 'a';
50134463Sbostic 		if (*t != ':') {
50225166Skarels 			errno = EOFFSET;
50330547Skarels 			goto badspec;
50425166Skarels 		}
50534463Sbostic 		for (++t; isspace(*t); ++t);
50634463Sbostic 		break;
50734463Sbostic 	case '/':
50834463Sbostic 	default:		/* default bootstrap unit and device */
50934463Sbostic #else
51034463Sbostic 	{
51134463Sbostic #endif /* SMALL */
51240500Smckusick 		file->i_dev = B_TYPE(bootdev);
51334463Sbostic 		file->i_adapt = B_ADAPTOR(bootdev);
51434463Sbostic 		file->i_ctlr = B_CONTROLLER(bootdev);
51534463Sbostic 		file->i_unit = B_UNIT(bootdev);
51634463Sbostic 		file->i_part = B_PARTITION(bootdev);
51734463Sbostic 		t = str;
51825166Skarels 	}
51934463Sbostic 
52040500Smckusick 	opendev = MAKEBOOTDEV(file->i_dev, file->i_adapt, file->i_ctlr,
52134463Sbostic 	    file->i_unit, file->i_part);
52234463Sbostic 
52330547Skarels 	if (errno = devopen(file))
52430547Skarels 		goto bad;
52534463Sbostic 
52634463Sbostic 	if (*t == '\0') {
52734463Sbostic 		file->i_flgs |= how + 1;
52825166Skarels 		file->i_cc = 0;
52925166Skarels 		file->i_offset = 0;
53025166Skarels 		return (fdesc+3);
53125166Skarels 	}
53234463Sbostic #ifndef SMALL
53334463Sbostic 	else if (how != 0) {
53434463Sbostic 		printf("Can't write files yet.. Sorry\n");
53534463Sbostic 		errno = EIO;
53634463Sbostic 		goto bad;
53734463Sbostic 	}
53833408Skarels #endif
5396068Smckusic 	file->i_ma = (char *)(&file->i_fs);
5406068Smckusic 	file->i_cc = SBSIZE;
54130768Skarels 	file->i_bn = SBOFF / DEV_BSIZE + file->i_boff;
5426068Smckusic 	file->i_offset = 0;
54311083Ssam 	if (devread(file) < 0) {
54411083Ssam 		errno = file->i_error;
54511083Ssam 		printf("super block read error\n");
54630547Skarels 		goto bad;
54711083Ssam 	}
54834463Sbostic 	if ((cnt = find(t, file)) == 0) {
54910022Ssam 		errno = ESRCH;
55030547Skarels 		goto bad;
551327Sbill 	}
55234463Sbostic 	if (openi(cnt, file) < 0) {
55311083Ssam 		errno = file->i_error;
55430547Skarels 		goto bad;
55511083Ssam 	}
556327Sbill 	file->i_offset = 0;
557327Sbill 	file->i_cc = 0;
558327Sbill 	file->i_flgs |= F_FILE | (how+1);
55910022Ssam 	return (fdesc+3);
56030547Skarels 
56133408Skarels #ifndef SMALL
56230547Skarels badspec:
56348826Swilliam 	printf("malformed device specification\nusage: device(adaptor, controller, drive, partition)file -or- <device><unit><partitionletter>:<file>\n");
56433408Skarels #endif
56530547Skarels bad:
56630547Skarels 	file->i_flgs = 0;
56730547Skarels 	return (-1);
568327Sbill }
569327Sbill 
57030924Skarels #ifndef SMALL
57130547Skarels static
57230547Skarels getdev(str, len)
57333408Skarels 	register char *str;
57430547Skarels 	int len;
57530547Skarels {
57630547Skarels 	register struct devsw *dp;
57733408Skarels 	register int i;
57834463Sbostic 	char savedch = str[len];
57930547Skarels 
58034463Sbostic 	str[len] = '\0';
58133408Skarels 	for (dp = devsw, i = 0; i < ndevs; dp++, i++)
58233408Skarels 		if (dp->dv_name && strcmp(str, dp->dv_name) == 0) {
58334463Sbostic 			str[len] = savedch;
58433408Skarels 			return (i);
58533408Skarels 		}
58633408Skarels 	printf("Unknown device\nKnown devices are:\n");
58733408Skarels 	for (dp = devsw, i = 0; i < ndevs; dp++, i++)
58833408Skarels 		if (dp->dv_name)
58933408Skarels 			printf(" %s", dp->dv_name);
59034463Sbostic 	printf("\n");
59130547Skarels 	errno = ENXIO;
59230547Skarels 	return (-1);
59330547Skarels }
59430547Skarels 
59530547Skarels static
59630547Skarels getunit(cp)
59730547Skarels 	register char *cp;
59830547Skarels {
59934463Sbostic 	int unit;
60030547Skarels 
60134463Sbostic 	unit = atoi(cp);
60234463Sbostic 	if ((u_int)unit > 255) {
60330547Skarels 		printf("minor device number out of range (0-255)\n");
60430547Skarels 		errno = EUNIT;
60534463Sbostic 		return (-1);
60630547Skarels 	}
60734463Sbostic 	return (unit);
60830547Skarels }
60934463Sbostic #endif /* SMALL */
61030547Skarels 
611327Sbill close(fdesc)
61210022Ssam 	int fdesc;
613327Sbill {
61448826Swilliam #ifndef SMALL
615327Sbill 	struct iob *file;
616327Sbill 
617327Sbill 	fdesc -= 3;
618*49117Sbostic 	if (fdesc < 0 || fdesc >= SOPEN_MAX ||
61910022Ssam 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
62010022Ssam 		errno = EBADF;
62110022Ssam 		return (-1);
62210022Ssam 	}
623327Sbill 	if ((file->i_flgs&F_FILE) == 0)
624327Sbill 		devclose(file);
625327Sbill 	file->i_flgs = 0;
62648826Swilliam #endif
62710022Ssam 	return (0);
628327Sbill }
629327Sbill 
63034463Sbostic #ifndef SMALL
63110022Ssam ioctl(fdesc, cmd, arg)
63210022Ssam 	int fdesc, cmd;
63310022Ssam 	char *arg;
63410022Ssam {
63510022Ssam 	register struct iob *file;
63610022Ssam 	int error = 0;
63710022Ssam 
63810331Shelge 	fdesc -= 3;
639*49117Sbostic 	if (fdesc < 0 || fdesc >= SOPEN_MAX ||
64010022Ssam 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
64110022Ssam 		errno = EBADF;
64210022Ssam 		return (-1);
64310022Ssam 	}
64410022Ssam 	switch (cmd) {
64510022Ssam 
64610022Ssam 	case SAIOHDR:
64710022Ssam 		file->i_flgs |= F_HDR;
64810022Ssam 		break;
64910022Ssam 
65010022Ssam 	case SAIOCHECK:
65110022Ssam 		file->i_flgs |= F_CHECK;
65210022Ssam 		break;
65310022Ssam 
65410022Ssam 	case SAIOHCHECK:
65510022Ssam 		file->i_flgs |= F_HCHECK;
65610022Ssam 		break;
65710022Ssam 
65810331Shelge 	case SAIONOBAD:
65910331Shelge 		file->i_flgs |= F_NBSF;
66010331Shelge 		break;
66110331Shelge 
66210331Shelge 	case SAIODOBAD:
66310331Shelge 		file->i_flgs &= ~F_NBSF;
66410331Shelge 		break;
66510331Shelge 
66610022Ssam 	default:
66710022Ssam 		error = devioctl(file, cmd, arg);
66810022Ssam 		break;
66910022Ssam 	}
67010022Ssam 	if (error < 0)
67110022Ssam 		errno = file->i_error;
67210022Ssam 	return (error);
67310022Ssam }
67434463Sbostic #endif /* SMALL */
67510022Ssam 
67648826Swilliam #ifndef i386
677327Sbill exit()
678327Sbill {
679327Sbill 	_stop("Exit called");
680327Sbill }
68148826Swilliam #endif
682327Sbill 
683327Sbill _stop(s)
68410022Ssam 	char *s;
685327Sbill {
6862391Stoy 	int i;
68741542Smckusick 	static int stopped = 0;
6882391Stoy 
68941542Smckusick 	if (!stopped) {
69041542Smckusick 		stopped++;
691*49117Sbostic 		for (i = 0; i < SOPEN_MAX; i++)
69241542Smckusick 			if (iob[i].i_flgs != 0)
69341542Smckusick 				close(i);
69441542Smckusick 	}
695327Sbill 	printf("%s\n", s);
696327Sbill 	_rtt();
697327Sbill }
698