xref: /csrg-svn/sys/stand.att/sys.c (revision 327)
1*327Sbill /*	sys.c	1.1	06/28/80	*/
2*327Sbill 
3*327Sbill #include <sys/param.h>
4*327Sbill #include <sys/ino.h>
5*327Sbill #include <sys/inode.h>
6*327Sbill #include <sys/filsys.h>
7*327Sbill #include <sys/dir.h>
8*327Sbill #include "saio.h"
9*327Sbill 
10*327Sbill ino_t	dlook();
11*327Sbill 
12*327Sbill static
13*327Sbill openi(n,io)
14*327Sbill register struct iob *io;
15*327Sbill {
16*327Sbill 	register struct dinode *dp;
17*327Sbill 
18*327Sbill 	io->i_offset = 0;
19*327Sbill 	io->i_bn = fsbtodb(itod(n)) + io->i_boff;
20*327Sbill 	io->i_cc = BSIZE;
21*327Sbill 	io->i_ma = io->i_buf;
22*327Sbill 	devread(io);
23*327Sbill 
24*327Sbill 	dp = (struct dinode *)io->i_buf;
25*327Sbill 	dp = &dp[itoo(n)];
26*327Sbill 	io->i_ino.i_number = n;
27*327Sbill 	io->i_ino.i_mode = dp->di_mode;
28*327Sbill 	io->i_ino.i_size = dp->di_size;
29*327Sbill 	l3tol((char *)io->i_ino.i_un.i_addr, (char *)dp->di_addr, NADDR);
30*327Sbill }
31*327Sbill 
32*327Sbill static
33*327Sbill find(path, file)
34*327Sbill register char *path;
35*327Sbill struct iob *file;
36*327Sbill {
37*327Sbill 	register char *q;
38*327Sbill 	char c;
39*327Sbill 	int n;
40*327Sbill 
41*327Sbill 	if (path==NULL || *path=='\0') {
42*327Sbill 		printf("null path\n");
43*327Sbill 		return(0);
44*327Sbill 	}
45*327Sbill 
46*327Sbill 	openi((ino_t) ROOTINO, file);
47*327Sbill 	while (*path) {
48*327Sbill 		while (*path == '/')
49*327Sbill 			path++;
50*327Sbill 		q = path;
51*327Sbill 		while(*q != '/' && *q != '\0')
52*327Sbill 			q++;
53*327Sbill 		c = *q;
54*327Sbill 		*q = '\0';
55*327Sbill 
56*327Sbill 		if ((n=dlook(path, file))!=0) {
57*327Sbill 			if (c=='\0')
58*327Sbill 				break;
59*327Sbill 			openi(n, file);
60*327Sbill 			*q = c;
61*327Sbill 			path = q;
62*327Sbill 			continue;
63*327Sbill 		} else {
64*327Sbill 			printf("%s not found\n",path);
65*327Sbill 			return(0);
66*327Sbill 		}
67*327Sbill 	}
68*327Sbill 	return(n);
69*327Sbill }
70*327Sbill 
71*327Sbill static daddr_t
72*327Sbill sbmap(io, bn)
73*327Sbill register struct iob *io;
74*327Sbill daddr_t bn;
75*327Sbill {
76*327Sbill 	register i;
77*327Sbill 	register struct inode *ip;
78*327Sbill 	int j, sh;
79*327Sbill 	daddr_t nb, *bap;
80*327Sbill 	int ibn = bn;
81*327Sbill 
82*327Sbill 	ip = &io->i_ino;
83*327Sbill 	if(bn < 0) {
84*327Sbill 		printf("bn negative\n");
85*327Sbill 		return((daddr_t)0);
86*327Sbill 	}
87*327Sbill 
88*327Sbill 	/*
89*327Sbill 	 * blocks 0..NADDR-4 are direct blocks
90*327Sbill 	 */
91*327Sbill 	if(bn < NADDR-3) {
92*327Sbill 		i = bn;
93*327Sbill 		nb = ip->i_un.i_addr[i];
94*327Sbill 		return(nb);
95*327Sbill 	}
96*327Sbill 
97*327Sbill 	/*
98*327Sbill 	 * addresses NADDR-3, NADDR-2, and NADDR-1
99*327Sbill 	 * have single, double, triple indirect blocks.
100*327Sbill 	 * the first step is to determine
101*327Sbill 	 * how many levels of indirection.
102*327Sbill 	 */
103*327Sbill 	sh = 0;
104*327Sbill 	nb = 1;
105*327Sbill 	bn -= NADDR-3;
106*327Sbill 	for(j=3; j>0; j--) {
107*327Sbill 		sh += NSHIFT;
108*327Sbill 		nb <<= NSHIFT;
109*327Sbill 		if(bn < nb)
110*327Sbill 			break;
111*327Sbill 		bn -= nb;
112*327Sbill 	}
113*327Sbill 	if(j == 0) {
114*327Sbill 		printf("bn ovf %D\n",bn);
115*327Sbill 		return((daddr_t)0);
116*327Sbill 	}
117*327Sbill 
118*327Sbill 	/*
119*327Sbill 	 * fetch the address from the inode
120*327Sbill 	 */
121*327Sbill 	nb = ip->i_un.i_addr[NADDR-j];
122*327Sbill 	if(nb == 0) {
123*327Sbill 		printf("bn void %D\n",bn);
124*327Sbill 		return((daddr_t)0);
125*327Sbill 	}
126*327Sbill 
127*327Sbill 	/*
128*327Sbill 	 * fetch through the indirect blocks
129*327Sbill 	 */
130*327Sbill 	for(; j<=3; j++) {
131*327Sbill 		if (blknos[j] != nb) {
132*327Sbill 			io->i_bn = fsbtodb(nb) + io->i_boff;
133*327Sbill 			io->i_ma = b[j];
134*327Sbill 			io->i_cc = BSIZE;
135*327Sbill 			devread(io);
136*327Sbill 			bap = (daddr_t *)b[j];
137*327Sbill 			blknos[j] = nb;
138*327Sbill 		}
139*327Sbill 		bap = (daddr_t *)b[j];
140*327Sbill 		sh -= NSHIFT;
141*327Sbill 		i = (bn>>sh) & NMASK;
142*327Sbill 		nb = bap[i];
143*327Sbill 		if(nb == 0) {
144*327Sbill 			printf("bn void %D\n",bn);
145*327Sbill 			return((daddr_t)0);
146*327Sbill 		}
147*327Sbill 	}
148*327Sbill 	return(nb);
149*327Sbill }
150*327Sbill 
151*327Sbill static ino_t
152*327Sbill dlook(s, io)
153*327Sbill char *s;
154*327Sbill register struct iob *io;
155*327Sbill {
156*327Sbill 	register struct direct *dp;
157*327Sbill 	register struct inode *ip;
158*327Sbill 	daddr_t bn;
159*327Sbill 	int n,dc;
160*327Sbill 
161*327Sbill 	if (s==NULL || *s=='\0')
162*327Sbill 		return(0);
163*327Sbill 	ip = &io->i_ino;
164*327Sbill 	if ((ip->i_mode&IFMT)!=IFDIR) {
165*327Sbill 		printf("not a directory\n");
166*327Sbill 		return(0);
167*327Sbill 	}
168*327Sbill 
169*327Sbill 	n = ip->i_size/sizeof(struct direct);
170*327Sbill 
171*327Sbill 	if (n==0) {
172*327Sbill 		printf("zero length directory\n");
173*327Sbill 		return(0);
174*327Sbill 	}
175*327Sbill 
176*327Sbill 	dc = BSIZE;
177*327Sbill 	bn = (daddr_t)0;
178*327Sbill 	while(n--) {
179*327Sbill 		if (++dc >= BSIZE/sizeof(struct direct)) {
180*327Sbill 			io->i_bn = fsbtodb(sbmap(io, bn++)) + io->i_boff;
181*327Sbill 			io->i_ma = io->i_buf;
182*327Sbill 			io->i_cc = BSIZE;
183*327Sbill 			devread(io);
184*327Sbill 			dp = (struct direct *)io->i_buf;
185*327Sbill 			dc = 0;
186*327Sbill 		}
187*327Sbill 
188*327Sbill 		if (match(s, dp->d_name))
189*327Sbill 			return(dp->d_ino);
190*327Sbill 		dp++;
191*327Sbill 	}
192*327Sbill 	return(0);
193*327Sbill }
194*327Sbill 
195*327Sbill static
196*327Sbill match(s1,s2)
197*327Sbill register char *s1,*s2;
198*327Sbill {
199*327Sbill 	register cc;
200*327Sbill 
201*327Sbill 	cc = DIRSIZ;
202*327Sbill 	while (cc--) {
203*327Sbill 		if (*s1 != *s2)
204*327Sbill 			return(0);
205*327Sbill 		if (*s1++ && *s2++)
206*327Sbill 			continue; else
207*327Sbill 			return(1);
208*327Sbill 	}
209*327Sbill 	return(1);
210*327Sbill }
211*327Sbill 
212*327Sbill lseek(fdesc, addr, ptr)
213*327Sbill int	fdesc;
214*327Sbill off_t	addr;
215*327Sbill int	ptr;
216*327Sbill {
217*327Sbill 	register struct iob *io;
218*327Sbill 
219*327Sbill 	if (ptr != 0) {
220*327Sbill 		printf("Seek not from beginning of file\n");
221*327Sbill 		return(-1);
222*327Sbill 	}
223*327Sbill 	fdesc -= 3;
224*327Sbill 	if (fdesc < 0 || fdesc >= NFILES || ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
225*327Sbill 		return(-1);
226*327Sbill 	io->i_offset = addr;
227*327Sbill 	io->i_bn = fsbtodb(addr/BSIZE) + io->i_boff;
228*327Sbill 	io->i_cc = 0;
229*327Sbill 	return(0);
230*327Sbill }
231*327Sbill 
232*327Sbill getc(fdesc)
233*327Sbill int	fdesc;
234*327Sbill {
235*327Sbill 	register struct iob *io;
236*327Sbill 	register char *p;
237*327Sbill 	register  c;
238*327Sbill 	int off;
239*327Sbill 
240*327Sbill 
241*327Sbill 	if (fdesc >= 0 && fdesc <= 2)
242*327Sbill 		return(getchar());
243*327Sbill 	fdesc -= 3;
244*327Sbill 	if (fdesc < 0 || fdesc >= NFILES || ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
245*327Sbill 		return(-1);
246*327Sbill 	p = io->i_ma;
247*327Sbill 	if (io->i_cc <= 0) {
248*327Sbill 		io->i_bn = fsbtodb(io->i_offset/(off_t)BSIZE);
249*327Sbill 		if (io->i_flgs&F_FILE)
250*327Sbill 			io->i_bn = fsbtodb(sbmap(io, dbtofsb(io->i_bn))) + io->i_boff;
251*327Sbill 		io->i_ma = io->i_buf;
252*327Sbill 		io->i_cc = BSIZE;
253*327Sbill 		devread(io);
254*327Sbill 		if (io->i_flgs&F_FILE) {
255*327Sbill 			off = io->i_offset % (off_t)BSIZE;
256*327Sbill 			if (io->i_offset+(BSIZE-off) >= io->i_ino.i_size)
257*327Sbill 				io->i_cc = io->i_ino.i_size - io->i_offset + off;
258*327Sbill 			io->i_cc -= off;
259*327Sbill 			if (io->i_cc <= 0)
260*327Sbill 				return(-1);
261*327Sbill 		} else
262*327Sbill 			off = 0;
263*327Sbill 		p = &io->i_buf[off];
264*327Sbill 	}
265*327Sbill 	io->i_cc--;
266*327Sbill 	io->i_offset++;
267*327Sbill 	c = (unsigned)*p++;
268*327Sbill 	io->i_ma = p;
269*327Sbill 	return(c);
270*327Sbill }
271*327Sbill /* does this port?
272*327Sbill getw(fdesc)
273*327Sbill int	fdesc;
274*327Sbill {
275*327Sbill 	register w,i;
276*327Sbill 	register char *cp;
277*327Sbill 	int val;
278*327Sbill 
279*327Sbill 	for (i = 0, val = 0, cp = &val; i < sizeof(val); i++) {
280*327Sbill 		w = getc(fdesc);
281*327Sbill 		if (w < 0) {
282*327Sbill 			if (i == 0)
283*327Sbill 				return(-1);
284*327Sbill 			else
285*327Sbill 				return(val);
286*327Sbill 		}
287*327Sbill 		*cp++ = w;
288*327Sbill 	}
289*327Sbill 	return(val);
290*327Sbill }
291*327Sbill */
292*327Sbill 
293*327Sbill read(fdesc, buf, count)
294*327Sbill int	fdesc;
295*327Sbill char	*buf;
296*327Sbill int	count;
297*327Sbill {
298*327Sbill 	register i;
299*327Sbill 	register struct iob *file;
300*327Sbill 
301*327Sbill 	if (fdesc >= 0 & fdesc <= 2) {
302*327Sbill 		i = count;
303*327Sbill 		do {
304*327Sbill 			*buf = getchar();
305*327Sbill 		} while (--i && *buf++ != '\n');
306*327Sbill 		return(count - i);
307*327Sbill 	}
308*327Sbill 	fdesc -= 3;
309*327Sbill 	if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
310*327Sbill 		return(-1);
311*327Sbill 	if ((file->i_flgs&F_READ) == 0)
312*327Sbill 		return(-1);
313*327Sbill 	if ((file->i_flgs&F_FILE) == 0) {
314*327Sbill 		file->i_cc = count;
315*327Sbill 		file->i_ma = buf;
316*327Sbill 		i = devread(file);
317*327Sbill 		file->i_bn += CLSIZE;
318*327Sbill 		return(i);
319*327Sbill 	}
320*327Sbill 	else {
321*327Sbill 		if (file->i_offset+count > file->i_ino.i_size)
322*327Sbill 			count = file->i_ino.i_size - file->i_offset;
323*327Sbill 		if ((i = count) <= 0)
324*327Sbill 			return(0);
325*327Sbill 		do {
326*327Sbill 			*buf++ = getc(fdesc+3);
327*327Sbill 		} while (--i);
328*327Sbill 		return(count);
329*327Sbill 	}
330*327Sbill }
331*327Sbill 
332*327Sbill write(fdesc, buf, count)
333*327Sbill int	fdesc;
334*327Sbill char	*buf;
335*327Sbill int	count;
336*327Sbill {
337*327Sbill 	register i;
338*327Sbill 	register struct iob *file;
339*327Sbill 
340*327Sbill 	if (fdesc >= 0 && fdesc <= 2) {
341*327Sbill 		i = count;
342*327Sbill 		while (i--)
343*327Sbill 			putchar(*buf++);
344*327Sbill 		return(count);
345*327Sbill 	}
346*327Sbill 	fdesc -= 3;
347*327Sbill 	if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
348*327Sbill 		return(-1);
349*327Sbill 	if ((file->i_flgs&F_WRITE) == 0)
350*327Sbill 		return(-1);
351*327Sbill 	file->i_cc = count;
352*327Sbill 	file->i_ma = buf;
353*327Sbill 	i = devwrite(file);
354*327Sbill 	file->i_bn += CLSIZE;
355*327Sbill 	return(i);
356*327Sbill }
357*327Sbill 
358*327Sbill open(str, how)
359*327Sbill char *str;
360*327Sbill int	how;
361*327Sbill {
362*327Sbill 	register char *cp;
363*327Sbill 	int i;
364*327Sbill 	register struct iob *file;
365*327Sbill 	register struct devsw *dp;
366*327Sbill 	int	fdesc;
367*327Sbill 	static first = 1;
368*327Sbill 	long	atol();
369*327Sbill 
370*327Sbill 	if (first) {
371*327Sbill 		for (i = 0; i < NFILES; i++)
372*327Sbill 			iob[i].i_flgs = 0;
373*327Sbill 		first = 0;
374*327Sbill 	}
375*327Sbill 
376*327Sbill 	for (fdesc = 0; fdesc < NFILES; fdesc++)
377*327Sbill 		if (iob[fdesc].i_flgs == 0)
378*327Sbill 			goto gotfile;
379*327Sbill 	_stop("No more file slots");
380*327Sbill gotfile:
381*327Sbill 	(file = &iob[fdesc])->i_flgs |= F_ALLOC;
382*327Sbill 
383*327Sbill 	for (cp = str; *cp && *cp != '('; cp++)
384*327Sbill 			;
385*327Sbill 	if (*cp != '(') {
386*327Sbill 		printf("Bad device\n");
387*327Sbill 		file->i_flgs = 0;
388*327Sbill 		return(-1);
389*327Sbill 	}
390*327Sbill 	*cp++ = '\0';
391*327Sbill 	for (dp = devsw; dp->dv_name; dp++) {
392*327Sbill 		if (match(str, dp->dv_name))
393*327Sbill 			goto gotdev;
394*327Sbill 	}
395*327Sbill 	printf("Unknown device\n");
396*327Sbill 	file->i_flgs = 0;
397*327Sbill 	return(-1);
398*327Sbill gotdev:
399*327Sbill 	*(cp-1) = '(';
400*327Sbill 	file->i_ino.i_dev = dp-devsw;
401*327Sbill 	file->i_unit = *cp++ - '0';
402*327Sbill 	if (file->i_unit < 0 || file->i_unit > 7) {
403*327Sbill 		printf("Bad unit specifier\n");
404*327Sbill 		file->i_flgs = 0;
405*327Sbill 		return(-1);
406*327Sbill 	}
407*327Sbill 	if (*cp++ != ',') {
408*327Sbill badoff:
409*327Sbill 		printf("Missing offset specification\n");
410*327Sbill 		file->i_flgs = 0;
411*327Sbill 		return(-1);
412*327Sbill 	}
413*327Sbill 	file->i_boff = atol(cp);
414*327Sbill 	for (;;) {
415*327Sbill 		if (*cp == ')')
416*327Sbill 			break;
417*327Sbill 		if (*cp++)
418*327Sbill 			continue;
419*327Sbill 		goto badoff;
420*327Sbill 	}
421*327Sbill 	devopen(file);
422*327Sbill 	if (*++cp == '\0') {
423*327Sbill 		file->i_flgs |= how+1;
424*327Sbill 		file->i_cc = 0;
425*327Sbill 		file->i_offset = 0;
426*327Sbill 		return(fdesc+3);
427*327Sbill 	}
428*327Sbill 	if ((i = find(cp, file)) == 0) {
429*327Sbill 		file->i_flgs = 0;
430*327Sbill 		return(-1);
431*327Sbill 	}
432*327Sbill 	if (how != 0) {
433*327Sbill 		printf("Can't write files yet.. Sorry\n");
434*327Sbill 		file->i_flgs = 0;
435*327Sbill 		return(-1);
436*327Sbill 	}
437*327Sbill 	openi(i, file);
438*327Sbill 	file->i_offset = 0;
439*327Sbill 	file->i_cc = 0;
440*327Sbill 	file->i_flgs |= F_FILE | (how+1);
441*327Sbill 	return(fdesc+3);
442*327Sbill }
443*327Sbill 
444*327Sbill close(fdesc)
445*327Sbill int	fdesc;
446*327Sbill {
447*327Sbill 	struct iob *file;
448*327Sbill 
449*327Sbill 	fdesc -= 3;
450*327Sbill 	if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
451*327Sbill 		return(-1);
452*327Sbill 	if ((file->i_flgs&F_FILE) == 0)
453*327Sbill 		devclose(file);
454*327Sbill 	file->i_flgs = 0;
455*327Sbill 	return(0);
456*327Sbill }
457*327Sbill 
458*327Sbill exit()
459*327Sbill {
460*327Sbill 	_stop("Exit called");
461*327Sbill }
462*327Sbill 
463*327Sbill _stop(s)
464*327Sbill char	*s;
465*327Sbill {
466*327Sbill 	printf("%s\n", s);
467*327Sbill 	_rtt();
468*327Sbill }
469*327Sbill 
470*327Sbill trap(ps)
471*327Sbill int ps;
472*327Sbill {
473*327Sbill 	printf("Trap %o\n", ps);
474*327Sbill 	for (;;)
475*327Sbill 		;
476*327Sbill }
477