xref: /csrg-svn/sys/i386/stand/sys.c (revision 41084)
1*41084Swilliam /*-
2*41084Swilliam  * Copyright (c) 1990 The Regents of the University of California.
3*41084Swilliam  * All rights reserved.
4*41084Swilliam  *
5*41084Swilliam  * This code is derived from software contributed to Berkeley by
6*41084Swilliam  * William Jolitz.
7*41084Swilliam  *
8*41084Swilliam  * %sccs.include.noredist.c%
9*41084Swilliam  *
10*41084Swilliam  *	@(#)sys.c	7.1 (Berkeley) 04/24/90
11*41084Swilliam  */
12*41084Swilliam 
13*41084Swilliam #include "../h/param.h"
14*41084Swilliam #include "../h/inode.h"
15*41084Swilliam #include "../h/fs.h"
16*41084Swilliam #undef KERNEL
17*41084Swilliam #include "../h/dir.h"
18*41084Swilliam #include "saio.h"
19*41084Swilliam 
20*41084Swilliam #define	DEV_IOSIZE	1024
21*41084Swilliam 
22*41084Swilliam #define DB	printf("%s:%d\n",__FILE__,__LINE__)
23*41084Swilliam ino_t	dlook();
24*41084Swilliam 
25*41084Swilliam struct dirstuff {
26*41084Swilliam 	int loc;
27*41084Swilliam 	struct iob *io;
28*41084Swilliam };
29*41084Swilliam 
30*41084Swilliam #undef	register
31*41084Swilliam 
32*41084Swilliam static
openi(n,io)33*41084Swilliam openi(n, io)
34*41084Swilliam 	register struct iob *io;
35*41084Swilliam {
36*41084Swilliam 	register struct dinode *dp;
37*41084Swilliam 	int cc;
38*41084Swilliam 
39*41084Swilliam 	io->i_offset = 0;
40*41084Swilliam 	io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff;
41*41084Swilliam 	io->i_cc = io->i_fs.fs_bsize;
42*41084Swilliam 	io->i_ma = io->i_buf;
43*41084Swilliam 	cc = devread(io);
44*41084Swilliam 	dp = (struct dinode *)io->i_buf;
45*41084Swilliam 	io->i_ino.i_ic = dp[itoo(&io->i_fs, n)].di_ic;
46*41084Swilliam 	return (cc);
47*41084Swilliam }
48*41084Swilliam 
49*41084Swilliam static
find(path,file)50*41084Swilliam find(path, file)
51*41084Swilliam 	register char *path;
52*41084Swilliam 	struct iob *file;
53*41084Swilliam {
54*41084Swilliam 	register char *q;
55*41084Swilliam 	char c;
56*41084Swilliam 	int n;
57*41084Swilliam 
58*41084Swilliam 	if (path==NULL || *path=='\0') {
59*41084Swilliam 		printf("null path\n");
60*41084Swilliam 		return (0);
61*41084Swilliam 	}
62*41084Swilliam 
63*41084Swilliam 	if (openi((ino_t) ROOTINO, file) < 0) {
64*41084Swilliam 		printf("can't read root inode\n");
65*41084Swilliam 		return (0);
66*41084Swilliam 	}
67*41084Swilliam 	while (*path) {
68*41084Swilliam 		while (*path == '/')
69*41084Swilliam 			path++;
70*41084Swilliam 		q = path;
71*41084Swilliam 		while(*q != '/' && *q != '\0')
72*41084Swilliam 			q++;
73*41084Swilliam 		c = *q;
74*41084Swilliam 		*q = '\0';
75*41084Swilliam 		if (path == q) path = "." ;	/* / means /. */
76*41084Swilliam 
77*41084Swilliam 		if ((n = dlook(path, file)) != 0) {
78*41084Swilliam 			if (c == '\0')
79*41084Swilliam 				break;
80*41084Swilliam 			if (openi(n, file) < 0)
81*41084Swilliam 				return (0);
82*41084Swilliam 			*q = c;
83*41084Swilliam 			path = q;
84*41084Swilliam 			continue;
85*41084Swilliam 		} else {
86*41084Swilliam 			printf("%s: not found\n", path);
87*41084Swilliam 			return (0);
88*41084Swilliam 		}
89*41084Swilliam 	}
90*41084Swilliam 	return (n);
91*41084Swilliam }
92*41084Swilliam 
93*41084Swilliam char b[MAXBSIZE];
94*41084Swilliam daddr_t blkno;
95*41084Swilliam 
96*41084Swilliam static daddr_t
sbmap(io,bn)97*41084Swilliam sbmap(io, bn)
98*41084Swilliam 	register struct iob *io;
99*41084Swilliam 	daddr_t bn;
100*41084Swilliam {
101*41084Swilliam 	register struct inode *ip;
102*41084Swilliam 	int i, j, sh;
103*41084Swilliam 	daddr_t nb, *bap;
104*41084Swilliam 
105*41084Swilliam 	ip = &io->i_ino;
106*41084Swilliam 	if (bn < 0) {
107*41084Swilliam 		printf("bn negative\n");
108*41084Swilliam 		return ((daddr_t)0);
109*41084Swilliam 	}
110*41084Swilliam 
111*41084Swilliam 	/*
112*41084Swilliam 	 * blocks 0..NDADDR are direct blocks
113*41084Swilliam 	 */
114*41084Swilliam 	if(bn < NDADDR) {
115*41084Swilliam 		nb = ip->i_db[bn];
116*41084Swilliam 		return (nb);
117*41084Swilliam 	}
118*41084Swilliam 
119*41084Swilliam 	/*
120*41084Swilliam 	 * addresses NIADDR have single and double indirect blocks.
121*41084Swilliam 	 * the first step is to determine how many levels of indirection.
122*41084Swilliam 	 */
123*41084Swilliam 	sh = 1;
124*41084Swilliam 	bn -= NDADDR;
125*41084Swilliam 	for (j = NIADDR; j > 0; j--) {
126*41084Swilliam 		sh *= NINDIR(&io->i_fs);
127*41084Swilliam 		if (bn < sh)
128*41084Swilliam 			break;
129*41084Swilliam 		bn -= sh;
130*41084Swilliam 	}
131*41084Swilliam 	if (j == 0) {
132*41084Swilliam 		printf("bn ovf %D\n", bn);
133*41084Swilliam 		return ((daddr_t)0);
134*41084Swilliam 	}
135*41084Swilliam 
136*41084Swilliam 	/*
137*41084Swilliam 	 * fetch the first indirect block address from the inode
138*41084Swilliam 	 */
139*41084Swilliam 	nb = ip->i_ib[NIADDR - j];
140*41084Swilliam 	if (nb == 0) {
141*41084Swilliam 		printf("bn void %D\n",bn);
142*41084Swilliam 		return ((daddr_t)0);
143*41084Swilliam 	}
144*41084Swilliam 
145*41084Swilliam 	/*
146*41084Swilliam 	 * fetch through the indirect blocks
147*41084Swilliam 	 */
148*41084Swilliam 	for (; j <= NIADDR; j++) {
149*41084Swilliam 		if (blkno != nb) {
150*41084Swilliam 			io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff;
151*41084Swilliam 			io->i_ma = b;
152*41084Swilliam 			io->i_cc = io->i_fs.fs_bsize;
153*41084Swilliam 			if (devread(io) != io->i_fs.fs_bsize) {
154*41084Swilliam 				if (io->i_error)
155*41084Swilliam 					errno = io->i_error;
156*41084Swilliam 				printf("bn %D: read error\n", io->i_bn);
157*41084Swilliam 				return ((daddr_t)0);
158*41084Swilliam 			}
159*41084Swilliam 			blkno = nb;
160*41084Swilliam 		}
161*41084Swilliam 		bap = (daddr_t *)b;
162*41084Swilliam 		sh /= NINDIR(&io->i_fs);
163*41084Swilliam 		i = (bn / sh) % NINDIR(&io->i_fs);
164*41084Swilliam 		nb = bap[i];
165*41084Swilliam 		if(nb == 0) {
166*41084Swilliam 			printf("bn void %D\n",bn);
167*41084Swilliam 			return ((daddr_t)0);
168*41084Swilliam 		}
169*41084Swilliam 	}
170*41084Swilliam 	return (nb);
171*41084Swilliam }
172*41084Swilliam 
173*41084Swilliam static ino_t
dlook(s,io)174*41084Swilliam dlook(s, io)
175*41084Swilliam 	char *s;
176*41084Swilliam 	register struct iob *io;
177*41084Swilliam {
178*41084Swilliam 	register struct direct *dp;
179*41084Swilliam 	register struct inode *ip;
180*41084Swilliam 	struct dirstuff dirp;
181*41084Swilliam 	int len;
182*41084Swilliam 
183*41084Swilliam 	if (s == NULL || *s == '\0')
184*41084Swilliam 		return (0);
185*41084Swilliam 	ip = &io->i_ino;
186*41084Swilliam 	if ((ip->i_mode&IFMT) != IFDIR) {
187*41084Swilliam 		printf("%s: not a directory\n", s);
188*41084Swilliam 		return (0);
189*41084Swilliam 	}
190*41084Swilliam 	if (ip->i_size == 0) {
191*41084Swilliam 		printf("%s: zero length directory\n", s);
192*41084Swilliam 		return (0);
193*41084Swilliam 	}
194*41084Swilliam 	len = strlen(s);
195*41084Swilliam 	dirp.loc = 0;
196*41084Swilliam 	dirp.io = io;
197*41084Swilliam 	for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
198*41084Swilliam 		if(dp->d_ino == 0)
199*41084Swilliam 			continue;
200*41084Swilliam 		if (dp->d_namlen == len && !strcmp(s, dp->d_name))
201*41084Swilliam 			return (dp->d_ino);
202*41084Swilliam 	}
203*41084Swilliam 	return (0);
204*41084Swilliam }
205*41084Swilliam 
206*41084Swilliam /*
207*41084Swilliam  * get next entry in a directory.
208*41084Swilliam  */
209*41084Swilliam struct direct *
readdir(dirp)210*41084Swilliam readdir(dirp)
211*41084Swilliam 	register struct dirstuff *dirp;
212*41084Swilliam {
213*41084Swilliam 	register struct direct *dp;
214*41084Swilliam 	register struct iob *io;
215*41084Swilliam 	daddr_t lbn, d;
216*41084Swilliam 	int off;
217*41084Swilliam 
218*41084Swilliam 	io = dirp->io;
219*41084Swilliam 	for(;;) {
220*41084Swilliam 		if (dirp->loc >= io->i_ino.i_size)
221*41084Swilliam 			return (NULL);
222*41084Swilliam 		off = blkoff(&io->i_fs, dirp->loc);
223*41084Swilliam 		if (off == 0) {
224*41084Swilliam 			lbn = lblkno(&io->i_fs, dirp->loc);
225*41084Swilliam 			d = sbmap(io, lbn);
226*41084Swilliam 			if(d == 0)
227*41084Swilliam 				return NULL;
228*41084Swilliam 			io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff;
229*41084Swilliam 			io->i_ma = io->i_buf;
230*41084Swilliam 			io->i_cc = blksize(&io->i_fs, &io->i_ino, lbn);
231*41084Swilliam 			if (devread(io) < 0) {
232*41084Swilliam 				errno = io->i_error;
233*41084Swilliam 				printf("bn %D: directory read error\n",
234*41084Swilliam 					io->i_bn);
235*41084Swilliam 				return (NULL);
236*41084Swilliam 			}
237*41084Swilliam 		}
238*41084Swilliam 		dp = (struct direct *)(io->i_buf + off);
239*41084Swilliam 		dirp->loc += dp->d_reclen;
240*41084Swilliam 		if (dp->d_ino == 0)
241*41084Swilliam 			continue;
242*41084Swilliam 		return (dp);
243*41084Swilliam 	}
244*41084Swilliam }
245*41084Swilliam 
lseek(fdesc,addr,ptr)246*41084Swilliam lseek(fdesc, addr, ptr)
247*41084Swilliam 	int fdesc, ptr;
248*41084Swilliam 	off_t addr;
249*41084Swilliam {
250*41084Swilliam 	register struct iob *io;
251*41084Swilliam 
252*41084Swilliam 	if (ptr != 0) {
253*41084Swilliam 		printf("seek not from beginning of file\n");
254*41084Swilliam 		errno = EOFFSET;
255*41084Swilliam 		return (-1);
256*41084Swilliam 	}
257*41084Swilliam 	fdesc -= 3;
258*41084Swilliam 	if (fdesc < 0 || fdesc >= NFILES ||
259*41084Swilliam 	    ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) {
260*41084Swilliam 		errno = EBADF;
261*41084Swilliam 		return (-1);
262*41084Swilliam 	}
263*41084Swilliam 	io->i_offset = addr;
264*41084Swilliam 	io->i_cc = 0;
265*41084Swilliam 	return (0);
266*41084Swilliam }
267*41084Swilliam 
getc(fdesc)268*41084Swilliam getc(fdesc)
269*41084Swilliam 	int fdesc;
270*41084Swilliam {
271*41084Swilliam 	register struct iob *io;
272*41084Swilliam 	register struct fs *fs;
273*41084Swilliam 	register char *p;
274*41084Swilliam 	int c, lbn, off, size, diff;
275*41084Swilliam 
276*41084Swilliam 
277*41084Swilliam 	errno = 0 ;
278*41084Swilliam 	if (fdesc >= 0 && fdesc <= 2)
279*41084Swilliam 		return (getchar());
280*41084Swilliam 	fdesc -= 3;
281*41084Swilliam 	if (fdesc < 0 || fdesc >= NFILES ||
282*41084Swilliam 	    ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
283*41084Swilliam 		errno = EBADF;
284*41084Swilliam 		return (-1);
285*41084Swilliam 	}
286*41084Swilliam 	p = io->i_ma;
287*41084Swilliam 	if (io->i_cc <= 0) {
288*41084Swilliam 		if ((io->i_flgs & F_FILE) != 0) {
289*41084Swilliam 			diff = io->i_ino.i_size - io->i_offset;
290*41084Swilliam 			if (diff <= 0)
291*41084Swilliam 				return (-1);
292*41084Swilliam 			fs = &io->i_fs;
293*41084Swilliam 			lbn = lblkno(fs, io->i_offset);
294*41084Swilliam 			io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff;
295*41084Swilliam 			off = blkoff(fs, io->i_offset);
296*41084Swilliam 			size = blksize(fs, &io->i_ino, lbn);
297*41084Swilliam 		} else {
298*41084Swilliam 			io->i_bn = io->i_offset / DEV_IOSIZE *
299*41084Swilliam 				(DEV_IOSIZE/DEV_BSIZE);
300*41084Swilliam 			off = io->i_offset % DEV_IOSIZE;
301*41084Swilliam 			size = DEV_IOSIZE;
302*41084Swilliam 		}
303*41084Swilliam 		io->i_ma = io->i_buf;
304*41084Swilliam 		io->i_cc = size;
305*41084Swilliam 		if (devread(io) <= 0) {
306*41084Swilliam 			errno = io->i_error;
307*41084Swilliam 			return (-1);
308*41084Swilliam 		}
309*41084Swilliam 		if ((io->i_flgs & F_FILE) != 0) {
310*41084Swilliam 			if (io->i_offset - off + size >= io->i_ino.i_size)
311*41084Swilliam 				io->i_cc = diff + off;
312*41084Swilliam 			io->i_cc -= off;
313*41084Swilliam 		}
314*41084Swilliam 		p = &io->i_buf[off];
315*41084Swilliam 	}
316*41084Swilliam 	io->i_cc--;
317*41084Swilliam 	io->i_offset++;
318*41084Swilliam 	c = (unsigned)*p++;
319*41084Swilliam 	io->i_ma = p;
320*41084Swilliam 	return (c);
321*41084Swilliam }
322*41084Swilliam 
323*41084Swilliam /* does this port?
324*41084Swilliam getw(fdesc)
325*41084Swilliam 	int fdesc;
326*41084Swilliam {
327*41084Swilliam 	register w,i;
328*41084Swilliam 	register char *cp;
329*41084Swilliam 	int val;
330*41084Swilliam 
331*41084Swilliam 	for (i = 0, val = 0, cp = &val; i < sizeof(val); i++) {
332*41084Swilliam 		w = getc(fdesc);
333*41084Swilliam 		if (w < 0) {
334*41084Swilliam 			if (i == 0)
335*41084Swilliam 				return (-1);
336*41084Swilliam 			else
337*41084Swilliam 				return (val);
338*41084Swilliam 		}
339*41084Swilliam 		*cp++ = w;
340*41084Swilliam 	}
341*41084Swilliam 	return (val);
342*41084Swilliam }
343*41084Swilliam */
344*41084Swilliam int	errno;
345*41084Swilliam 
read(fdesc,buf,count)346*41084Swilliam read(fdesc, buf, count)
347*41084Swilliam 	int fdesc, count;
348*41084Swilliam 	char *buf;
349*41084Swilliam {
350*41084Swilliam 	register int i, size;
351*41084Swilliam 	register struct iob *io;
352*41084Swilliam 	register struct fs *fs;
353*41084Swilliam 	int lbn, off;
354*41084Swilliam 
355*41084Swilliam 	errno = 0;
356*41084Swilliam 	if (fdesc >= 0 & fdesc <= 2) {
357*41084Swilliam 		i = count;
358*41084Swilliam 		do {
359*41084Swilliam 			*buf = getchar();
360*41084Swilliam 		} while (--i && *buf++ != '\n');
361*41084Swilliam 		return (count - i);
362*41084Swilliam 	}
363*41084Swilliam 	fdesc -= 3;
364*41084Swilliam 	if (fdesc < 0 || fdesc >= NFILES ||
365*41084Swilliam 	    ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
366*41084Swilliam 		errno = EBADF;
367*41084Swilliam 		return (-1);
368*41084Swilliam 	}
369*41084Swilliam 	if ((io->i_flgs&F_READ) == 0) {
370*41084Swilliam 		errno = EBADF;
371*41084Swilliam 		return (-1);
372*41084Swilliam 	}
373*41084Swilliam /*#ifndef SMALL*/
374*41084Swilliam 	if ((io->i_flgs & F_FILE) == 0) {
375*41084Swilliam #ifndef SMALL
376*41084Swilliam 		if (io->i_offset % 512 || count % 512) {
377*41084Swilliam #endif
378*41084Swilliam 			i = count;
379*41084Swilliam 			do {
380*41084Swilliam 				*buf++ = getc(fdesc+3);
381*41084Swilliam 			} while (--i);
382*41084Swilliam 			return (count - i);
383*41084Swilliam #ifndef SMALL
384*41084Swilliam 		} else {
385*41084Swilliam 			io->i_cc = count;
386*41084Swilliam 			io->i_ma = buf;
387*41084Swilliam 			io->i_bn = io->i_boff + (io->i_offset / DEV_BSIZE);
388*41084Swilliam 			i = devread(io);
389*41084Swilliam 			io->i_offset += count;
390*41084Swilliam 			if (i < 0)
391*41084Swilliam 				errno = io->i_error;
392*41084Swilliam 			return (i);
393*41084Swilliam 		}
394*41084Swilliam #endif
395*41084Swilliam 	}
396*41084Swilliam 	if (io->i_offset+count > io->i_ino.i_size)
397*41084Swilliam 		count = io->i_ino.i_size - io->i_offset;
398*41084Swilliam 	if ((i = count) <= 0)
399*41084Swilliam 		return (0);
400*41084Swilliam 	/*
401*41084Swilliam 	 * While reading full blocks, do I/O into user buffer.
402*41084Swilliam 	 * Anything else uses getc().
403*41084Swilliam 	 */
404*41084Swilliam 	fs = &io->i_fs;
405*41084Swilliam 	while (i) {
406*41084Swilliam 		off = blkoff(fs, io->i_offset);
407*41084Swilliam 		lbn = lblkno(fs, io->i_offset);
408*41084Swilliam 		size = blksize(fs, &io->i_ino, lbn);
409*41084Swilliam 		if (off == 0 && size <= i) {
410*41084Swilliam 			io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff;
411*41084Swilliam 			io->i_cc = size;
412*41084Swilliam 			io->i_ma = buf;
413*41084Swilliam 			if (devread(io) < 0) {
414*41084Swilliam 				errno = io->i_error;
415*41084Swilliam 				return (-1);
416*41084Swilliam 			}
417*41084Swilliam 			io->i_offset += size;
418*41084Swilliam 			io->i_cc = 0;
419*41084Swilliam 			buf += size;
420*41084Swilliam 			i -= size;
421*41084Swilliam 		} else {
422*41084Swilliam 			size -= off;
423*41084Swilliam 			if (size > i)
424*41084Swilliam 				size = i;
425*41084Swilliam 			i -= size;
426*41084Swilliam 			do {
427*41084Swilliam 				*buf++ = getc(fdesc+3);
428*41084Swilliam 			} while (--size);
429*41084Swilliam 		}
430*41084Swilliam 	}
431*41084Swilliam 	return (count);
432*41084Swilliam }
433*41084Swilliam 
434*41084Swilliam #ifndef SMALL
write(fdesc,buf,count)435*41084Swilliam write(fdesc, buf, count)
436*41084Swilliam 	int fdesc, count;
437*41084Swilliam 	char *buf;
438*41084Swilliam {
439*41084Swilliam 	register int i;
440*41084Swilliam 	register struct iob *file;
441*41084Swilliam 
442*41084Swilliam 	errno = 0;
443*41084Swilliam 	if (fdesc >= 0 && fdesc <= 2) {
444*41084Swilliam 		i = count;
445*41084Swilliam 		while (i--)
446*41084Swilliam 			putchar(*buf++);
447*41084Swilliam 		return (count);
448*41084Swilliam 	}
449*41084Swilliam 	fdesc -= 3;
450*41084Swilliam 	if (fdesc < 0 || fdesc >= NFILES ||
451*41084Swilliam 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
452*41084Swilliam 		errno = EBADF;
453*41084Swilliam 		return (-1);
454*41084Swilliam 	}
455*41084Swilliam 	if ((file->i_flgs&F_WRITE) == 0) {
456*41084Swilliam 		errno = EBADF;
457*41084Swilliam 		return (-1);
458*41084Swilliam 	}
459*41084Swilliam 	file->i_cc = count;
460*41084Swilliam 	file->i_ma = buf;
461*41084Swilliam 	file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
462*41084Swilliam 	i = devwrite(file);
463*41084Swilliam 	file->i_offset += count;
464*41084Swilliam 	if (i < 0)
465*41084Swilliam 		errno = file->i_error;
466*41084Swilliam 	return (i);
467*41084Swilliam }
468*41084Swilliam #endif
469*41084Swilliam 
470*41084Swilliam int	openfirst = 1;
471*41084Swilliam int	opendev;	/* last device opened; for boot to set bootdev */
472*41084Swilliam 
open(str,how)473*41084Swilliam open(str, how)
474*41084Swilliam 	char *str;
475*41084Swilliam 	int how;
476*41084Swilliam {
477*41084Swilliam 	register char *cp;
478*41084Swilliam 	int i;
479*41084Swilliam 	register struct iob *file;
480*41084Swilliam 	register struct devsw *dp;
481*41084Swilliam 	int fdesc;
482*41084Swilliam 	long atol();
483*41084Swilliam 	extern int bootdev;
484*41084Swilliam 
485*41084Swilliam 	if (openfirst) {
486*41084Swilliam 		for (i = 0; i < NFILES; i++)
487*41084Swilliam 			iob[i].i_flgs = 0;
488*41084Swilliam 		openfirst = 0;
489*41084Swilliam 	}
490*41084Swilliam 
491*41084Swilliam 	for (fdesc = 0; fdesc < NFILES; fdesc++)
492*41084Swilliam 		if (iob[fdesc].i_flgs == 0)
493*41084Swilliam 			goto gotfile;
494*41084Swilliam 	_stop("no more file slots");
495*41084Swilliam gotfile:
496*41084Swilliam 	(file = &iob[fdesc])->i_flgs |= F_ALLOC;
497*41084Swilliam 
498*41084Swilliam 	for (cp = str; *cp && *cp != '/' && *cp != ':'; cp++)
499*41084Swilliam 			;
500*41084Swilliam 	if (*cp != ':') {
501*41084Swilliam 		/* default bootstrap unit and device */
502*41084Swilliam 		file->i_ino.i_dev = bootdev;
503*41084Swilliam 		cp = str;
504*41084Swilliam 	} else {
505*41084Swilliam # define isdigit(n)	((n>='0') && (n<='9'))
506*41084Swilliam 		/*
507*41084Swilliam 	 	 * syntax for possible device name:
508*41084Swilliam 	 	 *	<alpha-string><digit-string><letter>:
509*41084Swilliam 	 	 */
510*41084Swilliam 		for (cp = str; *cp != ':' && !isdigit(*cp); cp++)
511*41084Swilliam 			;
512*41084Swilliam 		for (dp = devsw; dp->dv_name; dp++) {
513*41084Swilliam 			if (!strncmp(str, dp->dv_name,cp-str))
514*41084Swilliam 				goto gotdev;
515*41084Swilliam 		}
516*41084Swilliam 		printf("unknown device\n");
517*41084Swilliam 		file->i_flgs = 0;
518*41084Swilliam 		errno = ENXIO;
519*41084Swilliam 		return (-1);
520*41084Swilliam 	gotdev:
521*41084Swilliam 		i = 0;
522*41084Swilliam 		while (*cp >= '0' && *cp <= '9')
523*41084Swilliam 			i = i * 10 + *cp++ - '0';
524*41084Swilliam 		if (i < 0 || i > 255) {
525*41084Swilliam 			printf("minor device number out of range (0-255)\n");
526*41084Swilliam 			file->i_flgs = 0;
527*41084Swilliam 			errno = EUNIT;
528*41084Swilliam 			return (-1);
529*41084Swilliam 		}
530*41084Swilliam 		if (*cp >= 'a' && *cp <= 'h') {
531*41084Swilliam 			if (i > 31) {
532*41084Swilliam 				printf("unit number out of range (0-31)\n");
533*41084Swilliam 				file->i_flgs = 0;
534*41084Swilliam 				errno = EUNIT;
535*41084Swilliam 				return (-1);
536*41084Swilliam 			}
537*41084Swilliam 			i = make_minor(i, *cp++ - 'a');
538*41084Swilliam 		}
539*41084Swilliam 
540*41084Swilliam 		if (*cp++ != ':') {
541*41084Swilliam 			printf("incorrect device specification\n");
542*41084Swilliam 			file->i_flgs = 0;
543*41084Swilliam 			errno = EOFFSET;
544*41084Swilliam 			return (-1);
545*41084Swilliam 		}
546*41084Swilliam 		file->i_ino.i_dev = makedev(dp-devsw, i);
547*41084Swilliam 	}
548*41084Swilliam 	file->i_boff = 0;
549*41084Swilliam 	devopen(file);
550*41084Swilliam 	opendev = file->i_ino.i_dev;
551*41084Swilliam 	if (cp != str && *cp == '\0') {
552*41084Swilliam 		file->i_flgs |= how+1;
553*41084Swilliam 		file->i_cc = 0;
554*41084Swilliam 		file->i_offset = 0;
555*41084Swilliam 		return (fdesc+3);
556*41084Swilliam 	}
557*41084Swilliam 	file->i_ma = file->i_buf;
558*41084Swilliam 	file->i_cc = SBSIZE;
559*41084Swilliam 	file->i_bn = SBLOCK + file->i_boff;
560*41084Swilliam 	file->i_offset = 0;
561*41084Swilliam 	if (devread(file) < 0) {
562*41084Swilliam 		errno = file->i_error;
563*41084Swilliam 		printf("super block read error\n");
564*41084Swilliam 		return (-1);
565*41084Swilliam 	}
566*41084Swilliam 	file->i_fs = *(struct fs *)(file->i_buf);
567*41084Swilliam 	if ((i = find(cp, file)) == 0) {
568*41084Swilliam 		file->i_flgs = 0;
569*41084Swilliam 		errno = ESRCH;
570*41084Swilliam 		return (-1);
571*41084Swilliam 	}
572*41084Swilliam 	if (how != 0) {
573*41084Swilliam 		printf("can't write files yet.. sorry\n");
574*41084Swilliam 		file->i_flgs = 0;
575*41084Swilliam 		errno = EIO;
576*41084Swilliam 		return (-1);
577*41084Swilliam 	}
578*41084Swilliam 	if (openi(i, file) < 0) {
579*41084Swilliam 		errno = file->i_error;
580*41084Swilliam 		return (-1);
581*41084Swilliam 	}
582*41084Swilliam 	file->i_offset = 0;
583*41084Swilliam 	file->i_cc = 0;
584*41084Swilliam 	file->i_flgs |= F_FILE | (how+1);
585*41084Swilliam 	return (fdesc+3);
586*41084Swilliam }
587*41084Swilliam 
close(fdesc)588*41084Swilliam close(fdesc)
589*41084Swilliam 	int fdesc;
590*41084Swilliam {
591*41084Swilliam 	struct iob *file;
592*41084Swilliam 
593*41084Swilliam 	fdesc -= 3;
594*41084Swilliam 	if (fdesc < 0 || fdesc >= NFILES ||
595*41084Swilliam 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
596*41084Swilliam 		errno = EBADF;
597*41084Swilliam 		return (-1);
598*41084Swilliam 	}
599*41084Swilliam 	if ((file->i_flgs&F_FILE) == 0)
600*41084Swilliam 		devclose(file);
601*41084Swilliam 	file->i_flgs = 0;
602*41084Swilliam 	return (0);
603*41084Swilliam }
604*41084Swilliam 
605*41084Swilliam #ifndef SMALL
ioctl(fdesc,cmd,arg)606*41084Swilliam ioctl(fdesc, cmd, arg)
607*41084Swilliam 	int fdesc, cmd;
608*41084Swilliam 	char *arg;
609*41084Swilliam {
610*41084Swilliam 	register struct iob *file;
611*41084Swilliam 	int error = 0;
612*41084Swilliam 
613*41084Swilliam 	fdesc -= 3;
614*41084Swilliam 	if (fdesc < 0 || fdesc >= NFILES ||
615*41084Swilliam 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
616*41084Swilliam 		errno = EBADF;
617*41084Swilliam 		return (-1);
618*41084Swilliam 	}
619*41084Swilliam 	switch (cmd) {
620*41084Swilliam 
621*41084Swilliam 	case SAIOHDR:
622*41084Swilliam 		file->i_flgs |= F_HDR;
623*41084Swilliam 		break;
624*41084Swilliam 
625*41084Swilliam 	case SAIOCHECK:
626*41084Swilliam 		file->i_flgs |= F_CHECK;
627*41084Swilliam 		break;
628*41084Swilliam 
629*41084Swilliam 	case SAIOHCHECK:
630*41084Swilliam 		file->i_flgs |= F_HCHECK;
631*41084Swilliam 		break;
632*41084Swilliam 
633*41084Swilliam 	case SAIONOBAD:
634*41084Swilliam 		file->i_flgs |= F_NBSF;
635*41084Swilliam 		break;
636*41084Swilliam 
637*41084Swilliam 	case SAIODOBAD:
638*41084Swilliam 		file->i_flgs &= ~F_NBSF;
639*41084Swilliam 		break;
640*41084Swilliam 
641*41084Swilliam 	case SAIOECCLIM:
642*41084Swilliam 		file->i_flgs |= F_ECCLM;
643*41084Swilliam 		break;
644*41084Swilliam 
645*41084Swilliam 	case SAIOECCUNL:
646*41084Swilliam 		file->i_flgs &= ~F_ECCLM;
647*41084Swilliam 		break;
648*41084Swilliam 
649*41084Swilliam 	case SAIOSEVRE:
650*41084Swilliam 		file->i_flgs |= F_SEVRE;
651*41084Swilliam 		break;
652*41084Swilliam 
653*41084Swilliam 	case SAIONSEVRE:
654*41084Swilliam 		file->i_flgs &= ~F_SEVRE;
655*41084Swilliam 		break;
656*41084Swilliam 
657*41084Swilliam 	default:
658*41084Swilliam 		error = devioctl(file, cmd, arg);
659*41084Swilliam 		break;
660*41084Swilliam 	}
661*41084Swilliam 	if (error < 0)
662*41084Swilliam 		errno = file->i_error;
663*41084Swilliam 	return (error);
664*41084Swilliam }
665*41084Swilliam #endif
666*41084Swilliam 
_stop(s)667*41084Swilliam _stop(s)
668*41084Swilliam 	char *s;
669*41084Swilliam {
670*41084Swilliam 	int i;
671*41084Swilliam 
672*41084Swilliam 	for (i = 0; i < NFILES; i++)
673*41084Swilliam 		if (iob[i].i_flgs != 0)
674*41084Swilliam 			close(i);
675*41084Swilliam 	printf("%s\n", s);
676*41084Swilliam 	_rtt();
677*41084Swilliam }
678*41084Swilliam 
trap(ps)679*41084Swilliam trap(ps)
680*41084Swilliam 	int ps;
681*41084Swilliam {
682*41084Swilliam 	printf("trap %o\n", ps);
683*41084Swilliam 	for (;;)
684*41084Swilliam 		;
685*41084Swilliam }
686