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