xref: /csrg-svn/sys/stand.att/sys.c (revision 6068)
1*6068Smckusic /*	sys.c	4.5	82/03/07	*/
2327Sbill 
3*6068Smckusic #include "../h/param.h"
4*6068Smckusic #include "../h/inode.h"
5*6068Smckusic #include "../h/fs.h"
6*6068Smckusic #include "../h/ndir.h"
7327Sbill #include "saio.h"
8327Sbill 
9327Sbill ino_t	dlook();
10327Sbill 
11*6068Smckusic struct dirstuff {
12*6068Smckusic 	int loc;
13*6068Smckusic 	struct iob *io;
14*6068Smckusic };
15*6068Smckusic 
16327Sbill static
17327Sbill openi(n,io)
18*6068Smckusic 	register struct iob *io;
19327Sbill {
20327Sbill 	register struct dinode *dp;
21327Sbill 
22327Sbill 	io->i_offset = 0;
23*6068Smckusic 	io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff;
24*6068Smckusic 	io->i_cc = io->i_fs.fs_bsize;
25327Sbill 	io->i_ma = io->i_buf;
26327Sbill 	devread(io);
27327Sbill 	dp = (struct dinode *)io->i_buf;
28*6068Smckusic 	io->i_ino.i_ic = dp[itoo(&io->i_fs, n)].di_ic;
29327Sbill }
30327Sbill 
31327Sbill static
32327Sbill find(path, file)
33*6068Smckusic 	register char *path;
34*6068Smckusic 	struct iob *file;
35327Sbill {
36327Sbill 	register char *q;
37327Sbill 	char c;
38327Sbill 	int n;
39327Sbill 
40327Sbill 	if (path==NULL || *path=='\0') {
41327Sbill 		printf("null path\n");
42327Sbill 		return(0);
43327Sbill 	}
44327Sbill 
45327Sbill 	openi((ino_t) ROOTINO, file);
46327Sbill 	while (*path) {
47327Sbill 		while (*path == '/')
48327Sbill 			path++;
49327Sbill 		q = path;
50327Sbill 		while(*q != '/' && *q != '\0')
51327Sbill 			q++;
52327Sbill 		c = *q;
53327Sbill 		*q = '\0';
54327Sbill 
55327Sbill 		if ((n=dlook(path, file))!=0) {
56327Sbill 			if (c=='\0')
57327Sbill 				break;
58327Sbill 			openi(n, file);
59327Sbill 			*q = c;
60327Sbill 			path = q;
61327Sbill 			continue;
62327Sbill 		} else {
63327Sbill 			printf("%s not found\n",path);
64327Sbill 			return(0);
65327Sbill 		}
66327Sbill 	}
67327Sbill 	return(n);
68327Sbill }
69327Sbill 
70327Sbill static daddr_t
71327Sbill sbmap(io, bn)
72*6068Smckusic 	register struct iob *io;
73*6068Smckusic 	daddr_t bn;
74327Sbill {
75327Sbill 	register struct inode *ip;
76*6068Smckusic 	int i, j, sh;
77327Sbill 	daddr_t nb, *bap;
78327Sbill 
79327Sbill 	ip = &io->i_ino;
80*6068Smckusic 	if (bn < 0) {
81327Sbill 		printf("bn negative\n");
82327Sbill 		return((daddr_t)0);
83327Sbill 	}
84327Sbill 
85327Sbill 	/*
86*6068Smckusic 	 * blocks 0..NDADDR are direct blocks
87327Sbill 	 */
88*6068Smckusic 	if(bn < NDADDR) {
89*6068Smckusic 		nb = ip->i_db[bn];
90327Sbill 		return(nb);
91327Sbill 	}
92327Sbill 
93327Sbill 	/*
94*6068Smckusic 	 * addresses NIADDR have single and double indirect blocks.
95*6068Smckusic 	 * the first step is to determine how many levels of indirection.
96327Sbill 	 */
97*6068Smckusic 	sh = 1;
98*6068Smckusic 	bn -= NDADDR;
99*6068Smckusic 	for (j = NIADDR; j > 0; j--) {
100*6068Smckusic 		sh *= NINDIR(&io->i_fs);
101*6068Smckusic 		if (bn < sh)
102327Sbill 			break;
103*6068Smckusic 		bn -= sh;
104327Sbill 	}
105*6068Smckusic 	if (j == 0) {
106*6068Smckusic 		printf("bn ovf %D\n", bn);
107*6068Smckusic 		return ((daddr_t)0);
108327Sbill 	}
109327Sbill 
110327Sbill 	/*
111*6068Smckusic 	 * fetch the first indirect block address from the inode
112327Sbill 	 */
113*6068Smckusic 	nb = ip->i_ib[NIADDR - j];
114*6068Smckusic 	if (nb == 0) {
115327Sbill 		printf("bn void %D\n",bn);
116327Sbill 		return((daddr_t)0);
117327Sbill 	}
118327Sbill 
119327Sbill 	/*
120327Sbill 	 * fetch through the indirect blocks
121327Sbill 	 */
122*6068Smckusic 	for (; j <= NIADDR; j++) {
123327Sbill 		if (blknos[j] != nb) {
124*6068Smckusic 			io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff;
125327Sbill 			io->i_ma = b[j];
126*6068Smckusic 			io->i_cc = io->i_fs.fs_bsize;
127327Sbill 			devread(io);
128327Sbill 			blknos[j] = nb;
129327Sbill 		}
130327Sbill 		bap = (daddr_t *)b[j];
131*6068Smckusic 		sh /= NINDIR(&io->i_fs);
132*6068Smckusic 		i = (bn / sh) % NINDIR(&io->i_fs);
133327Sbill 		nb = bap[i];
134327Sbill 		if(nb == 0) {
135327Sbill 			printf("bn void %D\n",bn);
136327Sbill 			return((daddr_t)0);
137327Sbill 		}
138327Sbill 	}
139327Sbill 	return(nb);
140327Sbill }
141327Sbill 
142327Sbill static ino_t
143327Sbill dlook(s, io)
144*6068Smckusic 	char *s;
145*6068Smckusic 	register struct iob *io;
146327Sbill {
147327Sbill 	register struct direct *dp;
148327Sbill 	register struct inode *ip;
149*6068Smckusic 	struct dirstuff dirp;
150*6068Smckusic 	int len;
151327Sbill 
152*6068Smckusic 	if (s == NULL || *s == '\0')
153327Sbill 		return(0);
154327Sbill 	ip = &io->i_ino;
155*6068Smckusic 	if ((ip->i_mode&IFMT) != IFDIR) {
156327Sbill 		printf("not a directory\n");
157327Sbill 		return(0);
158327Sbill 	}
159*6068Smckusic 	if (ip->i_size == 0) {
160327Sbill 		printf("zero length directory\n");
161327Sbill 		return(0);
162327Sbill 	}
163*6068Smckusic 	len = strlen(s);
164*6068Smckusic 	dirp.loc = 0;
165*6068Smckusic 	dirp.io = io;
166*6068Smckusic 	for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
167*6068Smckusic 		if(dp->d_ino == 0)
168*6068Smckusic 			continue;
169*6068Smckusic 		if (dp->d_namlen == len && !strcmp(s, dp->d_name))
170327Sbill 			return(dp->d_ino);
171327Sbill 	}
172327Sbill 	return(0);
173327Sbill }
174327Sbill 
175*6068Smckusic /*
176*6068Smckusic  * get next entry in a directory.
177*6068Smckusic  */
178*6068Smckusic struct direct *
179*6068Smckusic readdir(dirp)
180*6068Smckusic 	register struct dirstuff *dirp;
181327Sbill {
182*6068Smckusic 	register struct direct *dp;
183*6068Smckusic 	register struct iob *io;
184*6068Smckusic 	daddr_t lbn, d;
185*6068Smckusic 	int off;
186327Sbill 
187*6068Smckusic 	io = dirp->io;
188*6068Smckusic 	for(;;) {
189*6068Smckusic 		if (dirp->loc >= io->i_ino.i_size)
190*6068Smckusic 			return NULL;
191*6068Smckusic 		off = blkoff(&io->i_fs, dirp->loc);
192*6068Smckusic 		if (off == 0) {
193*6068Smckusic 			lbn = lblkno(&io->i_fs, dirp->loc);
194*6068Smckusic 			d = sbmap(io, lbn);
195*6068Smckusic 			if(d == 0)
196*6068Smckusic 				return NULL;
197*6068Smckusic 			io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff;
198*6068Smckusic 			io->i_ma = io->i_buf;
199*6068Smckusic 			io->i_cc = blksize(&io->i_fs, &io->i_ino, lbn);
200*6068Smckusic 			devread(io);
201*6068Smckusic 		}
202*6068Smckusic 		dp = (struct direct *)(io->i_buf + off);
203*6068Smckusic 		dirp->loc += dp->d_reclen;
204*6068Smckusic 		if (dp->d_ino == 0)
205*6068Smckusic 			continue;
206*6068Smckusic 		return (dp);
207327Sbill 	}
208327Sbill }
209327Sbill 
210327Sbill lseek(fdesc, addr, ptr)
211*6068Smckusic 	int	fdesc;
212*6068Smckusic 	off_t	addr;
213*6068Smckusic 	int	ptr;
214327Sbill {
215327Sbill 	register struct iob *io;
216327Sbill 
217327Sbill 	if (ptr != 0) {
218327Sbill 		printf("Seek not from beginning of file\n");
219327Sbill 		return(-1);
220327Sbill 	}
221327Sbill 	fdesc -= 3;
222*6068Smckusic 	if (fdesc < 0 || fdesc >= NFILES ||
223*6068Smckusic 	    ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0)
224327Sbill 		return(-1);
225327Sbill 	io->i_offset = addr;
226*6068Smckusic 	io->i_bn = addr / DEV_BSIZE;
227327Sbill 	io->i_cc = 0;
228327Sbill 	return(0);
229327Sbill }
230327Sbill 
231327Sbill getc(fdesc)
232*6068Smckusic 	int	fdesc;
233327Sbill {
234327Sbill 	register struct iob *io;
235*6068Smckusic 	register struct fs *fs;
236327Sbill 	register char *p;
237*6068Smckusic 	int c, lbn, off, size, diff;
238327Sbill 
239327Sbill 
240327Sbill 	if (fdesc >= 0 && fdesc <= 2)
241327Sbill 		return(getchar());
242327Sbill 	fdesc -= 3;
243*6068Smckusic 	if (fdesc < 0 || fdesc >= NFILES ||
244*6068Smckusic 	    ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
245327Sbill 		return(-1);
246327Sbill 	p = io->i_ma;
247327Sbill 	if (io->i_cc <= 0) {
248*6068Smckusic 		if ((io->i_flgs & F_FILE) != 0) {
249*6068Smckusic 			diff = io->i_ino.i_size - io->i_offset;
250*6068Smckusic 			if (diff <= 0)
251*6068Smckusic 				return (-1);
252*6068Smckusic 			fs = &io->i_fs;
253*6068Smckusic 			lbn = lblkno(fs, io->i_offset);
254*6068Smckusic 			io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff;
255*6068Smckusic 			off = blkoff(fs, io->i_offset);
256*6068Smckusic 			size = blksize(fs, &io->i_ino, lbn);
257*6068Smckusic 		} else {
258*6068Smckusic 			io->i_bn = io->i_offset / DEV_BSIZE;
259*6068Smckusic 			off = 0;
260*6068Smckusic 			size = DEV_BSIZE;
261*6068Smckusic 		}
262327Sbill 		io->i_ma = io->i_buf;
263*6068Smckusic 		io->i_cc = size;
264327Sbill 		devread(io);
265*6068Smckusic 		if ((io->i_flgs & F_FILE) != 0) {
266*6068Smckusic 			if (io->i_offset - off + size >= io->i_ino.i_size)
267*6068Smckusic 				io->i_cc = diff + off;
268327Sbill 			io->i_cc -= off;
269*6068Smckusic 		}
270327Sbill 		p = &io->i_buf[off];
271327Sbill 	}
272327Sbill 	io->i_cc--;
273327Sbill 	io->i_offset++;
274327Sbill 	c = (unsigned)*p++;
275327Sbill 	io->i_ma = p;
276327Sbill 	return(c);
277327Sbill }
278*6068Smckusic 
279327Sbill /* does this port?
280327Sbill getw(fdesc)
281*6068Smckusic 	int	fdesc;
282327Sbill {
283327Sbill 	register w,i;
284327Sbill 	register char *cp;
285327Sbill 	int val;
286327Sbill 
287327Sbill 	for (i = 0, val = 0, cp = &val; i < sizeof(val); i++) {
288327Sbill 		w = getc(fdesc);
289327Sbill 		if (w < 0) {
290327Sbill 			if (i == 0)
291327Sbill 				return(-1);
292327Sbill 			else
293327Sbill 				return(val);
294327Sbill 		}
295327Sbill 		*cp++ = w;
296327Sbill 	}
297327Sbill 	return(val);
298327Sbill }
299327Sbill */
300327Sbill 
301327Sbill read(fdesc, buf, count)
302*6068Smckusic 	int	fdesc;
303*6068Smckusic 	char	*buf;
304*6068Smckusic 	int	count;
305327Sbill {
306327Sbill 	register i;
307327Sbill 	register struct iob *file;
308327Sbill 
309327Sbill 	if (fdesc >= 0 & fdesc <= 2) {
310327Sbill 		i = count;
311327Sbill 		do {
312327Sbill 			*buf = getchar();
313327Sbill 		} while (--i && *buf++ != '\n');
314327Sbill 		return(count - i);
315327Sbill 	}
316327Sbill 	fdesc -= 3;
317*6068Smckusic 	if (fdesc < 0 || fdesc >= NFILES ||
318*6068Smckusic 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
319327Sbill 		return(-1);
320327Sbill 	if ((file->i_flgs&F_READ) == 0)
321327Sbill 		return(-1);
322*6068Smckusic 	if ((file->i_flgs & F_FILE) == 0) {
323327Sbill 		file->i_cc = count;
324327Sbill 		file->i_ma = buf;
325327Sbill 		i = devread(file);
326*6068Smckusic 		file->i_bn += (count / DEV_BSIZE);
327327Sbill 		return(i);
328*6068Smckusic 	} else {
329327Sbill 		if (file->i_offset+count > file->i_ino.i_size)
330327Sbill 			count = file->i_ino.i_size - file->i_offset;
331327Sbill 		if ((i = count) <= 0)
332327Sbill 			return(0);
333327Sbill 		do {
334327Sbill 			*buf++ = getc(fdesc+3);
335327Sbill 		} while (--i);
336327Sbill 		return(count);
337327Sbill 	}
338327Sbill }
339327Sbill 
340327Sbill write(fdesc, buf, count)
341*6068Smckusic 	int	fdesc;
342*6068Smckusic 	char	*buf;
343*6068Smckusic 	int	count;
344327Sbill {
345327Sbill 	register i;
346327Sbill 	register struct iob *file;
347327Sbill 
348327Sbill 	if (fdesc >= 0 && fdesc <= 2) {
349327Sbill 		i = count;
350327Sbill 		while (i--)
351327Sbill 			putchar(*buf++);
352327Sbill 		return(count);
353327Sbill 	}
354327Sbill 	fdesc -= 3;
355*6068Smckusic 	if (fdesc < 0 || fdesc >= NFILES ||
356*6068Smckusic 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
357327Sbill 		return(-1);
358327Sbill 	if ((file->i_flgs&F_WRITE) == 0)
359327Sbill 		return(-1);
360327Sbill 	file->i_cc = count;
361327Sbill 	file->i_ma = buf;
362327Sbill 	i = devwrite(file);
363*6068Smckusic 	file->i_bn += (count / DEV_BSIZE);
364327Sbill 	return(i);
365327Sbill }
366327Sbill 
3673349Swnj int	openfirst = 1;
3683349Swnj 
369327Sbill open(str, how)
370*6068Smckusic 	char *str;
371*6068Smckusic 	int	how;
372327Sbill {
373327Sbill 	register char *cp;
374327Sbill 	int i;
375327Sbill 	register struct iob *file;
376327Sbill 	register struct devsw *dp;
377327Sbill 	int	fdesc;
378327Sbill 	long	atol();
379327Sbill 
3803349Swnj 	if (openfirst) {
381327Sbill 		for (i = 0; i < NFILES; i++)
382327Sbill 			iob[i].i_flgs = 0;
3833349Swnj 		openfirst = 0;
384327Sbill 	}
385327Sbill 
386327Sbill 	for (fdesc = 0; fdesc < NFILES; fdesc++)
387327Sbill 		if (iob[fdesc].i_flgs == 0)
388327Sbill 			goto gotfile;
389327Sbill 	_stop("No more file slots");
390327Sbill gotfile:
391327Sbill 	(file = &iob[fdesc])->i_flgs |= F_ALLOC;
392327Sbill 
393327Sbill 	for (cp = str; *cp && *cp != '('; cp++)
394327Sbill 			;
395327Sbill 	if (*cp != '(') {
396327Sbill 		printf("Bad device\n");
397327Sbill 		file->i_flgs = 0;
398327Sbill 		return(-1);
399327Sbill 	}
400327Sbill 	*cp++ = '\0';
401327Sbill 	for (dp = devsw; dp->dv_name; dp++) {
402*6068Smckusic 		if (!strcmp(str, dp->dv_name))
403327Sbill 			goto gotdev;
404327Sbill 	}
405327Sbill 	printf("Unknown device\n");
406327Sbill 	file->i_flgs = 0;
407327Sbill 	return(-1);
408327Sbill gotdev:
409327Sbill 	*(cp-1) = '(';
410327Sbill 	file->i_ino.i_dev = dp-devsw;
411327Sbill 	file->i_unit = *cp++ - '0';
4123274Swnj 	if (*cp >= '0' && *cp <= '9')
4133274Swnj 		file->i_unit = file->i_unit * 10 + *cp++ - '0';
4143274Swnj 	if (file->i_unit < 0 || file->i_unit > 31) {
415327Sbill 		printf("Bad unit specifier\n");
416327Sbill 		file->i_flgs = 0;
417327Sbill 		return(-1);
418327Sbill 	}
419327Sbill 	if (*cp++ != ',') {
420327Sbill badoff:
421327Sbill 		printf("Missing offset specification\n");
422327Sbill 		file->i_flgs = 0;
423327Sbill 		return(-1);
424327Sbill 	}
425327Sbill 	file->i_boff = atol(cp);
426327Sbill 	for (;;) {
427327Sbill 		if (*cp == ')')
428327Sbill 			break;
429327Sbill 		if (*cp++)
430327Sbill 			continue;
431327Sbill 		goto badoff;
432327Sbill 	}
433327Sbill 	devopen(file);
434327Sbill 	if (*++cp == '\0') {
435327Sbill 		file->i_flgs |= how+1;
436327Sbill 		file->i_cc = 0;
437327Sbill 		file->i_offset = 0;
438327Sbill 		return(fdesc+3);
439327Sbill 	}
440*6068Smckusic 	file->i_ma = (char *)(&file->i_fs);
441*6068Smckusic 	file->i_cc = SBSIZE;
442*6068Smckusic 	file->i_bn = SBLOCK;
443*6068Smckusic 	file->i_offset = 0;
444*6068Smckusic 	devread(file);
445327Sbill 	if ((i = find(cp, file)) == 0) {
446327Sbill 		file->i_flgs = 0;
447327Sbill 		return(-1);
448327Sbill 	}
449327Sbill 	if (how != 0) {
450327Sbill 		printf("Can't write files yet.. Sorry\n");
451327Sbill 		file->i_flgs = 0;
452327Sbill 		return(-1);
453327Sbill 	}
454327Sbill 	openi(i, file);
455327Sbill 	file->i_offset = 0;
456327Sbill 	file->i_cc = 0;
457327Sbill 	file->i_flgs |= F_FILE | (how+1);
458327Sbill 	return(fdesc+3);
459327Sbill }
460327Sbill 
461327Sbill close(fdesc)
462*6068Smckusic 	int	fdesc;
463327Sbill {
464327Sbill 	struct iob *file;
465327Sbill 
466327Sbill 	fdesc -= 3;
467*6068Smckusic 	if (fdesc < 0 || fdesc >= NFILES ||
468*6068Smckusic 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
469327Sbill 		return(-1);
470327Sbill 	if ((file->i_flgs&F_FILE) == 0)
471327Sbill 		devclose(file);
472327Sbill 	file->i_flgs = 0;
473327Sbill 	return(0);
474327Sbill }
475327Sbill 
476327Sbill exit()
477327Sbill {
478327Sbill 	_stop("Exit called");
479327Sbill }
480327Sbill 
481327Sbill _stop(s)
482*6068Smckusic 	char	*s;
483327Sbill {
4842391Stoy 	int i;
4852391Stoy 
4862391Stoy 	for (i = 0; i < NFILES; i++)
4872391Stoy 		if (iob[i].i_flgs != 0)
4882391Stoy 			close(i);
489327Sbill 	printf("%s\n", s);
490327Sbill 	_rtt();
491327Sbill }
492327Sbill 
493327Sbill trap(ps)
494*6068Smckusic 	int ps;
495327Sbill {
496327Sbill 	printf("Trap %o\n", ps);
497327Sbill 	for (;;)
498327Sbill 		;
499327Sbill }
500