xref: /csrg-svn/sys/stand.att/sys.c (revision 2391)
1*2391Stoy /*	sys.c	4.2	02/09/81	*/
2327Sbill 
3327Sbill #include <sys/param.h>
4327Sbill #include <sys/ino.h>
5327Sbill #include <sys/inode.h>
6327Sbill #include <sys/filsys.h>
7327Sbill #include <sys/dir.h>
8327Sbill #include "saio.h"
9327Sbill 
10327Sbill ino_t	dlook();
11327Sbill 
12327Sbill static
13327Sbill openi(n,io)
14327Sbill register struct iob *io;
15327Sbill {
16327Sbill 	register struct dinode *dp;
17327Sbill 
18327Sbill 	io->i_offset = 0;
19327Sbill 	io->i_bn = fsbtodb(itod(n)) + io->i_boff;
20327Sbill 	io->i_cc = BSIZE;
21327Sbill 	io->i_ma = io->i_buf;
22327Sbill 	devread(io);
23327Sbill 
24327Sbill 	dp = (struct dinode *)io->i_buf;
25327Sbill 	dp = &dp[itoo(n)];
26327Sbill 	io->i_ino.i_number = n;
27327Sbill 	io->i_ino.i_mode = dp->di_mode;
28327Sbill 	io->i_ino.i_size = dp->di_size;
29327Sbill 	l3tol((char *)io->i_ino.i_un.i_addr, (char *)dp->di_addr, NADDR);
30327Sbill }
31327Sbill 
32327Sbill static
33327Sbill find(path, file)
34327Sbill register char *path;
35327Sbill struct iob *file;
36327Sbill {
37327Sbill 	register char *q;
38327Sbill 	char c;
39327Sbill 	int n;
40327Sbill 
41327Sbill 	if (path==NULL || *path=='\0') {
42327Sbill 		printf("null path\n");
43327Sbill 		return(0);
44327Sbill 	}
45327Sbill 
46327Sbill 	openi((ino_t) ROOTINO, file);
47327Sbill 	while (*path) {
48327Sbill 		while (*path == '/')
49327Sbill 			path++;
50327Sbill 		q = path;
51327Sbill 		while(*q != '/' && *q != '\0')
52327Sbill 			q++;
53327Sbill 		c = *q;
54327Sbill 		*q = '\0';
55327Sbill 
56327Sbill 		if ((n=dlook(path, file))!=0) {
57327Sbill 			if (c=='\0')
58327Sbill 				break;
59327Sbill 			openi(n, file);
60327Sbill 			*q = c;
61327Sbill 			path = q;
62327Sbill 			continue;
63327Sbill 		} else {
64327Sbill 			printf("%s not found\n",path);
65327Sbill 			return(0);
66327Sbill 		}
67327Sbill 	}
68327Sbill 	return(n);
69327Sbill }
70327Sbill 
71327Sbill static daddr_t
72327Sbill sbmap(io, bn)
73327Sbill register struct iob *io;
74327Sbill daddr_t bn;
75327Sbill {
76327Sbill 	register i;
77327Sbill 	register struct inode *ip;
78327Sbill 	int j, sh;
79327Sbill 	daddr_t nb, *bap;
80327Sbill 	int ibn = bn;
81327Sbill 
82327Sbill 	ip = &io->i_ino;
83327Sbill 	if(bn < 0) {
84327Sbill 		printf("bn negative\n");
85327Sbill 		return((daddr_t)0);
86327Sbill 	}
87327Sbill 
88327Sbill 	/*
89327Sbill 	 * blocks 0..NADDR-4 are direct blocks
90327Sbill 	 */
91327Sbill 	if(bn < NADDR-3) {
92327Sbill 		i = bn;
93327Sbill 		nb = ip->i_un.i_addr[i];
94327Sbill 		return(nb);
95327Sbill 	}
96327Sbill 
97327Sbill 	/*
98327Sbill 	 * addresses NADDR-3, NADDR-2, and NADDR-1
99327Sbill 	 * have single, double, triple indirect blocks.
100327Sbill 	 * the first step is to determine
101327Sbill 	 * how many levels of indirection.
102327Sbill 	 */
103327Sbill 	sh = 0;
104327Sbill 	nb = 1;
105327Sbill 	bn -= NADDR-3;
106327Sbill 	for(j=3; j>0; j--) {
107327Sbill 		sh += NSHIFT;
108327Sbill 		nb <<= NSHIFT;
109327Sbill 		if(bn < nb)
110327Sbill 			break;
111327Sbill 		bn -= nb;
112327Sbill 	}
113327Sbill 	if(j == 0) {
114327Sbill 		printf("bn ovf %D\n",bn);
115327Sbill 		return((daddr_t)0);
116327Sbill 	}
117327Sbill 
118327Sbill 	/*
119327Sbill 	 * fetch the address from the inode
120327Sbill 	 */
121327Sbill 	nb = ip->i_un.i_addr[NADDR-j];
122327Sbill 	if(nb == 0) {
123327Sbill 		printf("bn void %D\n",bn);
124327Sbill 		return((daddr_t)0);
125327Sbill 	}
126327Sbill 
127327Sbill 	/*
128327Sbill 	 * fetch through the indirect blocks
129327Sbill 	 */
130327Sbill 	for(; j<=3; j++) {
131327Sbill 		if (blknos[j] != nb) {
132327Sbill 			io->i_bn = fsbtodb(nb) + io->i_boff;
133327Sbill 			io->i_ma = b[j];
134327Sbill 			io->i_cc = BSIZE;
135327Sbill 			devread(io);
136327Sbill 			bap = (daddr_t *)b[j];
137327Sbill 			blknos[j] = nb;
138327Sbill 		}
139327Sbill 		bap = (daddr_t *)b[j];
140327Sbill 		sh -= NSHIFT;
141327Sbill 		i = (bn>>sh) & NMASK;
142327Sbill 		nb = bap[i];
143327Sbill 		if(nb == 0) {
144327Sbill 			printf("bn void %D\n",bn);
145327Sbill 			return((daddr_t)0);
146327Sbill 		}
147327Sbill 	}
148327Sbill 	return(nb);
149327Sbill }
150327Sbill 
151327Sbill static ino_t
152327Sbill dlook(s, io)
153327Sbill char *s;
154327Sbill register struct iob *io;
155327Sbill {
156327Sbill 	register struct direct *dp;
157327Sbill 	register struct inode *ip;
158327Sbill 	daddr_t bn;
159327Sbill 	int n,dc;
160327Sbill 
161327Sbill 	if (s==NULL || *s=='\0')
162327Sbill 		return(0);
163327Sbill 	ip = &io->i_ino;
164327Sbill 	if ((ip->i_mode&IFMT)!=IFDIR) {
165327Sbill 		printf("not a directory\n");
166327Sbill 		return(0);
167327Sbill 	}
168327Sbill 
169327Sbill 	n = ip->i_size/sizeof(struct direct);
170327Sbill 
171327Sbill 	if (n==0) {
172327Sbill 		printf("zero length directory\n");
173327Sbill 		return(0);
174327Sbill 	}
175327Sbill 
176327Sbill 	dc = BSIZE;
177327Sbill 	bn = (daddr_t)0;
178327Sbill 	while(n--) {
179327Sbill 		if (++dc >= BSIZE/sizeof(struct direct)) {
180327Sbill 			io->i_bn = fsbtodb(sbmap(io, bn++)) + io->i_boff;
181327Sbill 			io->i_ma = io->i_buf;
182327Sbill 			io->i_cc = BSIZE;
183327Sbill 			devread(io);
184327Sbill 			dp = (struct direct *)io->i_buf;
185327Sbill 			dc = 0;
186327Sbill 		}
187327Sbill 
188327Sbill 		if (match(s, dp->d_name))
189327Sbill 			return(dp->d_ino);
190327Sbill 		dp++;
191327Sbill 	}
192327Sbill 	return(0);
193327Sbill }
194327Sbill 
195327Sbill static
196327Sbill match(s1,s2)
197327Sbill register char *s1,*s2;
198327Sbill {
199327Sbill 	register cc;
200327Sbill 
201327Sbill 	cc = DIRSIZ;
202327Sbill 	while (cc--) {
203327Sbill 		if (*s1 != *s2)
204327Sbill 			return(0);
205327Sbill 		if (*s1++ && *s2++)
206327Sbill 			continue; else
207327Sbill 			return(1);
208327Sbill 	}
209327Sbill 	return(1);
210327Sbill }
211327Sbill 
212327Sbill lseek(fdesc, addr, ptr)
213327Sbill int	fdesc;
214327Sbill off_t	addr;
215327Sbill int	ptr;
216327Sbill {
217327Sbill 	register struct iob *io;
218327Sbill 
219327Sbill 	if (ptr != 0) {
220327Sbill 		printf("Seek not from beginning of file\n");
221327Sbill 		return(-1);
222327Sbill 	}
223327Sbill 	fdesc -= 3;
224327Sbill 	if (fdesc < 0 || fdesc >= NFILES || ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
225327Sbill 		return(-1);
226327Sbill 	io->i_offset = addr;
227327Sbill 	io->i_bn = fsbtodb(addr/BSIZE) + io->i_boff;
228327Sbill 	io->i_cc = 0;
229327Sbill 	return(0);
230327Sbill }
231327Sbill 
232327Sbill getc(fdesc)
233327Sbill int	fdesc;
234327Sbill {
235327Sbill 	register struct iob *io;
236327Sbill 	register char *p;
237327Sbill 	register  c;
238327Sbill 	int off;
239327Sbill 
240327Sbill 
241327Sbill 	if (fdesc >= 0 && fdesc <= 2)
242327Sbill 		return(getchar());
243327Sbill 	fdesc -= 3;
244327Sbill 	if (fdesc < 0 || fdesc >= NFILES || ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
245327Sbill 		return(-1);
246327Sbill 	p = io->i_ma;
247327Sbill 	if (io->i_cc <= 0) {
248327Sbill 		io->i_bn = fsbtodb(io->i_offset/(off_t)BSIZE);
249327Sbill 		if (io->i_flgs&F_FILE)
250327Sbill 			io->i_bn = fsbtodb(sbmap(io, dbtofsb(io->i_bn))) + io->i_boff;
251327Sbill 		io->i_ma = io->i_buf;
252327Sbill 		io->i_cc = BSIZE;
253327Sbill 		devread(io);
254327Sbill 		if (io->i_flgs&F_FILE) {
255327Sbill 			off = io->i_offset % (off_t)BSIZE;
256327Sbill 			if (io->i_offset+(BSIZE-off) >= io->i_ino.i_size)
257327Sbill 				io->i_cc = io->i_ino.i_size - io->i_offset + off;
258327Sbill 			io->i_cc -= off;
259327Sbill 			if (io->i_cc <= 0)
260327Sbill 				return(-1);
261327Sbill 		} else
262327Sbill 			off = 0;
263327Sbill 		p = &io->i_buf[off];
264327Sbill 	}
265327Sbill 	io->i_cc--;
266327Sbill 	io->i_offset++;
267327Sbill 	c = (unsigned)*p++;
268327Sbill 	io->i_ma = p;
269327Sbill 	return(c);
270327Sbill }
271327Sbill /* does this port?
272327Sbill getw(fdesc)
273327Sbill int	fdesc;
274327Sbill {
275327Sbill 	register w,i;
276327Sbill 	register char *cp;
277327Sbill 	int val;
278327Sbill 
279327Sbill 	for (i = 0, val = 0, cp = &val; i < sizeof(val); i++) {
280327Sbill 		w = getc(fdesc);
281327Sbill 		if (w < 0) {
282327Sbill 			if (i == 0)
283327Sbill 				return(-1);
284327Sbill 			else
285327Sbill 				return(val);
286327Sbill 		}
287327Sbill 		*cp++ = w;
288327Sbill 	}
289327Sbill 	return(val);
290327Sbill }
291327Sbill */
292327Sbill 
293327Sbill read(fdesc, buf, count)
294327Sbill int	fdesc;
295327Sbill char	*buf;
296327Sbill int	count;
297327Sbill {
298327Sbill 	register i;
299327Sbill 	register struct iob *file;
300327Sbill 
301327Sbill 	if (fdesc >= 0 & fdesc <= 2) {
302327Sbill 		i = count;
303327Sbill 		do {
304327Sbill 			*buf = getchar();
305327Sbill 		} while (--i && *buf++ != '\n');
306327Sbill 		return(count - i);
307327Sbill 	}
308327Sbill 	fdesc -= 3;
309327Sbill 	if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
310327Sbill 		return(-1);
311327Sbill 	if ((file->i_flgs&F_READ) == 0)
312327Sbill 		return(-1);
313327Sbill 	if ((file->i_flgs&F_FILE) == 0) {
314327Sbill 		file->i_cc = count;
315327Sbill 		file->i_ma = buf;
316327Sbill 		i = devread(file);
317327Sbill 		file->i_bn += CLSIZE;
318327Sbill 		return(i);
319327Sbill 	}
320327Sbill 	else {
321327Sbill 		if (file->i_offset+count > file->i_ino.i_size)
322327Sbill 			count = file->i_ino.i_size - file->i_offset;
323327Sbill 		if ((i = count) <= 0)
324327Sbill 			return(0);
325327Sbill 		do {
326327Sbill 			*buf++ = getc(fdesc+3);
327327Sbill 		} while (--i);
328327Sbill 		return(count);
329327Sbill 	}
330327Sbill }
331327Sbill 
332327Sbill write(fdesc, buf, count)
333327Sbill int	fdesc;
334327Sbill char	*buf;
335327Sbill int	count;
336327Sbill {
337327Sbill 	register i;
338327Sbill 	register struct iob *file;
339327Sbill 
340327Sbill 	if (fdesc >= 0 && fdesc <= 2) {
341327Sbill 		i = count;
342327Sbill 		while (i--)
343327Sbill 			putchar(*buf++);
344327Sbill 		return(count);
345327Sbill 	}
346327Sbill 	fdesc -= 3;
347327Sbill 	if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
348327Sbill 		return(-1);
349327Sbill 	if ((file->i_flgs&F_WRITE) == 0)
350327Sbill 		return(-1);
351327Sbill 	file->i_cc = count;
352327Sbill 	file->i_ma = buf;
353327Sbill 	i = devwrite(file);
354327Sbill 	file->i_bn += CLSIZE;
355327Sbill 	return(i);
356327Sbill }
357327Sbill 
358327Sbill open(str, how)
359327Sbill char *str;
360327Sbill int	how;
361327Sbill {
362327Sbill 	register char *cp;
363327Sbill 	int i;
364327Sbill 	register struct iob *file;
365327Sbill 	register struct devsw *dp;
366327Sbill 	int	fdesc;
367327Sbill 	static first = 1;
368327Sbill 	long	atol();
369327Sbill 
370327Sbill 	if (first) {
371327Sbill 		for (i = 0; i < NFILES; i++)
372327Sbill 			iob[i].i_flgs = 0;
373327Sbill 		first = 0;
374327Sbill 	}
375327Sbill 
376327Sbill 	for (fdesc = 0; fdesc < NFILES; fdesc++)
377327Sbill 		if (iob[fdesc].i_flgs == 0)
378327Sbill 			goto gotfile;
379327Sbill 	_stop("No more file slots");
380327Sbill gotfile:
381327Sbill 	(file = &iob[fdesc])->i_flgs |= F_ALLOC;
382327Sbill 
383327Sbill 	for (cp = str; *cp && *cp != '('; cp++)
384327Sbill 			;
385327Sbill 	if (*cp != '(') {
386327Sbill 		printf("Bad device\n");
387327Sbill 		file->i_flgs = 0;
388327Sbill 		return(-1);
389327Sbill 	}
390327Sbill 	*cp++ = '\0';
391327Sbill 	for (dp = devsw; dp->dv_name; dp++) {
392327Sbill 		if (match(str, dp->dv_name))
393327Sbill 			goto gotdev;
394327Sbill 	}
395327Sbill 	printf("Unknown device\n");
396327Sbill 	file->i_flgs = 0;
397327Sbill 	return(-1);
398327Sbill gotdev:
399327Sbill 	*(cp-1) = '(';
400327Sbill 	file->i_ino.i_dev = dp-devsw;
401327Sbill 	file->i_unit = *cp++ - '0';
402327Sbill 	if (file->i_unit < 0 || file->i_unit > 7) {
403327Sbill 		printf("Bad unit specifier\n");
404327Sbill 		file->i_flgs = 0;
405327Sbill 		return(-1);
406327Sbill 	}
407327Sbill 	if (*cp++ != ',') {
408327Sbill badoff:
409327Sbill 		printf("Missing offset specification\n");
410327Sbill 		file->i_flgs = 0;
411327Sbill 		return(-1);
412327Sbill 	}
413327Sbill 	file->i_boff = atol(cp);
414327Sbill 	for (;;) {
415327Sbill 		if (*cp == ')')
416327Sbill 			break;
417327Sbill 		if (*cp++)
418327Sbill 			continue;
419327Sbill 		goto badoff;
420327Sbill 	}
421327Sbill 	devopen(file);
422327Sbill 	if (*++cp == '\0') {
423327Sbill 		file->i_flgs |= how+1;
424327Sbill 		file->i_cc = 0;
425327Sbill 		file->i_offset = 0;
426327Sbill 		return(fdesc+3);
427327Sbill 	}
428327Sbill 	if ((i = find(cp, file)) == 0) {
429327Sbill 		file->i_flgs = 0;
430327Sbill 		return(-1);
431327Sbill 	}
432327Sbill 	if (how != 0) {
433327Sbill 		printf("Can't write files yet.. Sorry\n");
434327Sbill 		file->i_flgs = 0;
435327Sbill 		return(-1);
436327Sbill 	}
437327Sbill 	openi(i, file);
438327Sbill 	file->i_offset = 0;
439327Sbill 	file->i_cc = 0;
440327Sbill 	file->i_flgs |= F_FILE | (how+1);
441327Sbill 	return(fdesc+3);
442327Sbill }
443327Sbill 
444327Sbill close(fdesc)
445327Sbill int	fdesc;
446327Sbill {
447327Sbill 	struct iob *file;
448327Sbill 
449327Sbill 	fdesc -= 3;
450327Sbill 	if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
451327Sbill 		return(-1);
452327Sbill 	if ((file->i_flgs&F_FILE) == 0)
453327Sbill 		devclose(file);
454327Sbill 	file->i_flgs = 0;
455327Sbill 	return(0);
456327Sbill }
457327Sbill 
458327Sbill exit()
459327Sbill {
460327Sbill 	_stop("Exit called");
461327Sbill }
462327Sbill 
463327Sbill _stop(s)
464327Sbill char	*s;
465327Sbill {
466*2391Stoy 	int i;
467*2391Stoy 
468*2391Stoy 	for (i = 0; i < NFILES; i++)
469*2391Stoy 		if (iob[i].i_flgs != 0)
470*2391Stoy 			close(i);
471327Sbill 	printf("%s\n", s);
472327Sbill 	_rtt();
473327Sbill }
474327Sbill 
475327Sbill trap(ps)
476327Sbill int ps;
477327Sbill {
478327Sbill 	printf("Trap %o\n", ps);
479327Sbill 	for (;;)
480327Sbill 		;
481327Sbill }
482