xref: /csrg-svn/sys/stand.att/sys.c (revision 7446)
1*7446Sroot /*	sys.c	4.6	82/07/15	*/
2327Sbill 
36068Smckusic #include "../h/param.h"
46068Smckusic #include "../h/inode.h"
56068Smckusic #include "../h/fs.h"
6*7446Sroot #include "../h/dir.h"
7327Sbill #include "saio.h"
8327Sbill 
9327Sbill ino_t	dlook();
10327Sbill 
116068Smckusic struct dirstuff {
126068Smckusic 	int loc;
136068Smckusic 	struct iob *io;
146068Smckusic };
156068Smckusic 
16327Sbill static
17327Sbill openi(n,io)
186068Smckusic 	register struct iob *io;
19327Sbill {
20327Sbill 	register struct dinode *dp;
21327Sbill 
22327Sbill 	io->i_offset = 0;
236068Smckusic 	io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff;
246068Smckusic 	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;
286068Smckusic 	io->i_ino.i_ic = dp[itoo(&io->i_fs, n)].di_ic;
29327Sbill }
30327Sbill 
31327Sbill static
32327Sbill find(path, file)
336068Smckusic 	register char *path;
346068Smckusic 	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)
726068Smckusic 	register struct iob *io;
736068Smckusic 	daddr_t bn;
74327Sbill {
75327Sbill 	register struct inode *ip;
766068Smckusic 	int i, j, sh;
77327Sbill 	daddr_t nb, *bap;
78327Sbill 
79327Sbill 	ip = &io->i_ino;
806068Smckusic 	if (bn < 0) {
81327Sbill 		printf("bn negative\n");
82327Sbill 		return((daddr_t)0);
83327Sbill 	}
84327Sbill 
85327Sbill 	/*
866068Smckusic 	 * blocks 0..NDADDR are direct blocks
87327Sbill 	 */
886068Smckusic 	if(bn < NDADDR) {
896068Smckusic 		nb = ip->i_db[bn];
90327Sbill 		return(nb);
91327Sbill 	}
92327Sbill 
93327Sbill 	/*
946068Smckusic 	 * addresses NIADDR have single and double indirect blocks.
956068Smckusic 	 * the first step is to determine how many levels of indirection.
96327Sbill 	 */
976068Smckusic 	sh = 1;
986068Smckusic 	bn -= NDADDR;
996068Smckusic 	for (j = NIADDR; j > 0; j--) {
1006068Smckusic 		sh *= NINDIR(&io->i_fs);
1016068Smckusic 		if (bn < sh)
102327Sbill 			break;
1036068Smckusic 		bn -= sh;
104327Sbill 	}
1056068Smckusic 	if (j == 0) {
1066068Smckusic 		printf("bn ovf %D\n", bn);
1076068Smckusic 		return ((daddr_t)0);
108327Sbill 	}
109327Sbill 
110327Sbill 	/*
1116068Smckusic 	 * fetch the first indirect block address from the inode
112327Sbill 	 */
1136068Smckusic 	nb = ip->i_ib[NIADDR - j];
1146068Smckusic 	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 	 */
1226068Smckusic 	for (; j <= NIADDR; j++) {
123327Sbill 		if (blknos[j] != nb) {
1246068Smckusic 			io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff;
125327Sbill 			io->i_ma = b[j];
1266068Smckusic 			io->i_cc = io->i_fs.fs_bsize;
127327Sbill 			devread(io);
128327Sbill 			blknos[j] = nb;
129327Sbill 		}
130327Sbill 		bap = (daddr_t *)b[j];
1316068Smckusic 		sh /= NINDIR(&io->i_fs);
1326068Smckusic 		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)
1446068Smckusic 	char *s;
1456068Smckusic 	register struct iob *io;
146327Sbill {
147327Sbill 	register struct direct *dp;
148327Sbill 	register struct inode *ip;
1496068Smckusic 	struct dirstuff dirp;
1506068Smckusic 	int len;
151327Sbill 
1526068Smckusic 	if (s == NULL || *s == '\0')
153327Sbill 		return(0);
154327Sbill 	ip = &io->i_ino;
1556068Smckusic 	if ((ip->i_mode&IFMT) != IFDIR) {
156327Sbill 		printf("not a directory\n");
157327Sbill 		return(0);
158327Sbill 	}
1596068Smckusic 	if (ip->i_size == 0) {
160327Sbill 		printf("zero length directory\n");
161327Sbill 		return(0);
162327Sbill 	}
1636068Smckusic 	len = strlen(s);
1646068Smckusic 	dirp.loc = 0;
1656068Smckusic 	dirp.io = io;
1666068Smckusic 	for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
1676068Smckusic 		if(dp->d_ino == 0)
1686068Smckusic 			continue;
1696068Smckusic 		if (dp->d_namlen == len && !strcmp(s, dp->d_name))
170327Sbill 			return(dp->d_ino);
171327Sbill 	}
172327Sbill 	return(0);
173327Sbill }
174327Sbill 
1756068Smckusic /*
1766068Smckusic  * get next entry in a directory.
1776068Smckusic  */
1786068Smckusic struct direct *
1796068Smckusic readdir(dirp)
1806068Smckusic 	register struct dirstuff *dirp;
181327Sbill {
1826068Smckusic 	register struct direct *dp;
1836068Smckusic 	register struct iob *io;
1846068Smckusic 	daddr_t lbn, d;
1856068Smckusic 	int off;
186327Sbill 
1876068Smckusic 	io = dirp->io;
1886068Smckusic 	for(;;) {
1896068Smckusic 		if (dirp->loc >= io->i_ino.i_size)
1906068Smckusic 			return NULL;
1916068Smckusic 		off = blkoff(&io->i_fs, dirp->loc);
1926068Smckusic 		if (off == 0) {
1936068Smckusic 			lbn = lblkno(&io->i_fs, dirp->loc);
1946068Smckusic 			d = sbmap(io, lbn);
1956068Smckusic 			if(d == 0)
1966068Smckusic 				return NULL;
1976068Smckusic 			io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff;
1986068Smckusic 			io->i_ma = io->i_buf;
1996068Smckusic 			io->i_cc = blksize(&io->i_fs, &io->i_ino, lbn);
2006068Smckusic 			devread(io);
2016068Smckusic 		}
2026068Smckusic 		dp = (struct direct *)(io->i_buf + off);
2036068Smckusic 		dirp->loc += dp->d_reclen;
2046068Smckusic 		if (dp->d_ino == 0)
2056068Smckusic 			continue;
2066068Smckusic 		return (dp);
207327Sbill 	}
208327Sbill }
209327Sbill 
210327Sbill lseek(fdesc, addr, ptr)
2116068Smckusic 	int	fdesc;
2126068Smckusic 	off_t	addr;
2136068Smckusic 	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;
2226068Smckusic 	if (fdesc < 0 || fdesc >= NFILES ||
2236068Smckusic 	    ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0)
224327Sbill 		return(-1);
225327Sbill 	io->i_offset = addr;
2266068Smckusic 	io->i_bn = addr / DEV_BSIZE;
227327Sbill 	io->i_cc = 0;
228327Sbill 	return(0);
229327Sbill }
230327Sbill 
231327Sbill getc(fdesc)
2326068Smckusic 	int	fdesc;
233327Sbill {
234327Sbill 	register struct iob *io;
2356068Smckusic 	register struct fs *fs;
236327Sbill 	register char *p;
2376068Smckusic 	int c, lbn, off, size, diff;
238327Sbill 
239327Sbill 
240327Sbill 	if (fdesc >= 0 && fdesc <= 2)
241327Sbill 		return(getchar());
242327Sbill 	fdesc -= 3;
2436068Smckusic 	if (fdesc < 0 || fdesc >= NFILES ||
2446068Smckusic 	    ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
245327Sbill 		return(-1);
246327Sbill 	p = io->i_ma;
247327Sbill 	if (io->i_cc <= 0) {
2486068Smckusic 		if ((io->i_flgs & F_FILE) != 0) {
2496068Smckusic 			diff = io->i_ino.i_size - io->i_offset;
2506068Smckusic 			if (diff <= 0)
2516068Smckusic 				return (-1);
2526068Smckusic 			fs = &io->i_fs;
2536068Smckusic 			lbn = lblkno(fs, io->i_offset);
2546068Smckusic 			io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff;
2556068Smckusic 			off = blkoff(fs, io->i_offset);
2566068Smckusic 			size = blksize(fs, &io->i_ino, lbn);
2576068Smckusic 		} else {
2586068Smckusic 			io->i_bn = io->i_offset / DEV_BSIZE;
2596068Smckusic 			off = 0;
2606068Smckusic 			size = DEV_BSIZE;
2616068Smckusic 		}
262327Sbill 		io->i_ma = io->i_buf;
2636068Smckusic 		io->i_cc = size;
264327Sbill 		devread(io);
2656068Smckusic 		if ((io->i_flgs & F_FILE) != 0) {
2666068Smckusic 			if (io->i_offset - off + size >= io->i_ino.i_size)
2676068Smckusic 				io->i_cc = diff + off;
268327Sbill 			io->i_cc -= off;
2696068Smckusic 		}
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 }
2786068Smckusic 
279327Sbill /* does this port?
280327Sbill getw(fdesc)
2816068Smckusic 	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)
3026068Smckusic 	int	fdesc;
3036068Smckusic 	char	*buf;
3046068Smckusic 	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;
3176068Smckusic 	if (fdesc < 0 || fdesc >= NFILES ||
3186068Smckusic 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
319327Sbill 		return(-1);
320327Sbill 	if ((file->i_flgs&F_READ) == 0)
321327Sbill 		return(-1);
3226068Smckusic 	if ((file->i_flgs & F_FILE) == 0) {
323*7446Sroot 		if (count % DEV_BSIZE)
324*7446Sroot 			printf("count=%d?\n", count);
325327Sbill 		file->i_cc = count;
326327Sbill 		file->i_ma = buf;
327*7446Sroot 		file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
328327Sbill 		i = devread(file);
329*7446Sroot 		file->i_offset += count;
330327Sbill 		return(i);
3316068Smckusic 	} else {
332327Sbill 		if (file->i_offset+count > file->i_ino.i_size)
333327Sbill 			count = file->i_ino.i_size - file->i_offset;
334327Sbill 		if ((i = count) <= 0)
335327Sbill 			return(0);
336327Sbill 		do {
337327Sbill 			*buf++ = getc(fdesc+3);
338327Sbill 		} while (--i);
339327Sbill 		return(count);
340327Sbill 	}
341327Sbill }
342327Sbill 
343327Sbill write(fdesc, buf, count)
3446068Smckusic 	int	fdesc;
3456068Smckusic 	char	*buf;
3466068Smckusic 	int	count;
347327Sbill {
348327Sbill 	register i;
349327Sbill 	register struct iob *file;
350327Sbill 
351327Sbill 	if (fdesc >= 0 && fdesc <= 2) {
352327Sbill 		i = count;
353327Sbill 		while (i--)
354327Sbill 			putchar(*buf++);
355327Sbill 		return(count);
356327Sbill 	}
357327Sbill 	fdesc -= 3;
3586068Smckusic 	if (fdesc < 0 || fdesc >= NFILES ||
3596068Smckusic 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
360327Sbill 		return(-1);
361327Sbill 	if ((file->i_flgs&F_WRITE) == 0)
362327Sbill 		return(-1);
363*7446Sroot 	if (count % DEV_BSIZE)
364*7446Sroot 		printf("count=%d?\n", count);
365327Sbill 	file->i_cc = count;
366327Sbill 	file->i_ma = buf;
367*7446Sroot 	file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
368327Sbill 	i = devwrite(file);
369*7446Sroot 	file->i_offset += count;
370327Sbill 	return(i);
371327Sbill }
372327Sbill 
3733349Swnj int	openfirst = 1;
3743349Swnj 
375327Sbill open(str, how)
3766068Smckusic 	char *str;
3776068Smckusic 	int	how;
378327Sbill {
379327Sbill 	register char *cp;
380327Sbill 	int i;
381327Sbill 	register struct iob *file;
382327Sbill 	register struct devsw *dp;
383327Sbill 	int	fdesc;
384327Sbill 	long	atol();
385327Sbill 
3863349Swnj 	if (openfirst) {
387327Sbill 		for (i = 0; i < NFILES; i++)
388327Sbill 			iob[i].i_flgs = 0;
3893349Swnj 		openfirst = 0;
390327Sbill 	}
391327Sbill 
392327Sbill 	for (fdesc = 0; fdesc < NFILES; fdesc++)
393327Sbill 		if (iob[fdesc].i_flgs == 0)
394327Sbill 			goto gotfile;
395327Sbill 	_stop("No more file slots");
396327Sbill gotfile:
397327Sbill 	(file = &iob[fdesc])->i_flgs |= F_ALLOC;
398327Sbill 
399327Sbill 	for (cp = str; *cp && *cp != '('; cp++)
400327Sbill 			;
401327Sbill 	if (*cp != '(') {
402327Sbill 		printf("Bad device\n");
403327Sbill 		file->i_flgs = 0;
404327Sbill 		return(-1);
405327Sbill 	}
406327Sbill 	*cp++ = '\0';
407327Sbill 	for (dp = devsw; dp->dv_name; dp++) {
4086068Smckusic 		if (!strcmp(str, dp->dv_name))
409327Sbill 			goto gotdev;
410327Sbill 	}
411327Sbill 	printf("Unknown device\n");
412327Sbill 	file->i_flgs = 0;
413327Sbill 	return(-1);
414327Sbill gotdev:
415327Sbill 	*(cp-1) = '(';
416327Sbill 	file->i_ino.i_dev = dp-devsw;
417327Sbill 	file->i_unit = *cp++ - '0';
4183274Swnj 	if (*cp >= '0' && *cp <= '9')
4193274Swnj 		file->i_unit = file->i_unit * 10 + *cp++ - '0';
4203274Swnj 	if (file->i_unit < 0 || file->i_unit > 31) {
421327Sbill 		printf("Bad unit specifier\n");
422327Sbill 		file->i_flgs = 0;
423327Sbill 		return(-1);
424327Sbill 	}
425327Sbill 	if (*cp++ != ',') {
426327Sbill badoff:
427327Sbill 		printf("Missing offset specification\n");
428327Sbill 		file->i_flgs = 0;
429327Sbill 		return(-1);
430327Sbill 	}
431327Sbill 	file->i_boff = atol(cp);
432327Sbill 	for (;;) {
433327Sbill 		if (*cp == ')')
434327Sbill 			break;
435327Sbill 		if (*cp++)
436327Sbill 			continue;
437327Sbill 		goto badoff;
438327Sbill 	}
439327Sbill 	devopen(file);
440327Sbill 	if (*++cp == '\0') {
441327Sbill 		file->i_flgs |= how+1;
442327Sbill 		file->i_cc = 0;
443327Sbill 		file->i_offset = 0;
444327Sbill 		return(fdesc+3);
445327Sbill 	}
4466068Smckusic 	file->i_ma = (char *)(&file->i_fs);
4476068Smckusic 	file->i_cc = SBSIZE;
448*7446Sroot 	file->i_bn = SBLOCK + file->i_boff;
4496068Smckusic 	file->i_offset = 0;
4506068Smckusic 	devread(file);
451327Sbill 	if ((i = find(cp, file)) == 0) {
452327Sbill 		file->i_flgs = 0;
453327Sbill 		return(-1);
454327Sbill 	}
455327Sbill 	if (how != 0) {
456327Sbill 		printf("Can't write files yet.. Sorry\n");
457327Sbill 		file->i_flgs = 0;
458327Sbill 		return(-1);
459327Sbill 	}
460327Sbill 	openi(i, file);
461327Sbill 	file->i_offset = 0;
462327Sbill 	file->i_cc = 0;
463327Sbill 	file->i_flgs |= F_FILE | (how+1);
464327Sbill 	return(fdesc+3);
465327Sbill }
466327Sbill 
467327Sbill close(fdesc)
4686068Smckusic 	int	fdesc;
469327Sbill {
470327Sbill 	struct iob *file;
471327Sbill 
472327Sbill 	fdesc -= 3;
4736068Smckusic 	if (fdesc < 0 || fdesc >= NFILES ||
4746068Smckusic 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
475327Sbill 		return(-1);
476327Sbill 	if ((file->i_flgs&F_FILE) == 0)
477327Sbill 		devclose(file);
478327Sbill 	file->i_flgs = 0;
479327Sbill 	return(0);
480327Sbill }
481327Sbill 
482327Sbill exit()
483327Sbill {
484327Sbill 	_stop("Exit called");
485327Sbill }
486327Sbill 
487327Sbill _stop(s)
4886068Smckusic 	char	*s;
489327Sbill {
4902391Stoy 	int i;
4912391Stoy 
4922391Stoy 	for (i = 0; i < NFILES; i++)
4932391Stoy 		if (iob[i].i_flgs != 0)
4942391Stoy 			close(i);
495327Sbill 	printf("%s\n", s);
496327Sbill 	_rtt();
497327Sbill }
498327Sbill 
499327Sbill trap(ps)
5006068Smckusic 	int ps;
501327Sbill {
502327Sbill 	printf("Trap %o\n", ps);
503327Sbill 	for (;;)
504327Sbill 		;
505327Sbill }
506